4 * gendec action file parser.
6 * Copyright (c) 2005 Nathan Keynes.
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.
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.
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 )
29 char *act = g_strchomp(action);
30 char opclean[strlen(operation)+1];
31 char *p = operation, *q = opclean;
34 // Strip c-style comments
36 if( *p == '/' && *(p+1) == '*' ) {
39 if( *p == '*' && *(p+1) == '/' ) {
45 } else if( *p == '/' && *(p+1) == '/' ) {
47 while( *p && *p != '\n' ) {
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++ ) {
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, "Duplicate actions for operation '%s'\n", operation );
73 actions[i].filename = file;
74 actions[i].lineno = line;
75 actions[i].text = act;
79 fprintf(stderr, "No operation found matching '%s'\n", operation );
90 struct ruleset *rules;
91 struct actiontoken token;
94 actionfile_t action_file_open( const char *filename, struct ruleset *rules )
97 FILE *f = fopen( filename, "ro" );
100 fstat( fileno(f), &st );
102 actionfile_t af = malloc( sizeof(struct actionfile) );
104 af->filename = filename;
105 af->length = st.st_size+1;
106 af->text = malloc( st.st_size+1 );
107 fread( af->text, st.st_size, 1, f );
108 af->text[st.st_size] = '\0';
112 af->token.symbol = NONE;
113 af->token.lineno = 1;
114 af->token.filename = filename;
119 actiontoken_t action_file_next( actionfile_t af )
121 if( af->token.symbol == ACTIONS ) {
122 /* Destroy previous actions */
123 memset( af->token.actions, 0, sizeof(af->token.actions) );
125 af->token.lineno = af->yyline;
126 if( af->yyposn == af->length ) {
127 af->token.symbol = END;
128 } else if( af->token.symbol == TEXT || /* ACTIONS must follow TEXT */
129 (af->token.symbol == NONE && af->text[af->yyposn] == '%' && af->text[af->yyposn+1] == '%') ) {
130 /* Begin action block */
131 af->token.symbol = ACTIONS;
133 char *operation = &af->text[af->yyposn];
134 while( af->yyposn < af->length ) {
135 if( af->text[af->yyposn] == '\n' ) {
137 if( af->text[af->yyposn+1] == '%' && af->text[af->yyposn+2] == '%' ) {
143 if( af->text[af->yyposn] == '{' && af->text[af->yyposn+1] == ':' ) {
144 af->text[af->yyposn] = '\0';
145 int line = af->yyline;
147 char *action = &af->text[af->yyposn];
148 while( af->yyposn < af->length ) {
149 if( af->text[af->yyposn] == ':' && af->text[af->yyposn+1] == '}' ) {
150 af->text[af->yyposn] = '\0';
152 if( add_action( af->token.actions, af->rules, operation, af->filename, line, action ) != 0 ) {
153 af->token.symbol = ERROR;
156 operation = &af->text[af->yyposn+1];
158 } else if( af->text[af->yyposn] == '\n' ) {
168 af->token.symbol = TEXT;
169 af->token.text = &af->text[af->yyposn];
170 while( af->yyposn < af->length ) {
172 if( af->text[af->yyposn-1] == '\n' ) {
174 if( af->text[af->yyposn] == '%' && af->text[af->yyposn+1] == '%' ) {
175 af->text[af->yyposn] = '\0';
185 void action_file_close( actionfile_t af )
.