Thanx.  I've applied this.  I also took this chance to move '_warn' out of C reserved namespace.

Can you please provide a few sentences of doc for the new options?

Thanx,
RJL

On Fri, Aug 21, 2009 at 2:11 PM, Andrei Boros <andrei@srr.ro> wrote:
Hi,

I've done some more work on the Pathaway module. Now it should safely
handle most of date/time errors or inconsistencies seamlessly.
Warnings and more information is available on debug levels 1,3,5 as to
the progress and inconsistencies in the data.

Anyway, by now I get clean conversions on my dataset (which is quite
large, taken with several revisions of pathaway through time).

Module adds dbicon parameter : set database icon (also known as vehicle
by pathaway)
Module adds deficon parameter : set point icon (other then input, or if
not input icon available).
Warnings now are more detailed and available at -D 1
More information on the inconsistent input records at -D 3
Dump of processing progress at -D 5

Date handling now consideres 8 digit date as YYYYMMDD (unless specified
by parameter) or 6 digit date as DDMMYY and uses the 1970 base for Y2K
handling.
Invalid date/time information is corrected or zeroed as much as
possible, also spaces are trimmed out (in newer revisions of Pathaway 4).

Pathaway 4 and 5 for Windows Mobile use a CSV like text file which I
haven't fully figured out yet, they are not handled by this module.

Attached patch is against yesterday's cvs tree.

Andrei


--- gpsbabel-cvs/pathaway.c     2009-07-18 23:25:24.000000000 +0300
+++ gpsbabel/pathaway.c 2009-08-21 21:51:30.000000000 +0300
@@ -70,6 +70,7 @@
 static unsigned char german_release = 0;
 static char *datefmt;
 static int ct;
+static int _warn = 0;

 typedef struct ppdb_appdata
 {
@@ -126,7 +127,7 @@
 #endif


-#define CHECK_INP(i, j, k) is_fatal((i != j), "Error in data structure (%s).", (k))
+#define CHECK_INP(i, j, k, l) is_fatal((i != j), "Error in data structure (in %s? Value is : %s).", (k), (l))

 /*
 * utilities
@@ -285,7 +286,7 @@

       if (*str < 'A')         /* only numeric */
       {
-           CHECK_INP(1, sscanf(str,"%lf", &val), "decode_coord(1)");
+           CHECK_INP(1, sscanf(str,"%lf", &val), "decode_coord(1) DD.dddd", str);
           return val;
       }
       else
@@ -297,12 +298,12 @@
           tmp = strchr(str, ' ');
           if ((tmp) && (tmp - str < 5))
           {
-               CHECK_INP(3, sscanf(str,"%c%d %lf", &dir, &deg, &val), "decode_coord(2)");
+               CHECK_INP(3, sscanf(str,"%c%d %lf", &dir, &deg, &val), "decode_coord(2) DD MM.mmm", str);
               val = deg + (val / 60.0);
           }
           else
           {
-               CHECK_INP(2, sscanf(str,"%c%lf", &dir, &val), "decode_coord(3)");
+               CHECK_INP(2, sscanf(str,"%c%lf", &dir, &val), "decode_coord(3) DD.dddd", str);
           }
           if ((dir == 'S') || (dir == 'W'))
               val = -val;
@@ -318,32 +319,62 @@
       int temp=0;
       char *cx;

-       while (*str == ' ') str++;      /* WORKAROUND may start with or contain several empty spaces, but no date or time info */
+       str = lrtrim(str);              /* time field may start/end with spaces, drop them */

-       if (*str == '\0') return 0;     /* empty date and time */
+        if (*str == '\0')
+        {
+               if (global_opts.debug_level > 0)
+               {
+                   warning(MYNAME ": Time value missing, reseting to 0\n");
+                   _warn = 1;
+               }
+                return 0;                       /* empty time field */
+        }

       if (strchr(str, '.'))           /* time in hhmmss.ms */
       {
               CHECK_INP(4, sscanf(str, "%02d%02d%02d.%d",
                       &tm->tm_hour, &tm->tm_min, &tm->tm_sec, &msec),
-                       "decode_tm(1)");
+                       "decode_tm(1) hhmmss.ss", str);
       }
       else if (sscanf(str,"%06d",&temp)==1)
                                       /* WORKAROUND read time info only if a valid 6 digit string found */
       {
               CHECK_INP(3, sscanf(str, "%02d%02d%02d",
                       &tm->tm_hour, &tm->tm_min, &tm->tm_sec),
-                       "decode_tm(2)");
+                       "decode_tm(2) hhmmss", str);
       }
       else
       {
+               if (global_opts.debug_level > 0)
+               {
+                   warning(MYNAME ": Invalid time value, reseting to 0\n");
+                    _warn = 1;
+               }
               return 0;               /* WORKAROUND maybe invalid time, just ignore it and continue */
       }
       cx = strchr(str, ' ');
-       if (cx == NULL) return 0;       /* no date */

