Add dmalloc testability.
[gedcom-parse.git] / gedcom.y
index 8aad4fd9f02ed3726ac82eaf78c800fbc3568f65..336426940b3bc8a9560c6ae18fa4ff0ca689a192 100644 (file)
--- a/gedcom.y
+++ b/gedcom.y
@@ -1,3 +1,12 @@
+/*  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.                                   *
+
+ (C) 2001 by The Genes Development Team
+ Original author: Peter Verthez (Peter.Verthez@advalvas.be)
+*/
+
 /* $Id$ */
 /* $Name$ */
 
 
 /* General notes:
 
-   - The syntax analysis doesn't handle the contents of the line values
-     or their encoding; this is done in the semantic analysis.
+   - The syntax analysis doesn't handle the contents of the line values;
+     this is done in the semantic analysis.
 
  */
 
 %{
 #include "gedcom.h"
 #include "multilex.h"
+#include "encoding.h"
 
 int  count_level    = 0;
 int  fail           = 0;
 int  compat_enabled = 1;
 int  gedcom_high_level_debug = 0; 
 int  compatibility  = 0; 
-MECHANISM error_mechanism=IMMED_FAIL;
-char string_buf[MAXGEDCLINELEN*4+1];
-char *string_buf_ptr;
+MECHANISM error_mechanism = IMMED_FAIL;
+char line_item_buf[MAXGEDCLINELEN * UTF_FACTOR + 1];
+char *line_item_buf_ptr;
 
 enum _COMPAT {
   C_FTREE = 0x01
@@ -212,6 +223,7 @@ int  compat_mode(int flags);
 %}
 
 %union {
+  int  number;
   char *string;
 }
 
@@ -219,7 +231,7 @@ int  compat_mode(int flags);
 %expect 300
 
 %token <string> BADTOKEN
-%token <string> OPEN
+%token <number> OPEN
 %token <string> CLOSE
 %token <string> ESCAPE
 %token <string> DELIM
@@ -420,7 +432,8 @@ head_sub     : head_sour_sect  { OCCUR2(SOUR, 1, 1) }
 /* HEAD.SOUR */
 head_sour_sect : OPEN DELIM TAG_SOUR mand_line_item 
                  { set_compatibility($4);
-                  gedcom_debug_print("===Source: '%s'\n", $4);
+                  gedcom_debug_print("===Source: '%s', '%s'\n",
+                                     $4, $3);
                   START(SOUR)
                 }
                  head_sour_subs
@@ -568,7 +581,8 @@ head_gedc_form_sect : OPEN DELIM TAG_FORM mand_line_item
 
 /* HEAD.CHAR */
 head_char_sect : OPEN DELIM TAG_CHAR mand_line_item 
-                 { START(CHAR) }
+                 { if (open_conv_to_internal($4) == 0) YYERROR;
+                  START(CHAR) }
                  head_char_subs
                 { CHECK0 }
                  CLOSE
@@ -2111,40 +2125,34 @@ opt_line_item : /* empty */ { }
               ;
 
 line_item   : anychar  { size_t i;
-                        CLEAR_BUFFER(string_buf);
-                         string_buf_ptr = string_buf;
+                        CLEAR_BUFFER(line_item_buf);
+                        line_item_buf_ptr = line_item_buf;
                         /* The following also takes care of '@@' */
                         if (!strncmp($1, "@@", 3))
-                          *string_buf_ptr++ = '@';
+                          *line_item_buf_ptr++ = '@';
                         else
                           for (i=0; i < strlen($1); i++)
-                            *string_buf_ptr++ = $1[i];
-                        $$ = string_buf;
+                            *line_item_buf_ptr++ = $1[i];
+                        $$ = line_item_buf;
                        }
-            | ESCAPE   { CLEAR_BUFFER(string_buf);
-                        string_buf_ptr = string_buf;
+            | ESCAPE   { CLEAR_BUFFER(line_item_buf);
+                        line_item_buf_ptr = line_item_buf;
                         /* For now, ignore escapes */
-                        $$ = string_buf;
+                        $$ = line_item_buf;
                       }
             | line_item anychar
-                  { if (strlen(string_buf) >= MAXGEDCLINELEN) {
-                     gedcom_error("Line too long");
-                     YYERROR;
-                   }
-                   else {
-                     size_t i;
-                     /* The following also takes care of '@@' */
-                     if (!strncmp($2, "@@", 3))
-                       *string_buf_ptr++ = '@';
-                     else
-                       for (i=0; i < strlen($2); i++)
-                         *string_buf_ptr++ = $2[i];
-                     $$ = string_buf;
-                   }
+                  { size_t i;
+                   /* The following also takes care of '@@' */
+                   if (!strncmp($2, "@@", 3))
+                     *line_item_buf_ptr++ = '@';
+                   else
+                     for (i=0; i < strlen($2); i++)
+                       *line_item_buf_ptr++ = $2[i];
+                   $$ = line_item_buf;
                  }
             | line_item ESCAPE
                   { /* For now, ignore escapes */
-                   $$ = string_buf;
+                   $$ = line_item_buf;
                  }
             ;
 
@@ -2331,7 +2339,7 @@ anystdtag   : TAG_ABBR
 /* Functions that handle the counting of subtags */
 
 int* count_arrays[MAXGEDCLEVEL+1];
-char tag_stack[MAXGEDCLEVEL+1][MAXSTDTAGLENGTH+1];
+char tag_stack[MAXGEDCLEVEL+1][MAXSTDTAGLEN+1];
 
 void push_countarray()
 {
@@ -2354,7 +2362,7 @@ void push_countarray()
 
 void set_parenttag(char* tag)
 {
-  strncpy(tag_stack[count_level], tag, MAXSTDTAGLENGTH+1);
+  strncpy(tag_stack[count_level], tag, MAXSTDTAGLEN+1);
 }
 
 char* get_parenttag()