From 617f9c9f7ab0938a2418a3f5dd961ec6263dda42 Mon Sep 17 00:00:00 2001 From: "raveit65 (via Travis CI)" Date: Sun, 19 Jul 2020 10:16:43 +0000 Subject: Deploy mate-desktop/libmateweather to github.com/mate-desktop/libmateweather.git:gh-pages --- .../0.html | 1368 ++++++++ .../1.html | 994 ++++++ .../10.html | 384 +++ .../11.html | 3562 ++++++++++++++++++++ .../2.html | 708 ++++ .../3.html | 330 ++ .../4.html | 350 ++ .../5.html | 336 ++ .../6.html | 1122 ++++++ .../7.html | 528 +++ .../8.html | 1324 ++++++++ .../9.html | 876 +++++ .../index.html | 167 + .../stats.html | 119 + .../style.css | 137 + 15 files changed, 12305 insertions(+) create mode 100644 2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/0.html create mode 100644 2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/1.html create mode 100644 2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/10.html create mode 100644 2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/11.html create mode 100644 2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/2.html create mode 100644 2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/3.html create mode 100644 2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/4.html create mode 100644 2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/5.html create mode 100644 2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/6.html create mode 100644 2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/7.html create mode 100644 2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/8.html create mode 100644 2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/9.html create mode 100644 2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/index.html create mode 100644 2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/stats.html create mode 100644 2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/style.css (limited to '2020-07-17-122136-1677-cppcheck@af3af510ab5b_master') diff --git a/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/0.html b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/0.html new file mode 100644 index 0000000..4be7c02 --- /dev/null +++ b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/0.html @@ -0,0 +1,1368 @@ + + + + + + Cppcheck - HTML report - libmateweather + + + + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* location-entry.c - Location-selecting text entry
+ *
+ * Copyright 2008, Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define MATEWEATHER_I_KNOW_THIS_IS_UNSTABLE
+#include "location-entry.h"
+
+#include <string.h>
+
+/**
+ * SECTION:location-entry
+ * @Title: MateWeatherLocationEntry
+ *
+ * A subclass of #GtkEntry that provides autocompletion on
+ * #MateWeatherLocation<!-- -->s
+ */
+
+G_DEFINE_TYPE (MateWeatherLocationEntry, mateweather_location_entry, GTK_TYPE_ENTRY)
+
+enum {
+    PROP_0,
+
+    PROP_TOP,
+    PROP_LOCATION,
+
+    LAST_PROP
+};
+
+static void mateweather_location_entry_build_model (MateWeatherLocationEntry *entry,
+						 MateWeatherLocation *top);
+static void set_property (GObject *object, guint prop_id,
+			  const GValue *value, GParamSpec *pspec);
+static void get_property (GObject *object, guint prop_id,
+			  GValue *value, GParamSpec *pspec);
+
+enum
+{
+    MATEWEATHER_LOCATION_ENTRY_COL_DISPLAY_NAME = 0,
+    MATEWEATHER_LOCATION_ENTRY_COL_LOCATION,
+    MATEWEATHER_LOCATION_ENTRY_COL_COMPARE_NAME,
+    MATEWEATHER_LOCATION_ENTRY_COL_SORT_NAME,
+    MATEWEATHER_LOCATION_ENTRY_NUM_COLUMNS
+};
+
+static gboolean matcher (GtkEntryCompletion *completion, const char *key,
+			 GtkTreeIter *iter, gpointer user_data);
+static gboolean match_selected (GtkEntryCompletion *completion,
+				GtkTreeModel       *model,
+				GtkTreeIter        *iter,
+				gpointer            entry);
+static void     entry_changed (MateWeatherLocationEntry *entry);
+
+static void
+mateweather_location_entry_init (MateWeatherLocationEntry *entry)
+{
+    GtkEntryCompletion *completion;
+
+    completion = gtk_entry_completion_new ();
+
+    gtk_entry_completion_set_popup_set_width (completion, FALSE);
+    gtk_entry_completion_set_text_column (completion, MATEWEATHER_LOCATION_ENTRY_COL_DISPLAY_NAME);
+    gtk_entry_completion_set_match_func (completion, matcher, NULL, NULL);
+
+    g_signal_connect (completion, "match_selected",
+		      G_CALLBACK (match_selected), entry);
+
+    gtk_entry_set_completion (GTK_ENTRY (entry), completion);
+    g_object_unref (completion);
+
+    entry->custom_text = FALSE;
+    g_signal_connect (entry, "changed",
+		      G_CALLBACK (entry_changed), NULL);
+}
+
+static void
+finalize (GObject *object)
+{
+    MateWeatherLocationEntry *entry = MATEWEATHER_LOCATION_ENTRY (object);
+
+    if (entry->location)
+	mateweather_location_unref (entry->location);
+    if (entry->top)
+	mateweather_location_unref (entry->top);
+
+    G_OBJECT_CLASS (mateweather_location_entry_parent_class)->finalize (object);
+}
+
+static void
+mateweather_location_entry_class_init (MateWeatherLocationEntryClass *location_entry_class)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (location_entry_class);
+
+    object_class->finalize = finalize;
+    object_class->set_property = set_property;
+    object_class->get_property = get_property;
+
+    /* properties */
+    g_object_class_install_property (
+	object_class, PROP_TOP,
+	g_param_spec_pointer ("top",
+			      "Top Location",
+			      "The MateWeatherLocation whose children will be used to fill in the entry",
+			      G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+    g_object_class_install_property (
+	object_class, PROP_LOCATION,
+	g_param_spec_pointer ("location",
+			      "Location",
+			      "The selected MateWeatherLocation",
+			      G_PARAM_READWRITE));
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+	      const GValue *value, GParamSpec *pspec)
+{
+    switch (prop_id) {
+    case PROP_TOP:
+	mateweather_location_entry_build_model (MATEWEATHER_LOCATION_ENTRY (object),
+					     g_value_get_pointer (value));
+	break;
+    case PROP_LOCATION:
+	mateweather_location_entry_set_location (MATEWEATHER_LOCATION_ENTRY (object),
+					      g_value_get_pointer (value));
+	break;
+    default:
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+	break;
+    }
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+	      GValue *value, GParamSpec *pspec)
+{
+    MateWeatherLocationEntry *entry = MATEWEATHER_LOCATION_ENTRY (object);
+
+    switch (prop_id) {
+    case PROP_LOCATION:
+	g_value_set_pointer (value, entry->location);
+	break;
+    default:
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+	break;
+    }
+}
+
+static void
+entry_changed (MateWeatherLocationEntry *entry)
+{
+    entry->custom_text = TRUE;
+}
+
+static void
+set_location_internal (MateWeatherLocationEntry *entry,
+		       GtkTreeModel          *model,
+		       GtkTreeIter           *iter)
+{
+    MateWeatherLocation *loc;
+    char *name;
+
+    if (entry->location)
+	mateweather_location_unref (entry->location);
+
+    if (iter) {
+	gtk_tree_model_get (model, iter,
+			    MATEWEATHER_LOCATION_ENTRY_COL_DISPLAY_NAME, &name,
+			    MATEWEATHER_LOCATION_ENTRY_COL_LOCATION, &loc,
+			    -1);
+	entry->location = mateweather_location_ref (loc);
+	gtk_entry_set_text (GTK_ENTRY (entry), name);
+	entry->custom_text = FALSE;
+	g_free (name);
+    } else {
+	entry->location = NULL;
+	gtk_entry_set_text (GTK_ENTRY (entry), "");
+	entry->custom_text = TRUE;
+    }
+
+    gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1);
+    g_object_notify (G_OBJECT (entry), "location");
+}
+
+/**
+ * mateweather_location_entry_set_location:
+ * @entry: a #MateWeatherLocationEntry
+ * @loc: (allow-none): a #MateWeatherLocation in @entry, or %NULL to
+ * clear @entry
+ *
+ * Sets @entry's location to @loc, and updates the text of the
+ * entry accordingly.
+ **/
+void
+mateweather_location_entry_set_location (MateWeatherLocationEntry *entry,
+				      MateWeatherLocation      *loc)
+{
+    GtkEntryCompletion *completion;
+    GtkTreeModel *model;
+    GtkTreeIter iter;
+    MateWeatherLocation *cmploc;
+
+    g_return_if_fail (MATEWEATHER_IS_LOCATION_ENTRY (entry));
+
+    completion = gtk_entry_get_completion (GTK_ENTRY (entry));
+    model = gtk_entry_completion_get_model (completion);
+
+    gtk_tree_model_get_iter_first (model, &iter);
+    do {
+	gtk_tree_model_get (model, &iter,
+			    MATEWEATHER_LOCATION_ENTRY_COL_LOCATION, &cmploc,
+			    -1);
+	if (loc == cmploc) {
+	    set_location_internal (entry, model, &iter);
+	    return;
+	}
+    } while (gtk_tree_model_iter_next (model, &iter));
+
+    set_location_internal (entry, model, NULL);
+}
+
+/**
+ * mateweather_location_entry_get_location:
+ * @entry: a #MateWeatherLocationEntry
+ *
+ * Gets the location that was set by a previous call to
+ * mateweather_location_entry_set_location() or was selected by the user.
+ *
+ * Return value: (transfer full) (allow-none): the selected location
+ * (which you must unref when you are done with it), or %NULL if no
+ * location is selected.
+ **/
+MateWeatherLocation *
+mateweather_location_entry_get_location (MateWeatherLocationEntry *entry)
+{
+    g_return_val_if_fail (MATEWEATHER_IS_LOCATION_ENTRY (entry), NULL);
+
+    if (entry->location)
+	return mateweather_location_ref (entry->location);
+    else
+	return NULL;
+}
+
+/**
+ * mateweather_location_entry_has_custom_text:
+ * @entry: a #MateWeatherLocationEntry
+ *
+ * Checks whether or not @entry's text has been modified by the user.
+ * Note that this does not mean that no location is associated with @entry.
+ * mateweather_location_entry_get_location() should be used for this.
+ *
+ * Return value: %TRUE if @entry's text was modified by the user, or %FALSE if
+ * it's set to the default text of a location.
+ **/
+gboolean
+mateweather_location_entry_has_custom_text (MateWeatherLocationEntry *entry)
+{
+    g_return_val_if_fail (MATEWEATHER_IS_LOCATION_ENTRY (entry), FALSE);
+
+    return entry->custom_text;
+}
+
+/**
+ * mateweather_location_entry_set_city:
+ * @entry: a #MateWeatherLocationEntry
+ * @city_name: (allow-none): the city name, or %NULL
+ * @code: the METAR station code
+ *
+ * Sets @entry's location to a city with the given @code, and given
+ * @city_name, if non-%NULL. If there is no matching city, sets
+ * @entry's location to %NULL.
+ *
+ * Return value: %TRUE if @entry's location could be set to a matching city,
+ * %FALSE otherwise.
+ **/
+gboolean
+mateweather_location_entry_set_city (MateWeatherLocationEntry *entry,
+				  const char            *city_name,
+				  const char            *code)
+{
+    GtkEntryCompletion *completion;
+    GtkTreeModel *model;
+    GtkTreeIter iter;
+    MateWeatherLocation *cmploc;
+    const char *cmpcode;
+    char *cmpname;
+
+    g_return_val_if_fail (MATEWEATHER_IS_LOCATION_ENTRY (entry), FALSE);
+    g_return_val_if_fail (code != NULL, FALSE);
+
+    completion = gtk_entry_get_completion (GTK_ENTRY (entry));
+    model = gtk_entry_completion_get_model (completion);
+
+    gtk_tree_model_get_iter_first (model, &iter);
+    do {
+	gtk_tree_model_get (model, &iter,
+			    MATEWEATHER_LOCATION_ENTRY_COL_LOCATION, &cmploc,
+			    -1);
+
+	cmpcode = mateweather_location_get_code (cmploc);
+	if (!cmpcode || strcmp (cmpcode, code) != 0)
+	    continue;
+
+	if (city_name) {
+	    cmpname = mateweather_location_get_city_name (cmploc);
+	    if (!cmpname || strcmp (cmpname, city_name) != 0) {
+		g_free (cmpname);
+		continue;
+	    }
+	    g_free (cmpname);
+	}
+
+	set_location_internal (entry, model, &iter);
+	return TRUE;
+    } while (gtk_tree_model_iter_next (model, &iter));
+
+    set_location_internal (entry, model, NULL);
+
+    return FALSE;
+}
+
+static void
+fill_location_entry_model (GtkTreeStore *store, MateWeatherLocation *loc,
+			   const char *parent_display_name,
+			   const char *parent_compare_name)
+{
+    MateWeatherLocation **children;
+    char *display_name, *compare_name;
+    GtkTreeIter iter;
+    int i;
+
+    children = mateweather_location_get_children (loc);
+
+    switch (mateweather_location_get_level (loc)) {
+    case MATEWEATHER_LOCATION_WORLD:
+    case MATEWEATHER_LOCATION_REGION:
+    case MATEWEATHER_LOCATION_ADM2:
+	/* Ignore these levels of hierarchy; just recurse, passing on
+	 * the names from the parent node.
+	 */
+	for (i = 0; children[i]; i++) {
+	    fill_location_entry_model (store, children[i],
+				       parent_display_name,
+				       parent_compare_name);
+	}
+	break;
+
+    case MATEWEATHER_LOCATION_COUNTRY:
+	/* Recurse, initializing the names to the country name */
+	for (i = 0; children[i]; i++) {
+	    fill_location_entry_model (store, children[i],
+				       mateweather_location_get_name (loc),
+				       mateweather_location_get_sort_name (loc));
+	}
+	break;
+
+    case MATEWEATHER_LOCATION_ADM1:
+	/* Recurse, adding the ADM1 name to the country name */
+	display_name = g_strdup_printf ("%s, %s", mateweather_location_get_name (loc), parent_display_name);
+	compare_name = g_strdup_printf ("%s, %s", mateweather_location_get_sort_name (loc), parent_compare_name);
+
+	for (i = 0; children[i]; i++) {
+	    fill_location_entry_model (store, children[i],
+				       display_name, compare_name);
+	}
+
+	g_free (display_name);
+	g_free (compare_name);
+	break;
+
+    case MATEWEATHER_LOCATION_CITY:
+	if (children[0] && children[1]) {
+	    /* If there are multiple (<location>) children, add a line
+	     * for each of them.
+	     */
+	    for (i = 0; children[i]; i++) {
+		display_name = g_strdup_printf ("%s (%s), %s",
+						mateweather_location_get_name (loc),
+						mateweather_location_get_name (children[i]),
+						parent_display_name);
+		compare_name = g_strdup_printf ("%s (%s), %s",
+						mateweather_location_get_sort_name (loc),
+						mateweather_location_get_sort_name (children[i]),
+						parent_compare_name);
+
+		gtk_tree_store_append (store, &iter, NULL);
+		gtk_tree_store_set (store, &iter,
+				    MATEWEATHER_LOCATION_ENTRY_COL_LOCATION, children[i],
+				    MATEWEATHER_LOCATION_ENTRY_COL_DISPLAY_NAME, display_name,
+				    MATEWEATHER_LOCATION_ENTRY_COL_COMPARE_NAME, compare_name,
+				    -1);
+
+		g_free (display_name);
+		g_free (compare_name);
+	    }
+	} else if (children[0]) {
+	    /* Else there's only one location. This is a mix of the
+	     * city-with-multiple-location case above and the
+	     * location-with-no-city case below.
+	     */
+	    display_name = g_strdup_printf ("%s, %s",
+					    mateweather_location_get_name (loc),
+					    parent_display_name);
+	    compare_name = g_strdup_printf ("%s, %s",
+					    mateweather_location_get_sort_name (loc),
+					    parent_compare_name);
+
+	    gtk_tree_store_append (store, &iter, NULL);
+	    gtk_tree_store_set (store, &iter,
+				MATEWEATHER_LOCATION_ENTRY_COL_LOCATION, children[0],
+				MATEWEATHER_LOCATION_ENTRY_COL_DISPLAY_NAME, display_name,
+				MATEWEATHER_LOCATION_ENTRY_COL_COMPARE_NAME, compare_name,
+				-1);
+
+	    g_free (display_name);
+	    g_free (compare_name);
+	}
+	break;
+
+    case MATEWEATHER_LOCATION_WEATHER_STATION:
+	/* <location> with no parent <city>, or <city> with a single
+	 * child <location>.
+	 */
+	display_name = g_strdup_printf ("%s, %s",
+					mateweather_location_get_name (loc),
+					parent_display_name);
+	compare_name = g_strdup_printf ("%s, %s",
+					mateweather_location_get_sort_name (loc),
+					parent_compare_name);
+
+	gtk_tree_store_append (store, &iter, NULL);
+	gtk_tree_store_set (store, &iter,
+			    MATEWEATHER_LOCATION_ENTRY_COL_LOCATION, loc,
+			    MATEWEATHER_LOCATION_ENTRY_COL_DISPLAY_NAME, display_name,
+			    MATEWEATHER_LOCATION_ENTRY_COL_COMPARE_NAME, compare_name,
+			    -1);
+
+	g_free (display_name);
+	g_free (compare_name);
+	break;
+    }
+
+    mateweather_location_free_children (loc, children);
+}
+
+static void
+mateweather_location_entry_build_model (MateWeatherLocationEntry *entry,
+				     MateWeatherLocation *top)
+{
+    GtkTreeStore *store = NULL;
+
+    g_return_if_fail (MATEWEATHER_IS_LOCATION_ENTRY (entry));
+    entry->top = mateweather_location_ref (top);
+
+    store = gtk_tree_store_new (4, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_STRING);
+    fill_location_entry_model (store, top, NULL, NULL);
+    gtk_entry_completion_set_model (gtk_entry_get_completion (GTK_ENTRY (entry)),
+				    GTK_TREE_MODEL (store));
+    g_object_unref (store);
+}
+
+static char *
+find_word (const char *full_name, const char *word, int word_len,
+	   gboolean whole_word, gboolean is_first_word)
+{
+    char *p = (char *)full_name - 1;
+
+    while ((p = strchr (p + 1, *word))) {
+	if (strncmp (p, word, word_len) != 0)
+	    continue;
+
+	if (p > (char *)full_name) {
+	    char *prev = g_utf8_prev_char (p);
+
+	    /* Make sure p points to the start of a word */
+	    if (g_unichar_isalpha (g_utf8_get_char (prev)))
+		continue;
+
+	    /* If we're matching the first word of the key, it has to
+	     * match the first word of the location, city, state, or
+	     * country. Eg, it either matches the start of the string
+	     * (which we already know it doesn't at this point) or
+	     * it is preceded by the string ", " (which isn't actually
+	     * a perfect test. FIXME)
+	     */
+	    if (is_first_word) {
+		if (prev == (char *)full_name || strncmp (prev - 1, ", ", 2) != 0)
+		    continue;
+	    }
+	}
+
+	if (whole_word && g_unichar_isalpha (g_utf8_get_char (p + word_len)))
+	    continue;
+
+	return p;
+    }
+    return NULL;
+}
+
+static gboolean
+matcher (GtkEntryCompletion *completion, const char *key,
+	 GtkTreeIter *iter, gpointer user_data)
+{
+    char *name, *name_mem;
+    MateWeatherLocation *loc;
+    gboolean is_first_word = TRUE, match;
+    int len;
+
+    gtk_tree_model_get (gtk_entry_completion_get_model (completion), iter,
+			MATEWEATHER_LOCATION_ENTRY_COL_COMPARE_NAME, &name_mem,
+			MATEWEATHER_LOCATION_ENTRY_COL_LOCATION, &loc,
+			-1);
+    name = name_mem;
+
+    if (!loc) {
+	g_free (name_mem);
+	return FALSE;
+    }
+
+    /* All but the last word in KEY must match a full word from NAME,
+     * in order (but possibly skipping some words from NAME).
+     */
+    len = strcspn (key, " ");
+    while (key[len]) {
+	name = find_word (name, key, len, TRUE, is_first_word);
+	if (!name) {
+	    g_free (name_mem);
+	    return FALSE;
+	}
+
+	key += len;
+	while (*key && !g_unichar_isalpha (g_utf8_get_char (key)))
+	    key = g_utf8_next_char (key);
+	while (*name && !g_unichar_isalpha (g_utf8_get_char (name)))
+	    name = g_utf8_next_char (name);
+
+	len = strcspn (key, " ");
+	is_first_word = FALSE;
+    }
+
+    /* The last word in KEY must match a prefix of a following word in NAME */
+    match = find_word (name, key, strlen (key), FALSE, is_first_word) != NULL;
+    g_free (name_mem);
+    return match;
+}
+
+static gboolean
+match_selected (GtkEntryCompletion *completion,
+		GtkTreeModel       *model,
+		GtkTreeIter        *iter,
+		gpointer            entry)
+{
+    set_location_internal (entry, model, iter);
+    return TRUE;
+}
+
+/**
+ * mateweather_location_entry_new:
+ * @top: the top-level location for the entry.
+ *
+ * Creates a new #MateWeatherLocationEntry.
+ *
+ * @top will normally be a location returned from
+ * mateweather_location_new_world(), but you can create an entry that
+ * only accepts a smaller set of locations if you want.
+ *
+ * Return value: the new #MateWeatherLocationEntry
+ **/
+GtkWidget *
+mateweather_location_entry_new (MateWeatherLocation *top)
+{
+    return g_object_new (MATEWEATHER_TYPE_LOCATION_ENTRY,
+			 "top", top,
+			 NULL);
+}
+
+
+
+
+ + + diff --git a/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/1.html b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/1.html new file mode 100644 index 0000000..8801b6f --- /dev/null +++ b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/1.html @@ -0,0 +1,994 @@ + + + + + + Cppcheck - HTML report - libmateweather + + + + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* mateweather-timezone.c - Timezone handling
+ *
+ * Copyright 2008, Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#define MATEWEATHER_I_KNOW_THIS_IS_UNSTABLE
+#include "mateweather-timezone.h"
+#include "parser.h"
+#include "weather-priv.h"
+
+/**
+ * SECTION:mateweather-timezone
+ * @Title: MateWeatherTimezone
+ *
+ * A timezone.
+ *
+ * There are no public methods for creating timezones; they can only
+ * be created by calling mateweather_location_new_world() to parse
+ * Locations.xml, and then calling various #MateWeatherLocation methods
+ * to extract relevant timezones from the location hierarchy.
+ */
+struct _MateWeatherTimezone {
+    char *id, *name;
+    int offset, dst_offset;
+    gboolean has_dst;
+
+    int ref_count;
+};
+
+#define TZ_MAGIC "TZif"
+#define TZ_HEADER_SIZE 44
+#define TZ_TIMECNT_OFFSET 32
+#define TZ_TRANSITIONS_OFFSET 44
+
+#define TZ_TTINFO_SIZE 6
+#define TZ_TTINFO_GMTOFF_OFFSET 0
+#define TZ_TTINFO_ISDST_OFFSET 4
+
+static gboolean
+parse_tzdata (const char *tzname, time_t start, time_t end,
+	      int *offset, gboolean *has_dst, int *dst_offset)
+{
+    char *filename, *contents;
+    gsize length;
+    int timecnt, transitions_size, ttinfo_map_size;
+    int initial_transition = -1, second_transition = -1;
+    gint32 *transitions;
+    char *ttinfo_map, *ttinfos;
+    gint32 initial_offset, second_offset;
+    char initial_isdst, second_isdst;
+    int i;
+
+    filename = g_build_filename (ZONEINFO_DIR, tzname, NULL);
+    if (!g_file_get_contents (filename, &contents, &length, NULL)) {
+	g_free (filename);
+	return FALSE;
+    }
+    g_free (filename);
+
+    if (length < TZ_HEADER_SIZE ||
+	strncmp (contents, TZ_MAGIC, strlen (TZ_MAGIC)) != 0) {
+	g_free (contents);
+	return FALSE;
+    }
+
+    timecnt = GUINT32_FROM_BE (*(guint32 *)(contents + TZ_TIMECNT_OFFSET));
+    transitions = (void *)(contents + TZ_TRANSITIONS_OFFSET);
+    transitions_size = timecnt * sizeof (*transitions);
+    ttinfo_map = (void *)(contents + TZ_TRANSITIONS_OFFSET + transitions_size);
+    ttinfo_map_size = timecnt;
+    ttinfos = (void *)(ttinfo_map + ttinfo_map_size);
+
+    /* @transitions is an array of @timecnt time_t values. We need to
+     * find the transition into the current offset, which is the last
+     * transition before @start. If the following transition is before
+     * @end, then note that one too, since it presumably means we're
+     * doing DST.
+     */
+    for (i = 1; i < timecnt && initial_transition == -1; i++) {
+	if (GINT32_FROM_BE (transitions[i]) > start) {
+	    initial_transition = ttinfo_map[i - 1];
+	    if (GINT32_FROM_BE (transitions[i]) < end)
+		second_transition = ttinfo_map[i];
+	}
+    }
+    if (initial_transition == -1) {
+	if (timecnt)
+	    initial_transition = ttinfo_map[timecnt - 1];
+	else
+	    initial_transition = 0;
+    }
+
+    /* Copy the data out of the corresponding ttinfo structs */
+    initial_offset = *(gint32 *)(ttinfos +
+				 initial_transition * TZ_TTINFO_SIZE +
+				 TZ_TTINFO_GMTOFF_OFFSET);
+    initial_offset = GINT32_FROM_BE (initial_offset);
+    initial_isdst = *(ttinfos +
+		      initial_transition * TZ_TTINFO_SIZE +
+		      TZ_TTINFO_ISDST_OFFSET);
+
+    if (second_transition != -1) {
+	second_offset = *(gint32 *)(ttinfos +
+				    second_transition * TZ_TTINFO_SIZE +
+				    TZ_TTINFO_GMTOFF_OFFSET);
+	second_offset = GINT32_FROM_BE (second_offset);
+	second_isdst = *(ttinfos +
+			 second_transition * TZ_TTINFO_SIZE +
+			 TZ_TTINFO_ISDST_OFFSET);
+
+	*has_dst = (initial_isdst != second_isdst);
+    } else
+	*has_dst = FALSE;
+
+    if (!*has_dst)
+	*offset = initial_offset / 60;
+    else {
+	if (initial_isdst) {
+	    *offset = second_offset / 60;
+	    *dst_offset = initial_offset / 60;
+	} else {
+	    *offset = initial_offset / 60;
+	    *dst_offset = second_offset / 60;
+	}
+    }
+
+    g_free (contents);
+    return TRUE;
+}
+
+static MateWeatherTimezone *
+parse_timezone (MateWeatherParser *parser)
+{
+    MateWeatherTimezone *zone = NULL;
+    char *id = NULL, *name = NULL;
+    int offset = 0, dst_offset = 0;
+    gboolean has_dst = FALSE;
+
+    id = (char *) xmlTextReaderGetAttribute (parser->xml, (xmlChar *) "id");
+    if (!id) {
+	xmlTextReaderNext (parser->xml);
+	return NULL;
+    }
+
+    if (!xmlTextReaderIsEmptyElement (parser->xml)) {
+	if (xmlTextReaderRead (parser->xml) != 1) {
+	    xmlFree (id);
+	    return NULL;
+	}
+
+	while (xmlTextReaderNodeType (parser->xml) != XML_READER_TYPE_END_ELEMENT) {
+	    if (xmlTextReaderNodeType (parser->xml) != XML_READER_TYPE_ELEMENT) {
+		if (xmlTextReaderRead (parser->xml) != 1)
+		    break;
+		continue;
+	    }
+
+	    if (!strcmp ((const char *) xmlTextReaderConstName (parser->xml), "name"))
+		name = mateweather_parser_get_localized_value (parser);
+	    else {
+		if (xmlTextReaderNext (parser->xml) != 1)
+		    break;
+	    }
+	}
+    }
+
+    if (parse_tzdata (id, parser->year_start, parser->year_end,
+		      &offset, &has_dst, &dst_offset)) {
+	zone = g_slice_new0 (MateWeatherTimezone);
+	zone->ref_count = 1;
+	zone->id = g_strdup (id);
+	zone->name = g_strdup (name);
+	zone->offset = offset;
+	zone->has_dst = has_dst;
+	zone->dst_offset = dst_offset;
+    }
+
+    xmlFree (id);
+    if (name)
+	xmlFree (name);
+
+    return zone;
+}
+
+MateWeatherTimezone **
+mateweather_timezones_parse_xml (MateWeatherParser *parser)
+{
+    GPtrArray *zones;
+    MateWeatherTimezone *zone;
+    const char *tagname;
+    int tagtype, i;
+
+    zones = g_ptr_array_new ();
+
+    if (xmlTextReaderRead (parser->xml) != 1)
+	goto error_out;
+    while ((tagtype = xmlTextReaderNodeType (parser->xml)) !=
+	   XML_READER_TYPE_END_ELEMENT) {
+	if (tagtype != XML_READER_TYPE_ELEMENT) {
+	    if (xmlTextReaderRead (parser->xml) != 1)
+		goto error_out;
+	    continue;
+	}
+
+	tagname = (const char *) xmlTextReaderConstName (parser->xml);
+
+	if (!strcmp (tagname, "timezone")) {
+	    zone = parse_timezone (parser);
+	    if (zone)
+		g_ptr_array_add (zones, zone);
+	}
+
+	if (xmlTextReaderNext (parser->xml) != 1)
+	    goto error_out;
+    }
+    if (xmlTextReaderRead (parser->xml) != 1)
+	goto error_out;
+
+    g_ptr_array_add (zones, NULL);
+    return (MateWeatherTimezone **)g_ptr_array_free (zones, FALSE);
+
+error_out:
+    for (i = 0; i < zones->len; i++)
+	mateweather_timezone_unref (zones->pdata[i]);
+    g_ptr_array_free (zones, TRUE);
+    return NULL;
+}
+
+/**
+ * mateweather_timezone_ref:
+ * @zone: a #MateWeatherTimezone
+ *
+ * Adds 1 to @zone's reference count.
+ *
+ * Return value: @zone
+ **/
+MateWeatherTimezone *
+mateweather_timezone_ref (MateWeatherTimezone *zone)
+{
+    g_return_val_if_fail (zone != NULL, NULL);
+
+    zone->ref_count++;
+    return zone;
+}
+
+/**
+ * mateweather_timezone_unref:
+ * @zone: a #MateWeatherTimezone
+ *
+ * Subtracts 1 from @zone's reference count and frees it if it reaches 0.
+ **/
+void
+mateweather_timezone_unref (MateWeatherTimezone *zone)
+{
+    g_return_if_fail (zone != NULL);
+
+    if (!--zone->ref_count) {
+	g_free (zone->id);
+	g_free (zone->name);
+	g_slice_free (MateWeatherTimezone, zone);
+    }
+}
+
+GType
+mateweather_timezone_get_type (void)
+{
+    static volatile gsize type_volatile = 0;
+
+    if (g_once_init_enter (&type_volatile)) {
+	GType type = g_boxed_type_register_static (
+	    g_intern_static_string ("MateWeatherTimezone"),
+	    (GBoxedCopyFunc) mateweather_timezone_ref,
+	    (GBoxedFreeFunc) mateweather_timezone_unref);
+	g_once_init_leave (&type_volatile, type);
+    }
+    return type_volatile;
+}
+
+/**
+ * mateweather_timezone_get_utc:
+ *
+ * Gets the UTC timezone.
+ *
+ * Return value: a #MateWeatherTimezone for UTC, or %NULL on error.
+ **/
+MateWeatherTimezone *
+mateweather_timezone_get_utc (void)
+{
+    MateWeatherTimezone *zone = NULL;
+
+    zone = g_slice_new0 (MateWeatherTimezone);
+    zone->ref_count = 1;
+    zone->id = g_strdup ("GMT");
+    zone->name = g_strdup (_("Greenwich Mean Time"));
+    zone->offset = 0;
+    zone->has_dst = FALSE;
+    zone->dst_offset = 0;
+
+    return zone;
+}
+
+/**
+ * mateweather_timezone_get_name:
+ * @zone: a #MateWeatherTimezone
+ *
+ * Gets @zone's name; a translated, user-presentable string.
+ *
+ * Note that the returned name might not be unique among timezones,
+ * and may not make sense to the user unless it is presented along
+ * with the timezone's country's name (or in some context where the
+ * country is obvious).
+ *
+ * Return value: @zone's name
+ **/
+const char *
+mateweather_timezone_get_name (MateWeatherTimezone *zone)
+{
+    g_return_val_if_fail (zone != NULL, NULL);
+    return zone->name;
+}
+
+/**
+ * mateweather_timezone_get_tzid:
+ * @zone: a #MateWeatherTimezone
+ *
+ * Gets @zone's tzdata identifier, eg "America/New_York".
+ *
+ * Return value: @zone's tzid
+ **/
+const char *
+mateweather_timezone_get_tzid (MateWeatherTimezone *zone)
+{
+    g_return_val_if_fail (zone != NULL, NULL);
+    return zone->id;
+}
+
+/**
+ * mateweather_timezone_get_offset:
+ * @zone: a #MateWeatherTimezone
+ *
+ * Gets @zone's standard offset from UTC, in minutes. Eg, a value of
+ * %120 would indicate "GMT+2".
+ *
+ * Return value: @zone's standard offset, in minutes
+ **/
+int
+mateweather_timezone_get_offset (MateWeatherTimezone *zone)
+{
+    g_return_val_if_fail (zone != NULL, 0);
+    return zone->offset;
+}
+
+/**
+ * mateweather_timezone_has_dst:
+ * @zone: a #MateWeatherTimezone
+ *
+ * Checks if @zone observes daylight/summer time for part of the year.
+ *
+ * Return value: %TRUE if @zone observes daylight/summer time.
+ **/
+gboolean
+mateweather_timezone_has_dst (MateWeatherTimezone *zone)
+{
+    g_return_val_if_fail (zone != NULL, FALSE);
+    return zone->has_dst;
+}
+
+/**
+ * mateweather_timezone_get_dst_offset:
+ * @zone: a #MateWeatherTimezone
+ *
+ * Gets @zone's daylight/summer time offset from UTC, in minutes. Eg,
+ * a value of %120 would indicate "GMT+2". This is only meaningful if
+ * mateweather_timezone_has_dst() returns %TRUE.
+ *
+ * Return value: @zone's daylight/summer time offset, in minutes
+ **/
+int
+mateweather_timezone_get_dst_offset (MateWeatherTimezone *zone)
+{
+    g_return_val_if_fail (zone != NULL, 0);
+    g_return_val_if_fail (zone->has_dst, 0);
+    return zone->dst_offset;
+}
+
+
+
+
+
+ + + diff --git a/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/10.html b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/10.html new file mode 100644 index 0000000..f134e12 --- /dev/null +++ b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/10.html @@ -0,0 +1,384 @@ + + + + + + Cppcheck - HTML report - libmateweather + + + + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* weather-wx.c - Weather server functions (WX Radar)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define MATEWEATHER_I_KNOW_THIS_IS_UNSTABLE
+#include "weather.h"
+#include "weather-priv.h"
+
+static void
+wx_finish (SoupSession *session, SoupMessage *msg, gpointer data)
+{
+    WeatherInfo *info = (WeatherInfo *)data;
+    GdkPixbufAnimation *animation;
+
+    g_return_if_fail (info != NULL);
+
+    if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
+	g_warning ("Failed to get radar map image: %d %s.\n",
+		   msg->status_code, msg->reason_phrase);
+	g_object_unref (info->radar_loader);
+	request_done (info, FALSE);
+	return;
+    }
+
+    gdk_pixbuf_loader_close (info->radar_loader, NULL);
+    animation = gdk_pixbuf_loader_get_animation (info->radar_loader);
+    if (animation != NULL) {
+	if (info->radar)
+	    g_object_unref (info->radar);
+	info->radar = animation;
+	g_object_ref (info->radar);
+    }
+    g_object_unref (info->radar_loader);
+
+    request_done (info, TRUE);
+}
+
+static void
+wx_got_chunk (SoupMessage *msg, SoupBuffer *chunk, gpointer data)
+{
+    WeatherInfo *info = (WeatherInfo *)data;<--- Assignment from '(struct _WeatherInfo*)data'
+    GError *error = NULL;
+
+    g_return_if_fail (info != NULL);<--- Assuming that condition 'info!=NULL' is not redundant
+
+    gdk_pixbuf_loader_write (info->radar_loader, (guchar *)chunk->data,<--- Null pointer dereference
+			     chunk->length, &error);
+    if (error) {
+	g_print ("%s \n", error->message);
+	g_error_free (error);
+    }
+}
+
+/* Get radar map and into newly allocated pixmap */
+void
+wx_start_open (WeatherInfo *info)
+{
+    gchar *url;
+    SoupMessage *msg;
+    WeatherLocation *loc;
+
+    g_return_if_fail (info != NULL);
+    info->radar = NULL;
+    info->radar_loader = gdk_pixbuf_loader_new ();
+    loc = info->location;
+    g_return_if_fail (loc != NULL);
+
+    if (info->radar_url)
+	url = g_strdup (info->radar_url);
+    else {
+	if (loc->radar[0] == '-')
+	    return;
+	url = g_strdup_printf ("http://image.weather.com/web/radar/us_%s_closeradar_medium_usen.jpg", loc->radar);
+    }
+
+    msg = soup_message_new ("GET", url);
+    if (!msg) {
+	g_warning ("Invalid radar URL: %s\n", url);
+	g_free (url);
+	return;
+    }
+
+    g_signal_connect (msg, "got-chunk", G_CALLBACK (wx_got_chunk), info);
+    soup_message_body_set_accumulate (msg->response_body, FALSE);
+    soup_session_queue_message (info->session, msg, wx_finish, info);
+    g_free (url);
+
+    info->requests_pending++;
+}
+
+
+
+
+ + + diff --git a/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/11.html b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/11.html new file mode 100644 index 0000000..3d73d28 --- /dev/null +++ b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/11.html @@ -0,0 +1,3562 @@ + + + + + + Cppcheck - HTML report - libmateweather + + + + + + +
+ +
+
   1
