changeset 789:99d6c48f9aaa

Fix bugs in the parser.
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 13 Jun 2009 08:13:00 +0000
parents e8ab49be9986
children 543e6a5e8637
files mkloc.c
diffstat 1 files changed, 59 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/mkloc.c	Fri Jun 12 09:17:48 2009 +0000
+++ b/mkloc.c	Sat Jun 13 08:13:00 2009 +0000
@@ -285,6 +285,20 @@
     }
 }
 
+void fprintfe(FILE *f, char *s)
+{
+    char *p = s;
+    
+    while (*p) {
+        switch (*p) {
+        case ';': fputs("\\;", f); break;
+        case '\\': fputs("\\", f); break;
+        default: fputc(*p, f);
+        }
+        p++;
+    }
+}
+
 
 BOOL addLocation(locations_t *l, int x, int y, int dir, int flags,
     char **names, char **coders, tm_t *added, BOOL addedValid,
@@ -528,6 +542,18 @@
 };
 
 
+BOOL checkForEOL(fileinfo_t *f, int *state)
+{
+    if (f->c == '\n' || f->c == '\r') {
+        *state = STATE_ERROR;
+        THERR("Unexpected EOL on line #%d of '%s'.\n",
+            f->lineNum, f->filename);
+        return FALSE;
+    } else
+        return TRUE;
+}
+
+
 BOOL parseLocationFile(char *filename, locations_t *l, int offX, int offY)
 {
     fileinfo_t f;
@@ -562,7 +588,15 @@
         case STATE_IDLE:
             if (f.c == EOF)
                 state = STATE_END;
-            else if (f.c == '#') {
+            else if (f.c == '\r') {
+                f.lineNum++;
+                f.c = fgetc(f.f);
+                if (f.c == '\n')
+                    f.c = fgetc(f.f);
+            } else if (f.c == '\n') {
+                f.lineNum++;
+                f.c = fgetc(f.f);
+            } else if (f.c == '#') {
                 prev = state;
                 state = STATE_COMMENT;
                 next = STATE_IDLE;
@@ -582,6 +616,14 @@
         
         case STATE_COMMENT:
             switch (f.c) {
+                case '\r':
+                    f.c = fgetc(f.f);
+                    if (f.c == '\n')
+                        f.c = fgetc(f.f);
+                    f.lineNum++;
+                    prev = state;
+                    state = next;
+                    break;
                 case '\n':
                     f.c = fgetc(f.f);
                     f.lineNum++;
@@ -615,17 +657,12 @@
                         THERR("Expected EOL on line #%d of '%s'.\n",
                             f.lineNum, f.filename);
                     } else {
+                        f.lineNum++;
                         f.c = fgetc(f.f);
                         if (i == '\r' && f.c == '\n')
                             f.c = fgetc(f.f);
                     }
                     break;
-                case '\n':
-                case '\r':
-                    state = STATE_ERROR;
-                    THERR("Unexpected EOL on line #%d of '%s'.\n",
-                        f.lineNum, f.filename);
-                    break;
                 default:
                     prev = state;
                     state = next;
@@ -648,6 +685,7 @@
             break;
         
         case STATE_FIELD:
+            if (field > 0 && field < 8 && !checkForEOL(&f, &state)) break;
             switch (field) {
                 case 1: /* X-coordinate */
                     res = parseFieldInt(&f, &tmpX);
@@ -659,6 +697,7 @@
                         state = STATE_NEXT;
                     }
                     break;
+                
                 case 2: /* Y-coordinate */
                     res = parseFieldInt(&f, &tmpY);
                     if (res) {
@@ -668,6 +707,7 @@
                         state = STATE_NEXT;
                     }
                     break;
+                
                 case 3: /* Label orientation and flags */
                     res = parseFieldInt(&f, &tmpOrient);
                     if (res)
@@ -679,6 +719,7 @@
                         state = STATE_NEXT;
                     }
                     break;
+                
                 case 4: /* Location name(s) */
                     if (subfield < 0) {
                         subfield = 0;
@@ -710,6 +751,7 @@
                         state = STATE_FIELD;
                     }
                     break;
+                
                 case 5: /* Coders */
                     if (subfield < 0) {
                         subfield = 0;
@@ -741,6 +783,7 @@
                         state = STATE_FIELD;
                     }
                     break;
+                
                 case 6: /* Date */
                     tmpTimeSet = FALSE;
                     tmpStr = parseFieldString(&f, fieldsep);
@@ -771,13 +814,13 @@
                     tmpURI = parseFieldString(&f, fieldsep);
                     field++;
                     prev = state;
-                    next = STATE_FIELD;
+                    next = STATE_FIELD_SEP;
                     state = STATE_NEXT;
                     break;
                 
                 case 8: /* Freeform */
                     tmpStr = parseFieldString(&f, "\r\n");
-                    
+
                     /* Check if location already exists */
                     tmpX += offX;
                     tmpY += offY;
@@ -806,6 +849,7 @@
                     }
                     th_free(tmpStr);
                     break;
+                
                 default:
                     THERR("FATAL ERROR! Invalid state=%d!\n", state);
                     state = STATE_ERROR;
@@ -1101,18 +1145,18 @@
             fputc('-', outFile);
         
         fprintf(outFile, "\t;");
-        printEscString(outFile, tmp->names[0]);
+        fprintfe(outFile, tmp->names[0]);
         for (n = 1; n < tmp->nnames; n++) {
             fprintf(outFile, "|");
-            printEscString(outFile, tmp->names[n]);
+            fprintfe(outFile, tmp->names[n]);
         }
         fprintf(outFile, ";");
         
         if (tmp->ncoders > 0) {
-            printEscString(outFile, tmp->coders[0]);
+            fprintfe(outFile, tmp->coders[0]);
             for (n = 1; n < tmp->ncoders; n++) {
                 fprintf(outFile, ",");
-                printEscString(outFile, tmp->coders[n]);
+                fprintfe(outFile, tmp->coders[n]);
             }
         }
         
@@ -1126,12 +1170,12 @@
         fprintf(outFile, ";");
         
         if (tmp->uri)
-            printEscString(outFile, tmp->uri);
+            fprintfe(outFile, tmp->uri);
         
         fprintf(outFile, ";");
         
         if (tmp->freeform)
-            printEscString(outFile, tmp->freeform);
+            fprintfe(outFile, tmp->freeform);
         
         fprintf(outFile, "\n");
     }