<html>
<body>
  <div id="body" style="background-color:#ffffff;" >
<table cellspacing="0" cellpadding="0" border="0" rules="cols">
<tr class="head" style="border-bottom-width:1px;border-bottom-style:solid;" ><td class="headtd" style="padding:0;padding-top:.2em;" colspan="4">Commit in <b><tt>lxdream/src/tools</tt></b></td></tr>
<tr><td><tt><a href="#file1">mdparse.c</a></tt></td><td id="added" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ddffdd;" align="right">+106</td><td id="removed" class="headtd2" style="padding-left:.3em;padding-right:.3em; background-color:#ffdddd;" align="right">-71</td><td class="headtd2" style="padding-left:.3em;padding-right:.3em;" nowrap="nowrap">700e16c321e5 -> 73da8fd129fb</td></tr>
</table>
<pre class="comment" style="white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;white-space:pre-wrap;word-wrap:break-word;padding:4px;border:1px dashed #000000;background-color:#ffffdd;" >
Add file inclusion support
</pre>
<hr /><a name="file1" /><div class="file" style="border:1px solid #eeeeee;margin-top:1em;margin-bottom:1em;" >
<span class="pathname" style="font-family:monospace; float:right;" >lxdream/src/tools</span><br />
<div class="fileheader" style="margin-bottom:.5em;" ><big><b>mdparse.c</b></big> <small id="info" style="color: #888888;" >700e16c321e5 -> 73da8fd129fb</small></div>
<pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >--- lxdream/src/tools/mdparse.c
+++ lxdream/src/tools/mdparse.c
@@ -113,15 +113,20 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     int slen;
 } token_data;
 
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-static char *yybuffer;
-static char *yyposn, *yylineposn;
-static char *yyend;
-static int yyline;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+struct yystate {
+    char *yybuffer;
+    char *yyfilename;
+    char *yyposn, *yylineposn, *yyend;
+    int yylineno;
+};
+
+static GList *yyfile_stack = NULL;
+static struct yystate yystate;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > static struct token_data yytok;
 
 #define YYPARSE_ERROR( msg, ... ) \
     do { \
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-        fprintf( stderr, "Parse error <span id="removedchars" style="background-color:#ff9999;font-weight:bolder;" >at %d:%d: " msg "\n"</span>, yytok.yyline, yytok.yycol, __VA_ARGS__ ); \
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+        fprintf( stderr, "Parse error <span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >in %s:%d:%d: " msg "\n", yystate.yyfilename</span>, yytok.yyline, yytok.yycol, __VA_ARGS__ ); \
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         exit(2); \
     } while(0)
 
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -135,6 +140,8 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > static int iolex( int expectToken );
 static int iolex_open( const char *filename );
 static void iolex_close();
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static int iolex_push( const char *filename );
+static int iolex_pop( );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > 
 static inline char *yystrdup()
 {
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -426,13 +433,21 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         return blocks;
 
     int tok;
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-    do {
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    while(1) {
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         tok = iolex(TOK_REGISTERS);
         if( tok == TOK_EOF ) {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-            return blocks;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+            int result = iolex_pop();
+            if( result == -1 )
+                break;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         } else if( tok == TOK_INCLUDE) {
             READ(TOK_STRING);
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+            char *tmp = yystrdup();
+            READ(TOK_SEMI);
+            int result = iolex_push( tmp );
+            if( result == -1 ) {
+                YYPARSE_ERROR("Unable to include file '%s'", tmp);
+            }
+            free(tmp);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         } else if( tok == TOK_SPACE ) {
         } else if( tok == TOK_REGISTERS ) {
             struct regblock *block = ioparse_regblock(block);
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -441,18 +456,36 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         } else {
             YYPARSE_ERROR("Expected REGISTERS but got %s\n", TOKEN_NAMES[tok] );
         }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-    } while( tok != TOK_EOF );
-
-    iolex_close();
-    if( count == 0 ) {
-        fprintf( stderr, "Warning: input file '%s' did not contain any register definitions\n" );
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     return blocks;
 }
 
 /**************************** Lexical analyser ***************************/
 
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+static int iolex_push( const char *filename )
+{
+    struct yystate *save = g_malloc(sizeof(struct yystate));
+    memcpy( save, &yystate, sizeof(struct yystate) );
+
+    int result = iolex_open(filename);
+    if( result == 0 ) {
+        yyfile_stack = g_list_prepend(yyfile_stack, save);
+    }
+    return result;
+}
+
+static int iolex_pop( )
+{
+    iolex_close();
+    if( yyfile_stack == NULL )
+        return -1;
+    struct yystate *top = (struct yystate *)yyfile_stack->data;
+    yyfile_stack = g_list_remove(yyfile_stack, top);
+    memcpy( &yystate, top, sizeof(struct yystate) );
+    g_free( top );
+    return 0;
+}
+
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > static int iolex_open( const char *filename )
 {
     struct stat st;
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -477,21 +510,23 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     close(fd);
     data[st.st_size] = 0;
 
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-    yybuffer = yyposn = data;
-    yyend = data + st.st_size;
-    yyline = 1;
-    yylineposn = yyposn;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    yystate.yybuffer = yystate.yyposn = data;
+    yystate.yyend = data + st.st_size;
+    yystate.yylineno = 1;
+    yystate.yylineposn = yystate.yyposn;
+    yystate.yyfilename = strdup(filename);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     return 0;
 }
 
 static void iolex_close()
 {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-    g_free(yybuffer);
-    yybuffer = yyend = NULL;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    g_free(yystate.yybuffer);
+    free(yystate.yyfilename);
+    memset(&yystate, 0, sizeof(struct yystate));
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > }
 
 #define YYRETURN(x) do{ \
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-    yytok.yylength = yyposn - yystart; \
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    yytok.yylength = yy<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >state.yy</span>posn - yystart; \
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >     return (x); \
 } while(0)
 
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -584,32 +619,32 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" > int iolex( int expectToken )
 {
     int count = 0;
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-    while( yyposn < yyend ) {
-        char *yystart = yytok.yytext = yyposn;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+    while( yystate.yyposn < yystate.yyend ) {
+        char *yystart = yytok.yytext = yystate.yyposn;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         yytok.yylength = 1;
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-        yytok.yyline = yyline;
-        yytok.yycol = yyposn - yylineposn+1;
-        int ch = *yyposn++;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+        yytok.yyline = yystate.yylineno;
+        yytok.yycol = yystate.yyposn - yystate.yylineposn+1;
+        int ch = *yystate.yyposn++;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >         if( isdigit(ch) ) {
             /* INTEGER */
             if( ch == '0' ) {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-                if( *yyposn == 'x' ) {
-                    while( yyposn < yyend && isxdigit(*++yyposn) ) ;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+                if( *yystate.yyposn == 'x' ) {
+                    while( yystate.yyposn < yystate.yyend && isxdigit(*++yystate.yyposn) ) ;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >                 } else {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-                    while( yyposn < yyend && *yyposn >= '0' && *yyposn <= '7' )
-                        yyposn++;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+                    while( yystate.yyposn < yystate.yyend && *yystate.yyposn >= '0' && *yystate.yyposn <= '7' )
+                        yystate.yyposn++;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >                 }
             } else {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-                while( yyposn < yyend && isdigit(*yyposn) )
-                    yyposn++;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+                while( yystate.yyposn < yystate.yyend && isdigit(*yystate.yyposn) )
+                    yystate.yyposn++;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >             }
             yytok.v.i = strtol( yystart, NULL, 0 );
             YYRETURN(TOK_INTEGER);
         } else if( isalpha(ch) || ch == '_' ) {
             /* IDENTIFIER */
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-            while( yyposn < yyend && (isalnum(*yyposn) || *yyposn == '_') )
-                yyposn++;
-            yytok.yylength = yyposn - yystart;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+            while( yystate.yyposn < yystate.yyend && (isalnum(*yystate.yyposn) || *yystate.yyposn == '_') )
+                yystate.yyposn++;
+            yytok.yylength = yystate.yyposn - yystart;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >             if( expectToken == TOK_IDENTIFIER ) {
                 YYRETURN(TOK_IDENTIFIER);
             }
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -623,15 +658,15 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >             YYRETURN(TOK_IDENTIFIER);
         } else if( isspace(ch) ) {
             if( ch == '\n' ) {
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-                yyline++;
-                yylineposn = yyposn;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+                yystate.yylineno++;
+                yystate.yylineposn = yystate.yyposn;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >             }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-            while( isspace(*yyposn) ) {
-                if( *yyposn == '\n' ) {
-                    yyline++;
-                    yylineposn = yyposn+1;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+            while( isspace(*yystate.yyposn) ) {
+                if( *yystate.yyposn == '\n' ) {
+                    yystate.yylineno++;
+                    yystate.yylineposn = yystate.yyposn+1;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >                 }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-                yyposn++;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+                yy<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >state.yy</span>posn++;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >             }
         } else {
             switch( ch ) {
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -644,48 +679,48 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >             case ';': YYRETURN(TOK_SEMI);
             case '=': YYRETURN(TOK_EQUALS);
             case '/':
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-                if( *yyposn == '/' ) { /* Line comment */
-                    while( yyposn < yyend && *++yyposn != '\n' ) ;
-                } else if( *yyposn == '*' ) { /* C comment */
-                    while( yyposn < yyend && (*++yyposn != '*' || *++yyposn != '/' ) ) {
-                        if( *yyposn == '\n' ) {
-                            yyline++;
-                            yylineposn = yyposn+1;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+                if( *yystate.yyposn == '/' ) { /* Line comment */
+                    while( yystate.yyposn < yystate.yyend && *++yystate.yyposn != '\n' ) ;
+                } else if( *yystate.yyposn == '*' ) { /* C comment */
+                    while( yystate.yyposn < yystate.yyend && (*++yystate.yyposn != '*' || *++yystate.yyposn != '/' ) ) {
+                        if( *yystate.yyposn == '\n' ) {
+                            yystate.yylineno++;
+                            yystate.yylineposn = yystate.yyposn+1;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >                         }
                     }
                 }
                 break;
             case '\'': /* STRING */
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-                while( *yyposn != '\'' ) {
-                    if( *yyposn == '\n' ) {
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+                while( *yystate.yyposn != '\'' ) {
+                    if( *yystate.yyposn == '\n' ) {
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >                         fprintf( stderr, "Unexpected newline in string constant!\n" );
                         YYRETURN(TOK_ERROR);
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-                    } else if( yyposn >= yyend ) {
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+                    } else if( yystate.yyposn >= yystate.yyend ) {
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >                         fprintf( stderr, "Unexpected EOF in string constant!\n" );
                         YYRETURN(TOK_ERROR);
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-                    } else if( *yyposn == '\\' && yyposn[1] == '\'' ) {
-                        yyposn++;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+                    } else if( *yystate.yyposn == '\\' && yystate.yyposn[1] == '\'' ) {
+                        yystate.yyposn++;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >                     }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-                    yyposn++;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+                    yy<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >state.yy</span>posn++;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >                 }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-                yyposn++;
-                yytok.v.s = iolex_getcstring(yystart+1, yyposn-1, &yytok.slen);
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+                yystate.yyposn++;
+                yytok.v.s = iolex_getcstring(yystart+1, yystate.yyposn-1, &yytok.slen);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >                 YYRETURN(TOK_STRING);
             case '\"': /* STRING */
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-                while( *yyposn != '\"' ) {
-                    if( *yyposn == '\n' ) {
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+                while( *yystate.yyposn != '\"' ) {
+                    if( *yystate.yyposn == '\n' ) {
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >                         fprintf( stderr, "Unexpected newline in string constant!\n" );
                         YYRETURN(TOK_ERROR);
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-                    } else if( yyposn >= yyend ) {
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+                    } else if( yystate.yyposn >= yystate.yyend ) {
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >                         fprintf( stderr, "Unexpected EOF in string constant!\n" );
                         YYRETURN(TOK_ERROR);
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-                    } else if( *yyposn == '\\' && yyposn[1] == '\"' ) {
-                        yyposn++;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+                    } else if( *yystate.yyposn == '\\' && yystate.yyposn[1] == '\"' ) {
+                        yystate.yyposn++;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >                     }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-                    yyposn++;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+                    yy<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >state.yy</span>posn++;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >                 }
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-                yyposn++;
-                yytok.v.s = iolex_getcstring(yystart+1, yyposn-1, &yytok.slen);
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+                yystate.yyposn++;
+                yytok.v.s = iolex_getcstring(yystart+1, yystate.yyposn-1, &yytok.slen);
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >                 YYRETURN(TOK_STRING);
             case '}':
                 YYRETURN(TOK_RBRACE);
</pre><pre class="diff" style="margin:0;" ><small id="info" style="color: #888888;" >@@ -694,18 +729,18 @@
</small></pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >                     YYRETURN(TOK_LBRACE);
                 } else {
                     count++;
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-                    while( count > 0 && yyposn < yyend ) {
-                        if( *yyposn == '{' )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+                    while( count > 0 && yystate.yyposn < yystate.yyend ) {
+                        if( *yystate.yyposn == '{' )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >                             count++;
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-                        if( *yyposn == '}' )
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+                        if( *yy<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >state.yy</span>posn == '}' )
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >                             count--;
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-                        yyposn++;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+                        yy<span id="addedchars" style="background-color:#99ff99;font-weight:bolder;" >state.yy</span>posn++;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >                     }
                     YYRETURN(TOK_ACTION);
                 }
             case '.':
</pre><pre id="removed" class="diff" style="margin:0; background-color:#ffdddd;" >-                if( *yyposn == '.' ) {
-                    yyposn++;
</pre><pre id="added" class="diff" style="margin:0; background-color:#ddffdd;" >+                if( *yystate.yyposn == '.' ) {
+                    yystate.yyposn++;
</pre><pre id="context" class="diff" style="margin:0; background-color:#eeeeee;" >                     YYRETURN(TOK_RANGE);
                 } else {
                     YYRETURN(TOK_PERIOD);
</pre></div>
<center><small>Chaos Theory</small></center>
</div></body></html>