Search
lxdream.org :: lxdream :: r1105:73da8fd129fb
lxdream 0.9.1
released Jun 29
Download Now
changeset1105:73da8fd129fb
parent1104:700e16c321e5
child1106:1879fd49ccf6
authornkeynes
dateMon Mar 15 22:31:20 2010 +1000 (10 years ago)
Add file inclusion support
src/tools/mdparse.c
1.1 --- a/src/tools/mdparse.c Mon Mar 15 22:10:24 2010 +1000
1.2 +++ b/src/tools/mdparse.c Mon Mar 15 22:31:20 2010 +1000
1.3 @@ -113,15 +113,20 @@
1.4 int slen;
1.5 } token_data;
1.6
1.7 -static char *yybuffer;
1.8 -static char *yyposn, *yylineposn;
1.9 -static char *yyend;
1.10 -static int yyline;
1.11 +struct yystate {
1.12 + char *yybuffer;
1.13 + char *yyfilename;
1.14 + char *yyposn, *yylineposn, *yyend;
1.15 + int yylineno;
1.16 +};
1.17 +
1.18 +static GList *yyfile_stack = NULL;
1.19 +static struct yystate yystate;
1.20 static struct token_data yytok;
1.21
1.22 #define YYPARSE_ERROR( msg, ... ) \
1.23 do { \
1.24 - fprintf( stderr, "Parse error at %d:%d: " msg "\n", yytok.yyline, yytok.yycol, __VA_ARGS__ ); \
1.25 + fprintf( stderr, "Parse error in %s:%d:%d: " msg "\n", yystate.yyfilename, yytok.yyline, yytok.yycol, __VA_ARGS__ ); \
1.26 exit(2); \
1.27 } while(0)
1.28
1.29 @@ -135,6 +140,8 @@
1.30 static int iolex( int expectToken );
1.31 static int iolex_open( const char *filename );
1.32 static void iolex_close();
1.33 +static int iolex_push( const char *filename );
1.34 +static int iolex_pop( );
1.35
1.36 static inline char *yystrdup()
1.37 {
1.38 @@ -426,13 +433,21 @@
1.39 return blocks;
1.40
1.41 int tok;
1.42 - do {
1.43 + while(1) {
1.44 tok = iolex(TOK_REGISTERS);
1.45 if( tok == TOK_EOF ) {
1.46 - return blocks;
1.47 + int result = iolex_pop();
1.48 + if( result == -1 )
1.49 + break;
1.50 } else if( tok == TOK_INCLUDE) {
1.51 READ(TOK_STRING);
1.52 -
1.53 + char *tmp = yystrdup();
1.54 + READ(TOK_SEMI);
1.55 + int result = iolex_push( tmp );
1.56 + if( result == -1 ) {
1.57 + YYPARSE_ERROR("Unable to include file '%s'", tmp);
1.58 + }
1.59 + free(tmp);
1.60 } else if( tok == TOK_SPACE ) {
1.61 } else if( tok == TOK_REGISTERS ) {
1.62 struct regblock *block = ioparse_regblock(block);
1.63 @@ -441,18 +456,36 @@
1.64 } else {
1.65 YYPARSE_ERROR("Expected REGISTERS but got %s\n", TOKEN_NAMES[tok] );
1.66 }
1.67 - } while( tok != TOK_EOF );
1.68 -
1.69 - iolex_close();
1.70 - if( count == 0 ) {
1.71 - fprintf( stderr, "Warning: input file '%s' did not contain any register definitions\n" );
1.72 }
1.73 -
1.74 return blocks;
1.75 }
1.76
1.77 /**************************** Lexical analyser ***************************/
1.78
1.79 +static int iolex_push( const char *filename )
1.80 +{
1.81 + struct yystate *save = g_malloc(sizeof(struct yystate));
1.82 + memcpy( save, &yystate, sizeof(struct yystate) );
1.83 +
1.84 + int result = iolex_open(filename);
1.85 + if( result == 0 ) {
1.86 + yyfile_stack = g_list_prepend(yyfile_stack, save);
1.87 + }
1.88 + return result;
1.89 +}
1.90 +
1.91 +static int iolex_pop( )
1.92 +{
1.93 + iolex_close();
1.94 + if( yyfile_stack == NULL )
1.95 + return -1;
1.96 + struct yystate *top = (struct yystate *)yyfile_stack->data;
1.97 + yyfile_stack = g_list_remove(yyfile_stack, top);
1.98 + memcpy( &yystate, top, sizeof(struct yystate) );
1.99 + g_free( top );
1.100 + return 0;
1.101 +}
1.102 +
1.103 static int iolex_open( const char *filename )
1.104 {
1.105 struct stat st;
1.106 @@ -477,21 +510,23 @@
1.107 close(fd);
1.108 data[st.st_size] = 0;
1.109
1.110 - yybuffer = yyposn = data;
1.111 - yyend = data + st.st_size;
1.112 - yyline = 1;
1.113 - yylineposn = yyposn;
1.114 + yystate.yybuffer = yystate.yyposn = data;
1.115 + yystate.yyend = data + st.st_size;
1.116 + yystate.yylineno = 1;
1.117 + yystate.yylineposn = yystate.yyposn;
1.118 + yystate.yyfilename = strdup(filename);
1.119 return 0;
1.120 }
1.121
1.122 static void iolex_close()
1.123 {
1.124 - g_free(yybuffer);
1.125 - yybuffer = yyend = NULL;
1.126 + g_free(yystate.yybuffer);
1.127 + free(yystate.yyfilename);
1.128 + memset(&yystate, 0, sizeof(struct yystate));
1.129 }
1.130
1.131 #define YYRETURN(x) do{ \
1.132 - yytok.yylength = yyposn - yystart; \
1.133 + yytok.yylength = yystate.yyposn - yystart; \
1.134 return (x); \
1.135 } while(0)
1.136
1.137 @@ -584,32 +619,32 @@
1.138 int iolex( int expectToken )
1.139 {
1.140 int count = 0;
1.141 - while( yyposn < yyend ) {
1.142 - char *yystart = yytok.yytext = yyposn;
1.143 + while( yystate.yyposn < yystate.yyend ) {
1.144 + char *yystart = yytok.yytext = yystate.yyposn;
1.145 yytok.yylength = 1;
1.146 - yytok.yyline = yyline;
1.147 - yytok.yycol = yyposn - yylineposn+1;
1.148 - int ch = *yyposn++;
1.149 + yytok.yyline = yystate.yylineno;
1.150 + yytok.yycol = yystate.yyposn - yystate.yylineposn+1;
1.151 + int ch = *yystate.yyposn++;
1.152 if( isdigit(ch) ) {
1.153 /* INTEGER */
1.154 if( ch == '0' ) {
1.155 - if( *yyposn == 'x' ) {
1.156 - while( yyposn < yyend && isxdigit(*++yyposn) ) ;
1.157 + if( *yystate.yyposn == 'x' ) {
1.158 + while( yystate.yyposn < yystate.yyend && isxdigit(*++yystate.yyposn) ) ;
1.159 } else {
1.160 - while( yyposn < yyend && *yyposn >= '0' && *yyposn <= '7' )
1.161 - yyposn++;
1.162 + while( yystate.yyposn < yystate.yyend && *yystate.yyposn >= '0' && *yystate.yyposn <= '7' )
1.163 + yystate.yyposn++;
1.164 }
1.165 } else {
1.166 - while( yyposn < yyend && isdigit(*yyposn) )
1.167 - yyposn++;
1.168 + while( yystate.yyposn < yystate.yyend && isdigit(*yystate.yyposn) )
1.169 + yystate.yyposn++;
1.170 }
1.171 yytok.v.i = strtol( yystart, NULL, 0 );
1.172 YYRETURN(TOK_INTEGER);
1.173 } else if( isalpha(ch) || ch == '_' ) {
1.174 /* IDENTIFIER */
1.175 - while( yyposn < yyend && (isalnum(*yyposn) || *yyposn == '_') )
1.176 - yyposn++;
1.177 - yytok.yylength = yyposn - yystart;
1.178 + while( yystate.yyposn < yystate.yyend && (isalnum(*yystate.yyposn) || *yystate.yyposn == '_') )
1.179 + yystate.yyposn++;
1.180 + yytok.yylength = yystate.yyposn - yystart;
1.181 if( expectToken == TOK_IDENTIFIER ) {
1.182 YYRETURN(TOK_IDENTIFIER);
1.183 }
1.184 @@ -623,15 +658,15 @@
1.185 YYRETURN(TOK_IDENTIFIER);
1.186 } else if( isspace(ch) ) {
1.187 if( ch == '\n' ) {
1.188 - yyline++;
1.189 - yylineposn = yyposn;
1.190 + yystate.yylineno++;
1.191 + yystate.yylineposn = yystate.yyposn;
1.192 }
1.193 - while( isspace(*yyposn) ) {
1.194 - if( *yyposn == '\n' ) {
1.195 - yyline++;
1.196 - yylineposn = yyposn+1;
1.197 + while( isspace(*yystate.yyposn) ) {
1.198 + if( *yystate.yyposn == '\n' ) {
1.199 + yystate.yylineno++;
1.200 + yystate.yylineposn = yystate.yyposn+1;
1.201 }
1.202 - yyposn++;
1.203 + yystate.yyposn++;
1.204 }
1.205 } else {
1.206 switch( ch ) {
1.207 @@ -644,48 +679,48 @@
1.208 case ';': YYRETURN(TOK_SEMI);
1.209 case '=': YYRETURN(TOK_EQUALS);
1.210 case '/':
1.211 - if( *yyposn == '/' ) { /* Line comment */
1.212 - while( yyposn < yyend && *++yyposn != '\n' ) ;
1.213 - } else if( *yyposn == '*' ) { /* C comment */
1.214 - while( yyposn < yyend && (*++yyposn != '*' || *++yyposn != '/' ) ) {
1.215 - if( *yyposn == '\n' ) {
1.216 - yyline++;
1.217 - yylineposn = yyposn+1;
1.218 + if( *yystate.yyposn == '/' ) { /* Line comment */
1.219 + while( yystate.yyposn < yystate.yyend && *++yystate.yyposn != '\n' ) ;
1.220 + } else if( *yystate.yyposn == '*' ) { /* C comment */
1.221 + while( yystate.yyposn < yystate.yyend && (*++yystate.yyposn != '*' || *++yystate.yyposn != '/' ) ) {
1.222 + if( *yystate.yyposn == '\n' ) {
1.223 + yystate.yylineno++;
1.224 + yystate.yylineposn = yystate.yyposn+1;
1.225 }
1.226 }
1.227 }
1.228 break;
1.229 case '\'': /* STRING */
1.230 - while( *yyposn != '\'' ) {
1.231 - if( *yyposn == '\n' ) {
1.232 + while( *yystate.yyposn != '\'' ) {
1.233 + if( *yystate.yyposn == '\n' ) {
1.234 fprintf( stderr, "Unexpected newline in string constant!\n" );
1.235 YYRETURN(TOK_ERROR);
1.236 - } else if( yyposn >= yyend ) {
1.237 + } else if( yystate.yyposn >= yystate.yyend ) {
1.238 fprintf( stderr, "Unexpected EOF in string constant!\n" );
1.239 YYRETURN(TOK_ERROR);
1.240 - } else if( *yyposn == '\\' && yyposn[1] == '\'' ) {
1.241 - yyposn++;
1.242 + } else if( *yystate.yyposn == '\\' && yystate.yyposn[1] == '\'' ) {
1.243 + yystate.yyposn++;
1.244 }
1.245 - yyposn++;
1.246 + yystate.yyposn++;
1.247 }
1.248 - yyposn++;
1.249 - yytok.v.s = iolex_getcstring(yystart+1, yyposn-1, &yytok.slen);
1.250 + yystate.yyposn++;
1.251 + yytok.v.s = iolex_getcstring(yystart+1, yystate.yyposn-1, &yytok.slen);
1.252 YYRETURN(TOK_STRING);
1.253 case '\"': /* STRING */
1.254 - while( *yyposn != '\"' ) {
1.255 - if( *yyposn == '\n' ) {
1.256 + while( *yystate.yyposn != '\"' ) {
1.257 + if( *yystate.yyposn == '\n' ) {
1.258 fprintf( stderr, "Unexpected newline in string constant!\n" );
1.259 YYRETURN(TOK_ERROR);
1.260 - } else if( yyposn >= yyend ) {
1.261 + } else if( yystate.yyposn >= yystate.yyend ) {
1.262 fprintf( stderr, "Unexpected EOF in string constant!\n" );
1.263 YYRETURN(TOK_ERROR);
1.264 - } else if( *yyposn == '\\' && yyposn[1] == '\"' ) {
1.265 - yyposn++;
1.266 + } else if( *yystate.yyposn == '\\' && yystate.yyposn[1] == '\"' ) {
1.267 + yystate.yyposn++;
1.268 }
1.269 - yyposn++;
1.270 + yystate.yyposn++;
1.271 }
1.272 - yyposn++;
1.273 - yytok.v.s = iolex_getcstring(yystart+1, yyposn-1, &yytok.slen);
1.274 + yystate.yyposn++;
1.275 + yytok.v.s = iolex_getcstring(yystart+1, yystate.yyposn-1, &yytok.slen);
1.276 YYRETURN(TOK_STRING);
1.277 case '}':
1.278 YYRETURN(TOK_RBRACE);
1.279 @@ -694,18 +729,18 @@
1.280 YYRETURN(TOK_LBRACE);
1.281 } else {
1.282 count++;
1.283 - while( count > 0 && yyposn < yyend ) {
1.284 - if( *yyposn == '{' )
1.285 + while( count > 0 && yystate.yyposn < yystate.yyend ) {
1.286 + if( *yystate.yyposn == '{' )
1.287 count++;
1.288 - if( *yyposn == '}' )
1.289 + if( *yystate.yyposn == '}' )
1.290 count--;
1.291 - yyposn++;
1.292 + yystate.yyposn++;
1.293 }
1.294 YYRETURN(TOK_ACTION);
1.295 }
1.296 case '.':
1.297 - if( *yyposn == '.' ) {
1.298 - yyposn++;
1.299 + if( *yystate.yyposn == '.' ) {
1.300 + yystate.yyposn++;
1.301 YYRETURN(TOK_RANGE);
1.302 } else {
1.303 YYRETURN(TOK_PERIOD);
.