+   2
+   3
+   4
+   5
+   6
+   7
+   8
+   9
+  10
+  11
+  12
+  13
+  14
+  15
+  16
+  17
+  18
+  19
+  20
+  21
+  22
+  23
+  24
+  25
+  26
+  27
+  28
+  29
+  30
+  31
+  32
+  33
+  34
+  35
+  36
+  37
+  38
+  39
+  40
+  41
+  42
+  43
+  44
+  45
+  46
+  47
+  48
+  49
+  50
+  51
+  52
+  53
+  54
+  55
+  56
+  57
+  58
+  59
+  60
+  61
+  62
+  63
+  64
+  65
+  66
+  67
+  68
+  69
+  70
+  71
+  72
+  73
+  74
+  75
+  76
+  77
+  78
+  79
+  80
+  81
+  82
+  83
+  84
+  85
+  86
+  87
+  88
+  89
+  90
+  91
+  92
+  93
+  94
+  95
+  96
+  97
+  98
+  99
+ 100
+ 101
+ 102
+ 103
+ 104
+ 105
+ 106
+ 107
+ 108
+ 109
+ 110
+ 111
+ 112
+ 113
+ 114
+ 115
+ 116
+ 117
+ 118
+ 119
+ 120
+ 121
+ 122
+ 123
+ 124
+ 125
+ 126
+ 127
+ 128
+ 129
+ 130
+ 131
+ 132
+ 133
+ 134
+ 135
+ 136
+ 137
+ 138
+ 139
+ 140
+ 141
+ 142
+ 143
+ 144
+ 145
+ 146
+ 147
+ 148
+ 149
+ 150
+ 151
+ 152
+ 153
+ 154
+ 155
+ 156
+ 157
+ 158
+ 159
+ 160
+ 161
+ 162
+ 163
+ 164
+ 165
+ 166
+ 167
+ 168
+ 169
+ 170
+ 171
+ 172
+ 173
+ 174
+ 175
+ 176
+ 177
+ 178
+ 179
+ 180
+ 181
+ 182
+ 183
+ 184
+ 185
+ 186
+ 187
+ 188
+ 189
+ 190
+ 191
+ 192
+ 193
+ 194
+ 195
+ 196
+ 197
+ 198
+ 199
+ 200
+ 201
+ 202
+ 203
+ 204
+ 205
+ 206
+ 207
+ 208
+ 209
+ 210
+ 211
+ 212
+ 213
+ 214
+ 215
+ 216
+ 217
+ 218
+ 219
+ 220
+ 221
+ 222
+ 223
+ 224
+ 225
+ 226
+ 227
+ 228
+ 229
+ 230
+ 231
+ 232
+ 233
+ 234
+ 235
+ 236
+ 237
+ 238
+ 239
+ 240
+ 241
+ 242
+ 243
+ 244
+ 245
+ 246
+ 247
+ 248
+ 249
+ 250
+ 251
+ 252
+ 253
+ 254
+ 255
+ 256
+ 257
+ 258
+ 259
+ 260
+ 261
+ 262
+ 263
+ 264
+ 265
+ 266
+ 267
+ 268
+ 269
+ 270
+ 271
+ 272
+ 273
+ 274
+ 275
+ 276
+ 277
+ 278
+ 279
+ 280
+ 281
+ 282
+ 283
+ 284
+ 285
+ 286
+ 287
+ 288
+ 289
+ 290
+ 291
+ 292
+ 293
+ 294
+ 295
+ 296
+ 297
+ 298
+ 299
+ 300
+ 301
+ 302
+ 303
+ 304
+ 305
+ 306
+ 307
+ 308
+ 309
+ 310
+ 311
+ 312
+ 313
+ 314
+ 315
+ 316
+ 317
+ 318
+ 319
+ 320
+ 321
+ 322
+ 323
+ 324
+ 325
+ 326
+ 327
+ 328
+ 329
+ 330
+ 331
+ 332
+ 333
+ 334
+ 335
+ 336
+ 337
+ 338
+ 339
+ 340
+ 341
+ 342
+ 343
+ 344
+ 345
+ 346
+ 347
+ 348
+ 349
+ 350
+ 351
+ 352
+ 353
+ 354
+ 355
+ 356
+ 357
+ 358
+ 359
+ 360
+ 361
+ 362
+ 363
+ 364
+ 365
+ 366
+ 367
+ 368
+ 369
+ 370
+ 371
+ 372
+ 373
+ 374
+ 375
+ 376
+ 377
+ 378
+ 379
+ 380
+ 381
+ 382
+ 383
+ 384
+ 385
+ 386
+ 387
+ 388
+ 389
+ 390
+ 391
+ 392
+ 393
+ 394
+ 395
+ 396
+ 397
+ 398
+ 399
+ 400
+ 401
+ 402
+ 403
+ 404
+ 405
+ 406
+ 407
+ 408
+ 409
+ 410
+ 411
+ 412
+ 413
+ 414
+ 415
+ 416
+ 417
+ 418
+ 419
+ 420
+ 421
+ 422
+ 423
+ 424
+ 425
+ 426
+ 427
+ 428
+ 429
+ 430
+ 431
+ 432
+ 433
+ 434
+ 435
+ 436
+ 437
+ 438
+ 439
+ 440
+ 441
+ 442
+ 443
+ 444
+ 445
+ 446
+ 447
+ 448
+ 449
+ 450
+ 451
+ 452
+ 453
+ 454
+ 455
+ 456
+ 457
+ 458
+ 459
+ 460
+ 461
+ 462
+ 463
+ 464
+ 465
+ 466
+ 467
+ 468
+ 469
+ 470
+ 471
+ 472
+ 473
+ 474
+ 475
+ 476
+ 477
+ 478
+ 479
+ 480
+ 481
+ 482
+ 483
+ 484
+ 485
+ 486
+ 487
+ 488
+ 489
+ 490
+ 491
+ 492
+ 493
+ 494
+ 495
+ 496
+ 497
+ 498
+ 499
+ 500
+ 501
+ 502
+ 503
+ 504
+ 505
+ 506
+ 507
+ 508
+ 509
+ 510
+ 511
+ 512
+ 513
+ 514
+ 515
+ 516
+ 517
+ 518
+ 519
+ 520
+ 521
+ 522
+ 523
+ 524
+ 525
+ 526
+ 527
+ 528
+ 529
+ 530
+ 531
+ 532
+ 533
+ 534
+ 535
+ 536
+ 537
+ 538
+ 539
+ 540
+ 541
+ 542
+ 543
+ 544
+ 545
+ 546
+ 547
+ 548
+ 549
+ 550
+ 551
+ 552
+ 553
+ 554
+ 555
+ 556
+ 557
+ 558
+ 559
+ 560
+ 561
+ 562
+ 563
+ 564
+ 565
+ 566
+ 567
+ 568
+ 569
+ 570
+ 571
+ 572
+ 573
+ 574
+ 575
+ 576
+ 577
+ 578
+ 579
+ 580
+ 581
+ 582
+ 583
+ 584
+ 585
+ 586
+ 587
+ 588
+ 589
+ 590
+ 591
+ 592
+ 593
+ 594
+ 595
+ 596
+ 597
+ 598
+ 599
+ 600
+ 601
+ 602
+ 603
+ 604
+ 605
+ 606
+ 607
+ 608
+ 609
+ 610
+ 611
+ 612
+ 613
+ 614
+ 615
+ 616
+ 617
+ 618
+ 619
+ 620
+ 621
+ 622
+ 623
+ 624
+ 625
+ 626
+ 627
+ 628
+ 629
+ 630
+ 631
+ 632
+ 633
+ 634
+ 635
+ 636
+ 637
+ 638
+ 639
+ 640
+ 641
+ 642
+ 643
+ 644
+ 645
+ 646
+ 647
+ 648
+ 649
+ 650
+ 651
+ 652
+ 653
+ 654
+ 655
+ 656
+ 657
+ 658
+ 659
+ 660
+ 661
+ 662
+ 663
+ 664
+ 665
+ 666
+ 667
+ 668
+ 669
+ 670
+ 671
+ 672
+ 673
+ 674
+ 675
+ 676
+ 677
+ 678
+ 679
+ 680
+ 681
+ 682
+ 683
+ 684
+ 685
+ 686
+ 687
+ 688
+ 689
+ 690
+ 691
+ 692
+ 693
+ 694
+ 695
+ 696
+ 697
+ 698
+ 699
+ 700
+ 701
+ 702
+ 703
+ 704
+ 705
+ 706
+ 707
+ 708
+ 709
+ 710
+ 711
+ 712
+ 713
+ 714
+ 715
+ 716
+ 717
+ 718
+ 719
+ 720
+ 721
+ 722
+ 723
+ 724
+ 725
+ 726
+ 727
+ 728
+ 729
+ 730
+ 731
+ 732
+ 733
+ 734
+ 735
+ 736
+ 737
+ 738
+ 739
+ 740
+ 741
+ 742
+ 743
+ 744
+ 745
+ 746
+ 747
+ 748
+ 749
+ 750
+ 751
+ 752
+ 753
+ 754
+ 755
+ 756
+ 757
+ 758
+ 759
+ 760
+ 761
+ 762
+ 763
+ 764
+ 765
+ 766
+ 767
+ 768
+ 769
+ 770
+ 771
+ 772
+ 773
+ 774
+ 775
+ 776
+ 777
+ 778
+ 779
+ 780
+ 781
+ 782
+ 783
+ 784
+ 785
+ 786
+ 787
+ 788
+ 789
+ 790
+ 791
+ 792
+ 793
+ 794
+ 795
+ 796
+ 797
+ 798
+ 799
+ 800
+ 801
+ 802
+ 803
+ 804
+ 805
+ 806
+ 807
+ 808
+ 809
+ 810
+ 811
+ 812
+ 813
+ 814
+ 815
+ 816
+ 817
+ 818
+ 819
+ 820
+ 821
+ 822
+ 823
+ 824
+ 825
+ 826
+ 827
+ 828
+ 829
+ 830
+ 831
+ 832
+ 833
+ 834
+ 835
+ 836
+ 837
+ 838
+ 839
+ 840
+ 841
+ 842
+ 843
+ 844
+ 845
+ 846
+ 847
+ 848
+ 849
+ 850
+ 851
+ 852
+ 853
+ 854
+ 855
+ 856
+ 857
+ 858
+ 859
+ 860
+ 861
+ 862
+ 863
+ 864
+ 865
+ 866
+ 867
+ 868
+ 869
+ 870
+ 871
+ 872
+ 873
+ 874
+ 875
+ 876
+ 877
+ 878
+ 879
+ 880
+ 881
+ 882
+ 883
+ 884
+ 885
+ 886
+ 887
+ 888
+ 889
+ 890
+ 891
+ 892
+ 893
+ 894
+ 895
+ 896
+ 897
+ 898
+ 899
+ 900
+ 901
+ 902
+ 903
+ 904
+ 905
+ 906
+ 907
+ 908
+ 909
+ 910
+ 911
+ 912
+ 913
+ 914
+ 915
+ 916
+ 917
+ 918
+ 919
+ 920
+ 921
+ 922
+ 923
+ 924
+ 925
+ 926
+ 927
+ 928
+ 929
+ 930
+ 931
+ 932
+ 933
+ 934
+ 935
+ 936
+ 937
+ 938
+ 939
+ 940
+ 941
+ 942
+ 943
+ 944
+ 945
+ 946
+ 947
+ 948
+ 949
+ 950
+ 951
+ 952
+ 953
+ 954
+ 955
+ 956
+ 957
+ 958
+ 959
+ 960
+ 961
+ 962
+ 963
+ 964
+ 965
+ 966
+ 967
+ 968
+ 969
+ 970
+ 971
+ 972
+ 973
+ 974
+ 975
+ 976
+ 977
+ 978
+ 979
+ 980
+ 981
+ 982
+ 983
+ 984
+ 985
+ 986
+ 987
+ 988
+ 989
+ 990
+ 991
+ 992
+ 993
+ 994
+ 995
+ 996
+ 997
+ 998
+ 999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* weather.c - Overall weather server functions
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+#include <fenv.h>
+
+#ifdef HAVE_VALUES_H
+#include <values.h>
+#endif
+
+#include <time.h>
+#include <unistd.h>
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#define MATEWEATHER_I_KNOW_THIS_IS_UNSTABLE
+#include "weather.h"
+#include "weather-priv.h"
+
+#define MOON_PHASES 36
+
+/**
+ * SECTION:weather
+ * @Title: weather
+ */
+
+static void _weather_internal_check (void);
+
+
+static inline void
+mateweather_gettext_init (void)
+{
+    static gsize mateweather_gettext_initialized = FALSE;
+
+    if (G_UNLIKELY (g_once_init_enter (&mateweather_gettext_initialized))) {
+        bindtextdomain (GETTEXT_PACKAGE, MATELOCALEDIR);
+#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+        bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+#endif
+        g_once_init_leave (&mateweather_gettext_initialized, TRUE);
+    }
+}
+
+const char *
+mateweather_gettext (const char *str)
+{
+    mateweather_gettext_init ();
+    return dgettext (GETTEXT_PACKAGE, str);
+}
+
+const char *
+mateweather_dpgettext (const char *context,
+                    const char *str)
+{
+    mateweather_gettext_init ();
+    return g_dpgettext2 (GETTEXT_PACKAGE, context, str);
+}
+
+/*
+ * Convert string of the form "DD-MM-SSH" to radians
+ * DD:degrees (to 3 digits), MM:minutes, SS:seconds H:hemisphere (NESW)
+ * Return value is positive for N,E; negative for S,W.
+ */
+static gdouble
+dmsh2rad (const gchar *latlon)
+{
+    char *p1, *p2;
+    int deg, min, sec, dir;
+    gdouble value;
+
+    if (latlon == NULL)
+	return DBL_MAX;
+    p1 = strchr (latlon, '-');
+    p2 = strrchr (latlon, '-');
+    if (p1 == NULL || p1 == latlon) {
+        return DBL_MAX;
+    } else if (p1 == p2) {
+	sscanf (latlon, "%d-%d", &deg, &min);
+	sec = 0;
+    } else if (p2 == 1 + p1) {
+	return DBL_MAX;
+    } else {
+	sscanf (latlon, "%d-%d-%d", &deg, &min, &sec);
+    }
+    if (deg > 180 || min >= 60 || sec >= 60)
+	return DBL_MAX;
+    value = (gdouble)((deg * 60 + min) * 60 + sec) * M_PI / 648000.;
+
+    dir = g_ascii_toupper (latlon[strlen (latlon) - 1]);
+    if (dir == 'W' || dir == 'S')
+	value = -value;
+    else if (dir != 'E' && dir != 'N' && (value != 0.0 || dir != '0'))
+	value = DBL_MAX;
+    return value;
+}
+
+WeatherLocation *
+weather_location_new (const gchar *name, const gchar *code,
+		      const gchar *zone, const gchar *radar,
+		      const gchar *coordinates,
+		      const gchar *country_code,
+		      const gchar *tz_hint)
+{
+    WeatherLocation *location;
+
+    _weather_internal_check ();
+
+    location = g_new (WeatherLocation, 1);
+
+    /* name and metar code must be set */
+    location->name = g_strdup (name);
+    location->code = g_strdup (code);
+
+    if (zone) {
+        location->zone = g_strdup (zone);
+    } else {
+        location->zone = g_strdup ("------");
+    }
+
+    if (radar) {
+        location->radar = g_strdup (radar);
+    } else {
+        location->radar = g_strdup ("---");
+    }
+
+    if (location->zone[0] == '-') {
+        location->zone_valid = FALSE;
+    } else {
+        location->zone_valid = TRUE;
+    }
+
+    location->coordinates = NULL;
+    if (coordinates)
+    {
+	char **pieces;
+
+	pieces = g_strsplit (coordinates, " ", -1);
+
+	if (g_strv_length (pieces) == 2)
+	{
+            location->coordinates = g_strdup (coordinates);
+            location->latitude = dmsh2rad (pieces[0]);
+	    location->longitude = dmsh2rad (pieces[1]);
+	}
+
+	g_strfreev (pieces);
+    }
+
+    if (!location->coordinates)
+    {
+        location->coordinates = g_strdup ("---");
+        location->latitude = DBL_MAX;
+        location->longitude = DBL_MAX;
+    }
+
+    location->latlon_valid = (location->latitude < DBL_MAX && location->longitude < DBL_MAX);
+
+    location->country_code = g_strdup (country_code);
+    location->tz_hint = g_strdup (tz_hint);
+
+    return location;
+}
+
+WeatherLocation *
+weather_location_clone (const WeatherLocation *location)
+{
+    WeatherLocation *clone;
+
+    g_return_val_if_fail (location != NULL, NULL);
+
+    clone = weather_location_new (location->name,
+				  location->code, location->zone,
+				  location->radar, location->coordinates,
+				  location->country_code, location->tz_hint);
+    clone->latitude = location->latitude;
+    clone->longitude = location->longitude;
+    clone->latlon_valid = location->latlon_valid;
+    return clone;
+}
+
+void
+weather_location_free (WeatherLocation *location)
+{
+    if (location) {
+        g_free (location->name);
+        g_free (location->code);
+        g_free (location->zone);
+        g_free (location->radar);
+        g_free (location->coordinates);
+        g_free (location->country_code);
+        g_free (location->tz_hint);
+
+        g_free (location);
+    }
+}
+
+gboolean
+weather_location_equal (const WeatherLocation *location1, const WeatherLocation *location2)
+{
+    /* if something is NULL, then it's TRUE if and only if both are NULL) */
+    if (location1 == NULL || location2 == NULL)
+        return (location1 == location2);
+    if (!location1->code || !location2->code)
+        return (location1->code == location2->code);
+    if (!location1->name || !location2->name)
+        return (location1->name == location2->name);
+
+    return ((strcmp (location1->code, location2->code) == 0) &&
+	    (strcmp (location1->name, location2->name) == 0));
+}
+
+static const gchar *wind_direction_str[] = {
+    N_("Variable"),
+    N_("North"), N_("North - NorthEast"), N_("Northeast"), N_("East - NorthEast"),
+    N_("East"), N_("East - Southeast"), N_("Southeast"), N_("South - Southeast"),
+    N_("South"), N_("South - Southwest"), N_("Southwest"), N_("West - Southwest"),
+    N_("West"), N_("West - Northwest"), N_("Northwest"), N_("North - Northwest")
+};
+
+const gchar *
+weather_wind_direction_string (WeatherWindDirection wind)
+{
+    if (wind <= WIND_INVALID || wind >= WIND_LAST)
+	return _("Invalid");
+
+    return _(wind_direction_str[(int)wind]);
+}
+
+static const gchar *sky_str[] = {
+    N_("Clear Sky"),
+    N_("Broken clouds"),
+    N_("Scattered clouds"),
+    N_("Few clouds"),
+    N_("Overcast")
+};
+
+const gchar *
+weather_sky_string (WeatherSky sky)
+{
+    if (sky <= SKY_INVALID || sky >= SKY_LAST)
+	return _("Invalid");
+
+    return _(sky_str[(int)sky]);
+}
+
+
+/*
+ * Even though tedious, I switched to a 2D array for weather condition
+ * strings, in order to facilitate internationalization, esp. for languages
+ * with genders.
+ */
+
+/*
+ * Almost all reportable combinations listed in
+ * http://www.crh.noaa.gov/arx/wx.tbl.php are entered below, except those
+ * having 2 qualifiers mixed together [such as "Blowing snow in vicinity"
+ * (VCBLSN), "Thunderstorm in vicinity" (VCTS), etc].
+ * Combinations that are not possible are filled in with "??".
+ * Some other exceptions not handled yet, such as "SN BLSN" which has
+ * special meaning.
+ */
+
+/*
+ * Note, magic numbers, when you change the size here, make sure to change
+ * the below function so that new values are recognized
+ */
+/*                   NONE                         VICINITY                             LIGHT                      MODERATE                      HEAVY                      SHALLOW                      PATCHES                         PARTIAL                      THUNDERSTORM                    BLOWING                      SHOWERS                         DRIFTING                      FREEZING                      */
+/*               *******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************/
+static const gchar *conditions_str[24][13] = {
+/* Translators: If you want to know what "blowing" "shallow" "partial"
+ * etc means, you can go to http://www.weather.com/glossary/ and
+ * http://www.crh.noaa.gov/arx/wx.tbl.php */
+    /* NONE          */ {"??",                        "??",                                "??",                      "??",                         "??",                      "??",                        "??",                           "??",                        N_("Thunderstorm"),             "??",                        "??",                           "??",                         "??"                         },
+    /* DRIZZLE       */ {N_("Drizzle"),               "??",                                N_("Light drizzle"),       N_("Moderate drizzle"),       N_("Heavy drizzle"),       "??",                        "??",                           "??",                        "??",                           "??",                        "??",                           "??",                         N_("Freezing drizzle")       },
+    /* RAIN          */ {N_("Rain"),                  "??",                                N_("Light rain"),          N_("Moderate rain"),          N_("Heavy rain"),          "??",                        "??",                           "??",                        N_("Thunderstorm"),             "??",                        N_("Rain showers"),             "??",                         N_("Freezing rain")          },
+    /* SNOW          */ {N_("Snow"),                  "??",                                N_("Light snow"),          N_("Moderate snow"),          N_("Heavy snow"),          "??",                        "??",                           "??",                        N_("Snowstorm"),                N_("Blowing snowfall"),      N_("Snow showers"),             N_("Drifting snow"),          "??"                         },
+    /* SNOW_GRAINS   */ {N_("Snow grains"),           "??",                                N_("Light snow grains"),   N_("Moderate snow grains"),   N_("Heavy snow grains"),   "??",                        "??",                           "??",                        "??",                           "??",                        "??",                           "??",                         "??"                         },
+    /* ICE_CRYSTALS  */ {N_("Ice crystals"),          "??",                                "??",                      N_("Ice crystals"),           "??",                      "??",                        "??",                           "??",                        "??",                           "??",                        "??",                           "??",                         "??"                         },
+    /* ICE_PELLETS   */ {N_("Ice pellets"),           "??",                                N_("Few ice pellets"),     N_("Moderate ice pellets"),   N_("Heavy ice pellets"),   "??",                        "??",                           "??",                        N_("Ice pellet storm"),         "??",                        N_("Showers of ice pellets"),   "??",                         "??"                         },
+    /* HAIL          */ {N_("Hail"),                  "??",                                "??",                      N_("Hail"),                   "??",                      "??",                        "??",                           "??",                        N_("Hailstorm"),                "??",                        N_("Hail showers"),             "??",                         "??",                        },
+    /* SMALL_HAIL    */ {N_("Small hail"),            "??",                                "??",                      N_("Small hail"),             "??",                      "??",                        "??",                           "??",                        N_("Small hailstorm"),          "??",                        N_("Showers of small hail"),    "??",                         "??"                         },
+    /* PRECIPITATION */ {N_("Unknown precipitation"), "??",                                "??",                      "??",                         "??",                      "??",                        "??",                           "??",                        "??",                           "??",                        "??",                           "??",                         "??"                         },
+    /* MIST          */ {N_("Mist"),                  "??",                                "??",                      N_("Mist"),                   "??",                      "??",                        "??",                           "??",                        "??",                           "??",                        "??",                           "??",                         "??"                         },
+    /* FOG           */ {N_("Fog"),                   N_("Fog in the vicinity") ,          "??",                      N_("Fog"),                    "??",                      N_("Shallow fog"),           N_("Patches of fog"),           N_("Partial fog"),           "??",                           "??",                        "??",                           "??",                         N_("Freezing fog")           },
+    /* SMOKE         */ {N_("Smoke"),                 "??",                                "??",                      N_("Smoke"),                  "??",                      "??",                        "??",                           "??",                        "??",                           "??",                        "??",                           "??",                         "??"                         },
+    /* VOLCANIC_ASH  */ {N_("Volcanic ash"),          "??",                                "??",                      N_("Volcanic ash"),           "??",                      "??",                        "??",                           "??",                        "??",                           "??",                        "??",                           "??",                         "??"                         },
+    /* SAND          */ {N_("Sand"),                  "??",                                "??",                      N_("Sand"),                   "??",                      "??",                        "??",                           "??",                        "??",                           N_("Blowing sand"),          "",                             N_("Drifting sand"),          "??"                         },
+    /* HAZE          */ {N_("Haze"),                  "??",                                "??",                      N_("Haze"),                   "??",                      "??",                        "??",                           "??",                        "??",                           "??",                        "??",                           "??",                         "??"                         },
+    /* SPRAY         */ {"??",                        "??",                                "??",                      "??",                         "??",                      "??",                        "??",                           "??",                        "??",                           N_("Blowing sprays"),        "??",                           "??",                         "??"                         },
+    /* DUST          */ {N_("Dust"),                  "??",                                "??",                      N_("Dust"),                   "??",                      "??",                        "??",                           "??",                        "??",                           N_("Blowing dust"),          "??",                           N_("Drifting dust"),          "??"                         },
+    /* SQUALL        */ {N_("Squall"),                "??",                                "??",                      N_("Squall"),                 "??",                      "??",                        "??",                           "??",                        "??",                           "??",                        "??",                           "??",                         "??"                         },
+    /* SANDSTORM     */ {N_("Sandstorm"),             N_("Sandstorm in the vicinity") ,    "??",                      N_("Sandstorm"),              N_("Heavy sandstorm"),     "??",                        "??",                           "??",                        "??",                           "??",                        "??",                           "??",                         "??"                         },
+    /* DUSTSTORM     */ {N_("Duststorm"),             N_("Duststorm in the vicinity") ,    "??",                      N_("Duststorm"),              N_("Heavy duststorm"),     "??",                        "??",                           "??",                        "??",                           "??",                        "??",                           "??",                         "??"                         },
+    /* FUNNEL_CLOUD  */ {N_("Funnel cloud"),          "??",                                "??",                      "??",                         "??",                      "??",                        "??",                           "??",                        "??",                           "??",                        "??",                           "??",                         "??"                         },
+    /* TORNADO       */ {N_("Tornado"),               "??",                                "??",                      "??",                         "??",                      "??",                        "??",                           "??",                        "??",                           "??",                        "??",                           "??",                         "??"                         },
+    /* DUST_WHIRLS   */ {N_("Dust whirls"),           N_("Dust whirls in the vicinity") ,  "??",                      N_("Dust whirls"),            "??",                      "??",                        "??",                           "??",                        "??",                           "??",                        "??",                           "??",                         "??"                         }
+};
+
+const gchar *
+weather_conditions_string (WeatherConditions cond)
+{
+    const gchar *str;
+
+    if (!cond.significant) {
+	return "-";
+    } else {
+	if (cond.phenomenon > PHENOMENON_INVALID &&
+	    cond.phenomenon < PHENOMENON_LAST &&
+	    cond.qualifier > QUALIFIER_INVALID &&
+	    cond.qualifier < QUALIFIER_LAST)
+	    str = _(conditions_str[(int)cond.phenomenon][(int)cond.qualifier]);
+	else
+	    str = _("Invalid");
+	return (strlen (str) > 0) ? str : "-";
+    }
+}
+
+/* Locals turned global to facilitate asynchronous HTTP requests */
+
+
+gboolean
+requests_init (WeatherInfo *info)
+{
+    if (info->requests_pending)
+        return FALSE;
+
+    return TRUE;
+}
+
+void request_done (WeatherInfo *info, gboolean ok)
+{
+    if (ok) {
+	(void) calc_sun (info);
+	info->moonValid = info->valid && calc_moon (info);
+    }
+    if (!--info->requests_pending)
+        info->finish_cb (info, info->cb_data);
+}
+
+/* it's OK to pass in NULL */
+void
+free_forecast_list (WeatherInfo *info)
+{
+    GSList *p;
+
+    if (!info)
+	return;
+
+    for (p = info->forecast_list; p; p = p->next)
+	weather_info_free (p->data);
+
+    if (info->forecast_list) {
+	g_slist_free (info->forecast_list);
+	info->forecast_list = NULL;
+    }
+}
+
+/* Relative humidity computation - thanks to <Olof.Oberg@modopaper.modogroup.com> */
+
+static inline gdouble
+calc_humidity (gdouble temp, gdouble dewp)
+{
+    gdouble esat, esurf;
+
+    if (temp > -500.0 && dewp > -500.0) {
+	temp = TEMP_F_TO_C (temp);
+	dewp = TEMP_F_TO_C (dewp);
+
+	esat = 6.11 * pow (10.0, (7.5 * temp) / (237.7 + temp));
+	esurf = 6.11 * pow (10.0, (7.5 * dewp) / (237.7 + dewp));
+    } else {
+	esurf = -1.0;
+	esat = 1.0;
+    }
+    return ((esurf/esat) * 100.0);
+}
+
+static inline gdouble
+calc_apparent (WeatherInfo *info)
+{
+    gdouble temp = info->temp;
+    gdouble wind = WINDSPEED_KNOTS_TO_MPH (info->windspeed);
+    gdouble apparent = -1000.;
+
+    /*
+     * Wind chill calculations as of 01-Nov-2001
+     * http://www.nws.noaa.gov/om/windchill/index.shtml
+     * Some pages suggest that the formula will soon be adjusted
+     * to account for solar radiation (bright sun vs cloudy sky)
+     */
+    if (temp <= 50.0) {
+        if (wind > 3.0) {
+	    gdouble v = pow (wind, 0.16);
+	    apparent = 35.74 + 0.6215 * temp - 35.75 * v + 0.4275 * temp * v;
+	} else if (wind >= 0.) {
+	    apparent = temp;
+	}
+    }
+    /*
+     * Heat index calculations:
+     * http://www.srh.noaa.gov/fwd/heatindex/heat5.html
+     */
+    else if (temp >= 80.0) {
+        if (info->temp >= -500. && info->dew >= -500.) {
+	    gdouble humidity = calc_humidity (info->temp, info->dew);
+	    gdouble t2 = temp * temp;
+	    gdouble h2 = humidity * humidity;
+
+#if 1
+	    /*
+	     * A really precise formula.  Note that overall precision is
+	     * constrained by the accuracy of the instruments and that the
+	     * we receive the temperature and dewpoints as integers.
+	     */
+	    gdouble t3 = t2 * temp;
+	    gdouble h3 = h2 * temp;
+
+	    apparent = 16.923
+		+ 0.185212 * temp
+		+ 5.37941 * humidity
+		- 0.100254 * temp * humidity
+		+ 9.41695e-3 * t2
+		+ 7.28898e-3 * h2
+		+ 3.45372e-4 * t2 * humidity
+		- 8.14971e-4 * temp * h2
+		+ 1.02102e-5 * t2 * h2
+		- 3.8646e-5 * t3
+		+ 2.91583e-5 * h3
+		+ 1.42721e-6 * t3 * humidity
+		+ 1.97483e-7 * temp * h3
+		- 2.18429e-8 * t3 * h2
+		+ 8.43296e-10 * t2 * h3
+		- 4.81975e-11 * t3 * h3;
+#else
+	    /*
+	     * An often cited alternative: values are within 5 degrees for
+	     * most ranges between 10% and 70% humidity and to 110 degrees.
+	     */
+	    apparent = - 42.379
+		+  2.04901523 * temp
+		+ 10.14333127 * humidity
+		-  0.22475541 * temp * humidity
+		-  6.83783e-3 * t2
+		-  5.481717e-2 * h2
+		+  1.22874e-3 * t2 * humidity
+		+  8.5282e-4 * temp * h2
+		-  1.99e-6 * t2 * h2;
+#endif
+	}
+    } else {
+        apparent = temp;
+    }
+
+    return apparent;
+}
+
+WeatherInfo *
+_weather_info_fill (WeatherInfo *info,
+		    WeatherLocation *location,
+		    const WeatherPrefs *prefs,
+		    WeatherInfoFunc cb,
+		    gpointer data)
+{
+    g_return_val_if_fail (((info == NULL) && (location != NULL)) || \
+			  ((info != NULL) && (location == NULL)), NULL);
+    g_return_val_if_fail (prefs != NULL, NULL);
+
+    /* FIXME: i'm not sure this works as intended anymore */
+    if (!info) {
+    	info = g_new0 (WeatherInfo, 1);
+    	info->requests_pending = 0;
+    	info->location = weather_location_clone (location);
+    } else {
+        location = info->location;<--- Assignment of function parameter has no effect outside the function. Did you forget dereferencing it?<--- Variable 'location' is assigned a value that is never used.
+	if (info->forecast)
+	    g_free (info->forecast);
+	info->forecast = NULL;
+
+	free_forecast_list (info);
+
+	if (info->radar != NULL) {
+	    g_object_unref (info->radar);
+	    info->radar = NULL;
+	}
+    }
+
+    /* Update in progress */
+    if (!requests_init (info)) {
+        return NULL;
+    }
+
+    /* Defaults (just in case...) */
+    /* Well, no just in case anymore.  We may actually fail to fetch some
+     * fields. */
+    info->forecast_type = prefs->type;
+
+    info->temperature_unit = prefs->temperature_unit;
+    info->speed_unit = prefs->speed_unit;
+    info->pressure_unit = prefs->pressure_unit;
+    info->distance_unit = prefs->distance_unit;
+
+    info->update = 0;
+    info->sky = -1;
+    info->cond.significant = FALSE;
+    info->cond.phenomenon = PHENOMENON_NONE;
+    info->cond.qualifier = QUALIFIER_NONE;
+    info->temp = -1000.0;
+    info->tempMinMaxValid = FALSE;
+    info->temp_min = -1000.0;
+    info->temp_max = -1000.0;
+    info->dew = -1000.0;
+    info->wind = -1;
+    info->windspeed = -1;
+    info->pressure = -1.0;
+    info->visibility = -1.0;
+    info->sunriseValid = FALSE;
+    info->sunsetValid = FALSE;
+    info->moonValid = FALSE;
+    info->sunrise = 0;
+    info->sunset = 0;
+    info->moonphase = 0;
+    info->moonlatitude = 0;
+    info->forecast = NULL;
+    info->forecast_list = NULL;
+    info->radar = NULL;
+    info->radar_url = prefs->radar && prefs->radar_custom_url ?
+    		      g_strdup (prefs->radar_custom_url) : NULL;
+    info->finish_cb = cb;
+    info->cb_data = data;
+
+    if (!info->session) {
+	info->session = soup_session_async_new ();
+	soup_session_add_feature_by_type (info->session, SOUP_TYPE_PROXY_RESOLVER_DEFAULT);
+    }
+
+    metar_start_open (info);
+    iwin_start_open (info);
+
+    if (prefs->radar) {
+        wx_start_open (info);
+    }
+
+    return info;
+}
+
+void
+weather_info_abort (WeatherInfo *info)
+{
+    g_return_if_fail (info != NULL);
+
+    if (info->session) {
+	soup_session_abort (info->session);
+	info->requests_pending = 0;
+    }
+}
+
+WeatherInfo *
+weather_info_clone (const WeatherInfo *info)
+{
+    WeatherInfo *clone;
+
+    g_return_val_if_fail (info != NULL, NULL);
+
+    clone = g_new (WeatherInfo, 1);
+
+
+    /* move everything */
+    memmove (clone, info, sizeof (WeatherInfo));
+
+
+    /* special moves */
+    clone->location = weather_location_clone (info->location);
+    /* This handles null correctly */
+    clone->forecast = g_strdup (info->forecast);
+    clone->radar_url = g_strdup (info->radar_url);
+
+    if (info->forecast_list) {
+	GSList *p;
+
+	clone->forecast_list = NULL;
+	for (p = info->forecast_list; p; p = p->next) {
+	    clone->forecast_list = g_slist_prepend (clone->forecast_list, weather_info_clone (p->data));
+	}
+
+	clone->forecast_list = g_slist_reverse (clone->forecast_list);
+    }
+
+    clone->radar = info->radar;
+    if (clone->radar != NULL)
+	g_object_ref (clone->radar);
+
+    return clone;
+}
+
+void
+weather_info_free (WeatherInfo *info)
+{
+    if (!info)
+        return;
+
+    weather_info_abort (info);
+    if (info->session)
+	g_object_unref (info->session);
+
+    weather_location_free (info->location);
+    info->location = NULL;
+
+    g_free (info->forecast);
+    info->forecast = NULL;
+
+    free_forecast_list (info);
+
+    if (info->radar != NULL) {
+        g_object_unref (info->radar);
+        info->radar = NULL;
+    }
+
+    g_free (info);
+}
+
+gboolean
+weather_info_is_valid (WeatherInfo *info)
+{
+    g_return_val_if_fail (info != NULL, FALSE);
+    return info->valid;
+}
+
+gboolean
+weather_info_network_error (WeatherInfo *info)
+{
+    g_return_val_if_fail (info != NULL, FALSE);
+    return info->network_error;
+}
+
+void
+weather_info_to_metric (WeatherInfo *info)
+{
+    g_return_if_fail (info != NULL);
+
+    info->temperature_unit = TEMP_UNIT_CENTIGRADE;
+    info->speed_unit = SPEED_UNIT_MS;
+    info->pressure_unit = PRESSURE_UNIT_HPA;
+    info->distance_unit = DISTANCE_UNIT_METERS;
+}
+
+void
+weather_info_to_imperial (WeatherInfo *info)
+{
+    g_return_if_fail (info != NULL);
+
+    info->temperature_unit = TEMP_UNIT_FAHRENHEIT;
+    info->speed_unit = SPEED_UNIT_MPH;
+    info->pressure_unit = PRESSURE_UNIT_INCH_HG;
+    info->distance_unit = DISTANCE_UNIT_MILES;
+}
+
+const WeatherLocation *
+weather_info_get_location (WeatherInfo *info)
+{
+    g_return_val_if_fail (info != NULL, NULL);
+    return info->location;
+}
+
+const gchar *
+weather_info_get_location_name (WeatherInfo *info)
+{
+    g_return_val_if_fail (info != NULL, NULL);
+    g_return_val_if_fail (info->location != NULL, NULL);
+    return info->location->name;
+}
+
+const gchar *
+weather_info_get_update (WeatherInfo *info)
+{
+    static gchar buf[200];
+    char *utf8, *timeformat;
+
+    g_return_val_if_fail (info != NULL, NULL);
+
+    if (!info->valid)
+        return "-";
+
+    if (info->update != 0) {
+        struct tm tm;
+        localtime_r (&info->update, &tm);
+	/* Translators: this is a format string for strftime
+	 *             see `man 3 strftime` for more details
+	 */
+	timeformat = g_locale_from_utf8 (_("%a, %b %d / %H:%M"), -1,
+					 NULL, NULL, NULL);
+	if (!timeformat) {
+	    strcpy (buf, "???");
+	}
+	else if (strftime (buf, sizeof (buf), timeformat, &tm) <= 0) {<--- Unsigned less than zero
+	    strcpy (buf, "???");
+	}
+	g_free (timeformat);
+
+	/* Convert to UTF-8 */
+	utf8 = g_locale_to_utf8 (buf, -1, NULL, NULL, NULL);
+	strcpy (buf, utf8);
+	g_free (utf8);
+    } else {
+        strncpy (buf, _("Unknown observation time"), sizeof (buf));
+	buf[sizeof (buf)-1] = '\0';
+    }
+
+    return buf;
+}
+
+const gchar *
+weather_info_get_sky (WeatherInfo *info)
+{
+    g_return_val_if_fail (info != NULL, NULL);
+    if (!info->valid)
+        return "-";
+    if (info->sky < 0)
+	return _("Unknown");
+    return weather_sky_string (info->sky);
+}
+
+const gchar *
+weather_info_get_conditions (WeatherInfo *info)
+{
+    g_return_val_if_fail (info != NULL, NULL);
+    if (!info->valid)
+        return "-";
+    return weather_conditions_string (info->cond);
+}
+
+static const gchar *
+temperature_string (gdouble temp, TempUnit to_unit, gboolean want_round)
+{
+    static gchar buf[100];
+
+    switch (to_unit) {
+    case TEMP_UNIT_FAHRENHEIT:
+	if (!want_round) {
+	    /* Translators: This is the temperature in degrees Fahrenheit (\302\260 is U+00B0 DEGREE SIGN) */
+	    g_snprintf (buf, sizeof (buf), _("%.1f \302\260F"), temp);
+	} else {
+	    const int range_problem = FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW;
+	    gdouble temp_r;
+
+	    feclearexcept(range_problem);
+	    temp_r = round (temp);
+	    if (fetestexcept(range_problem))
+	        g_snprintf (buf, sizeof (buf), _("n/a"));
+	    else
+	        /* Translators: This is the temperature in degrees Fahrenheit (\302\260 is U+00B0 DEGREE SIGN) */
+	        g_snprintf (buf, sizeof (buf), _("%d \302\260F"), (int)temp_r);
+	}
+	break;
+    case TEMP_UNIT_CENTIGRADE:
+	if (!want_round) {
+	    /* Translators: This is the temperature in degrees Celsius (\302\260 is U+00B0 DEGREE SIGN) */
+	    g_snprintf (buf, sizeof (buf), _("%.1f \302\260C"), TEMP_F_TO_C (temp));
+	} else {
+	    const int range_problem = FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW;
+	    gdouble temp_r;
+
+	    feclearexcept(range_problem);
+	    temp_r = round (TEMP_F_TO_C (temp));
+	    if (fetestexcept(range_problem))
+	        g_snprintf (buf, sizeof (buf), _("n/a"));
+	    else
+	        /* Translators: This is the temperature in degrees Celsius (\302\260 is U+00B0 DEGREE SIGN) */
+	        g_snprintf (buf, sizeof (buf), _("%d \302\260C"), (int)temp_r);
+	}
+	break;
+    case TEMP_UNIT_KELVIN:
+	if (!want_round) {
+	    /* Translators: This is the temperature in kelvin */
+	    g_snprintf (buf, sizeof (buf), _("%.1f K"), TEMP_F_TO_K (temp));
+	} else {
+	    const int range_problem = FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW;
+	    gdouble temp_r;
+
+	    feclearexcept(range_problem);
+	    temp_r = round (TEMP_F_TO_K (temp));
+	    if (fetestexcept(range_problem))
+	        g_snprintf (buf, sizeof (buf), _("n/a"));
+	    else
+	        /* Translators: This is the temperature in kelvin */
+	        g_snprintf (buf, sizeof (buf), _("%d K"), (int)temp_r);
+	}
+	break;
+
+    case TEMP_UNIT_INVALID:
+    case TEMP_UNIT_DEFAULT:
+    default:
+	g_warning ("Conversion to illegal temperature unit: %d", to_unit);
+	return _("Unknown");
+    }
+
+    return buf;
+}
+
+const gchar *
+weather_info_get_temp (WeatherInfo *info)
+{
+    g_return_val_if_fail (info != NULL, NULL);
+
+    if (!info->valid)
+        return "-";
+    if (info->temp < -500.0)
+        return _("Unknown");
+
+    return temperature_string (info->temp, info->temperature_unit, FALSE);
+}
+
+const gchar *
+weather_info_get_temp_min (WeatherInfo *info)
+{
+    g_return_val_if_fail (info != NULL, NULL);
+
+    if (!info->valid || !info->tempMinMaxValid)
+        return "-";
+    if (info->temp_min < -500.0)
+        return _("Unknown");
+
+    return temperature_string (info->temp_min, info->temperature_unit, FALSE);
+}
+
+const gchar *
+weather_info_get_temp_max (WeatherInfo *info)
+{
+    g_return_val_if_fail (info != NULL, NULL);
+
+    if (!info->valid || !info->tempMinMaxValid)
+        return "-";
+    if (info->temp_max < -500.0)
+        return _("Unknown");
+
+    return temperature_string (info->temp_max, info->temperature_unit, FALSE);
+}
+
+const gchar *
+weather_info_get_dew (WeatherInfo *info)
+{
+    g_return_val_if_fail (info != NULL, NULL);
+
+    if (!info->valid)
+        return "-";
+    if (info->dew < -500.0)
+        return _("Unknown");
+
+    return temperature_string (info->dew, info->temperature_unit, FALSE);
+}
+
+const gchar *
+weather_info_get_humidity (WeatherInfo *info)
+{
+    static gchar buf[20];
+    gdouble humidity;
+
+    g_return_val_if_fail (info != NULL, NULL);
+
+    if (!info->valid)
+        return "-";
+
+    humidity = calc_humidity (info->temp, info->dew);
+    if (humidity < 0.0)
+        return _("Unknown");
+
+    /* Translators: This is the humidity in percent */
+    g_snprintf (buf, sizeof (buf), _("%.f%%"), humidity);
+    return buf;
+}
+
+const gchar *
+weather_info_get_apparent (WeatherInfo *info)
+{
+    gdouble apparent;
+
+    g_return_val_if_fail (info != NULL, NULL);
+    if (!info->valid)
+        return "-";
+
+    apparent = calc_apparent (info);
+    if (apparent < -500.0)
+        return _("Unknown");
+
+    return temperature_string (apparent, info->temperature_unit, FALSE);
+}
+
+static const gchar *
+windspeed_string (gfloat knots, SpeedUnit to_unit)
+{
+    static gchar buf[100];
+
+    switch (to_unit) {
+    case SPEED_UNIT_KNOTS:
+	/* Translators: This is the wind speed in knots */
+	g_snprintf (buf, sizeof (buf), _("%0.1f knots"), knots);
+	break;
+    case SPEED_UNIT_MPH:
+	/* Translators: This is the wind speed in miles per hour */
+	g_snprintf (buf, sizeof (buf), _("%.1f mph"), WINDSPEED_KNOTS_TO_MPH (knots));
+	break;
+    case SPEED_UNIT_KPH:
+	/* Translators: This is the wind speed in kilometers per hour */
+	g_snprintf (buf, sizeof (buf), _("%.1f km/h"), WINDSPEED_KNOTS_TO_KPH (knots));
+	break;
+    case SPEED_UNIT_MS:
+	/* Translators: This is the wind speed in meters per second */
+	g_snprintf (buf, sizeof (buf), _("%.1f m/s"), WINDSPEED_KNOTS_TO_MS (knots));
+	break;
+    case SPEED_UNIT_BFT:
+	/* Translators: This is the wind speed as a Beaufort force factor
+	 * (commonly used in nautical wind estimation).
+	 */
+	g_snprintf (buf, sizeof (buf), _("Beaufort force %.1f"),
+		    WINDSPEED_KNOTS_TO_BFT (knots));
+	break;
+    case SPEED_UNIT_INVALID:
+    case SPEED_UNIT_DEFAULT:
+    default:
+	g_warning ("Conversion to illegal speed unit: %d", to_unit);
+	return _("Unknown");
+    }
+
+    return buf;
+}
+
+const gchar *
+weather_info_get_wind (WeatherInfo *info)
+{
+    static gchar buf[200];
+
+    g_return_val_if_fail (info != NULL, NULL);
+
+    if (!info->valid)
+        return "-";
+    if (info->windspeed < 0.0 || info->wind < 0)
+        return _("Unknown");
+    if (info->windspeed == 0.00) {
+        strncpy (buf, _("Calm"), sizeof (buf));
+	buf[sizeof (buf)-1] = '\0';
+    } else {
+        /* Translators: This is 'wind direction' / 'wind speed' */
+        g_snprintf (buf, sizeof (buf), _("%s / %s"),
+		    weather_wind_direction_string (info->wind),
+		    windspeed_string (info->windspeed, info->speed_unit));
+    }
+    return buf;
+}
+
+const gchar *
+weather_info_get_pressure (WeatherInfo *info)
+{
+    static gchar buf[100];
+
+    g_return_val_if_fail (info != NULL, NULL);
+
+    if (!info->valid)
+        return "-";
+    if (info->pressure < 0.0)
+        return _("Unknown");
+
+    switch (info->pressure_unit) {
+    case PRESSURE_UNIT_INCH_HG:
+	/* Translators: This is pressure in inches of mercury */
+	g_snprintf (buf, sizeof (buf), _("%.2f inHg"), info->pressure);
+	break;
+    case PRESSURE_UNIT_MM_HG:
+	/* Translators: This is pressure in millimeters of mercury */
+	g_snprintf (buf, sizeof (buf), _("%.1f mmHg"), PRESSURE_INCH_TO_MM (info->pressure));
+	break;
+    case PRESSURE_UNIT_KPA:
+	/* Translators: This is pressure in kiloPascals */
+	g_snprintf (buf, sizeof (buf), _("%.2f kPa"), PRESSURE_INCH_TO_KPA (info->pressure));
+	break;
+    case PRESSURE_UNIT_HPA:
+	/* Translators: This is pressure in hectoPascals */
+	g_snprintf (buf, sizeof (buf), _("%.2f hPa"), PRESSURE_INCH_TO_HPA (info->pressure));
+	break;
+    case PRESSURE_UNIT_MB:
+	/* Translators: This is pressure in millibars */
+	g_snprintf (buf, sizeof (buf), _("%.2f mb"), PRESSURE_INCH_TO_MB (info->pressure));
+	break;
+    case PRESSURE_UNIT_ATM:
+	/* Translators: This is pressure in atmospheres */
+	g_snprintf (buf, sizeof (buf), _("%.3f atm"), PRESSURE_INCH_TO_ATM (info->pressure));
+	break;
+
+    case PRESSURE_UNIT_INVALID:
+    case PRESSURE_UNIT_DEFAULT:
+    default:
+	g_warning ("Conversion to illegal pressure unit: %d", info->pressure_unit);
+	return _("Unknown");
+    }
+
+    return buf;
+}
+
+const gchar *
+weather_info_get_visibility (WeatherInfo *info)
+{
+    static gchar buf[100];
+
+    g_return_val_if_fail (info != NULL, NULL);
+
+    if (!info->valid)
+        return "-";
+    if (info->visibility < 0.0)
+        return _("Unknown");
+
+    switch (info->distance_unit) {
+    case DISTANCE_UNIT_MILES:
+	/* Translators: This is the visibility in miles */
+	g_snprintf (buf, sizeof (buf), _("%.1f miles"), info->visibility);
+	break;
+    case DISTANCE_UNIT_KM:
+	/* Translators: This is the visibility in kilometers */
+	g_snprintf (buf, sizeof (buf), _("%.1f km"), VISIBILITY_SM_TO_KM (info->visibility));
+	break;
+    case DISTANCE_UNIT_METERS:
+	/* Translators: This is the visibility in meters */
+	g_snprintf (buf, sizeof (buf), _("%.0fm"), VISIBILITY_SM_TO_M (info->visibility));
+	break;
+
+    case DISTANCE_UNIT_INVALID:
+    case DISTANCE_UNIT_DEFAULT:
+    default:
+	g_warning ("Conversion to illegal visibility unit: %d", info->pressure_unit);
+	return _("Unknown");
+    }
+
+    return buf;
+}
+
+const gchar *
+weather_info_get_sunrise (WeatherInfo *info)
+{
+    static gchar buf[200];
+    struct tm tm;
+
+    g_return_val_if_fail (info && info->location, NULL);
+
+    if (!info->location->latlon_valid)
+        return "-";
+    if (!info->valid)
+        return "-";
+    if (!calc_sun (info))
+        return "-";
+
+    localtime_r (&info->sunrise, &tm);
+    if (strftime (buf, sizeof (buf), _("%H:%M"), &tm) <= 0)<--- Unsigned less than zero
+        return "-";
+    return buf;
+}
+
+const gchar *
+weather_info_get_sunset (WeatherInfo *info)
+{
+    static gchar buf[200];
+    struct tm tm;
+
+    g_return_val_if_fail (info && info->location, NULL);
+
+    if (!info->location->latlon_valid)
+        return "-";
+    if (!info->valid)
+        return "-";
+    if (!calc_sun (info))
+        return "-";
+
+    localtime_r (&info->sunset, &tm);
+    if (strftime (buf, sizeof (buf), _("%H:%M"), &tm) <= 0)<--- Unsigned less than zero
+        return "-";
+    return buf;
+}
+
+const gchar *
+weather_info_get_forecast (WeatherInfo *info)
+{
+    g_return_val_if_fail (info != NULL, NULL);
+    return info->forecast;
+}
+
+/**
+ * weather_info_get_forecast_list:
+ * Returns list of WeatherInfo* objects for the forecast.
+ * The list is owned by the 'info' object thus is alive as long
+ * as the 'info'. This list is filled only when requested with
+ * type FORECAST_LIST and if available for given location.
+ * The 'update' property is the date/time when the forecast info
+ * is used for.
+ **/
+GSList *
+weather_info_get_forecast_list (WeatherInfo *info)
+{
+    g_return_val_if_fail (info != NULL, NULL);
+
+    if (!info->valid)
+	return NULL;
+
+    return info->forecast_list;
+}
+
+GdkPixbufAnimation *
+weather_info_get_radar (WeatherInfo *info)
+{
+    g_return_val_if_fail (info != NULL, NULL);
+    return info->radar;
+}
+
+const gchar *
+weather_info_get_temp_summary (WeatherInfo *info)
+{
+    g_return_val_if_fail (info != NULL, NULL);
+
+    if (!info->valid || info->temp < -500.0)
+        return "--";
+
+    return temperature_string (info->temp, info->temperature_unit, TRUE);
+
+}
+
+gchar *
+weather_info_get_weather_summary (WeatherInfo *info)
+{
+    const gchar *buf;
+
+    g_return_val_if_fail (info != NULL, NULL);
+
+    if (!info->valid)
+	return g_strdup (_("Retrieval failed"));
+    buf = weather_info_get_conditions (info);
+    if (!strcmp (buf, "-"))
+        buf = weather_info_get_sky (info);
+    return g_strdup_printf ("%s: %s", weather_info_get_location_name (info), buf);
+}
+
+const gchar *
+weather_info_get_icon_name (WeatherInfo *info)
+{
+    WeatherConditions cond;
+    WeatherSky        sky;
+    time_t            current_time;
+    gboolean          daytime;
+    gchar*            icon;
+    static gchar      icon_buffer[32];
+    WeatherMoonPhase  moonPhase;
+    WeatherMoonLatitude moonLat;
+    gint              phase;
+
+    g_return_val_if_fail (info != NULL, NULL);
+
+    if (!info->valid)
+        return NULL;
+
+    cond = info->cond;
+    sky = info->sky;
+
+    if (cond.significant) {
+	if (cond.phenomenon != PHENOMENON_NONE &&
+	    cond.qualifier == QUALIFIER_THUNDERSTORM)
+            return "weather-storm";
+
+        switch (cond.phenomenon) {
+	case PHENOMENON_INVALID:
+	case PHENOMENON_LAST:
+	case PHENOMENON_NONE:
+	    break;
+
+	case PHENOMENON_DRIZZLE:
+	case PHENOMENON_RAIN:
+	case PHENOMENON_UNKNOWN_PRECIPITATION:
+	case PHENOMENON_HAIL:
+	case PHENOMENON_SMALL_HAIL:
+	    return "weather-showers";
+
+	case PHENOMENON_SNOW:
+	case PHENOMENON_SNOW_GRAINS:
+	case PHENOMENON_ICE_PELLETS:
+	case PHENOMENON_ICE_CRYSTALS:
+	    return "weather-snow";
+
+	case PHENOMENON_TORNADO:
+	case PHENOMENON_SQUALL:
+	    return "weather-storm";
+
+	case PHENOMENON_MIST:
+	case PHENOMENON_FOG:
+	case PHENOMENON_SMOKE:
+	case PHENOMENON_VOLCANIC_ASH:
+	case PHENOMENON_SAND:
+	case PHENOMENON_HAZE:
+	case PHENOMENON_SPRAY:
+	case PHENOMENON_DUST:
+	case PHENOMENON_SANDSTORM:
+	case PHENOMENON_DUSTSTORM:
+	case PHENOMENON_FUNNEL_CLOUD:
+	case PHENOMENON_DUST_WHIRLS:
+	    return "weather-fog";
+        }
+    }
+
+    if (info->midnightSun ||
+	(!info->sunriseValid && !info->sunsetValid))
+	daytime = TRUE;
+    else if (info->polarNight)
+	daytime = FALSE;
+    else {
+	current_time = time (NULL);
+	daytime =
+	    ( !info->sunriseValid || (current_time >= info->sunrise) ) &&
+	    ( !info->sunsetValid || (current_time < info->sunset) );
+    }
+
+    switch (sky) {
+    case SKY_INVALID:
+    case SKY_LAST:
+    case SKY_CLEAR:
+	if (daytime)
+	    return "weather-clear";
+	else {
+	    icon = g_stpcpy(icon_buffer, "weather-clear-night");
+	    break;
+	}
+
+    case SKY_BROKEN:
+    case SKY_SCATTERED:
+    case SKY_FEW:
+	if (daytime)
+	    return "weather-few-clouds";
+	else {
+	    icon = g_stpcpy(icon_buffer, "weather-few-clouds-night");
+	    break;
+	}
+
+    case SKY_OVERCAST:
+	return "weather-overcast";
+
+    default: /* unrecognized */
+	return NULL;
+    }
+
+    /*
+     * A phase-of-moon icon is to be returned.
+     * Determine which one based on the moon's location
+     */
+    if (info->moonValid && weather_info_get_value_moonphase(info, &moonPhase, &moonLat)) {
+	phase = (gint)((moonPhase * MOON_PHASES / 360.) + 0.5);
+	if (phase == MOON_PHASES) {
+	    phase = 0;
+	} else if (phase > 0 &&
+		   (RADIANS_TO_DEGREES(weather_info_get_location(info)->latitude)
+		    < moonLat)) {
+	    /*
+	     * Locations south of the moon's latitude will see the moon in the
+	     * northern sky.  The moon waxes and wanes from left to right
+	     * so we reference an icon running in the opposite direction.
+	     */
+	    phase = MOON_PHASES - phase;
+	}
+
+	/*
+	 * If the moon is not full then append the angle to the icon string.
+	 * Note that an icon by this name is not required to exist:
+	 * the caller can use GTK_ICON_LOOKUP_GENERIC_FALLBACK to fall back to
+	 * the full moon image.
+	 */
+	if ((0 == (MOON_PHASES & 0x1)) && (MOON_PHASES/2 != phase)) {
+	    g_snprintf(icon, sizeof(icon_buffer) - strlen(icon_buffer),
+		       "-%03d", phase * 360 / MOON_PHASES);
+	}
+    }
+    return icon_buffer;
+}
+
+static gboolean
+temperature_value (gdouble temp_f,
+		   TempUnit to_unit,
+		   gdouble *value,
+		   TempUnit def_unit)
+{
+    gboolean ok = TRUE;
+
+    *value = 0.0;
+    if (temp_f < -500.0)
+	return FALSE;
+
+    if (to_unit == TEMP_UNIT_DEFAULT)
+	    to_unit = def_unit;
+
+    switch (to_unit) {
+        case TEMP_UNIT_FAHRENHEIT:
+	    *value = temp_f;
+	    break;
+        case TEMP_UNIT_CENTIGRADE:
+	    *value = TEMP_F_TO_C (temp_f);
+	    break;
+        case TEMP_UNIT_KELVIN:
+	    *value = TEMP_F_TO_K (temp_f);
+	    break;
+        case TEMP_UNIT_INVALID:
+        case TEMP_UNIT_DEFAULT:
+	default:
+	    ok = FALSE;
+	    break;
+    }
+
+    return ok;
+}
+
+static gboolean
+speed_value (gdouble knots, SpeedUnit to_unit, gdouble *value, SpeedUnit def_unit)
+{
+    gboolean ok = TRUE;
+
+    *value = -1.0;
+
+    if (knots < 0.0)
+	return FALSE;
+
+    if (to_unit == SPEED_UNIT_DEFAULT)
+	    to_unit = def_unit;
+
+    switch (to_unit) {
+        case SPEED_UNIT_KNOTS:
+            *value = knots;
+	    break;
+        case SPEED_UNIT_MPH:
+            *value = WINDSPEED_KNOTS_TO_MPH (knots);
+	    break;
+        case SPEED_UNIT_KPH:
+            *value = WINDSPEED_KNOTS_TO_KPH (knots);
+	    break;
+        case SPEED_UNIT_MS:
+            *value = WINDSPEED_KNOTS_TO_MS (knots);
+	    break;
+	case SPEED_UNIT_BFT:
+	    *value = WINDSPEED_KNOTS_TO_BFT (knots);
+	    break;
+        case SPEED_UNIT_INVALID:
+        case SPEED_UNIT_DEFAULT:
+        default:
+            ok = FALSE;
+            break;
+    }
+
+    return ok;
+}
+
+static gboolean
+pressure_value (gdouble inHg, PressureUnit to_unit, gdouble *value, PressureUnit def_unit)
+{
+    gboolean ok = TRUE;
+
+    *value = -1.0;
+
+    if (inHg < 0.0)
+	return FALSE;
+
+    if (to_unit == PRESSURE_UNIT_DEFAULT)
+	    to_unit = def_unit;
+
+    switch (to_unit) {
+        case PRESSURE_UNIT_INCH_HG:
+            *value = inHg;
+	    break;
+        case PRESSURE_UNIT_MM_HG:
+            *value = PRESSURE_INCH_TO_MM (inHg);
+	    break;
+        case PRESSURE_UNIT_KPA:
+            *value = PRESSURE_INCH_TO_KPA (inHg);
+	    break;
+        case PRESSURE_UNIT_HPA:
+            *value = PRESSURE_INCH_TO_HPA (inHg);
+	    break;
+        case PRESSURE_UNIT_MB:
+            *value = PRESSURE_INCH_TO_MB (inHg);
+	    break;
+        case PRESSURE_UNIT_ATM:
+            *value = PRESSURE_INCH_TO_ATM (inHg);
+	    break;
+        case PRESSURE_UNIT_INVALID:
+        case PRESSURE_UNIT_DEFAULT:
+        default:
+	    ok = FALSE;
+	    break;
+    }
+
+    return ok;
+}
+
+static gboolean
+distance_value (gdouble miles, DistanceUnit to_unit, gdouble *value, DistanceUnit def_unit)
+{
+    gboolean ok = TRUE;
+
+    *value = -1.0;
+
+    if (miles < 0.0)
+	return FALSE;
+
+    if (to_unit == DISTANCE_UNIT_DEFAULT)
+	    to_unit = def_unit;
+
+    switch (to_unit) {
+        case DISTANCE_UNIT_MILES:
+            *value = miles;
+            break;
+        case DISTANCE_UNIT_KM:
+            *value = VISIBILITY_SM_TO_KM (miles);
+            break;
+        case DISTANCE_UNIT_METERS:
+            *value = VISIBILITY_SM_TO_M (miles);
+            break;
+        case DISTANCE_UNIT_INVALID:
+        case DISTANCE_UNIT_DEFAULT:
+        default:
+	    ok = FALSE;
+	    break;
+    }
+
+    return ok;
+}
+
+gboolean
+weather_info_get_value_sky (WeatherInfo *info, WeatherSky *sky)
+{
+    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (sky != NULL, FALSE);
+
+    if (!info->valid)
+	return FALSE;
+
+    if (info->sky <= SKY_INVALID || info->sky >= SKY_LAST)
+	return FALSE;
+
+    *sky = info->sky;
+
+    return TRUE;
+}
+
+gboolean
+weather_info_get_value_conditions (WeatherInfo *info, WeatherConditionPhenomenon *phenomenon, WeatherConditionQualifier *qualifier)
+{
+    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (phenomenon != NULL, FALSE);
+    g_return_val_if_fail (qualifier != NULL, FALSE);
+
+    if (!info->valid)
+	return FALSE;
+
+    if (!info->cond.significant)
+	return FALSE;
+
+    if (!(info->cond.phenomenon > PHENOMENON_INVALID &&
+	  info->cond.phenomenon < PHENOMENON_LAST &&
+	  info->cond.qualifier > QUALIFIER_INVALID &&
+	  info->cond.qualifier < QUALIFIER_LAST))
+        return FALSE;
+
+    *phenomenon = info->cond.phenomenon;
+    *qualifier = info->cond.qualifier;
+
+    return TRUE;
+}
+
+gboolean
+weather_info_get_value_temp (WeatherInfo *info, TempUnit unit, gdouble *value)
+{
+    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (value != NULL, FALSE);
+
+    if (!info->valid)
+	return FALSE;
+
+    return temperature_value (info->temp, unit, value, info->temperature_unit);
+}
+
+gboolean
+weather_info_get_value_temp_min (WeatherInfo *info, TempUnit unit, gdouble *value)
+{
+    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (value != NULL, FALSE);
+
+    if (!info->valid || !info->tempMinMaxValid)
+	return FALSE;
+
+    return temperature_value (info->temp_min, unit, value, info->temperature_unit);
+}
+
+gboolean
+weather_info_get_value_temp_max (WeatherInfo *info, TempUnit unit, gdouble *value)
+{
+    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (value != NULL, FALSE);
+
+    if (!info->valid || !info->tempMinMaxValid)
+	return FALSE;
+
+    return temperature_value (info->temp_max, unit, value, info->temperature_unit);
+}
+
+gboolean
+weather_info_get_value_dew (WeatherInfo *info, TempUnit unit, gdouble *value)
+{
+    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (value != NULL, FALSE);
+
+    if (!info->valid)
+	return FALSE;
+
+    return temperature_value (info->dew, unit, value, info->temperature_unit);
+}
+
+gboolean
+weather_info_get_value_apparent (WeatherInfo *info, TempUnit unit, gdouble *value)
+{
+    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (value != NULL, FALSE);
+
+    if (!info->valid)
+	return FALSE;
+
+    return temperature_value (calc_apparent (info), unit, value, info->temperature_unit);
+}
+
+gboolean
+weather_info_get_value_update (WeatherInfo *info, time_t *value)
+{
+    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (value != NULL, FALSE);
+
+    if (!info->valid)
+	return FALSE;
+
+    *value = info->update;
+
+    return TRUE;
+}
+
+gboolean
+weather_info_get_value_sunrise (WeatherInfo *info, time_t *value)
+{
+    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (value != NULL, FALSE);
+
+    if (!info->valid || !info->sunriseValid)
+	return FALSE;
+
+    *value = info->sunrise;
+
+    return TRUE;
+}
+
+gboolean
+weather_info_get_value_sunset (WeatherInfo *info, time_t *value)
+{
+    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (value != NULL, FALSE);
+
+    if (!info->valid || !info->sunsetValid)
+	return FALSE;
+
+    *value = info->sunset;
+
+    return TRUE;
+}
+
+gboolean
+weather_info_get_value_moonphase (WeatherInfo      *info,
+				  WeatherMoonPhase *value,
+				  WeatherMoonLatitude *lat)
+{
+    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (value != NULL, FALSE);
+
+    if (!info->valid || !info->moonValid)
+	return FALSE;
+
+    *value = info->moonphase;
+    *lat   = info->moonlatitude;
+
+    return TRUE;
+}
+
+gboolean
+weather_info_get_value_wind (WeatherInfo *info, SpeedUnit unit, gdouble *speed, WeatherWindDirection *direction)
+{
+    gboolean res = FALSE;
+
+    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (speed != NULL, FALSE);
+    g_return_val_if_fail (direction != NULL, FALSE);
+
+    if (!info->valid)
+	return FALSE;
+
+    if (info->windspeed < 0.0 || info->wind <= WIND_INVALID || info->wind >= WIND_LAST)
+        return FALSE;
+
+    res = speed_value (info->windspeed, unit, speed, info->speed_unit);
+    *direction = info->wind;
+
+    return res;
+}
+
+gboolean
+weather_info_get_value_pressure (WeatherInfo *info, PressureUnit unit, gdouble *value)
+{
+    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (value != NULL, FALSE);
+
+    if (!info->valid)
+	return FALSE;
+
+    return pressure_value (info->pressure, unit, value, info->pressure_unit);
+}
+
+gboolean
+weather_info_get_value_visibility (WeatherInfo *info, DistanceUnit unit, gdouble *value)
+{
+    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (value != NULL, FALSE);
+
+    if (!info->valid)
+	return FALSE;
+
+    return distance_value (info->visibility, unit, value, info->distance_unit);
+}
+
+/**
+ * weather_info_get_upcoming_moonphases:
+ * @info:   WeatherInfo containing the time_t of interest
+ * @phases: An array of four time_t values that will hold the returned values.
+ *    The values are estimates of the time of the next new, quarter, full and
+ *    three-quarter moons.
+ *
+ * Returns: gboolean indicating success or failure
+ */
+gboolean
+weather_info_get_upcoming_moonphases (WeatherInfo *info, time_t *phases)
+{
+    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (phases != NULL, FALSE);
+
+    return calc_moon_phases(info, phases);
+}
+
+static void
+_weather_internal_check (void)
+{
+    g_assert (G_N_ELEMENTS (wind_direction_str) == WIND_LAST);
+    g_assert (G_N_ELEMENTS (sky_str) == SKY_LAST);
+    g_assert (G_N_ELEMENTS (conditions_str) == PHENOMENON_LAST);
+    g_assert (G_N_ELEMENTS (conditions_str[0]) == QUALIFIER_LAST);
+}
+
+
+
+
+ + + diff --git a/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/2.html b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/2.html new file mode 100644 index 0000000..02a2882 --- /dev/null +++ b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/2.html @@ -0,0 +1,708 @@ + + + + + + Cppcheck - HTML report - libmateweather + + + + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* parser.c - Locations.xml parser
+ *
+ * Copyright 2008, Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#define MATEWEATHER_I_KNOW_THIS_IS_UNSTABLE
+#include "weather-priv.h"
+
+#include "parser.h"
+
+#include <string.h>
+#include <glib.h>
+#include <libxml/xmlreader.h>
+
+/**
+ * mateweather_parser_get_value:
+ * @parser: a #MateWeatherParser
+ *
+ * Gets the text of the element whose start tag @parser is pointing to.
+ * Leaves @parser pointing at the next node after the element's end tag.
+ *
+ * Return value: the text of the current node, as a libxml-allocated
+ * string, or %NULL if the node is empty.
+ **/
+char *
+mateweather_parser_get_value (MateWeatherParser *parser)
+{
+    char *value;
+
+    /* check for null node */
+    if (xmlTextReaderIsEmptyElement (parser->xml))
+	return NULL;
+
+    /* the next "node" is the text node containing the value we want to get */
+    if (xmlTextReaderRead (parser->xml) != 1)
+	return NULL;
+
+    value = (char *) xmlTextReaderValue (parser->xml);
+
+    /* move on to the end of this node */
+    while (xmlTextReaderNodeType (parser->xml) != XML_READER_TYPE_END_ELEMENT) {
+	if (xmlTextReaderRead (parser->xml) != 1) {
+	    xmlFree (value);
+	    return NULL;
+	}
+    }
+
+    /* consume the end element too */
+    if (xmlTextReaderRead (parser->xml) != 1) {
+	xmlFree (value);
+	return NULL;
+    }
+
+    return value;
+}
+
+/**
+ * mateweather_parser_get_localized_value:
+ * @parser: a #MateWeatherParser
+ *
+ * Looks at the name of the element @parser is currently pointing to, and
+ * returns the content of either that node, or a following node with
+ * the same name but an "xml:lang" attribute naming one of the locale
+ * languages. Leaves @parser pointing to the next node after the last
+ * consecutive element with the same name as the original element.
+ *
+ * Return value: the localized (or unlocalized) text, as a
+ * libxml-allocated string, or %NULL if the node is empty.
+ **/
+char *
+mateweather_parser_get_localized_value (MateWeatherParser *parser)
+{
+    const char *this_language;
+    int best_match = INT_MAX;
+    const char *lang, *tagname, *next_tagname;
+    gboolean keep_going;
+    char *name = NULL;
+    int i;
+
+    tagname = (const char *) xmlTextReaderConstName (parser->xml);
+
+    do {
+	/* First let's get the language */
+	lang = (const char *) xmlTextReaderConstXmlLang (parser->xml);
+
+	if (lang == NULL)
+	    this_language = "C";
+	else
+	    this_language = lang;
+
+	/* the next "node" is text node containing the actual name */
+	if (xmlTextReaderRead (parser->xml) != 1) {
+	    if (name)
+		xmlFree (name);
+	    return NULL;
+	}
+
+	for (i = 0; parser->locales[i] && i < best_match; i++) {
+	    if (!strcmp (parser->locales[i], this_language)) {
+		/* if we've already encounted a less accurate
+		   translation, then free it */
+		g_free (name);
+
+		name = (char *) xmlTextReaderValue (parser->xml);
+		best_match = i;
+
+		break;
+	    }
+	}
+
+	/* Skip to close tag */
+	while (xmlTextReaderNodeType (parser->xml) != XML_READER_TYPE_END_ELEMENT) {
+	    if (xmlTextReaderRead (parser->xml) != 1) {
+		xmlFree (name);
+		return NULL;
+	    }
+	}
+
+	/* Skip junk */
+	do {
+	    if (xmlTextReaderRead (parser->xml) != 1) {
+		xmlFree (name);
+		return NULL;
+	    }
+	} while (xmlTextReaderNodeType (parser->xml) != XML_READER_TYPE_ELEMENT &&
+		 xmlTextReaderNodeType (parser->xml) != XML_READER_TYPE_END_ELEMENT);
+
+	/* if the next tag has the same name then keep going */
+	next_tagname = (const char *) xmlTextReaderConstName (parser->xml);
+	keep_going = !strcmp (next_tagname, tagname);
+
+    } while (keep_going);
+
+    return name;
+}
+
+MateWeatherParser *
+mateweather_parser_new (gboolean use_regions)
+{
+    MateWeatherParser *parser;
+    int zlib_support;
+    int i, keep_going;
+    char *filename;
+    char *tagname, *format;
+    time_t now;
+    struct tm tm;
+
+    parser = g_slice_new0 (MateWeatherParser);
+    parser->use_regions = use_regions;
+    parser->locales = g_get_language_names ();
+
+    zlib_support = xmlHasFeature (XML_WITH_ZLIB);
+
+    /* First try to load a locale-specific XML. It's much faster. */
+    filename = NULL;
+    for (i = 0; parser->locales[i] != NULL; i++) {
+	filename = g_strdup_printf ("%s/Locations.%s.xml",
+				    MATEWEATHER_XML_LOCATION_DIR,
+				    parser->locales[i]);
+
+	if (g_file_test (filename, G_FILE_TEST_IS_REGULAR))
+	    break;
+
+	g_free (filename);
+	filename = NULL;
+
+        if (!zlib_support)
+            continue;
+
+	filename = g_strdup_printf ("%s/Locations.%s.xml.gz",
+				    MATEWEATHER_XML_LOCATION_DIR,
+				    parser->locales[i]);
+
+	if (g_file_test (filename, G_FILE_TEST_IS_REGULAR))
+	    break;
+
+	g_free (filename);
+	filename = NULL;
+    }
+
+    /* Fall back on the file containing either all translations, or only
+     * the english names (depending on the configure flags).
+     */
+    if (!filename)
+	filename = g_build_filename (MATEWEATHER_XML_LOCATION_DIR, "Locations.xml", NULL);
+
+    if (!g_file_test (filename, G_FILE_TEST_IS_REGULAR) && zlib_support) {
+        g_free (filename);
+	filename = g_build_filename (MATEWEATHER_XML_LOCATION_DIR, "Locations.xml.gz", NULL);
+    }
+
+    /* Open the xml file containing the different locations */
+    parser->xml = xmlNewTextReaderFilename (filename);
+    g_free (filename);
+
+    if (parser->xml == NULL)
+	goto error_out;
+
+    /* fast forward to the first element */
+    do {
+	/* if we encounter a problem here, exit right away */
+	if (xmlTextReaderRead (parser->xml) != 1)
+	    goto error_out;
+    } while (xmlTextReaderNodeType (parser->xml) != XML_READER_TYPE_ELEMENT);
+
+    /* check the name and format */
+    tagname = (char *) xmlTextReaderName (parser->xml);
+    keep_going = tagname && !strcmp (tagname, "mateweather");
+    xmlFree (tagname);
+
+    if (!keep_going)
+	goto error_out;
+
+    format = (char *) xmlTextReaderGetAttribute (parser->xml, (xmlChar *) "format");
+    keep_going = format && !strcmp (format, "1.0");
+    xmlFree (format);
+
+    if (!keep_going)
+	goto error_out;
+
+    /* Get timestamps for the start and end of this year */
+    now = time (NULL);
+    tm = *gmtime (&now);
+    tm.tm_mon = 0;
+    tm.tm_mday = 1;
+    tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
+    parser->year_start = mktime (&tm);
+    tm.tm_year++;
+    parser->year_end = mktime (&tm);
+
+    return parser;
+
+error_out:
+    mateweather_parser_free (parser);
+    return NULL;
+}
+
+void
+mateweather_parser_free (MateWeatherParser *parser)
+{
+    if (parser->xml)
+	xmlFreeTextReader (parser->xml);
+    g_slice_free (MateWeatherParser, parser);
+}
+
+
+
+
+ + + diff --git a/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/3.html b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/3.html new file mode 100644 index 0000000..2bd6a15 --- /dev/null +++ b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/3.html @@ -0,0 +1,330 @@ + + + + + + Cppcheck - HTML report - libmateweather + + + + + + +
+ +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/*
+ * Simple program to reproduce METAR parsing results from command line
+ */
+
+#include <glib.h>
+#include <string.h>
+#include <stdio.h>
+#define MATEWEATHER_I_KNOW_THIS_IS_UNSTABLE
+#include "weather-priv.h"
+
+#ifndef BUFLEN
+#define BUFLEN 4096
+#endif /* BUFLEN */
+
+int
+main (int argc, char **argv)
+{
+    FILE*  stream = stdin;
+    gchar* filename = NULL;<--- Assignment 'filename=NULL', assigned value is 0
+    GOptionEntry entries[] = {
+	{ "file", 'f', 0, G_OPTION_ARG_FILENAME, &filename,
+	  "file constaining metar observations", NULL },
+	{ NULL }
+    };
+    GOptionContext* context;
+    GError* error = NULL;
+    char buf[BUFLEN];
+    int len;
+    WeatherInfo info;
+
+    context = g_option_context_new ("- test libmateweather metar parser");
+    g_option_context_add_main_entries (context, entries, NULL);
+    g_option_context_parse (context, &argc, &argv, &error);
+
+    if (error) {<--- Assuming condition is false
+	perror (error->message);
+	return error->code;
+    }
+    if (filename) {<--- Condition 'filename' is always false
+	stream = fopen (filename, "r");
+	if (!stream) {
+	    perror ("fopen");
+	    return -1;
+	}
+    } else {
+	fprintf (stderr, "Enter a METAR string...\n");
+    }
+
+    while (fgets (buf, sizeof (buf), stream)) {
+	len = strlen (buf);
+	if (buf[len - 1] == '\n') {
+	    buf[--len] = '\0';
+	}
+	printf ("\n%s\n", buf);
+
+	memset (&info, 0, sizeof (info));
+	info.valid = 1;
+	metar_parse (buf, &info);
+	weather_info_to_metric (&info);
+	printf ("Returned info:\n");
+	printf ("  update:   %s", ctime (&info.update));
+	printf ("  sky:      %s\n", weather_info_get_sky (&info));
+	printf ("  cond:     %s\n", weather_info_get_conditions (&info));
+	printf ("  temp:     %s\n", weather_info_get_temp (&info));
+	printf ("  dewp:     %s\n", weather_info_get_dew (&info));
+	printf ("  wind:     %s\n", weather_info_get_wind (&info));
+	printf ("  pressure: %s\n", weather_info_get_pressure (&info));
+	printf ("  vis:      %s\n", weather_info_get_visibility (&info));
+
+	// TODO: retrieve location's lat/lon to display sunrise/set times
+    }
+    return 0;
+}
+
+
+
+
+ + + diff --git a/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/4.html b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/4.html new file mode 100644 index 0000000..5f42729 --- /dev/null +++ b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/4.html @@ -0,0 +1,350 @@ + + + + + + Cppcheck - HTML report - libmateweather + + + + + + +
+ +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+
+#include <glib.h>
+#include <string.h>
+#include <time.h>
+
+#define MATEWEATHER_I_KNOW_THIS_IS_UNSTABLE
+#include "weather-priv.h"
+
+int
+main (int argc, char **argv)
+{
+    WeatherInfo     info;
+    GOptionContext* context;
+    GError*         error = NULL;
+    gdouble         latitude, longitude;
+    WeatherLocation location;
+    gchar*          gtime = NULL;<--- Assignment 'gtime=NULL', assigned value is 0
+    GDate           gdate;
+    struct tm       tm;
+    gboolean        bmoon;
+    time_t          phases[4];
+    const GOptionEntry entries[] = {
+	{ "latitude", 0, 0, G_OPTION_ARG_DOUBLE, &latitude,
+	  "observer's latitude in degrees north", NULL },
+	{ "longitude", 0, 0,  G_OPTION_ARG_DOUBLE, &longitude,
+	  "observer's longitude in degrees east", NULL },
+	{ "time", 0, 0, G_OPTION_ARG_STRING, &gtime,
+	  "time in seconds from Unix epoch", NULL },
+	{ NULL }
+    };
+
+    memset(&location, 0, sizeof(WeatherLocation));
+    memset(&info, 0, sizeof(WeatherInfo));
+
+    context = g_option_context_new ("- test libmateweather sun/moon calculations");
+    g_option_context_add_main_entries (context, entries, NULL);
+    g_option_context_parse (context, &argc, &argv, &error);
+
+    if (error) {
+	perror (error->message);
+	return error->code;
+    }
+    else if (latitude < -90. || latitude > 90.) {
+	perror ("invalid latitude: should be [-90 .. 90]");
+	return -1;
+    } else if (longitude < -180. || longitude > 180.) {
+	perror ("invalid longitude: should be [-180 .. 180]");
+	return -1;
+    }
+
+    location.latitude = DEGREES_TO_RADIANS(latitude);
+    location.longitude = DEGREES_TO_RADIANS(longitude);
+    location.latlon_valid = TRUE;
+    info.location = &location;
+    info.valid = TRUE;
+
+    if (gtime != NULL) {<--- Condition 'gtime!=NULL' is always false
+	//	printf(" gtime=%s\n", gtime);
+	g_date_set_parse(&gdate, gtime);
+	g_date_to_struct_tm(&gdate, &tm);
+	info.update = mktime(&tm);
+    } else {
+	info.update = time(NULL);
+    }
+
+    calc_sun_time(&info, info.update);
+    bmoon = calc_moon(&info);
+
+    printf ("  Latitude %7.3f %c  Longitude %7.3f %c for %s  All times UTC\n",
+	    fabs(latitude), (latitude >= 0. ? 'N' : 'S'),
+	    fabs(longitude), (longitude >= 0. ? 'E' : 'W'),
+	    asctime(gmtime(&info.update)));<--- Obsolete function 'asctime' called. It is recommended to use 'strftime' instead.
+    printf("sunrise:   %s",
+	   (info.sunriseValid ? ctime(&info.sunrise) : "(invalid)\n"));
+    printf("sunset:    %s",
+	   (info.sunsetValid ? ctime(&info.sunset)  : "(invalid)\n"));
+    if (bmoon) {
+	printf("moonphase: %g\n", info.moonphase);
+	printf("moonlat:   %g\n", info.moonlatitude);
+
+	if (calc_moon_phases(&info, phases)) {
+	    printf("    New:   %s", asctime(gmtime(&phases[0])));<--- Obsolete function 'asctime' called. It is recommended to use 'strftime' instead.
+	    printf("    1stQ:  %s", asctime(gmtime(&phases[1])));<--- Obsolete function 'asctime' called. It is recommended to use 'strftime' instead.
+	    printf("    Full:  %s", asctime(gmtime(&phases[2])));<--- Obsolete function 'asctime' called. It is recommended to use 'strftime' instead.
+	    printf("    3rdQ:  %s", asctime(gmtime(&phases[3])));<--- Obsolete function 'asctime' called. It is recommended to use 'strftime' instead.
+	}
+    }
+    return 0;
+}
+
+
+
+
+ + + diff --git a/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/5.html b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/5.html new file mode 100644 index 0000000..04f87bd --- /dev/null +++ b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/5.html @@ -0,0 +1,336 @@ + + + + + + Cppcheck - HTML report - libmateweather + + + + + + +
+ +
+
 1
