]> git.mxchange.org Git - simgear.git/blobdiff - simgear/environment/metar.cxx
Merge branch 'maint'
[simgear.git] / simgear / environment / metar.cxx
index 1c19196354b67e4a5c4e5d0808032a8618649824..79401e39419d3680ae0495f1d68b34da42cfb987 100644 (file)
@@ -16,7 +16,7 @@
 //
 // You should have received a copy of the GNU General Public License
 // along with this program; if not, write to the Free Software
-// Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 //
 // $Id$
 
@@ -24,6 +24,9 @@
  * @file metar.cxx
  * Interface for encoded Meteorological Aerodrome Reports (METAR).
  */
+#ifdef HAVE_CONFIG_H
+#  include <simgear_config.h>
+#endif
 
 #include <string>
 #include <time.h>
@@ -156,7 +159,7 @@ void SGMetar::useCurrentDate()
 {
        struct tm now;
        time_t now_sec = time(0);
-#if defined( _MSC_VER ) || defined ( __MINGW32__ )
+#ifdef _WIN32
        now = *gmtime(&now_sec);
 #else
        gmtime_r(&now_sec, &now);
@@ -218,7 +221,7 @@ char *SGMetar::loadData(const char *id, const string& proxy, const string& port,
        while ((i = sock->readline(buf, buflen))) {
                if (i <= 2 && isspace(buf[0]) && (!buf[1] || isspace(buf[1])))
                        break;
-               if (!strncmp(buf, "X-MetarProxy: ", 9))
+               if (!strncmp(buf, "X-MetarProxy: ", 13))
                        _x_proxy = true;
        }
        if (i) {
@@ -490,7 +493,6 @@ bool SGMetar::scanVisibility()
                distance = i;
        } else {
 // M?(\d{1,2}|\d{1,2}/\d{1,2}|\d{1,2} \d{1,2}/\d{1,2})(SM|KM)
-               modifier = 0;
                if (*m == 'M')
                        m++, modifier = SGMetarVisibility::LESS_THAN;
 
@@ -609,56 +611,56 @@ bool SGMetar::scanRwyVisRange()
 
 
 static const struct Token special[] = {
-       "NSW",  "no significant weather",
-       "VCSH", "showers in the vicinity",
-       "VCTS", "thunderstorm in the vicinity",
-       0, 0
+       { "NSW",  "no significant weather" },
+       { "VCSH", "showers in the vicinity" },
+       { "VCTS", "thunderstorm in the vicinity" },
+       { 0, 0 }
 };
 
 
 static const struct Token description[] = {
-       "SH",   "showers of",
-       "TS",   "thunderstorm with",
-       "BC",   "patches of",
-       "BL",   "blowing",
-       "DR",   "low drifting",
-       "FZ",   "freezing",
-       "MI",   "shallow",
-       "PR",   "partial",
-       0, 0
+       { "SH", "showers of" },
+       { "TS", "thunderstorm with" },
+       { "BC", "patches of" },
+       { "BL", "blowing" },
+       { "DR", "low drifting" },
+       { "FZ", "freezing" },
+       { "MI", "shallow" },
+       { "PR", "partial" },
+       { 0, 0 }
 };
 
 
 static const struct Token phenomenon[] = {
-       "DZ",   "drizzle",
-       "GR",   "hail",
-       "GS",   "small hail and/or snow pellets",
-       "IC",   "ice crystals",
-       "PE",   "ice pellets",
-       "RA",   "rain",
-       "SG",   "snow grains",
-       "SN",   "snow",
-       "UP",   "unknown precipitation",
-       "BR",   "mist",
-       "DU",   "widespread dust",
-       "SG",   "fog",
-       "SGBR", "fog bank",
-       "FU",   "smoke",
-       "HZ",   "haze",
-       "PY",   "spray",
-       "SA",   "sand",
-       "VA",   "volcanic ash",
-       "DS",   "duststorm",
-       "FC",   "funnel cloud/tornado waterspout",
-       "PO",   "well-developed dust/sand whirls",
-       "SQ",   "squalls",
-       "SS",   "sandstorm",
-       "UP",   "unknown",      // ... due to failed automatic acquisition
-       0, 0
+       { "DZ",   "drizzle" },
+       { "GR",   "hail" },
+       { "GS",   "small hail and/or snow pellets" },
+       { "IC",   "ice crystals" },
+       { "PE",   "ice pellets" },
+       { "RA",   "rain" },
+       { "SG",   "snow grains" },
+       { "SN",   "snow" },
+       { "UP",   "unknown precipitation" },
+       { "BR",   "mist" },
+       { "DU",   "widespread dust" },
+       { "FG",   "fog" },
+       { "FGBR", "fog bank" },
+       { "FU",   "smoke" },
+       { "HZ",   "haze" },
+       { "PY",   "spray" },
+       { "SA",   "sand" },
+       { "VA",   "volcanic ash" },
+       { "DS",   "duststorm" },
+       { "FC",   "funnel cloud/tornado waterspout" },
+       { "PO",   "well-developed dust/sand whirls" },
+       { "SQ",   "squalls" },
+       { "SS",   "sandstorm" },
+       { "UP",   "unknown" },  // ... due to failed automatic acquisition
+       { 0, 0 }
 };
 
 
-// (+|-|VC)?(NSW|MI|PR|BC|DR|BL|SH|TS|FZ)?((DZ|RA|SN|SG|IC|PE|GR|GS|UP){0,3})(BR|SG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS){0,3}
+// (+|-|VC)?(NSW|MI|PR|BC|DR|BL|SH|TS|FZ)?((DZ|RA|SN|SG|IC|PE|GR|GS|UP){0,3})(BR|FG|FU|VA|DU|SA|HZ|PY|PO|SQ|FC|SS|DS){0,3}
 bool SGMetar::scanWeather()
 {
        char *m = _m;
@@ -714,26 +716,26 @@ bool SGMetar::scanWeather()
 
 
 static const struct Token cloud_types[] = {
-       "AC",    "altocumulus",
-       "ACC",   "altocumulus castellanus",
-       "ACSL",  "altocumulus standing lenticular",
-       "AS",    "altostratus",
-       "CB",    "cumulonimbus",
-       "CBMAM", "cumulonimbus mammatus",
-       "CC",    "cirrocumulus",
-       "CCSL",  "cirrocumulus standing lenticular",
-       "CI",    "cirrus",
-       "CS",    "cirrostratus",
-       "CU",    "cumulus",
-       "CUFRA", "cumulus fractus",
-       "NS",    "nimbostratus",
-       "SAC",   "stratoaltocumulus",           // guessed
-       "SC",    "stratocumulus",
-       "SCSL",  "stratocumulus standing lenticular",
-       "ST",    "stratus",
-       "STFRA", "stratus fractus",
-       "TCU",   "towering cumulus",
-       0, 0
+       { "AC",    "altocumulus" },
+       { "ACC",   "altocumulus castellanus" },
+       { "ACSL",  "altocumulus standing lenticular" },
+       { "AS",    "altostratus" },
+       { "CB",    "cumulonimbus" },
+       { "CBMAM", "cumulonimbus mammatus" },
+       { "CC",    "cirrocumulus" },
+       { "CCSL",  "cirrocumulus standing lenticular" },
+       { "CI",    "cirrus" },
+       { "CS",    "cirrostratus" },
+       { "CU",    "cumulus" },
+       { "CUFRA", "cumulus fractus" },
+       { "NS",    "nimbostratus" },
+       { "SAC",   "stratoaltocumulus" },               // guessed
+       { "SC",    "stratocumulus" },
+       { "SCSL",  "stratocumulus standing lenticular" },
+       { "ST",    "stratus" },
+       { "STFRA", "stratus fractus" },
+       { "TCU",   "towering cumulus" },
+       { 0, 0 }
 };
 
 
@@ -744,6 +746,14 @@ bool SGMetar::scanSkyCondition()
        int i;
        SGMetarCloud cl;
 
+       if (!strncmp(m, "//////", 6)) {
+               m += 6;
+               if (!scanBoundary(&m))
+                       return false;
+               _m = m;
+               return true;
+       }
+
        if (!strncmp(m, "CLR", i = 3)                           // clear
                        || !strncmp(m, "SKC", i = 3)            // sky clear
                        || !strncmp(m, "NSC", i = 3)            // no significant clouds
@@ -833,7 +843,7 @@ bool SGMetar::scanTemperature()
                return false;
        if (!scanBoundary(&m)) {
                if (!strncmp(m, "XX", 2))       // not spec compliant!
-                       m += 2, sign = 0;
+                       m += 2, sign = 0, dew = temp;
                else {
                        sign = 1;
                        if (*m == 'M')
@@ -958,11 +968,13 @@ bool SGMetar::scanRunwayReport()
                        m++;
                else
                        return false;
+
                if (*m == '1' || *m == '2' || *m == '5' || *m == '9') { // extent of deposit
                        r._extent = *m - '0';
                        r._extent_string = runway_deposit_extent[*m - '0'];
                } else if (*m != '/')
                        return false;
+
                m++;
                i = -1;
                if (!strncmp(m, "//", 2))
@@ -971,7 +983,7 @@ bool SGMetar::scanRunwayReport()
                        return false;
 
                if (i == 0)
-                       r._depth = 0.5;                                 // < 1 mm deep (let's say 0.5 :-)
+                       r._depth = 0.0005;                              // < 1 mm deep (let's say 0.5 :-)
                else if (i > 0 && i <= 90)
                        r._depth = i / 1000.0;                          // i mm deep
                else if (i >= 92 && i <= 98)
@@ -997,6 +1009,7 @@ bool SGMetar::scanRunwayReport()
                return false;
 
        _runways[id]._deposit = r._deposit;
+       _runways[id]._deposit_string = r._deposit_string;
        _runways[id]._extent = r._extent;
        _runways[id]._extent_string = r._extent_string;
        _runways[id]._depth = r._depth;
@@ -1076,13 +1089,13 @@ bool SGMetar::scanTrendForecast()
 
 // (BLU|WHT|GRN|YLO|AMB|RED)
 static const struct Token colors[] = {
-       "BLU", "Blue",          // 2500 ft,  8.0 km
-       "WHT", "White",         // 1500 ft,  5.0 km
-       "GRN", "Green",         //  700 ft,  3.7 km
-       "YLO", "Yellow",        //  300 ft,  1.6 km
-       "AMB", "Amber",         //  200 ft,  0.8 km
-       "RED", "Red",           // <200 ft, <0.8 km
-       0, 0
+       { "BLU", "Blue" },      // 2500 ft,  8.0 km
+       { "WHT", "White" },     // 1500 ft,  5.0 km
+       { "GRN", "Green" },     //  700 ft,  3.7 km
+       { "YLO", "Yellow" },    //  300 ft,  1.6 km
+       { "AMB", "Amber" },     //  200 ft,  0.8 km
+       { "RED", "Red" },       // <200 ft, <0.8 km
+       { 0, 0 }
 };
 
 
@@ -1168,7 +1181,7 @@ const struct Token *SGMetar::scanToken(char **str, const struct Token *list)
 {
        const struct Token *longest = 0;
        int maxlen = 0, len;
-       char *s;
+       const char *s;
        for (int i = 0; (s = list[i].id); i++) {
                len = strlen(s);
                if (!strncmp(s, *str, len) && len > maxlen) {