Merge pull request #1203 from esdrubal/protect
[mono.git] / mcs / jay / reader.c
index 7096a6b4bba1c3c1c007423b833e85067198ce01..9d8fdcb4f2466bc538feaa83c7e3540ad79c21d3 100644 (file)
@@ -40,6 +40,11 @@ static char sccsid[] = "@(#)reader.c 5.7 (Berkeley) 1/20/91";
 
 #include "defs.h"
 
+/* this resolves "unresolved symbol _snprintf" on Windows */   
+#if defined (_MSC_VER)
+#define snprintf _snprintf
+#endif
+
 /*  The line size must be a positive integer.  One hundred was chosen  */
 /*  because few lines in Yacc input grammars exceed 100 characters.    */
 /*  Note that if a line exceeds LINESIZE characters, the line buffer   */
@@ -68,6 +73,8 @@ bucket **pitem;
 int maxrules;
 bucket **plhs;
 
+int maxmethods;
+
 int name_pool_size;
 char *name_pool;
 
@@ -846,6 +853,7 @@ initialize_grammar()
     pitem[2] = 0;
     pitem[3] = 0;
 
+       nmethods = 0;
     nrules = 3;
     maxrules = 100;
     plhs = (bucket **) MALLOC(maxrules*sizeof(bucket *));
@@ -871,6 +879,7 @@ expand_items()
     maxitems += 300;
     pitem = (bucket **) REALLOC(pitem, maxitems*sizeof(bucket *));
     if (pitem == 0) no_space();
+    memset(pitem+maxitems-300, 0, 300*sizeof(bucket *));
 }
 
 
@@ -955,6 +964,8 @@ end_rule()
 {
     register int i;
 
+    if (nitems >= maxitems) expand_items();
+
     if (!last_was_action && plhs[nrules]->tag)
     {
        for (i = nitems - 1; pitem[i]; --i) continue;
@@ -963,7 +974,6 @@ end_rule()
     }                                  /** bug: could be superclass... **/
 
     last_was_action = 0;
-    if (nitems >= maxitems) expand_items();
     pitem[nitems] = 0;
     ++nitems;
     ++nrules;
@@ -1037,21 +1047,25 @@ copy_action()
     int depth;
     int quote;
     char *tag;
-    register FILE *f = action_file;
+    FILE *f = action_file;
     int a_lineno = lineno;
     char *a_line = dup_line();
     char *a_cptr = a_line + (cptr - line);
+       char buffer [10000];
+       int len = 0;
+       int comment_lines = 0;
+       char *mbody;
+       memset (buffer, 0, 10000);
 
     if (last_was_action)
        insert_empty_rule();
     last_was_action = 1;
 
     fprintf(f, "case %d:\n", nrules - 2);
-    fprintf(f, line_format, lineno, input_file_name);
-    putc(' ', f); putc(' ', f);
     if (*cptr == '=') ++cptr;
 
     n = 0;
+
     for (i = nitems - 1; pitem[i]; --i) ++n;
 
     depth = 0;
@@ -1069,9 +1083,13 @@ loop:
            tag = get_tag(1);
            c = *cptr;
            if (c == '$')
-           {   if (tag && strcmp(tag, "Object"))
-                                       fprintf(f, "((%s)yyVal)", tag);
-               else fprintf(f, "yyVal");
+           {   
+                       if (tag && strcmp(tag, "Object")) {
+                               len += sprintf(buffer + len, "((%s)yyVal)", tag);
+                       } else {
+                               strcat (buffer + len, "yyVal");
+                               len += 5;
+                       }
                ++cptr;
                FREE(d_line);
                goto loop;
@@ -1081,8 +1099,9 @@ loop:
                i = get_number();
                if (i > n) dollar_warning(d_lineno, i);
                if (tag && strcmp(tag, "Object"))
-                       fprintf(f, "((%s)yyVals[%d+yyTop])", tag, i - n);
-               else fprintf(f, "yyVals[%d+yyTop]", i - n);
+                       len += sprintf(buffer + len, "((%s)yyVals[%d+yyTop])", tag, i - n);
+               else
+                       len += sprintf(buffer + len, "yyVals[%d+yyTop]", i - n);
                FREE(d_line);
                goto loop;
            }
@@ -1091,8 +1110,9 @@ loop:
                ++cptr;
                i = -get_number() - n;
                if (tag && strcmp(tag, "Object"))
-                       fprintf(f, "((%s)yyVals[%d+yyTop])", tag, i);
-               else fprintf(f, "yyVals[%d+yyTop]", i);
+                       len += sprintf(buffer + len, "((%s)yyVals[%d+yyTop])", tag, i);
+               else
+                       len += sprintf(buffer + len, "yyVals[%d+yyTop]", i);
                FREE(d_line);
                goto loop;
            }
@@ -1103,7 +1123,8 @@ loop:
        {
            if (ntags && plhs[nrules]->tag == 0)
                untyped_lhs();
-           fprintf(f, "yyVal");
+               strcat (buffer, "yyVal");
+               len += 5;
            cptr += 2;
            goto loop;
        }
@@ -1118,17 +1139,18 @@ loop:
                tag = pitem[nitems + i - n - 1]->tag;
                if (tag == 0)
                    untyped_rhs(i, pitem[nitems + i - n - 1]->name),
-                   fprintf(f, "yyVals[%d+yyTop]", i - n);
+                   len += sprintf(buffer + len, "yyVals[%d+yyTop]", i - n);
                else if (strcmp(tag, "Object"))
-                   fprintf(f, "((%s)yyVals[%d+yyTop])", tag, i - n);
+                   len += sprintf(buffer + len, "((%s)yyVals[%d+yyTop])", tag, i - n);
                else
-                   fprintf(f, "yyVals[%d+yyTop]", i - n);
+                   len += sprintf(buffer + len, "yyVals[%d+yyTop]", i - n);
            }
            else
            {
                if (i > n)
                    dollar_warning(lineno, i);
-               fprintf(f, "yyVals[%d+yyTop]", i - n);
+
+               len += sprintf(buffer + len,"yyVals[%d+yyTop]", i - n);
            }
            goto loop;
        }
