Bug Summary

File:weather-sun.c
Warning:line 165, column 13
Value stored to 'obsLon' during its initialization is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name weather-sun.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/libcafeweather -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I .. -I /usr/include/ctk-3.0 -I /usr/include/pango-1.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/harfbuzz -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/fribidi -I /usr/include/cairo -I /usr/include/pixman-1 -I /usr/include/gdk-pixbuf-2.0 -I /usr/include/x86_64-linux-gnu -I /usr/include/webp -I /usr/include/gio-unix-2.0 -I /usr/include/atk-1.0 -I /usr/include/at-spi2-atk/2.0 -I /usr/include/at-spi-2.0 -I /usr/include/dbus-1.0 -I /usr/lib/x86_64-linux-gnu/dbus-1.0/include -I .. -I . -I /usr/include/libxml2 -I /usr/include/libsoup-3.0 -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/libmount -I /usr/include/blkid -I /usr/include/glib-2.0 -I /usr/lib/x86_64-linux-gnu/glib-2.0/include -I /usr/include/sysprof-6 -I /usr/include/libmount -I /usr/include/blkid -D G_LOG_DOMAIN="CafeWeather" -D CAFELOCALEDIR="/usr/share/locale" -D CAFEWEATHER_XML_LOCATION_DIR="/usr/share/libcafeweather" -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/libcafeweather -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-08-25-170056-14500-1 -x c weather-sun.c
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
2/* weather-sun.c - Astronomy calculations for cafeweather
3 *
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, see
16 * <http://www.gnu.org/licenses/>.
17 */
18
19/*
20 * Formulas from:
21 * "Practical Astronomy With Your Calculator" (3e), Peter Duffett-Smith
22 * Cambridge University Press 1988
23 * Unless otherwise noted, comments referencing "steps" are related to
24 * the algorithm presented in section 49 of above
25 */
26
27#ifdef HAVE_CONFIG_H1
28#include <config.h>
29#endif
30
31#include <math.h>
32#include <time.h>
33#include <glib.h>
34
35#define CAFEWEATHER_I_KNOW_THIS_IS_UNSTABLE
36#include "weather-priv.h"
37
38#define ECCENTRICITY(d)(0.01671123 - (d)/36525.*0.00004392) (0.01671123 - (d)/36525.*0.00004392)
39
40/*
41 * Ecliptic longitude of the sun at specified time (UT)
42 * The algoithm is described in section 47 of Duffett-Smith
43 * Return value is in radians
44 */
45gdouble
46sunEclipLongitude(time_t t)
47{
48 gdouble ndays, meanAnom, eccenAnom, delta, e, longitude;
49
50 /*
51 * Start with an esticafe based on a fixed daily rate
52 */
53 ndays = EPOCH_TO_J2000(t)((gdouble)(t)-946727935.816) / 86400.;
54 meanAnom = DEGREES_TO_RADIANS(MEAN_ECLIPTIC_LONGITUDE(ndays)((fmod (((280.46457166 + (ndays)/36525.*35999.37244981) - (282.93768193
+ (ndays)/36525.*0.32327364)),360.) / 180.) * 3.14159265358979323846
)
55 - PERIGEE_LONGITUDE(ndays))((fmod (((280.46457166 + (ndays)/36525.*35999.37244981) - (282.93768193
+ (ndays)/36525.*0.32327364)),360.) / 180.) * 3.14159265358979323846
)
;
56
57 /*
58 * Approximate solution of Kepler's equation:
59 * Find E which satisfies E - e sin(E) = M (mean anomaly)
60 */
61 eccenAnom = meanAnom;
62 e = ECCENTRICITY(ndays)(0.01671123 - (ndays)/36525.*0.00004392);
63
64 while (1e-12 < fabs( delta = eccenAnom - e * sin(eccenAnom) - meanAnom))
65 {
66 eccenAnom -= delta / (1.- e * cos(eccenAnom));
67 }
68
69 /*
70 * Earth's longitude on the ecliptic
71 */
72 longitude = fmod( DEGREES_TO_RADIANS (PERIGEE_LONGITUDE(ndays))((fmod (((282.93768193 + (ndays)/36525.*0.32327364)),360.) / 180.
) * 3.14159265358979323846)
73 + 2. * atan (sqrt ((1.+e)/(1.-e))
74 * tan (eccenAnom / 2.)),
75 2. * M_PI3.14159265358979323846);
76 if (longitude < 0.) {
77 longitude += 2 * M_PI3.14159265358979323846;
78 }
79 return longitude;
80}
81
82static gdouble
83ecliptic_obliquity (gdouble time)
84{
85 gdouble jc = EPOCH_TO_J2000 (time)((gdouble)(time)-946727935.816) / (36525. * 86400.);
86 gdouble eclip_secs = (84381.448
87 - (46.84024 * jc)
88 - (59.e-5 * jc * jc)
89 + (1.813e-3 * jc * jc * jc));
90 return DEGREES_TO_RADIANS(eclip_secs / 3600.)((fmod ((eclip_secs / 3600.),360.) / 180.) * 3.14159265358979323846
)
;
91}
92
93/*
94 * Convert ecliptic longitude and latitude (radians) to equitorial
95 * coordinates, expressed as right ascension (hours) and
96 * declination (radians)
97 */
98void
99ecl2equ (gdouble time,
100 gdouble eclipLon, gdouble eclipLat,
101 gdouble *ra, gdouble *decl)
102{
103 gdouble mEclipObliq = ecliptic_obliquity(time);
104
105 if (ra) {
106 *ra = RADIANS_TO_HOURS (atan2 ((sin (eclipLon) * cos (mEclipObliq)((atan2 ((sin (eclipLon) * cos (mEclipObliq) - tan (eclipLat)
* sin(mEclipObliq)), cos (eclipLon))) * 12. / 3.14159265358979323846
)
107 - tan (eclipLat) * sin(mEclipObliq)),((atan2 ((sin (eclipLon) * cos (mEclipObliq) - tan (eclipLat)
* sin(mEclipObliq)), cos (eclipLon))) * 12. / 3.14159265358979323846
)
108 cos (eclipLon)))((atan2 ((sin (eclipLon) * cos (mEclipObliq) - tan (eclipLat)
* sin(mEclipObliq)), cos (eclipLon))) * 12. / 3.14159265358979323846
)
;
109 if (*ra < 0.)
110 *ra += 24.;
111 }
112 if (decl) {
113 *decl = asin (( sin (eclipLat) * cos (mEclipObliq))
114 + cos (eclipLat) * sin (mEclipObliq) * sin(eclipLon));
115 }
116}
117
118/*
119 * Calculate rising and setting times for an object
120 * based on it equitorial coordinates (section 33 & 15)
121 * Returned "rise" and "set" values are sideral times in hours
122 */
123static void
124gstObsv (gdouble ra, gdouble decl,
125 gdouble obsLat, gdouble obsLon,
126 gdouble *rise, gdouble *set)
127{
128 double a = acos (-tan (obsLat) * tan (decl));
129 double b;
130
131 if (isnan (a)__builtin_isnan (a) != 0) {
132 *set = *rise = a;
133 return;
134 }
135 a = RADIANS_TO_HOURS (a)((a) * 12. / 3.14159265358979323846);
136 b = 24. - a + ra;
137 a += ra;
138 a -= RADIANS_TO_HOURS (obsLon)((obsLon) * 12. / 3.14159265358979323846);
139 b -= RADIANS_TO_HOURS (obsLon)((obsLon) * 12. / 3.14159265358979323846);
140 if ((a = fmod (a, 24.)) < 0)
141 a += 24.;
142 if ((b = fmod (b, 24.)) < 0)
143 b += 24.;
144
145 *set = a;
146 *rise = b;
147}
148
149
150static gdouble
151t0 (time_t date)
152{
153 gdouble t = ((gdouble)(EPOCH_TO_J2000 (date)((gdouble)(date)-946727935.816) / 86400)) / 36525.0;
154 gdouble t0 = fmod (6.697374558 + 2400.051366 * t + 2.5862e-5 * t * t, 24.);
155 if (t0 < 0.)
156 t0 += 24.;
157 return t0;
158}
159
160
161static gboolean
162calc_sun2 (WeatherInfo *info, time_t t)
163{
164 gdouble obsLat = info->location->latitude;
165 gdouble obsLon = info->location->longitude;
Value stored to 'obsLon' during its initialization is never read
166 time_t gm_midn;
167 time_t lcl_midn;
168 gdouble gm_hoff, lambda;
169 gdouble ra1, ra2;
170 gdouble decl1, decl2;
171 gdouble decl_midn, decl_noon;
172 gdouble rise1, rise2;
173 gdouble set1, set2;
174 gdouble tt, t00;
175 gdouble x, u, dt;
176
177 /* Approximate preceding local midnight at observer's longitude */
178 obsLat = info->location->latitude;
179 obsLon = info->location->longitude;
180 gm_midn = t - (t % 86400);
181 gm_hoff = floor ((RADIANS_TO_DEGREES (obsLon)((obsLon) * 180. / 3.14159265358979323846) + 7.5) / 15.);
182 lcl_midn = gm_midn - 3600. * gm_hoff;
183 if (t - lcl_midn >= 86400)
184 lcl_midn += 86400;
185 else if (lcl_midn > t)
186 lcl_midn -= 86400;
187
188 lambda = sunEclipLongitude (lcl_midn);
189
190 /*
191 * Calculate equitorial coordinates of sun at previous
192 * and next local midnights
193 */
194 ecl2equ (lcl_midn, lambda, 0., &ra1, &decl1);
195 ecl2equ (lcl_midn + 86400.,
196 lambda + DEGREES_TO_RADIANS(SOL_PROGRESSION)((fmod (((360./365.242191)),360.) / 180.) * 3.14159265358979323846
)
, 0.,
197 &ra2, &decl2);
198
199 /*
200 * If the observer is within the Arctic or Antarctic Circles then
201 * the sun may be above or below the horizon for the full day.
202 */
203 decl_midn = MIN(decl1,decl2)(((decl1) < (decl2)) ? (decl1) : (decl2));
204 decl_noon = (decl1+decl2)/2.;
205 info->midnightSun =
206 (obsLat > (M_PI3.14159265358979323846/2.-decl_midn)) || (obsLat < (-M_PI3.14159265358979323846/2.-decl_midn));
207 info->polarNight =
208 (obsLat > (M_PI3.14159265358979323846/2.+decl_noon)) || (obsLat < (-M_PI3.14159265358979323846/2.+decl_noon));
209 if (info->midnightSun || info->polarNight) {
210 info->sunriseValid = info->sunsetValid = FALSE(0);
211 return FALSE(0);
212 }
213
214 /*
215 * Convert to rise and set times based positions for the preceding
216 * and following local midnights.
217 */
218 gstObsv (ra1, decl1, obsLat, obsLon - (gm_hoff * M_PI3.14159265358979323846 / 12.), &rise1, &set1);
219 gstObsv (ra2, decl2, obsLat, obsLon - (gm_hoff * M_PI3.14159265358979323846 / 12.), &rise2, &set2);
220
221 /* TODO: include calculations for regions near the poles. */
222 if (isnan(rise1)__builtin_isnan (rise1) || isnan(rise2)__builtin_isnan (rise2)) {
223 info->sunriseValid = info->sunsetValid = FALSE(0);
224 return FALSE(0);
225 }
226
227 if (rise2 < rise1) {
228 rise2 += 24.;
229 }
230 if (set2 < set1) {
231 set2 += 24.;
232 }
233
234 tt = t0(lcl_midn);
235 t00 = tt - (gm_hoff + RADIANS_TO_HOURS(obsLon)((obsLon) * 12. / 3.14159265358979323846)) * 1.002737909;
236
237 if (t00 < 0.)
238 t00 += 24.;
239
240 if (rise1 < t00) {
241 rise1 += 24.;
242 rise2 += 24.;
243 }
244 if (set1 < t00) {
245 set1 += 24.;
246 set2 += 24.;
247 }
248
249 /*
250 * Interpolate between the two to get a rise and set time
251 * based on the sun's position at local noon (step 8)
252 */
253 rise1 = (24.07 * rise1 - t00 * (rise2 - rise1)) / (24.07 + rise1 - rise2);
254 set1 = (24.07 * set1 - t00 * (set2 - set1)) / (24.07 + set1 - set2);
255
256 /*
257 * Calculate an adjustment value to account for parallax,
258 * refraction and the Sun's finite diameter (steps 9,10)
259 */
260 decl2 = (decl1 + decl2) / 2.;
261 x = DEGREES_TO_RADIANS(0.830725)((fmod ((0.830725),360.) / 180.) * 3.14159265358979323846);
262 u = acos ( sin(obsLat) / cos(decl2) );
263 dt = RADIANS_TO_HOURS ( asin ( sin(x) / sin(u) ) / cos(decl2) )((asin ( sin(x) / sin(u) ) / cos(decl2)) * 12. / 3.14159265358979323846
)
;
264
265 /*
266 * Subtract the correction value from sunrise and add to sunset,
267 * then (step 11) convert sideral times to UT
268 */
269 rise1 = (rise1 - dt - tt) * 0.9972695661;
270 if (rise1 < 0.)
271 rise1 += 24;
272 else if (rise1 >= 24.)
273 rise1 -= 24.;
274 info->sunriseValid = ((rise1 >= 0.) && (rise1 < 24.));
275 info->sunrise = (rise1 * 3600.) + lcl_midn;
276
277 set1 = (set1 + dt - tt) * 0.9972695661;
278 if (set1 < 0.)
279 set1 += 24;
280 else if (set1 >= 24.)
281 set1 -= 24.;
282 info->sunsetValid = ((set1 >= 0.) && (set1 < 24.));
283 info->sunset = (set1 * 3600.) + lcl_midn;
284
285 return (info->sunriseValid || info->sunsetValid);
286}
287
288
289/**
290 * calc_sun_time:
291 * @info: #WeatherInfo structure containing the observer's latitude
292 * and longitude in radians, fills in the sunrise and sunset times.
293 * @t: time_t
294 *
295 * Returns: gboolean indicating if the results are valid.
296 */
297gboolean
298calc_sun_time (WeatherInfo *info, time_t t)
299{
300 return info->location->latlon_valid && calc_sun2 (info, t);
301}
302
303/**
304 * calc_sun:
305 * @info: #WeatherInfo structure containing the observer's latitude
306 * and longitude in radians, fills in the sunrise and sunset times.
307 *
308 * Returns: gboolean indicating if the results are valid.
309 */
310gboolean
311calc_sun (WeatherInfo *info)
312{
313 return calc_sun_time(info, time(NULL((void*)0)));
314}
315
316
317/**
318 * weather_info_next_sun_event:
319 * @info: #WeatherInfo structure
320 *
321 * Returns: the interval, in seconds, until the next "sun event":
322 * - local midnight, when rise and set times are recomputed
323 * - next sunrise, when icon changes to daytime version
324 * - next sunset, when icon changes to nighttime version
325 */
326gint
327weather_info_next_sun_event (WeatherInfo *info)
328{
329 time_t now = time (NULL((void*)0));
330 struct tm ltm;
331 time_t nxtEvent;
332
333 g_return_val_if_fail (info != NULL, -1)do { if ((info != ((void*)0))) { } else { g_return_if_fail_warning
("CafeWeather", ((const char*) (__func__)), "info != NULL");
return (-1); } } while (0)
;
334
335 if (!calc_sun (info))
336 return -1;
337
338 /* Determine when the next local midnight occurs */
339 (void) localtime_r (&now, &ltm);
340 ltm.tm_sec = 0;
341 ltm.tm_min = 0;
342 ltm.tm_hour = 0;
343 ltm.tm_mday++;
344 nxtEvent = mktime (&ltm);
345
346 if (info->sunsetValid &&
347 (info->sunset > now) && (info->sunset < nxtEvent))
348 nxtEvent = info->sunset;
349 if (info->sunriseValid &&
350 (info->sunrise > now) && (info->sunrise < nxtEvent))
351 nxtEvent = info->sunrise;
352 return (gint)(nxtEvent - now);
353}