6 #define is_letter( c) ( isalpha( c) || isdigit( c) || c == '_')
7 #define save_or_put(c) if(previous_state==TEXT)putchar(c);else *bufptr++=c
11 /* This program processes the file 'as.c', and will take care of things like
12 * %d( <expression>), @func( arg), %$( ), etc.
13 * The main-loop is constructed as a finite automat.
19 char buffer[256], *bufptr = buffer;
20 int c, state = TEXT, previous_state = TEXT, depth = 0;
23 while ( ( c = getchar()) != EOF)
27 case '/' : state = SLASH;
28 previous_state = TEXT;
31 case '"' : state = STRING;
32 previous_state = TEXT;
35 case '\'': state = CHAR_CONST;
36 previous_state = TEXT;
39 case '@' : state = AT;
41 default : putchar( c);
48 state = ( c == '*' ? COMMENT : TEXT);
58 state = previous_state;
68 state = previous_state;
70 state = BACKSLASH_in_STRING;
74 case BACKSLASH_in_STRING :
84 state = previous_state;
86 state = BACKSLASH_in_CHAR_CONST;
90 case BACKSLASH_in_CHAR_CONST :
97 case AT : /* @if '(' <CONDITION> ')'
98 * @elsif '(' <CONDITION> ')'
101 * @<IDENTIFIER> '(' <PARAM_LIST> ')'
114 else if ( c == '(') {
117 state = CAL_or_QUEST;
121 pr_ELSE_or_FI( buffer);
128 case CAL_or_QUEST : /* match ')' */
136 pr_CALL_or_QUEST( buffer);
141 case '/' : state = SLASH;
142 previous_state = CAL_or_QUEST;
144 case '"' : state = STRING;
145 previous_state = CAL_or_QUEST;
147 case '\'': state = CHAR_CONST;
148 previous_state = CAL_or_QUEST;
153 fprintf( stderr, "Unknown state : %d\n", state);
161 printf( "#include \"as_parser.h\"\n");
162 printf( "#line 1 \"as.c\"\n");
169 if ( strncmp( str, "else", 4) == 0)
170 printf( "fprint( outfile, \"}\else {\");%s", str+4);
171 else if ( strncmp( str, "fi", 2) == 0)
172 printf( "fprint( outfile, \"}\");%s", str+2);
174 fprintf( stderr, "%s unexpected!!\n", str);
178 pr_CALL_or_QUEST( str)
181 if ( strncmp( str, "if", 2) == 0 && !(is_letter( *(str+2))))
183 else if ( strncmp( str, "elsif", 5) == 0 && !(is_letter( *(str+5))))
190 /* Adjust 'cur_pos' when necessary */
198 if ( strncmp( "text", call, 4) == 0 && isdigit( *(call+4)))
199 printf( "cur_pos += %d;", *(call+4) - '0');
200 else if ( strncmp( "reloc", call, 5) == 0 && isdigit( *(call+5)))
201 printf( "cur_pos += %d;", *(call+5) - '0');
203 pr_text_with_conversions( call);
204 printf( "fprint( outfile, \";\");");
206 for (; ( c = getchar()) != ';' ; putchar( c)); /* skip ';' */
212 printf( "fprint( outfile, \"}\else if\");");
213 pr_text_with_conversions( quest+5);
214 printf( "fprint( outfile, \"{\");");
220 pr_text_with_conversions( quest);
221 printf( "fprint( outfile, \"{\");");
225 pr_text_with_conversions( str)
228 char *ptr, *next_conversion(), *pr_conversion();
230 while ( ptr = next_conversion( str)) {
231 /* ptr points to '%'-sign */
233 printf( "fprint( outfile, \"");
237 str = pr_conversion( ptr);
239 printf( "fprint( outfile, \"");
248 for ( ; *s != '\0'; s++)
250 case '"' : printf( "\\\"");
253 case '\\': printf( "\\\\");
256 case '\n': printf( "\\n");
259 default : printf( "%c", *s);
264 char *next_conversion( str)
269 while ( *str && *str != '%') {
271 case '\'' : str = match( '\'', str) + 1;
273 case '"' : str = match( '"', str) + 1;
277 return( *str == '%' ? str : (char *)0);
283 while ( *str && ( *str != c || *(str-1) == '\\'))
285 return( *str ? str : str-1);
288 char *match_bracket( str)
291 /* find ')', but look at nesting '('-')' pairs, return position of ')'.
298 while ( *str && depth != 0) {
300 case '\'' : str = match( '\'', str+1) + 1;
302 case '"' : str = match( '"', str+1) + 1;
317 while ( *str && *str != c)
322 char *pr_conversion( str)
325 /* str points to '%'-sign, returns pointer to first character AFTER the
329 char *start, *ptr, *match_bracket(), *find();
331 start = find( '(', str+1);
334 ptr = match_bracket( start);
337 if ( *(str+1) == '$')
338 printf( "eval( %s);", start);
339 else if ( strncmp( str+1, "dist", 4) == 0)
340 printf( "dist( %s);", start);
342 printf( "fprint( outfile, \"%%%s\", %s);", str+1, start);