+ 2
+ 3
+ 4
+ 5
+ 6
+ 7
+ 8
+ 9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* weather-bom.c - Australian Bureau of Meteorology forecast source
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#define MATEWEATHER_I_KNOW_THIS_IS_UNSTABLE
+#include "weather.h"
+#include "weather-priv.h"
+
+static void
+bom_finish (SoupSession *session, SoupMessage *msg, gpointer data)
+{
+    char *p, *rp;
+    WeatherInfo *info = (WeatherInfo *)data;
+
+    g_return_if_fail (info != NULL);
+
+    if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
+        g_warning ("Failed to get BOM forecast data: %d %s.\n",
+		   msg->status_code, msg->reason_phrase);
+        request_done (info, FALSE);
+	return;
+    }
+
+    p = strstr (msg->response_body->data, "Forecast for the rest");
+    if (p != NULL) {
+        rp = strstr (p, "The next routine forecast will be issued");
+        if (rp == NULL)
+            info->forecast = g_strdup (p);
+        else
+            info->forecast = g_strndup (p, rp - p);
+    }
+
+    if (info->forecast == NULL)
+        info->forecast = g_strdup (msg->response_body->data);
+
+    g_print ("%s\n",  info->forecast);
+    request_done (info, TRUE);
+}
+
+void
+bom_start_open (WeatherInfo *info)
+{
+    gchar *url;
+    SoupMessage *msg;
+    WeatherLocation *loc;
+
+    loc = info->location;
+
+    url = g_strdup_printf ("http://www.bom.gov.au/fwo/%s.txt",
+			   loc->zone + 1);
+
+    msg = soup_message_new ("GET", url);
+    soup_session_queue_message (info->session, msg, bom_finish, info);
+    g_free (url);
+
+    info->requests_pending++;
+}
+
+
+
+
+ + + diff --git a/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/6.html b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/6.html new file mode 100644 index 0000000..c485435 --- /dev/null +++ b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/6.html @@ -0,0 +1,1122 @@ + + + + + + Cppcheck - HTML report - libmateweather + + + + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* weather-iwin.c - US National Weather Service IWIN forecast source
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libxml/parser.h>
+
+#define MATEWEATHER_I_KNOW_THIS_IS_UNSTABLE
+#include "weather.h"
+#include "weather-priv.h"
+
+/**
+ *  Humans don't deal well with .MONDAY...SUNNY AND BLAH BLAH.TUESDAY...THEN THIS AND THAT.WEDNESDAY...RAINY BLAH BLAH.
+ *  This function makes it easier to read.
+ */
+static gchar *
+formatWeatherMsg (gchar *forecast)
+{
+    gchar *ptr = forecast;
+    gchar *startLine = NULL;
+
+    while (0 != *ptr) {
+        if (ptr[0] == '\n' && ptr[1] == '.') {
+          /* This removes the preamble by shifting the relevant data
+           * down to the start of the buffer. */
+            if (NULL == startLine) {
+                memmove (forecast, ptr, strlen (ptr) + 1);
+                ptr = forecast;
+                ptr[0] = ' ';
+            }
+            ptr[1] = '\n';
+            ptr += 2;
+            startLine = ptr;
+        } else if (ptr[0] == '.' && ptr[1] == '.' && ptr[2] == '.' && NULL != startLine) {
+            memmove (startLine + 2, startLine, (ptr - startLine) * sizeof (gchar));
+            startLine[0] = ' ';
+            startLine[1] = '\n';
+            ptr[2] = '\n';
+
+            ptr += 3;
+
+        } else if (ptr[0] == '$' && ptr[1] == '$') {
+            ptr[0] = ptr[1] = ' ';
+
+        } else {
+            ptr++;
+        }
+    }
+
+    return forecast;
+}
+
+static gboolean
+hasAttr (xmlNode *node, const char *attr_name, const char *attr_value)
+{
+    xmlChar *attr;
+    gboolean res = FALSE;
+
+    if (!node)
+        return res;
+
+    attr = xmlGetProp (node, (const xmlChar *) attr_name);
+
+    if (!attr)
+        return res;
+
+    res = g_str_equal ((const char *)attr, attr_value);
+
+    xmlFree (attr);
+
+    return res;
+}
+
+static GSList *
+parseForecastXml (const char *buff, WeatherInfo *master_info)
+{
+    GSList *res = NULL;
+    xmlDocPtr doc;
+    xmlNode *root, *node;
+
+    g_return_val_if_fail (master_info != NULL, NULL);
+
+    if (!buff || !*buff)
+        return NULL;
+
+    #define XC (const xmlChar *)
+    #define isElem(_node,_name) g_str_equal ((const char *)_node->name, _name)
+
+    doc = xmlParseMemory (buff, strlen (buff));
+    if (!doc)
+        return NULL;
+
+    /* Description at http://www.weather.gov/mdl/XML/Design/MDL_XML_Design.pdf */
+    root = xmlDocGetRootElement (doc);
+    for (node = root->xmlChildrenNode; node; node = node->next) {
+        if (node->name == NULL || node->type != XML_ELEMENT_NODE)
+            continue;
+
+        if (isElem (node, "data")) {
+            xmlNode *n;
+            char *time_layout = NULL;
+            time_t update_times[7] = {0};
+
+            for (n = node->children; n; n = n->next) {
+                if (!n->name)
+                    continue;
+
+                if (isElem (n, "time-layout")) {
+                    if (!time_layout && hasAttr (n, "summarization", "24hourly")) {
+                        xmlNode *c;
+                        int count = 0;
+
+                        for (c = n->children; c && (count < 7 || !time_layout); c = c->next) {
+                            if (c->name && !time_layout && isElem (c, "layout-key")) {
+                                xmlChar *val = xmlNodeGetContent (c);
+
+                                if (val) {
+                                    time_layout = g_strdup ((const char *)val);
+                                    xmlFree (val);
+                                }
+                            } else if (c->name && isElem (c, "start-valid-time")) {
+                                xmlChar *val = xmlNodeGetContent (c);
+
+                                if (val) {
+                                    GDateTime *dt = g_date_time_new_from_iso8601 ((const char *)val, NULL);
+                                    if (dt != NULL) {
+                                        update_times[count] = g_date_time_to_unix (dt);
+                                        g_date_time_unref (dt);
+                                    } else {
+                                        update_times[count] = 0;
+                                    }
+
+                                    count++;
+
+                                    xmlFree (val);
+                                }
+                            }
+                        }
+
+                        if (count != 7) {
+                            /* There can be more than one time-layout element, the other
+                               with only few children, which is not the one to use. */
+                            g_free (time_layout);
+                            time_layout = NULL;
+                        }
+                    }
+                } else if (isElem (n, "parameters")) {
+                    xmlNode *p;
+
+                    /* time-layout should be always before parameters */
+                    if (!time_layout)
+                        break;
+
+                    if (!res) {
+                        int i;
+
+                        for (i = 0; i < 7;  i++) {
+                            WeatherInfo *nfo = weather_info_clone (master_info);
+
+                            if (nfo) {
+                                nfo->valid = FALSE;
+                                nfo->forecast_type = FORECAST_ZONE;
+                                nfo->update = update_times [i];
+                                nfo->sky = -1;
+                                nfo->temperature_unit = TEMP_UNIT_FAHRENHEIT;
+                                nfo->temp = -1000.0;
+                                nfo->temp_min = -1000.0;
+                                nfo->temp_max = -1000.0;
+                                nfo->tempMinMaxValid = FALSE;
+                                nfo->cond.significant = FALSE;
+                                nfo->cond.phenomenon = PHENOMENON_NONE;
+                                nfo->cond.qualifier = QUALIFIER_NONE;
+                                nfo->dew = -1000.0;
+                                nfo->wind = -1;
+                                nfo->windspeed = -1;
+                                nfo->pressure = -1.0;
+                                nfo->visibility = -1.0;
+                                nfo->sunriseValid = FALSE;
+                                nfo->sunsetValid = FALSE;
+                                nfo->sunrise = 0;
+                                nfo->sunset = 0;
+                                g_free (nfo->forecast);
+                                nfo->forecast = NULL;
+				nfo->session = NULL;
+				nfo->requests_pending = 0;
+				nfo->finish_cb = NULL;
+				nfo->cb_data = NULL;
+                                res = g_slist_append (res, nfo);
+                            }
+                        }
+                    }
+
+                    for (p = n->children; p; p = p->next) {
+                        if (p->name && isElem (p, "temperature") && hasAttr (p, "time-layout", time_layout)) {
+                            xmlNode *c;
+                            GSList *at = res;
+                            gboolean is_max = hasAttr (p, "type", "maximum");
+
+                            if (!is_max && !hasAttr (p, "type", "minimum"))
+                                break;
+
+                            for (c = p->children; c && at; c = c->next) {
+                                if (isElem (c, "value")) {
+                                    WeatherInfo *nfo = (WeatherInfo *)at->data;
+                                    xmlChar *val = xmlNodeGetContent (c);
+
+                                    /* can pass some values as <value xsi:nil="true"/> */
+                                    if (!val || !*val) {
+                                        if (is_max)
+                                            nfo->temp_max = nfo->temp_min;
+                                        else
+                                            nfo->temp_min = nfo->temp_max;
+                                    } else {
+                                        if (is_max)
+                                            nfo->temp_max = atof ((const char *)val);
+                                        else
+                                            nfo->temp_min = atof ((const char *)val);
+                                    }
+
+                                    if (val)
+                                        xmlFree (val);
+
+                                    nfo->tempMinMaxValid = nfo->tempMinMaxValid || (nfo->temp_max > -999.0 && nfo->temp_min > -999.0);
+                                    nfo->valid = nfo->tempMinMaxValid;
+
+                                    at = at->next;
+                                }
+                            }
+                        } else if (p->name && isElem (p, "weather") && hasAttr (p, "time-layout", time_layout)) {
+                            xmlNode *c;
+                            GSList *at = res;
+
+                            for (c = p->children; c && at; c = c->next) {
+                                if (c->name && isElem (c, "weather-conditions")) {
+                                    WeatherInfo *nfo = at->data;
+                                    xmlChar *val = xmlGetProp (c, XC "weather-summary");
+
+                                    if (val && nfo) {
+                                        /* Checking from top to bottom, if 'value' contains 'name', then that win,
+                                           thus put longer (more precise) values to the top. */
+                                        int i;
+                                        struct _ph_list {
+                                            const char *name;
+                                            WeatherConditionPhenomenon ph;
+                                        } ph_list[] = {
+                                            { "Ice Crystals", PHENOMENON_ICE_CRYSTALS } ,
+                                            { "Volcanic Ash", PHENOMENON_VOLCANIC_ASH } ,
+                                            { "Blowing Sand", PHENOMENON_SANDSTORM } ,
+                                            { "Blowing Dust", PHENOMENON_DUSTSTORM } ,
+                                            { "Blowing Snow", PHENOMENON_FUNNEL_CLOUD } ,
+                                            { "Drizzle", PHENOMENON_DRIZZLE } ,
+                                            { "Rain", PHENOMENON_RAIN } ,
+                                            { "Snow", PHENOMENON_SNOW } ,
+                                            { "Fog", PHENOMENON_FOG } ,
+                                            { "Smoke", PHENOMENON_SMOKE } ,
+                                            { "Sand", PHENOMENON_SAND } ,
+                                            { "Haze", PHENOMENON_HAZE } ,
+                                            { "Dust", PHENOMENON_DUST } /*,
+                                            { "", PHENOMENON_SNOW_GRAINS } ,
+                                            { "", PHENOMENON_ICE_PELLETS } ,
+                                            { "", PHENOMENON_HAIL } ,
+                                            { "", PHENOMENON_SMALL_HAIL } ,
+                                            { "", PHENOMENON_UNKNOWN_PRECIPITATION } ,
+                                            { "", PHENOMENON_MIST } ,
+                                            { "", PHENOMENON_SPRAY } ,
+                                            { "", PHENOMENON_SQUALL } ,
+                                            { "", PHENOMENON_TORNADO } ,
+                                            { "", PHENOMENON_DUST_WHIRLS } */
+                                        };
+                                        struct _sky_list {
+                                            const char *name;
+                                            WeatherSky sky;
+                                        } sky_list[] = {
+                                            { "Mostly Sunny", SKY_BROKEN } ,
+                                            { "Mostly Clear", SKY_BROKEN } ,
+                                            { "Partly Cloudy", SKY_SCATTERED } ,
+                                            { "Mostly Cloudy", SKY_FEW } ,
+                                            { "Sunny", SKY_CLEAR } ,
+                                            { "Clear", SKY_CLEAR } ,
+                                            { "Cloudy", SKY_OVERCAST } ,
+                                            { "Clouds", SKY_SCATTERED } ,
+                                            { "Rain", SKY_SCATTERED } ,
+                                            { "Snow", SKY_SCATTERED }
+                                        };
+
+                                        nfo->valid = TRUE;
+                                        g_free (nfo->forecast);
+                                        nfo->forecast = g_strdup ((const char *)val);
+
+                                        for (i = 0; i < G_N_ELEMENTS (ph_list); i++) {
+                                            if (strstr ((const char *)val, ph_list [i].name)) {
+                                                nfo->cond.phenomenon = ph_list [i].ph;
+                                                break;
+                                            }
+                                        }
+
+                                        for (i = 0; i < G_N_ELEMENTS (sky_list); i++) {
+                                            if (strstr ((const char *)val, sky_list [i].name)) {
+                                                nfo->sky = sky_list [i].sky;
+                                                break;
+                                            }
+                                        }
+                                    }
+
+                                    if (val)
+                                        xmlFree (val);
+
+                                    at = at->next;
+                                }
+                            }
+                        }
+                    }
+
+                    if (res) {
+                        gboolean have_any = FALSE;
+                        GSList *r;
+
+                        /* Remove invalid forecast data from the list.
+                           They should be all valid or all invalid. */
+                        for (r = res; r; r = r->next) {
+                            WeatherInfo *nfo = r->data;
+
+                            if (!nfo || !nfo->valid) {
+                                if (r->data)
+                                    weather_info_free (r->data);
+
+                                r->data = NULL;
+                            } else {
+                                have_any = TRUE;
+
+                                if (nfo->tempMinMaxValid)
+                                    nfo->temp = (nfo->temp_min + nfo->temp_max) / 2.0;
+                            }
+                        }
+
+                        if (!have_any) {
+                            /* data members are freed already */
+                            g_slist_free (res);
+                            res = NULL;
+                        }
+                    }
+
+                    break;
+                }
+            }
+
+            g_free (time_layout);
+
+            /* stop seeking XML */
+            break;
+        }
+    }
+    xmlFreeDoc (doc);
+
+    #undef XC
+    #undef isElem
+
+    return res;
+}
+
+static void
+iwin_finish (SoupSession *session, SoupMessage *msg, gpointer data)
+{
+    WeatherInfo *info = (WeatherInfo *)data;
+
+    g_return_if_fail (info != NULL);
+
+    if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
+        /* forecast data is not really interesting anyway ;) */
+        g_warning ("Failed to get IWIN forecast data: %d %s\n",
+                   msg->status_code, msg->reason_phrase);
+        request_done (info, FALSE);
+        return;
+    }
+
+    if (info->forecast_type == FORECAST_LIST)
+        info->forecast_list = parseForecastXml (msg->response_body->data, info);
+    else
+        info->forecast = formatWeatherMsg (g_strdup (msg->response_body->data));
+
+    request_done (info, TRUE);
+}
+
+/* Get forecast into newly alloc'ed string */
+void
+iwin_start_open (WeatherInfo *info)
+{
+    gchar *url, *state, *zone;
+    WeatherLocation *loc;
+    SoupMessage *msg;
+
+    g_return_if_fail (info != NULL);
+    loc = info->location;<--- Assignment 'loc=info->location', assigned value is 0
+    g_return_if_fail (loc != NULL);<--- Assuming that condition 'loc!=NULL' is not redundant
+
+    if (loc->zone[0] == '-' && (info->forecast_type != FORECAST_LIST || !loc->latlon_valid))<--- Null pointer dereference
+        return;
+
+    if (info->forecast) {
+        g_free (info->forecast);
+        info->forecast = NULL;
+    }
+
+    free_forecast_list (info);
+
+    if (info->forecast_type == FORECAST_LIST) {
+        /* see the description here: http://www.weather.gov/forecasts/xml/ */
+        if (loc->latlon_valid) {
+            GDateTime *dt;
+            gint year, month, day;
+
+            dt = g_date_time_new_now_local ();
+            g_date_time_get_ymd (dt, &year, &month, &day);
+            g_date_time_unref (dt);
+
+            url = g_strdup_printf ("http://www.weather.gov/forecasts/xml/sample_products/browser_interface/ndfdBrowserClientByDay.php?&lat=%.02f&lon=%.02f&format=24+hourly&startDate=%04d-%02d-%02d&numDays=7",
+                       RADIANS_TO_DEGREES (loc->latitude), RADIANS_TO_DEGREES (loc->longitude), year, month, day);
+
+            msg = soup_message_new ("GET", url);
+            g_free (url);
+            soup_session_queue_message (info->session, msg, iwin_finish, info);
+
+            info->requests_pending++;
+        }
+        return;
+    }
+
+    if (loc->zone[0] == ':') {
+        /* Met Office Region Names */
+        metoffice_start_open (info);
+        return;
+    } else if (loc->zone[0] == '@') {
+        /* Australian BOM forecasts */
+        bom_start_open (info);
+        return;
+    }
+
+    /* The zone for Pittsburgh (for example) is given as PAZ021 in the locations
+    ** file (the PA stands for the state pennsylvania). The url used wants the state
+    ** as pa, and the zone as lower case paz021.
+    */
+    zone = g_ascii_strdown (loc->zone, -1);
+    state = g_strndup (zone, 2);
+
+    url = g_strdup_printf ("http://tgftp.nws.noaa.gov/data/forecasts/zone/%s/%s.txt", state, zone);
+
+    g_free (zone);
+    g_free (state);
+
+    msg = soup_message_new ("GET", url);
+    g_free (url);
+    soup_session_queue_message (info->session, msg, iwin_finish, info);
+
+    info->requests_pending++;
+}
+
+
+
+
+ + + diff --git a/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/7.html b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/7.html new file mode 100644 index 0000000..636f6cf --- /dev/null +++ b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/7.html @@ -0,0 +1,528 @@ + + + + + + Cppcheck - HTML report - libmateweather + + + + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* weather-met.c - UK Met Office forecast source
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define MATEWEATHER_I_KNOW_THIS_IS_UNSTABLE
+#include "weather.h"
+#include "weather-priv.h"
+
+static char *
+met_reprocess (char *x, int len)
+{
+    char *p = x;
+    char *o;
+    int spacing = 0;
+    static gchar *buf;
+    static gint buflen = 0;
+    gchar *lastspace = NULL;
+    int count = 0;
+
+    if (buflen < len)
+    {
+	if (buf)
+	    g_free (buf);
+	buf = g_malloc (len + 1);
+	buflen = len;
+    }
+
+    o = buf;
+    x += len;       /* End mark */
+
+    while (*p && p < x) {
+	if (g_ascii_isspace (*p)) {
+	    if (!spacing) {
+		spacing = 1;
+		lastspace = o;
+		count++;
+		*o++ = ' ';
+	    }
+	    p++;
+	    continue;
+	}
+	spacing = 0;
+	if (count > 75 && lastspace) {
+	    count = o - lastspace - 1;
+	    *lastspace = '\n';
+	    lastspace = NULL;
+	}
+
+	if (*p == '&') {
+	    if (g_ascii_strncasecmp (p, "&amp;", 5) == 0) {
+		*o++ = '&';
+		count++;
+		p += 5;
+		continue;
+	    }
+	    if (g_ascii_strncasecmp (p, "&lt;", 4) == 0) {
+		*o++ = '<';
+		count++;
+		p += 4;
+		continue;
+	    }
+	    if (g_ascii_strncasecmp (p, "&gt;", 4) == 0) {
+		*o++ = '>';
+		count++;
+		p += 4;
+		continue;
+	    }
+	}
+	if (*p == '<') {
+	    if (g_ascii_strncasecmp (p, "<BR>", 4) == 0) {
+		*o++ = '\n';
+		count = 0;
+	    }
+	    if (g_ascii_strncasecmp (p, "<B>", 3) == 0) {
+		*o++ = '\n';
+		*o++ = '\n';
+		count = 0;
+	    }
+	    p++;
+	    while (*p && *p != '>')
+		p++;
+	    if (*p)
+		p++;
+	    continue;
+	}
+	*o++ = *p++;
+	count++;
+    }
+    *o = 0;
+    return buf;
+}
+
+
+/*
+ * Parse the metoffice forecast info.
+ * For mate 3.0 we want to just embed an HTML matecomponent component and
+ * be done with this ;)
+ */
+
+static gchar *
+met_parse (const gchar *meto)
+{
+    gchar *p;
+    gchar *rp;
+    gchar *r = g_strdup ("Met Office Forecast\n");
+    gchar *t;
+
+    g_return_val_if_fail (meto != NULL, r);
+
+    p = strstr (meto, "Summary: </b>");<--- Assignment 'p=strstr(meto,"Summary: ")', assigned value is 0<--- Assignment 'p=strstr(meto,"Summary: ")', assigned value is 0
+    g_return_val_if_fail (p != NULL, r);<--- Assuming that condition 'p!=NULL' is not redundant<--- Assuming that condition 'p!=NULL' is not redundant
+
+    rp = strstr (p, "Text issued at:");<--- Null pointer dereference
+    g_return_val_if_fail (rp != NULL, r);
+
+    p += 13;<--- Null pointer addition
+    /* p to rp is the text block we want but in HTML malformat */
+    t = g_strconcat (r, met_reprocess (p, rp - p), NULL);
+    g_free (r);
+
+    return t;
+}
+
+static void
+met_finish (SoupSession *session, SoupMessage *msg, gpointer data)
+{
+    WeatherInfo *info = (WeatherInfo *)data;
+
+    g_return_if_fail (info != NULL);
+
+    if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
+	g_warning ("Failed to get Met Office forecast data: %d %s.\n",
+		   msg->status_code, msg->reason_phrase);
+        request_done (info, FALSE);
+        return;
+    }
+
+    info->forecast = met_parse (msg->response_body->data);
+    request_done (info, TRUE);
+}
+
+void
+metoffice_start_open (WeatherInfo *info)
+{
+    gchar *url;
+    SoupMessage *msg;
+    WeatherLocation *loc;
+
+    loc = info->location;
+    url = g_strdup_printf ("http://www.metoffice.gov.uk/weather/europe/uk/%s.html", loc->zone + 1);
+
+    msg = soup_message_new ("GET", url);
+    soup_session_queue_message (info->session, msg, met_finish, info);
+    g_free (url);
+
+    info->requests_pending++;
+}
+
+
+
+
+ + + diff --git a/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/8.html b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/8.html new file mode 100644 index 0000000..8378edf --- /dev/null +++ b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/8.html @@ -0,0 +1,1324 @@ + + + + + + Cppcheck - HTML report - libmateweather + + + + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* weather-metar.c - Weather server functions (METAR)
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <regex.h>
+
+#define MATEWEATHER_I_KNOW_THIS_IS_UNSTABLE
+#include "weather.h"
+#include "weather-priv.h"
+
+enum {
+    TIME_RE,
+    WIND_RE,
+    VIS_RE,
+    COND_RE,
+    CLOUD_RE,
+    TEMP_RE,
+    PRES_RE,
+
+    RE_NUM
+};
+
+/* Return time of weather report as secs since epoch UTC */
+static time_t
+make_time (gint utcDate, gint utcHour, gint utcMin)
+{
+    const time_t now = time (NULL);
+    struct tm tm;
+
+    localtime_r (&now, &tm);
+
+    /* If last reading took place just before midnight UTC on the
+     * first, adjust the date downward to allow for the month
+     * change-over.  This ASSUMES that the reading won't be more than
+     * 24 hrs old! */
+    if ((utcDate > tm.tm_mday) && (tm.tm_mday == 1)) {
+        tm.tm_mday = 0; /* mktime knows this is the last day of the previous
+                         * month. */
+    } else {
+        tm.tm_mday = utcDate;
+    }
+    tm.tm_hour = utcHour;
+    tm.tm_min  = utcMin;
+    tm.tm_sec  = 0;
+
+    /* mktime() assumes value is local, not UTC.  Use tm_gmtoff to compensate */
+#ifdef HAVE_TM_TM_GMOFF
+    return tm.tm_gmtoff + mktime (&tm);
+#elif defined HAVE_TIMEZONE
+    return timezone + mktime (&tm);
+#endif
+}
+
+static void
+metar_tok_time (gchar *tokp, WeatherInfo *info)
+{
+    gint day, hr, min;
+
+    sscanf (tokp, "%2u%2u%2u", &day, &hr, &min);
+    info->update = make_time (day, hr, min);
+}
+
+static void
+metar_tok_wind (gchar *tokp, WeatherInfo *info)
+{
+    gchar sdir[4], sspd[4], sgust[4];
+    gint dir, spd = -1;
+    gchar *gustp;
+    size_t glen;
+
+    strncpy (sdir, tokp, 3);
+    sdir[3] = 0;
+    dir = (!strcmp (sdir, "VRB")) ? -1 : atoi (sdir);
+
+    memset (sspd, 0, sizeof (sspd));
+    glen = strspn (tokp + 3, CONST_DIGITS);
+    strncpy (sspd, tokp + 3, glen);
+    spd = atoi (sspd);
+    tokp += glen + 3;
+
+    gustp = strchr (tokp, 'G');
+    if (gustp) {
+        memset (sgust, 0, sizeof (sgust));
+        glen = strspn (gustp + 1, CONST_DIGITS);
+        strncpy (sgust, gustp + 1, glen);
+        tokp = gustp + 1 + glen;
+    }
+
+    if (!strcmp (tokp, "MPS"))
+        info->windspeed = WINDSPEED_MS_TO_KNOTS ((WeatherWindSpeed)spd);
+    else
+        info->windspeed = (WeatherWindSpeed)spd;
+
+    if ((349 <= dir) || (dir <= 11))<--- Assuming that condition '349<=dir' is not redundant
+        info->wind = WIND_N;
+    else if ((12 <= dir) && (dir <= 33))
+        info->wind = WIND_NNE;
+    else if ((34 <= dir) && (dir <= 56))
+        info->wind = WIND_NE;
+    else if ((57 <= dir) && (dir <= 78))
+        info->wind = WIND_ENE;
+    else if ((79 <= dir) && (dir <= 101))
+        info->wind = WIND_E;
+    else if ((102 <= dir) && (dir <= 123))
+        info->wind = WIND_ESE;
+    else if ((124 <= dir) && (dir <= 146))
+        info->wind = WIND_SE;
+    else if ((147 <= dir) && (dir <= 168))
+        info->wind = WIND_SSE;
+    else if ((169 <= dir) && (dir <= 191))
+        info->wind = WIND_S;
+    else if ((192 <= dir) && (dir <= 213))
+        info->wind = WIND_SSW;
+    else if ((214 <= dir) && (dir <= 236))
+        info->wind = WIND_SW;
+    else if ((237 <= dir) && (dir <= 258))
+        info->wind = WIND_WSW;
+    else if ((259 <= dir) && (dir <= 281))
+        info->wind = WIND_W;
+    else if ((282 <= dir) && (dir <= 303))
+        info->wind = WIND_WNW;
+    else if ((304 <= dir) && (dir <= 326))
+        info->wind = WIND_NW;
+    else if ((327 <= dir) && (dir <= 348))<--- Condition 'dir<=348' is always true
+        info->wind = WIND_NNW;
+}
+
+static void
+metar_tok_vis (gchar *tokp, WeatherInfo *info)
+{
+    gchar *pfrac, *pend, *psp;
+    gchar sval[6];
+    gint num, den, val;
+
+    memset (sval, 0, sizeof (sval));
+
+    if (!strcmp (tokp,"CAVOK")) {
+        // "Ceiling And Visibility OK": visibility >= 10 KM
+        info->visibility=10000. / VISIBILITY_SM_TO_M (1.);
+        info->sky = SKY_CLEAR;
+    } else if (0 != (pend = strstr (tokp, "SM"))) {
+        // US observation: field ends with "SM"
+        pfrac = strchr (tokp, '/');
+        if (pfrac) {
+            if (*tokp == 'M') {
+                info->visibility = 0.001;
+            } else {
+                num = (*(pfrac - 1) - '0');
+                strncpy (sval, pfrac + 1, pend - pfrac - 1);
+                den = atoi (sval);
+                info->visibility =
+                    ((WeatherVisibility)num / ((WeatherVisibility)den));
+
+                psp = strchr (tokp, ' ');
+                if (psp) {
+                    *psp = '\0';
+                    val = atoi (tokp);
+                    info->visibility += (WeatherVisibility)val;
+                }
+            }
+        } else {
+            strncpy (sval, tokp, pend - tokp);
+            val = atoi (sval);
+            info->visibility = (WeatherVisibility)val;
+        }
+    } else {
+        // International observation: NNNN(DD NNNNDD)?
+        // For now: use only the minimum visibility and ignore its direction
+        strncpy (sval, tokp, strspn (tokp, CONST_DIGITS));
+        val = atoi (sval);
+        info->visibility = (WeatherVisibility)val / VISIBILITY_SM_TO_M (1.);
+    }
+}
+
+static void
+metar_tok_cloud (gchar *tokp, WeatherInfo *info)
+{
+    gchar stype[4], salt[4];
+
+    strncpy (stype, tokp, 3);
+    stype[3] = 0;
+    if (strlen (tokp) == 6) {
+        strncpy (salt, tokp + 3, 3);
+        salt[3] = 0;
+    }
+
+    if (!strcmp (stype, "CLR")) {
+        info->sky = SKY_CLEAR;
+    } else if (!strcmp (stype, "SKC")) {
+        info->sky = SKY_CLEAR;
+    } else if (!strcmp (stype, "NSC")) {
+        info->sky = SKY_CLEAR;
+    } else if (!strcmp (stype, "BKN")) {
+        info->sky = SKY_BROKEN;
+    } else if (!strcmp (stype, "SCT")) {
+        info->sky = SKY_SCATTERED;
+    } else if (!strcmp (stype, "FEW")) {
+        info->sky = SKY_FEW;
+    } else if (!strcmp (stype, "OVC")) {
+        info->sky = SKY_OVERCAST;
+    }
+}
+
+static void
+metar_tok_pres (gchar *tokp, WeatherInfo *info)
+{
+    if (*tokp == 'A') {
+        gchar sintg[3], sfract[3];
+        gint intg, fract;
+
+        strncpy (sintg, tokp + 1, 2);
+        sintg[2] = 0;
+        intg = atoi (sintg);
+
+        strncpy (sfract, tokp + 3, 2);
+        sfract[2] = 0;
+        fract = atoi (sfract);
+
+        info->pressure = (WeatherPressure)intg + (((WeatherPressure)fract)/100.0);
+    } else {  /* *tokp == 'Q' */
+        gchar spres[5];
+        gint pres;
+
+        strncpy (spres, tokp + 1, 4);
+        spres[4] = 0;
+        pres = atoi (spres);
+
+        info->pressure = PRESSURE_MBAR_TO_INCH ((WeatherPressure)pres);
+    }
+}
+
+static void
+metar_tok_temp (gchar *tokp, WeatherInfo *info)
+{
+    gchar *ptemp, *pdew, *psep;
+
+    psep = strchr (tokp, '/');
+    *psep = 0;
+    ptemp = tokp;
+    pdew = psep + 1;
+
+    info->temp = (*ptemp == 'M') ? TEMP_C_TO_F (-atoi (ptemp + 1))
+        : TEMP_C_TO_F (atoi (ptemp));
+    if (*pdew) {
+        info->dew = (*pdew == 'M') ? TEMP_C_TO_F (-atoi (pdew + 1))
+            : TEMP_C_TO_F (atoi (pdew));
+    } else {
+        info->dew = -1000.0;
+    }
+}
+
+static void
+metar_tok_cond (gchar *tokp, WeatherInfo *info)
+{
+    gchar squal[3], sphen[4];
+    gchar *pphen;
+
+    if ((strlen (tokp) > 3) && ((*tokp == '+') || (*tokp == '-')))
+        ++tokp;   /* FIX */
+
+    if ((*tokp == '+') || (*tokp == '-'))
+        pphen = tokp + 1;
+    else if (strlen (tokp) < 4)
+        pphen = tokp;
+    else
+        pphen = tokp + 2;
+
+    memset (squal, 0, sizeof (squal));
+    strncpy (squal, tokp, pphen - tokp);
+    squal[pphen - tokp] = 0;
+
+    memset (sphen, 0, sizeof (sphen));
+    strncpy (sphen, pphen, sizeof (sphen));
+    sphen[sizeof (sphen)-1] = '\0';
+
+    /* Defaults */
+    info->cond.qualifier = QUALIFIER_NONE;
+    info->cond.phenomenon = PHENOMENON_NONE;
+    info->cond.significant = FALSE;
+
+    if (!strcmp (squal, "")) {
+        info->cond.qualifier = QUALIFIER_MODERATE;
+    } else if (!strcmp (squal, "-")) {
+        info->cond.qualifier = QUALIFIER_LIGHT;
+    } else if (!strcmp (squal, "+")) {
+        info->cond.qualifier = QUALIFIER_HEAVY;
+    } else if (!strcmp (squal, "VC")) {
+        info->cond.qualifier = QUALIFIER_VICINITY;
+    } else if (!strcmp (squal, "MI")) {
+        info->cond.qualifier = QUALIFIER_SHALLOW;
+    } else if (!strcmp (squal, "BC")) {
+        info->cond.qualifier = QUALIFIER_PATCHES;
+    } else if (!strcmp (squal, "PR")) {
+        info->cond.qualifier = QUALIFIER_PARTIAL;
+    } else if (!strcmp (squal, "TS")) {
+        info->cond.qualifier = QUALIFIER_THUNDERSTORM;
+    } else if (!strcmp (squal, "BL")) {
+        info->cond.qualifier = QUALIFIER_BLOWING;
+    } else if (!strcmp (squal, "SH")) {
+        info->cond.qualifier = QUALIFIER_SHOWERS;
+    } else if (!strcmp (squal, "DR")) {
+        info->cond.qualifier = QUALIFIER_DRIFTING;
+    } else if (!strcmp (squal, "FZ")) {
+        info->cond.qualifier = QUALIFIER_FREEZING;
+    } else {
+        return;
+    }
+
+    if (!strcmp (sphen, "DZ")) {
+        info->cond.phenomenon = PHENOMENON_DRIZZLE;
+    } else if (!strcmp (sphen, "RA")) {
+        info->cond.phenomenon = PHENOMENON_RAIN;
+    } else if (!strcmp (sphen, "SN")) {
+        info->cond.phenomenon = PHENOMENON_SNOW;
+    } else if (!strcmp (sphen, "SG")) {
+        info->cond.phenomenon = PHENOMENON_SNOW_GRAINS;
+    } else if (!strcmp (sphen, "IC")) {
+        info->cond.phenomenon = PHENOMENON_ICE_CRYSTALS;
+    } else if (!strcmp (sphen, "PE")) {
+        info->cond.phenomenon = PHENOMENON_ICE_PELLETS;
+    } else if (!strcmp (sphen, "GR")) {
+        info->cond.phenomenon = PHENOMENON_HAIL;
+    } else if (!strcmp (sphen, "GS")) {
+        info->cond.phenomenon = PHENOMENON_SMALL_HAIL;
+    } else if (!strcmp (sphen, "UP")) {
+        info->cond.phenomenon = PHENOMENON_UNKNOWN_PRECIPITATION;
+    } else if (!strcmp (sphen, "BR")) {
+        info->cond.phenomenon = PHENOMENON_MIST;
+    } else if (!strcmp (sphen, "FG")) {
+        info->cond.phenomenon = PHENOMENON_FOG;
+    } else if (!strcmp (sphen, "FU")) {
+        info->cond.phenomenon = PHENOMENON_SMOKE;
+    } else if (!strcmp (sphen, "VA")) {
+        info->cond.phenomenon = PHENOMENON_VOLCANIC_ASH;
+    } else if (!strcmp (sphen, "SA")) {
+        info->cond.phenomenon = PHENOMENON_SAND;
+    } else if (!strcmp (sphen, "HZ")) {
+        info->cond.phenomenon = PHENOMENON_HAZE;
+    } else if (!strcmp (sphen, "PY")) {
+        info->cond.phenomenon = PHENOMENON_SPRAY;
+    } else if (!strcmp (sphen, "DU")) {
+        info->cond.phenomenon = PHENOMENON_DUST;
+    } else if (!strcmp (sphen, "SQ")) {
+        info->cond.phenomenon = PHENOMENON_SQUALL;
+    } else if (!strcmp (sphen, "SS")) {
+        info->cond.phenomenon = PHENOMENON_SANDSTORM;
+    } else if (!strcmp (sphen, "DS")) {
+        info->cond.phenomenon = PHENOMENON_DUSTSTORM;
+    } else if (!strcmp (sphen, "PO")) {
+        info->cond.phenomenon = PHENOMENON_DUST_WHIRLS;
+    } else if (!strcmp (sphen, "+FC")) {
+        info->cond.phenomenon = PHENOMENON_TORNADO;
+    } else if (!strcmp (sphen, "FC")) {
+        info->cond.phenomenon = PHENOMENON_FUNNEL_CLOUD;
+    } else {
+        return;
+    }
+
+    if ((info->cond.qualifier != QUALIFIER_NONE) || (info->cond.phenomenon != PHENOMENON_NONE))
+        info->cond.significant = TRUE;
+}
+
+#define TIME_RE_STR  "([0-9]{6})Z"
+#define WIND_RE_STR  "(([0-9]{3})|VRB)([0-9]?[0-9]{2})(G[0-9]?[0-9]{2})?(KT|MPS)"
+#define VIS_RE_STR   "((([0-9]?[0-9])|(M?([12] )?([1357]/1?[0-9])))SM)|" \
+    "([0-9]{4}(N|NE|E|SE|S|SW|W|NW( [0-9]{4}(N|NE|E|SE|S|SW|W|NW))?)?)|" \
+    "CAVOK"
+#define COND_RE_STR  "(-|\\+)?(VC|MI|BC|PR|TS|BL|SH|DR|FZ)?(DZ|RA|SN|SG|IC|PE|GR|GS|UP|BR|FG|FU|VA|SA|HZ|PY|DU|SQ|SS|DS|PO|\\+?FC)"
+#define CLOUD_RE_STR "((CLR|BKN|SCT|FEW|OVC|SKC|NSC)([0-9]{3}|///)?(CB|TCU|///)?)"
+#define TEMP_RE_STR  "(M?[0-9][0-9])/(M?(//|[0-9][0-9])?)"
+#define PRES_RE_STR  "(A|Q)([0-9]{4})"
+
+/* POSIX regular expressions do not allow us to express "match whole words
+ * only" in a simple way, so we have to wrap them all into
+ *   (^| )(...regex...)( |$)
+ */
+#define RE_PREFIX "(^| )("
+#define RE_SUFFIX ")( |$)"
+
+static regex_t metar_re[RE_NUM];
+static void (*metar_f[RE_NUM]) (gchar *tokp, WeatherInfo *info);
+
+static void
+metar_init_re (void)
+{
+    static gboolean initialized = FALSE;
+    if (initialized)
+        return;
+    initialized = TRUE;
+
+    regcomp (&metar_re[TIME_RE], RE_PREFIX TIME_RE_STR RE_SUFFIX, REG_EXTENDED);
+    regcomp (&metar_re[WIND_RE], RE_PREFIX WIND_RE_STR RE_SUFFIX, REG_EXTENDED);
+    regcomp (&metar_re[VIS_RE], RE_PREFIX VIS_RE_STR RE_SUFFIX, REG_EXTENDED);
+    regcomp (&metar_re[COND_RE], RE_PREFIX COND_RE_STR RE_SUFFIX, REG_EXTENDED);
+    regcomp (&metar_re[CLOUD_RE], RE_PREFIX CLOUD_RE_STR RE_SUFFIX, REG_EXTENDED);
+    regcomp (&metar_re[TEMP_RE], RE_PREFIX TEMP_RE_STR RE_SUFFIX, REG_EXTENDED);
+    regcomp (&metar_re[PRES_RE], RE_PREFIX PRES_RE_STR RE_SUFFIX, REG_EXTENDED);
+
+    metar_f[TIME_RE] = metar_tok_time;
+    metar_f[WIND_RE] = metar_tok_wind;
+    metar_f[VIS_RE] = metar_tok_vis;
+    metar_f[COND_RE] = metar_tok_cond;
+    metar_f[CLOUD_RE] = metar_tok_cloud;
+    metar_f[TEMP_RE] = metar_tok_temp;
+    metar_f[PRES_RE] = metar_tok_pres;
+}
+
+gboolean
+metar_parse (gchar *metar, WeatherInfo *info)
+{
+    gchar *p;
+    //gchar *rmk;
+    gint i, i2;
+    regmatch_t rm, rm2;
+    gchar *tokp;
+
+    g_return_val_if_fail (info != NULL, FALSE);
+    g_return_val_if_fail (metar != NULL, FALSE);
+
+    metar_init_re ();
+
+    /*
+     * Force parsing to end at "RMK" field.  This prevents a subtle
+     * problem when info within the remark happens to match an earlier state
+     * and, as a result, throws off all the remaining expression
+     */
+    if (0 != (p = strstr (metar, " RMK "))) {
+        *p = '\0';
+        //rmk = p + 5;   // uncomment this if RMK data becomes useful
+    }
+
+    p = metar;
+    i = TIME_RE;<--- Variable 'i' is assigned a value that is never used.
+    while (*p) {
+
+        i2 = RE_NUM;
+        rm2.rm_so = strlen (p);
+        rm2.rm_eo = rm2.rm_so;
+
+        for (i = 0; i < RE_NUM && rm2.rm_so > 0; i++) {
+            if (0 == regexec (&metar_re[i], p, 1, &rm, 0)
+                && rm.rm_so < rm2.rm_so)
+            {
+                i2 = i;
+                /* Skip leading and trailing space characters, if present.
+                   (the regular expressions include those characters to
+                   only get matches limited to whole words). */
+                if (p[rm.rm_so] == ' ') rm.rm_so++;
+                if (p[rm.rm_eo - 1] == ' ') rm.rm_eo--;
+                rm2.rm_so = rm.rm_so;
+                rm2.rm_eo = rm.rm_eo;
+            }
+        }
+
+        if (i2 != RE_NUM) {
+            tokp = g_strndup (p + rm2.rm_so, rm2.rm_eo - rm2.rm_so);
+            metar_f[i2] (tokp, info);
+            g_free (tokp);
+        }
+
+        p += rm2.rm_eo;
+        p += strspn (p, " ");
+    }
+    return TRUE;
+}
+
+static void
+metar_finish (SoupSession *session, SoupMessage *msg, gpointer data)
+{
+    WeatherInfo *info = (WeatherInfo *)data;
+    WeatherLocation *loc;
+    const gchar *p, *endtag;
+    gchar *searchkey, *metar;
+    gboolean success = FALSE;
+
+    g_return_if_fail (info != NULL);
+
+    if (!SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
+        if (SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code))
+            info->network_error = TRUE;
+        else {
+            /* Translators: %d is an error code, and %s the error string */
+            g_warning (_("Failed to get METAR data: %d %s.\n"),
+                       msg->status_code, msg->reason_phrase);
+        }
+        request_done (info, FALSE);
+        return;
+    }
+
+    loc = info->location;
+
+    searchkey = g_strdup_printf ("<raw_text>%s", loc->code);
+    p = strstr (msg->response_body->data, searchkey);
+    g_free (searchkey);
+    if (p) {
+        p += WEATHER_LOCATION_CODE_LEN + 11;
+        endtag = strstr (p, "</raw_text>");
+        if (endtag)
+            metar = g_strndup (p, endtag - p);
+        else
+            metar = g_strdup (p);
+        success = metar_parse (metar, info);
+        g_free (metar);
+    } else if (!strstr (msg->response_body->data, "aviationweather.gov")) {
+        /* The response doesn't even seem to have come from NOAA...
+         * most likely it is a wifi hotspot login page. Call that a
+         * network error.
+         */
+        info->network_error = TRUE;
+    }
+
+    info->valid = success;
+    request_done (info, TRUE);
+}
+
+/* Read current conditions and fill in info structure */
+void
+metar_start_open (WeatherInfo *info)
+{
+    WeatherLocation *loc;
+    SoupMessage *msg;
+
+    g_return_if_fail (info != NULL);
+    info->valid = info->network_error = FALSE;
+    loc = info->location;
+    if (loc == NULL) {
+        g_warning (_("WeatherInfo missing location"));
+        return;
+    }
+
+    msg = soup_form_request_new (
+        "GET", "https://www.aviationweather.gov/adds/dataserver_current/httpparam",
+        "dataSource", "metars",
+        "requestType", "retrieve",
+        "format", "xml",
+        "hoursBeforeNow", "3",
+        "mostRecent", "true",
+        "fields", "raw_text",
+        "stationString", loc->code,
+        NULL);
+    soup_session_queue_message (info->session, msg, metar_finish, info);
+
+    info->requests_pending++;
+}
+
+
+
+
+ + + diff --git a/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/9.html b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/9.html new file mode 100644 index 0000000..2872af8 --- /dev/null +++ b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/9.html @@ -0,0 +1,876 @@ + + + + + + Cppcheck - HTML report - libmateweather + + + + + + +
+ +
+
  1
