filename | src/tools/actparse.c |
changeset | 981:79fcace1ab43 |
prev | 979:2cc7b486ea6c |
next | 1169:23a9613aceb1 |
author | nkeynes |
date | Thu Jun 10 22:13:16 2010 +1000 (13 years ago) |
permissions | -rw-r--r-- |
last change | Integrate executable wrapping into the user interface - command-line now loads wrapped by default, -e <bin> to run binary - add support for .bin executables - Add useful (internal) error codes |
view | annotate | diff | log | raw |
1 /**
2 * $Id$
3 *
4 * gendec action file parser.
5 *
6 * Copyright (c) 2005 Nathan Keynes.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 */
19 #include <stdlib.h>
20 #include <stdio.h>
21 #include <string.h>
22 #include <ctype.h>
23 #include <sys/stat.h>
24 #include <glib/gstrfuncs.h>
25 #include "tools/gendec.h"
27 static int add_action( struct action *actions, struct ruleset *rules, char *operation, const char *file, int line, char *action )
28 {
29 char *act = g_strchomp(action);
30 char opclean[strlen(operation)+1];
31 char *p = operation, *q = opclean;
32 int i;
34 // Strip c-style comments
35 while( *p ) {
36 if( *p == '/' && *(p+1) == '*' ) {
37 p+=2;
38 while( *p ) {
39 if( *p == '*' && *(p+1) == '/' ) {
40 p+=2;
41 break;
42 }
43 p++;
44 }
45 } else if( *p == '/' && *(p+1) == '/' ) {
46 p+=2;
47 while( *p && *p != '\n' ) {
48 p++;
49 }
50 } else {
51 *q++ = *p++;
52 }
53 }
54 *q = '\0';
56 /* Drop any leading blank lines from the start of the action (and add them
57 * to the line number ) */
58 for( p=act; isspace(*p); p++ ) {
59 if( *p == '\n' ) {
60 act = p+1;
61 line++;
62 }
63 }
65 strcpy( operation, g_strstrip(opclean) );
67 for( i=0; i<rules->rule_count; i++ ) {
68 if( strcasecmp(rules->rules[i]->format, operation) == 0 ) {
69 if( actions[i].text != NULL ) {
70 fprintf( stderr, "gendec:%d: Duplicate actions for operation '%s' (previous action on line %d)\n", line, operation,
71 actions[i].lineno );
72 return -1;
73 }
74 actions[i].filename = file;
75 actions[i].lineno = line;
76 actions[i].text = act;
77 return 0;
78 }
79 }
80 fprintf(stderr, "gendec:%d: No operation found matching '%s'\n", line, operation );
81 return -1;
82 }
84 struct actionfile {
85 FILE *f;
86 const char *filename;
87 char *text;
88 int length;
89 int yyposn;
90 int yyline;
91 struct ruleset *rules;
92 struct actiontoken token;
93 };
95 actionfile_t action_file_open( const char *filename, struct ruleset *rules )
96 {
97 struct stat st;
98 FILE *f = fopen( filename, "ro" );
99 if( f == NULL )
100 return NULL;
101 fstat( fileno(f), &st );
103 actionfile_t af = malloc( sizeof(struct actionfile) );
104 af->f = f;
105 af->filename = filename;
106 af->length = st.st_size+1;
107 af->text = malloc( st.st_size+1 );
108 fread( af->text, st.st_size, 1, f );
109 af->text[st.st_size] = '\0';
110 af->yyline = 1;
111 af->yyposn = 0;
112 af->rules = rules;
113 af->token.symbol = NONE;
114 af->token.lineno = 1;
115 af->token.filename = filename;
117 return af;
118 }
120 actiontoken_t action_file_next( actionfile_t af )
121 {
122 af->token.lineno = af->yyline;
123 if( af->yyposn == af->length ) {
124 af->token.symbol = END;
125 } else if( af->token.symbol == TEXT || /* ACTIONS must follow TEXT */
126 (af->token.symbol == NONE && af->text[af->yyposn] == '%' && af->text[af->yyposn+1] == '%') ) {
127 /* Begin action block */
128 af->token.symbol = ACTIONS;
129 memset( af->token.actions, 0, sizeof(af->token.actions) );
131 char *operation = &af->text[af->yyposn];
132 while( af->yyposn < af->length ) {
133 if( af->text[af->yyposn] == '\n' ) {
134 af->yyline++;
135 if( af->text[af->yyposn+1] == '%' && af->text[af->yyposn+2] == '%' ) {
136 af->yyposn += 3;
137 break;
138 }
139 }
141 if( af->text[af->yyposn] == '{' && af->text[af->yyposn+1] == ':' ) {
142 af->text[af->yyposn] = '\0';
143 int line = af->yyline;
144 af->yyposn+=2;
145 char *action = &af->text[af->yyposn];
146 while( af->yyposn < af->length ) {
147 if( af->text[af->yyposn] == ':' && af->text[af->yyposn+1] == '}' ) {
148 af->text[af->yyposn] = '\0';
149 af->yyposn++;
150 if( add_action( af->token.actions, af->rules, operation, af->filename, line, action ) != 0 ) {
151 af->token.symbol = ERROR;
152 return &af->token;
153 }
154 operation = &af->text[af->yyposn+1];
155 break;
156 } else if( af->text[af->yyposn] == '\n' ) {
157 af->yyline++;
158 }
159 af->yyposn++;
160 }
161 }
162 af->yyposn++;
163 }
164 } else {
165 /* Text block */
166 af->token.symbol = TEXT;
167 af->token.text = &af->text[af->yyposn];
168 while( af->yyposn < af->length ) {
169 af->yyposn++;
170 if( af->text[af->yyposn-1] == '\n' ) {
171 af->yyline++;
172 if( af->text[af->yyposn] == '%' && af->text[af->yyposn+1] == '%' ) {
173 af->text[af->yyposn] = '\0';
174 af->yyposn += 2;
175 break;
176 }
177 }
178 }
179 }
180 return &af->token;
181 }
183 void action_file_close( actionfile_t af )
184 {
185 free( af->text );
186 fclose( af->f );
187 free( af );
188 }
.