-       while (*cx == ' ') cx++;
-       if (*cx == '\0') return 0;      /* no date */
+        if (cx == NULL)
+        {
+               if (global_opts.debug_level > 0)
+               {
+                   warning(MYNAME ": Date value missing, reseting to 0\n");
+                   _warn = 1;
+               }
+                return 0;       /* empty date field */
+        }
+
+        cx = lrtrim(cx);
+        if (*cx == '\0')
+        {
+               if (global_opts.debug_level > 0)
+               {
+                   warning(MYNAME ": Date value missing, found only spaces, reseting to 0\n");
+                   _warn = 1;
+               }
+                return 0;       /* empty date field */
+        }

       if (datefmt)
       {
@@ -363,28 +394,23 @@
               time_t tnow;
               struct tm now;

-               if (strlen(cx) != 8)
-               {
-                       printf(MYNAME ": Date from first record is %s.\n", cx);
-                       printf(MYNAME ": Please use option 'date' to specify how this is formatted.\n");
-                       fatal(MYNAME  ": (... -i pathaway,date=DDMMYY ...)\n");
-               }
-
-               CHECK_INP(4, sscanf(cx, "%02d%02d%02d%02d", &d1, &d2, &d3, &d4), "decode_tm(3)");

               tnow = current_time();
               now = *localtime(&tnow);
               now.tm_year += 1900;
               now.tm_mon++;

-               year = (d1 * 100) + d2;
+               if (strlen(cx) == 8)
+               {
+                   CHECK_INP(4, sscanf(cx, "%02d%02d%02d%02d", &d1, &d2, &d3, &d4), "decode_tm(3) invalid date (YYYYMMDD)", cx);

+                   year = (d1 * 100) + d2;
               /* the coordinates comes before date and time in
                  the dataset, so the flag "german_release" is set yet. */

               /* next code works for most, except for 19. and 20. of month */

-               if ((german_release != 0) || (year < 1980) || (year > now.tm_year))     /* YYYYMMDD or DDMMYYY ????? */
+                   if ((german_release != 0) || (year < 1980) || (year > now.tm_year)) /* YYYYMMDD or DDMMYYYY ????? */
               {
                   tm->tm_year = (d3 * 100) + d4;
                   tm->tm_mon = d2;
@@ -396,6 +422,26 @@
                   tm->tm_mon = d3;
                   tm->tm_mday = d4;
               }
+               } else if (strlen(cx) == 6)
+               {
+                   CHECK_INP(3, sscanf(cx, "%02d%02d%02d", &d1, &d2, &d3), "decode_tm(3) invalid date (DDMMYY)", cx);
+                   if (d3 < 1970)                      /* Usual Y2K interpretation */
+                       year = d3 + 2000;
+                   else
+                       year = d3 + 1900;
+
+/* I don't know how a german release handles this
+ * so for now I will assume only DDMMYY if date has 6 digits
+ */
+                   tm->tm_year = year;
+                   tm->tm_mon = d2;
+                   tm->tm_mday = d1;
+               } else                  /* date string is neither 8 nor 6 digits */
+               {
+                       printf(MYNAME ": Date from first record is %s.\n", cx);
+                       printf(MYNAME ": Please use option 'date' to specify how this is formatted.\n");
+                       fatal(MYNAME  ": (... -i pathaway,date=DDMMYY ...)\n");
+               }
       }
       return 1;
 }
@@ -412,7 +458,15 @@
               int line = 0;
               char *tmp = data;

-//             while ((str = csv_lineparse(tmp, ",", """", line++))) {
+/* Print the whole input record. All input records are printed before processing. */
+               if (global_opts.debug_level >= 5)
+               {
+                       DBG(("\n\
+--- BEGIN Input data record -----------------------------------------------\n\
+%s\n\
+--- END Input data record -------------------------------------------------\n",data));
+               }
+
               while ((str = csv_lineparse(tmp, ",", "\"", line++))) {
                   tmp = NULL;
                   switch(line)
@@ -426,7 +480,7 @@
                       case 3:         /* altitude */
                           if (*str != '\0')
                           {
-                               CHECK_INP(1, sscanf(str, "%lf", &altfeet), "altitude");
+                               CHECK_INP(1, sscanf(str, "%lf", &altfeet), "altitude", str);
                               if (altfeet != -9999)
                                   wpt_tmp->altitude = FEET_TO_METERS(altfeet);
                           }
@@ -456,6 +510,16 @@
                   }
               }

+/* Print the whole input record, should a warning be triggered.
+ * Use warning() here instead of DBG() to print the data record
+ * right after the warning is issued.
+ */
+               if (_warn && (global_opts.debug_level > 1) && (global_opts.debug_level < 5))
+               {
+                       warning("Faulty input data record : %s\n",data);
+                       _warn = 0;
+               }
+
               if (head && isRoute )
                   route_add_wpt(head, wpt_tmp);
               else if (head)
@@ -671,8 +735,7 @@
                               /* 6 icon */

       tmp = str_pool_getcpy(wpt->icon_descr, opt_deficon);    /* point icon or deficon from options */
-       buff = ppdb_strcat(buff, tmp, "0", &len);
-       /* buff = ppdb_strcat(buff, opt_deficon, "0", &len);*/
+       buff = ppdb_strcat(buff, tmp, NULL, &len);
       buff = ppdb_strcat(buff, ",", NULL, &len);
                               /* 7 description */

@@ -710,13 +773,15 @@
       file_out->version = 3;

 /*     Waypoint target does use vehicleStr from appinfo block
-       Actually, all 3 types have vehicle information.
-       if (global_opts.objective != wptdata)   / * Waypoint target do not need appinfo block * /
-       {   */
+ *     Actually, all 3 types have vehicle information.
+ *     if (global_opts.objective != wptdata)   / * Waypoint target do not need appinfo block * /
+ *     {
+ */
           appinfo = xcalloc(1, sizeof(*appinfo));
           file_out->appinfo = (void *)appinfo;
           file_out->appinfo_len = PPDB_APPINFO_SIZE;
-/*     }   */
+/*     }
+ */
       if (opt_dbicon != NULL) strncpy(appinfo->vehicleStr, opt_dbicon, VEHICLE_LEN);

       switch(global_opts.objective)           /* Only one target is possible */

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
Gpsbabel-code mailing list  http://www.gpsbabel.org
Gpsbabel-code@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/gpsbabel-code