+  2
+  3
+  4
+  5
+  6
+  7
+  8
+  9
+ 10
+ 11
+ 12
+ 13
+ 14
+ 15
+ 16
+ 17
+ 18
+ 19
+ 20
+ 21
+ 22
+ 23
+ 24
+ 25
+ 26
+ 27
+ 28
+ 29
+ 30
+ 31
+ 32
+ 33
+ 34
+ 35
+ 36
+ 37
+ 38
+ 39
+ 40
+ 41
+ 42
+ 43
+ 44
+ 45
+ 46
+ 47
+ 48
+ 49
+ 50
+ 51
+ 52
+ 53
+ 54
+ 55
+ 56
+ 57
+ 58
+ 59
+ 60
+ 61
+ 62
+ 63
+ 64
+ 65
+ 66
+ 67
+ 68
+ 69
+ 70
+ 71
+ 72
+ 73
+ 74
+ 75
+ 76
+ 77
+ 78
+ 79
+ 80
+ 81
+ 82
+ 83
+ 84
+ 85
+ 86
+ 87
+ 88
+ 89
+ 90
+ 91
+ 92
+ 93
+ 94
+ 95
+ 96
+ 97
+ 98
+ 99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 4 -*- */
+/* weather-sun.c - Astronomy calculations for mateweather
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+/*
+ * Formulas from:
+ * "Practical Astronomy With Your Calculator" (3e), Peter Duffett-Smith
+ * Cambridge University Press 1988
+ * Unless otherwise noted, comments referencing "steps" are related to
+ * the algorithm presented in section 49 of above
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+#include <time.h>
+#include <glib.h>
+
+#define MATEWEATHER_I_KNOW_THIS_IS_UNSTABLE
+#include "weather-priv.h"
+
+#define ECCENTRICITY(d)         (0.01671123 - (d)/36525.*0.00004392)
+
+/*
+ * Ecliptic longitude of the sun at specified time (UT)
+ * The algoithm is described in section 47 of Duffett-Smith
+ * Return value is in radians
+ */
+gdouble
+sunEclipLongitude(time_t t)
+{
+    gdouble ndays, meanAnom, eccenAnom, delta, e, longitude;
+
+    /*
+     * Start with an estimate based on a fixed daily rate
+     */
+    ndays = EPOCH_TO_J2000(t) / 86400.;
+    meanAnom = DEGREES_TO_RADIANS(MEAN_ECLIPTIC_LONGITUDE(ndays)
+				  - PERIGEE_LONGITUDE(ndays));
+
+    /*
+     * Approximate solution of Kepler's equation:
+     * Find E which satisfies  E - e sin(E) = M (mean anomaly)
+     */
+    eccenAnom = meanAnom;
+    e = ECCENTRICITY(ndays);
+
+    while (1e-12 < fabs( delta = eccenAnom - e * sin(eccenAnom) - meanAnom))
+    {
+	eccenAnom -= delta / (1.- e * cos(eccenAnom));
+    }
+
+    /*
+     * Earth's longitude on the ecliptic
+     */
+    longitude = fmod( DEGREES_TO_RADIANS (PERIGEE_LONGITUDE(ndays))
+		      + 2. * atan (sqrt ((1.+e)/(1.-e))
+				   * tan (eccenAnom / 2.)),
+		      2. * M_PI);
+    if (longitude < 0.) {
+	longitude += 2 * M_PI;
+    }
+    return longitude;
+}
+
+static gdouble
+ecliptic_obliquity (gdouble time)
+{
+    gdouble jc = EPOCH_TO_J2000 (time) / (36525. * 86400.);
+    gdouble eclip_secs = (84381.448
+			  - (46.84024 * jc)
+			  - (59.e-5 * jc * jc)
+			  + (1.813e-3 * jc * jc * jc));
+    return DEGREES_TO_RADIANS(eclip_secs / 3600.);
+}
+
+/*
+ * Convert ecliptic longitude and latitude (radians) to equitorial
+ * coordinates, expressed as right ascension (hours) and
+ * declination (radians)
+ */
+void
+ecl2equ (gdouble time,
+	 gdouble eclipLon, gdouble eclipLat,
+	 gdouble *ra, gdouble *decl)
+{
+    gdouble mEclipObliq = ecliptic_obliquity(time);
+
+    if (ra) {
+	*ra = RADIANS_TO_HOURS (atan2 ((sin (eclipLon) * cos (mEclipObliq)
+					- tan (eclipLat) * sin(mEclipObliq)),
+				       cos (eclipLon)));
+	if (*ra < 0.)
+	    *ra += 24.;
+    }
+    if (decl) {
+	*decl = asin (( sin (eclipLat) * cos (mEclipObliq))
+		      + cos (eclipLat) * sin (mEclipObliq) * sin(eclipLon));
+    }
+}
+
+/*
+ * Calculate rising and setting times for an object
+ * based on it equitorial coordinates (section 33 & 15)
+ * Returned "rise" and "set" values are sideral times in hours
+ */
+static void
+gstObsv (gdouble ra, gdouble decl,
+	 gdouble obsLat, gdouble obsLon,
+	 gdouble *rise, gdouble *set)
+{
+    double a = acos (-tan (obsLat) * tan (decl));
+    double b;
+
+    if (isnan (a) != 0) {
+	*set = *rise = a;
+	return;
+    }
+    a = RADIANS_TO_HOURS (a);
+    b = 24. - a + ra;
+    a += ra;
+    a -= RADIANS_TO_HOURS (obsLon);
+    b -= RADIANS_TO_HOURS (obsLon);
+    if ((a = fmod (a, 24.)) < 0)
+	a += 24.;
+    if ((b = fmod (b, 24.)) < 0)
+	b += 24.;
+
+    *set = a;
+    *rise = b;
+}
+
+
+static gdouble
+t0 (time_t date)
+{
+    gdouble t = ((gdouble)(EPOCH_TO_J2000 (date) / 86400)) / 36525.0;
+    gdouble t0 = fmod (6.697374558 + 2400.051366 * t + 2.5862e-5 * t * t, 24.);
+    if (t0 < 0.)
+        t0 += 24.;
+    return t0;
+}
+
+
+static gboolean
+calc_sun2 (WeatherInfo *info, time_t t)
+{
+    gdouble obsLat = info->location->latitude;<--- obsLat is initialized
+    gdouble obsLon = info->location->longitude;<--- obsLon is initialized
+    time_t gm_midn;
+    time_t lcl_midn;
+    gdouble gm_hoff, lambda;
+    gdouble ra1, ra2;
+    gdouble decl1, decl2;
+    gdouble decl_midn, decl_noon;
+    gdouble rise1, rise2;
+    gdouble set1, set2;
+    gdouble tt, t00;
+    gdouble x, u, dt;
+
+    /* Approximate preceding local midnight at observer's longitude */
+    obsLat = info->location->latitude;<--- obsLat is overwritten
+    obsLon = info->location->longitude;<--- obsLon is overwritten
+    gm_midn = t - (t % 86400);
+    gm_hoff = floor ((RADIANS_TO_DEGREES (obsLon) + 7.5) / 15.);
+    lcl_midn = gm_midn - 3600. * gm_hoff;
+    if (t - lcl_midn >= 86400)
+        lcl_midn += 86400;
+    else if (lcl_midn > t)
+        lcl_midn -= 86400;
+
+    lambda = sunEclipLongitude (lcl_midn);
+
+    /*
+     * Calculate equitorial coordinates of sun at previous
+     * and next local midnights
+     */
+    ecl2equ (lcl_midn, lambda, 0., &ra1, &decl1);
+    ecl2equ (lcl_midn + 86400.,
+	     lambda + DEGREES_TO_RADIANS(SOL_PROGRESSION), 0.,
+	     &ra2, &decl2);
+
+    /*
+     * If the observer is within the Arctic or Antarctic Circles then
+     * the sun may be above or below the horizon for the full day.
+     */
+    decl_midn = MIN(decl1,decl2);
+    decl_noon = (decl1+decl2)/2.;
+    info->midnightSun =
+	(obsLat > (M_PI/2.-decl_midn)) || (obsLat < (-M_PI/2.-decl_midn));
+    info->polarNight =
+	(obsLat > (M_PI/2.+decl_noon)) || (obsLat < (-M_PI/2.+decl_noon));
+    if (info->midnightSun || info->polarNight) {
+	info->sunriseValid = info->sunsetValid = FALSE;
+	return FALSE;
+    }
+
+    /*
+     * Convert to rise and set times based positions for the preceding
+     * and following local midnights.
+     */
+    gstObsv (ra1, decl1, obsLat, obsLon - (gm_hoff * M_PI / 12.), &rise1, &set1);
+    gstObsv (ra2, decl2, obsLat, obsLon - (gm_hoff * M_PI / 12.), &rise2, &set2);
+
+    /* TODO: include calculations for regions near the poles. */
+    if (isnan(rise1) || isnan(rise2)) {
+	info->sunriseValid = info->sunsetValid = FALSE;
+        return FALSE;
+    }
+
+    if (rise2 < rise1) {
+        rise2 += 24.;
+    }
+    if (set2 < set1) {
+        set2 += 24.;
+    }
+
+    tt = t0(lcl_midn);
+    t00 = tt - (gm_hoff + RADIANS_TO_HOURS(obsLon)) * 1.002737909;
+
+    if (t00 < 0.)
+        t00 += 24.;
+
+    if (rise1 < t00) {
+        rise1 += 24.;
+        rise2 += 24.;
+    }
+    if (set1 < t00) {
+        set1  += 24.;
+        set2  += 24.;
+    }
+
+    /*
+     * Interpolate between the two to get a rise and set time
+     * based on the sun's position at local noon (step 8)
+     */
+    rise1 = (24.07 * rise1 - t00 * (rise2 - rise1)) / (24.07 + rise1 - rise2);
+    set1 = (24.07 * set1 - t00 * (set2 - set1)) / (24.07 + set1 - set2);
+
+    /*
+     * Calculate an adjustment value to account for parallax,
+     * refraction and the Sun's finite diameter (steps 9,10)
+     */
+    decl2 = (decl1 + decl2) / 2.;
+    x = DEGREES_TO_RADIANS(0.830725);
+    u = acos ( sin(obsLat) / cos(decl2) );
+    dt = RADIANS_TO_HOURS ( asin ( sin(x) / sin(u) ) / cos(decl2) );
+
+    /*
+     * Subtract the correction value from sunrise and add to sunset,
+     * then (step 11) convert sideral times to UT
+     */
+    rise1 = (rise1 - dt - tt) * 0.9972695661;
+    if (rise1 < 0.)
+	rise1 += 24;
+    else if (rise1 >= 24.)
+	rise1 -= 24.;
+    info->sunriseValid = ((rise1 >= 0.) && (rise1 < 24.));
+    info->sunrise = (rise1 * 3600.) + lcl_midn;
+
+    set1  = (set1 + dt - tt) * 0.9972695661;
+    if (set1 < 0.)
+	set1 += 24;
+    else if (set1 >= 24.)
+	set1 -= 24.;
+    info->sunsetValid = ((set1 >= 0.) && (set1 < 24.));
+    info->sunset = (set1 * 3600.) + lcl_midn;
+
+    return (info->sunriseValid || info->sunsetValid);
+}
+
+
+/**
+ * calc_sun_time:
+ * @info: #WeatherInfo structure containing the observer's latitude
+ * and longitude in radians, fills in the sunrise and sunset times.
+ * @t: time_t
+ *
+ * Returns: gboolean indicating if the results are valid.
+ */
+gboolean
+calc_sun_time (WeatherInfo *info, time_t t)
+{
+    return info->location->latlon_valid && calc_sun2 (info, t);
+}
+
+/**
+ * calc_sun:
+ * @info: #WeatherInfo structure containing the observer's latitude
+ * and longitude in radians, fills in the sunrise and sunset times.
+ *
+ * Returns: gboolean indicating if the results are valid.
+ */
+gboolean
+calc_sun (WeatherInfo *info)
+{
+    return calc_sun_time(info, time(NULL));
+}
+
+
+/**
+ * weather_info_next_sun_event:
+ * @info: #WeatherInfo structure
+ *
+ * Returns: the interval, in seconds, until the next "sun event":
+ *  - local midnight, when rise and set times are recomputed
+ *  - next sunrise, when icon changes to daytime version
+ *  - next sunset, when icon changes to nighttime version
+ */
+gint
+weather_info_next_sun_event (WeatherInfo *info)
+{
+    time_t    now = time (NULL);
+    struct tm ltm;
+    time_t    nxtEvent;
+
+    g_return_val_if_fail (info != NULL, -1);
+
+    if (!calc_sun (info))
+	return -1;
+
+    /* Determine when the next local midnight occurs */
+    (void) localtime_r (&now, &ltm);
+    ltm.tm_sec = 0;
+    ltm.tm_min = 0;
+    ltm.tm_hour = 0;
+    ltm.tm_mday++;
+    nxtEvent = mktime (&ltm);
+
+    if (info->sunsetValid &&
+	(info->sunset > now) && (info->sunset < nxtEvent))
+	nxtEvent = info->sunset;
+    if (info->sunriseValid &&
+	(info->sunrise > now) && (info->sunrise < nxtEvent))
+	nxtEvent = info->sunrise;
+    return (gint)(nxtEvent - now);
+}
+
+
+
+
+ + + diff --git a/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/index.html b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/index.html new file mode 100644 index 0000000..41601d4 --- /dev/null +++ b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/index.html @@ -0,0 +1,167 @@ + + + + + + Cppcheck - HTML report - libmateweather + + + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LineIdCWESeverityMessage
missingIncludeinformationCppcheck cannot find all the include files (use --check-config for details)
libmateweather/location-entry.c
303variableScope398styleThe scope of the variable 'cmpcode' can be reduced.
libmateweather/mateweather-timezone.c
71variableScope398styleThe scope of the variable 'second_isdst' can be reduced.
libmateweather/parser.c
94variableScope398styleThe scope of the variable 'next_tagname' can be reduced.
117arrayIndexThenCheck398styleArray index 'i' is used before limits check.
libmateweather/test_metar.c
29variableScope398styleThe scope of the variable 'len' can be reduced.
40knownConditionTrueFalse570styleCondition 'filename' is always false
libmateweather/test_sun_moon.c
58knownConditionTrueFalse570styleCondition 'gtime!=NULL' is always false
73asctimeCalled477styleObsolete function 'asctime' called. It is recommended to use 'strftime' instead.
83asctimeCalled477styleObsolete function 'asctime' called. It is recommended to use 'strftime' instead.
84asctimeCalled477styleObsolete function 'asctime' called. It is recommended to use 'strftime' instead.
85asctimeCalled477styleObsolete function 'asctime' called. It is recommended to use 'strftime' instead.
86asctimeCalled477styleObsolete function 'asctime' called. It is recommended to use 'strftime' instead.
libmateweather/weather-bom.c
32variableScope398styleThe scope of the variable 'rp' can be reduced.
libmateweather/weather-iwin.c
417nullPointerRedundantCheck476warningEither the condition 'loc!=NULL' is redundant or there is possible null pointer dereference: loc.
libmateweather/weather-met.c
135nullPointerRedundantCheck476warningEither the condition 'p!=NULL' is redundant or there is possible null pointer dereference: p.
138nullPointerArithmeticRedundantCheck682warningEither the condition 'p!=NULL' is redundant or there is pointer arithmetic with NULL pointer.
libmateweather/weather-metar.c
145knownConditionTrueFalse571styleCondition 'dir<=348' is always true
454unreadVariable563styleVariable 'i' is assigned a value that is never used.
493variableScope398styleThe scope of the variable 'endtag' can be reduced.
494variableScope398styleThe scope of the variable 'metar' can be reduced.
libmateweather/weather-sun.c
178redundantInitialization563styleRedundant initialization for 'obsLat'. The initialized value is overwritten before it is read.
179redundantInitialization563styleRedundant initialization for 'obsLon'. The initialized value is overwritten before it is read.
libmateweather/weather-wx.c
64nullPointerRedundantCheck476warningEither the condition 'info!=NULL' is redundant or there is possible null pointer dereference: info.
libmateweather/weather.c
326variableScope398styleThe scope of the variable 'str' can be reduced.
498uselessAssignmentPtrArg398warningAssignment of function parameter has no effect outside the function. Did you forget dereferencing it?
498unreadVariable563styleVariable 'location' is assigned a value that is never used.
700variableScope398styleThe scope of the variable 'utf8' can be reduced.
700variableScope398styleThe scope of the variable 'timeformat' can be reduced.
718unsignedLessThanZero570styleChecking if unsigned expression 'strftime(buf,sizeof(buf),timeformat,&tm)' is less than zero.
1073unsignedLessThanZero570styleChecking if unsigned expression 'strftime(buf,sizeof(buf),mateweather_gettext("%H:%M"),&tm)' is less than zero.
1094unsignedLessThanZero570styleChecking if unsigned expression 'strftime(buf,sizeof(buf),mateweather_gettext("%H:%M"),&tm)' is less than zero.
+
+
+ + + diff --git a/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/stats.html b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/stats.html new file mode 100644 index 0000000..e001184 --- /dev/null +++ b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/stats.html @@ -0,0 +1,119 @@ + + + + + + Cppcheck - HTML report - libmateweather + + + + + + +
+ +
+