@@ -1138,7 +1160,7 @@ loop:
            i = get_number();
            if (ntags)
                unknown_rhs(-i);
-           fprintf(f, "yyVals[%d+yyTop]", -i - n);
+           len += sprintf(buffer + len, "yyVals[%d+yyTop]", -i - n);
            goto loop;
        }
     }
@@ -1146,12 +1168,12 @@ loop:
     {
        do
        {
-           putc(c, f);
+           buffer[len++] = c;
            c = *++cptr;
        } while (isalnum(c) || c == '_' || c == '$');
        goto loop;
     }
-    putc(c, f);
+       buffer[len++] = c;
     ++cptr;
     switch (c)
     {
@@ -1163,8 +1185,7 @@ loop:
 
     case ';':
        if (depth > 0) goto loop;
-       fprintf(f, "\nbreak;\n");
-       return;
+       break;
 
     case '{':
        ++depth;
@@ -1172,8 +1193,7 @@ loop:
 
     case '}':
        if (--depth > 0) goto loop;
-       fprintf(f, "\n  break;\n");
-       return;
+       break;
 
     case '\'':
     case '"':
@@ -1186,7 +1206,7 @@ loop:
            for (;;)
            {
                c = *cptr++;
-               putc(c, f);
+               buffer[len++] = c;
                if (c == quote)
                {
                    FREE(s_line);
@@ -1197,7 +1217,7 @@ loop:
                if (c == '\\')
                {
                    c = *cptr++;
-                   putc(c, f);
+                   buffer[len++] = c;
                    if (c == '\n')
                    {
                        get_line();
@@ -1212,15 +1232,19 @@ loop:
        c = *cptr;
        if (c == '/')
        {
-           putc('*', f);
+           buffer[len++] = '*';
            while ((c = *++cptr) != '\n')
            {
-               if (c == '*' && cptr[1] == '/')
-                   fprintf(f, "* ");
-               else
-                   putc(c, f);
-           }
-           fprintf(f, "*/\n");
+                       if (c == '*' && cptr[1] == '/'){
+                               buffer[len++] = '*';
+                               buffer[len++] = ' ';
+                       } else {
+                               buffer[len++] = c;
+                       }
+               }
+           buffer[len++] = '*';
+               buffer[len++] = '/';
+               buffer[len++] = '\n';
            goto next_line;
        }
        if (c == '*')
@@ -1229,21 +1253,22 @@ loop:
            char *c_line = dup_line();
            char *c_cptr = c_line + (cptr - line - 1);
 
-           putc('*', f);
+           buffer[len++] = '*';
            ++cptr;
            for (;;)
            {
                c = *cptr++;
-               putc(c, f);
+               buffer[len++] = c;
                if (c == '*' && *cptr == '/')
                {
-                   putc('/', f);
+                   buffer[len++] = '/';
                    ++cptr;
                    FREE(c_line);
                    goto loop;
                }
                if (c == '\n')
                {
+                       ++comment_lines;
                    get_line();
                    if (line == 0)
                        unterminated_comment(c_lineno, c_line, c_cptr);
@@ -1255,6 +1280,53 @@ loop:
     default:
        goto loop;
     }
+
+       if (comment_lines > 0)
+               comment_lines++;
+
+       if ((lineno - (a_lineno + comment_lines)) > 2)
+       {
+               char mname[28];
+               char *line_define;
+
+               // the maximum size of of an unsigned int in characters is 20, with 8 for 'case_()\0'
+               sprintf(mname, "case_%d()", nrules - 2);
+
+               putc(' ', f); putc(' ', f);
+               fputs(mname, f);
+               fprintf(f, ";");
+               if (nmethods == 0)
+               {
+                       maxmethods = 100;
+                       methods = NEW2(maxmethods, char *);
+               }
+               else if (nmethods == maxmethods)
+               {
+                       maxmethods += 500;
+                       methods = REALLOC (methods, maxmethods*sizeof(char *));
+               }
+
+               line_define = NEW2(snprintf(NULL, 0, line_format, a_lineno, input_file_name)+1, char);
+               sprintf(line_define, line_format, a_lineno, input_file_name);
+
+               mbody = NEW2(5+strlen(line_define)+1+strlen(mname)+strlen(buffer)+1, char);
+               strcpy(mbody, "void ");
+               strcat(mbody, mname);
+               strcat(mbody, "\n");
+               strcat(mbody, line_define);
+               strcat(mbody, buffer);
+               methods[nmethods++] = mbody;
+
+               FREE(line_define);
+       }
+       else
+       {
+           fprintf(f, line_format, lineno, input_file_name);
+               putc(' ', f); putc(' ', f);
+               fwrite(buffer, 1, len, f);
+       }
+
+       fprintf(f, "\n  break;\n");
 }