filename | src/tools/actparse.c |
changeset | 1169:23a9613aceb1 |
prev | 981:79fcace1ab43 |
next | 1296:30ecee61f811 |
author | Nathan Keynes <nkeynes@lxdream.org> |
date | Sat Sep 17 22:39:36 2011 +1000 (12 years ago) |
permissions | -rw-r--r-- |
last change | Fix structure packing on v55 nero images (64-bit) Add basic support for track mode 16 (CDDA + subchannel data, 2448 bytes) |
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 <errno.h>
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <ctype.h>
24 #include <sys/stat.h>
25 #include <glib/gstrfuncs.h>
26 #include "tools/gendec.h"
28 static int add_action( struct action *actions, struct ruleset *rules, char *operation, const char *file, int line, char *action )
29 {
30 char *act = g_strchomp(action);
31 char opclean[strlen(operation)+1];
32 char *p = operation, *q = opclean;
33 int i;
35 // Strip c-style comments
36 while( *p ) {
37 if( *p == '/' && *(p+1) == '*' ) {
38 p+=2;
39 while( *p ) {
40 if( *p == '*' && *(p+1) == '/' ) {
41 p+=2;
42 break;
43 }
44 p++;
45 }
46 } else if( *p == '/' && *(p+1) == '/' ) {
47 p+=2;
48 while( *p && *p != '\n' ) {
49 p++;
50 }
51 } else {
52 *q++ = *p++;
53 }
54 }
55 *q = '\0';
57 /* Drop any leading blank lines from the start of the action (and add them
58 * to the line number ) */
59 for( p=act; isspace(*p); p++ ) {
60 if( *p == '\n' ) {
61 act = p+1;
62 line++;
63 }
64 }
66 strcpy( operation, g_strstrip(opclean) );
68 for( i=0; i<rules->rule_count; i++ ) {
69 if( strcasecmp(rules->rules[i]->format, operation) == 0 ) {
70 if( actions[i].text != NULL ) {
71 fprintf( stderr, "gendec:%d: Duplicate actions for operation '%s' (previous action on line %d)\n", line, operation,
72 actions[i].lineno );
73 return -1;
74 }
75 actions[i].filename = file;
76 actions[i].lineno = line;
77 actions[i].text = act;
78 return 0;
79 }
80 }
81 fprintf(stderr, "gendec:%d: No operation found matching '%s'\n", line, operation );
82 return -1;
83 }
85 struct actionfile {
86 FILE *f;
87 const char *filename;
88 char *text;
89 int length;
90 int yyposn;
91 int yyline;
92 struct ruleset *rules;
93 struct actiontoken token;
94 };
96 actionfile_t action_file_open( const char *filename, struct ruleset *rules )
97 {
98 struct stat st;
99 FILE *f = fopen( filename, "ro" );
100 if( f == NULL )
101 return NULL;
102 fstat( fileno(f), &st );
104 actionfile_t af = malloc( sizeof(struct actionfile) );
105 af->f = f;
106 af->filename = filename;
107 af->length = st.st_size+1;
108 af->text = malloc( st.st_size+1 );
109 if( fread( af->text, st.st_size, 1, f ) != 1 ) {
110 fprintf( stderr, "Error: unable to read from file '%s' (%s)\n", filename, strerror(errno));
111 free(af);
112 fclose(f);
113 return NULL;
114 }
115 af->text[st.st_size] = '\0';
116 af->yyline = 1;
117 af->yyposn = 0;
118 af->rules = rules;
119 af->token.symbol = NONE;
120 af->token.lineno = 1;
121 af->token.filename = filename;
122 return af;
123 }
125 actiontoken_t action_file_next( actionfile_t af )
126 {
127 af->token.lineno = af->yyline;
128 if( af->yyposn == af->length ) {
129 af->token.symbol = END;
130 } else if( af->token.symbol == TEXT || /* ACTIONS must follow TEXT */
131 (af->token.symbol == NONE && af->text[af->yyposn] == '%' && af->text[af->yyposn+1] == '%') ) {
132 /* Begin action block */
133 af->token.symbol = ACTIONS;
134 memset( af->token.actions, 0, sizeof(af->token.actions) );
136 char *operation = &af->text[af->yyposn];
137 while( af->yyposn < af->length ) {
138 if( af->text[af->yyposn] == '\n' ) {
139 af->yyline++;
140 if( af->text[af->yyposn+1] == '%' && af->text[af->yyposn+2] == '%' ) {
141 af->yyposn += 3;
142 break;
143 }
144 }
146 if( af->text[af->yyposn] == '{' && af->text[af->yyposn+1] == ':' ) {
147 af->text[af->yyposn] = '\0';
148 int line = af->yyline;
149 af->yyposn+=2;
150 char *action = &af->text[af->yyposn];
151 while( af->yyposn < af->length ) {
152 if( af->text[af->yyposn] == ':' && af->text[af->yyposn+1] == '}' ) {
153 af->text[af->yyposn] = '\0';
154 af->yyposn++;
155 if( add_action( af->token.actions, af->rules, operation, af->filename, line, action ) != 0 ) {
156 af->token.symbol = ERROR;
157 return &af->token;
158 }
159 operation = &af->text[af->yyposn+1];
160 break;
161 } else if( af->text[af->yyposn] == '\n' ) {
162 af->yyline++;
163 }
164 af->yyposn++;
165 }
166 }
167 af->yyposn++;
168 }
169 } else {
170 /* Text block */
171 af->token.symbol = TEXT;
172 af->token.text = &af->text[af->yyposn];
173 while( af->yyposn < af->length ) {
174 af->yyposn++;
175 if( af->text[af->yyposn-1] == '\n' ) {
176 af->yyline++;
177 if( af->text[af->yyposn] == '%' && af->text[af->yyposn+1] == '%' ) {
178 af->text[af->yyposn] = '\0';
179 af->yyposn += 2;
180 break;
181 }
182 }
183 }
184 }
185 return &af->token;
186 }
188 void action_file_close( actionfile_t af )
189 {
190 free( af->text );
191 fclose( af->f );
192 free( af );
193 }
.