Top 10 files for warning severity, total findings: 5
+   2  libmateweather/weather-met.c
+   1  libmateweather/weather.c
+   1  libmateweather/weather-wx.c
+   1  libmateweather/weather-iwin.c
+

+

Top 10 files for style severity, total findings: 26
+   7  libmateweather/weather.c
+   6  libmateweather/test_sun_moon.c
+   4  libmateweather/weather-metar.c
+   2  libmateweather/weather-sun.c
+   2  libmateweather/test_metar.c
+   2  libmateweather/parser.c
+   1  libmateweather/weather-bom.c
+   1  libmateweather/mateweather-timezone.c
+   1  libmateweather/location-entry.c
+

+ +
+
+ + + diff --git a/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/style.css b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/style.css new file mode 100644 index 0000000..07125f4 --- /dev/null +++ b/2020-07-17-122136-1677-cppcheck@af3af510ab5b_master/style.css @@ -0,0 +1,137 @@ + +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif; + font-size: 13px; + line-height: 1.5; + margin: 0; + width: auto; +} + +h1 { + margin: 10px; +} + +.header { + border-bottom: thin solid #aaa; +} + +.footer { + border-top: thin solid #aaa; + font-size: 90%; + margin-top: 5px; +} + +.footer ul { + list-style-type: none; + padding-left: 0; +} + +.footer > p { + margin: 4px; +} + +.wrapper { + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + justify-content: space-between; +} + +#menu, +#menu_index { + text-align: left; + width: 350px; + height: 90vh; + min-height: 200px; + overflow: auto; + position: -webkit-sticky; + position: sticky; + top: 0; + padding: 0 15px 15px 15px; +} + +#menu > a { + display: block; + margin-left: 10px; + font-size: 12px; + z-index: 1; +} + +#content, +#content_index { + background-color: #fff; + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; + padding: 0 15px 15px 15px; + width: calc(100% - 350px); + height: 100%; + overflow-x: auto; +} + +#filename { + margin-left: 10px; + font-size: 12px; + z-index: 1; +} + +.error { + background-color: #ffb7b7; +} + +.error2 { + background-color: #faa; + display: inline-block; + margin-left: 4px; +} + +.inconclusive { + background-color: #b6b6b4; +} + +.inconclusive2 { + background-color: #b6b6b4; + display: inline-block; + margin-left: 4px; +} + +.verbose { + display: inline-block; + vertical-align: top; + cursor: help; +} + +.verbose .content { + display: none; + position: absolute; + padding: 10px; + margin: 4px; + max-width: 40%; + white-space: pre-wrap; + border: 1px solid #000; + background-color: #ffffcc; + cursor: auto; +} + +.highlight .hll { + padding: 1px; +} + +.highlighttable { + background-color: #fff; + z-index: 10; + position: relative; + margin: -10px; +} + +.linenos { + border-right: thin solid #aaa; + color: #d3d3d3; + padding-right: 6px; +} + +.d-none { + display: none; +} -- cgit v1.2.1