4 code for parsing calibration file, generated by bison
6 Copyright (C) 2003 Frank Mori Hess <fmhess@users.sourceforge.net>
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation, version 2.1
13 This library 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 GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
25 #include "libinternal.h"
28 #include "calib_yacc.h"
30 #define YYERROR_VERBOSE
31 #define YYPARSE_PARAM parse_arg
35 comedi_calibration_t *parsed_file;
36 comedi_caldac_t caldac;
38 } calib_yyparse_private_t;
42 static inline calib_yyparse_private_t* priv( calib_yyparse_private_t *parse_arg)
47 static void free_calibration_setting( comedi_calibration_setting_t *setting )
49 if( setting->channels );
51 free( setting->channels );
52 setting->channels = NULL;
53 setting->num_channels = 0;
55 if( setting->ranges );
57 free( setting->ranges );
58 setting->ranges = NULL;
59 setting->num_ranges = 0;
61 setting->num_arefs = 0;
62 if( setting->caldacs );
64 free( setting->caldacs );
65 setting->caldacs = NULL;
66 setting->num_caldacs = 0;
70 static void free_settings( comedi_calibration_t *file_contents )
74 if( file_contents->settings == NULL ) return;
76 for( i = 0; i < file_contents->num_settings; i++ )
78 free_calibration_setting( &file_contents->settings[ i ] );
80 file_contents->settings = NULL;
83 static int add_calibration_setting( comedi_calibration_t *file_contents )
85 comedi_calibration_setting_t *temp;
87 temp = realloc( file_contents->settings,
88 ( file_contents->num_settings + 1 ) * sizeof( comedi_calibration_setting_t ) );
89 if( temp == NULL ) return -1;
90 file_contents->settings = temp;
91 memset( &file_contents->settings[ file_contents->num_settings ],
92 0, sizeof( comedi_calibration_setting_t ) );
94 file_contents->num_settings++;
98 static comedi_calibration_setting_t* current_setting( calib_yyparse_private_t *priv )
102 while( priv->cal_index >= priv->parsed_file->num_settings )
104 retval = add_calibration_setting( priv->parsed_file );
105 if( retval < 0 ) return NULL;
107 return &priv->parsed_file->settings[ priv->cal_index ];
110 static int add_channel( calib_yyparse_private_t *priv, int channel )
113 comedi_calibration_setting_t *setting;
115 setting = current_setting( priv );
116 if( setting == NULL ) return -1;
118 temp = realloc( setting->channels, ( setting->num_channels + 1 ) * sizeof( int ) );
119 if( temp == NULL ) return -1;
120 setting->channels = temp;
121 setting->channels[ setting->num_channels++ ] = channel;
125 static int add_range( calib_yyparse_private_t *priv, int range )
128 comedi_calibration_setting_t *setting;
130 setting = current_setting( priv );
131 if( setting == NULL ) return -1;
133 temp = realloc( setting->ranges, ( setting->num_ranges + 1 ) * sizeof( int ) );
134 if( temp == NULL ) return -1;
135 setting->ranges = temp;
136 setting->ranges[ setting->num_ranges++ ] = range;
140 static int add_aref( calib_yyparse_private_t *priv, int aref )
142 comedi_calibration_setting_t *setting;
144 setting = current_setting( priv );
145 if( setting == NULL ) return -1;
147 if( setting->num_arefs >= sizeof( setting->arefs ) /
148 sizeof( setting->arefs[ 0 ] ) )
150 setting->arefs[ setting->num_arefs++ ] = aref;
154 static int add_caldac( calib_yyparse_private_t *priv,
155 comedi_caldac_t caldac )
157 comedi_caldac_t *temp;
158 comedi_calibration_setting_t *setting;
160 setting = current_setting( priv );
161 if( setting == NULL ) return -1;
163 temp = realloc( setting->caldacs, ( setting->num_caldacs + 1 ) *
164 sizeof( comedi_caldac_t ) );
165 if( temp == NULL ) return -1;
166 setting->caldacs = temp;
167 setting->caldacs[ setting->num_caldacs++ ] = caldac;
171 static comedi_calibration_t* alloc_calib_parse( void )
173 comedi_calibration_t *file_contents;
175 file_contents = malloc( sizeof( *file_contents ) );
176 if( file_contents == NULL ) return file_contents;
177 memset( file_contents, 0, sizeof( *file_contents ) );
178 return file_contents;
181 EXPORT_ALIAS_DEFAULT(_comedi_cleanup_calibration,comedi_cleanup_calibration,0.7.20);
182 extern void _comedi_cleanup_calibration( comedi_calibration_t *file_contents )
184 if( file_contents->driver_name )
186 free( file_contents->driver_name );
187 file_contents->driver_name = NULL;
189 if( file_contents->board_name )
191 free( file_contents->board_name );
192 file_contents->board_name = NULL;
194 free_settings( file_contents );
195 free( file_contents );
196 file_contents = NULL;
199 EXPORT_ALIAS_DEFAULT(_comedi_parse_calibration_file,comedi_parse_calibration_file,0.7.20);
200 extern comedi_calibration_t* _comedi_parse_calibration_file( const char *cal_file_path )
202 calib_yyparse_private_t priv;
205 if( cal_file_path == NULL ) return NULL;
207 priv.parsed_file = alloc_calib_parse();
208 if( priv.parsed_file == NULL ) return NULL;
211 file = fopen( cal_file_path, "r" );
214 COMEDILIB_DEBUG( 3, "failed to open file\n" );
217 calib_yyrestart( file );
218 if( calib_yyparse( &priv ) )
220 comedi_cleanup_calibration( priv.parsed_file );
221 priv.parsed_file = NULL;
224 return priv.parsed_file;
237 %token T_DRIVER_NAME T_BOARD_NAME T_CALIBRATIONS T_SUBDEVICE T_CHANNELS
238 %token T_RANGES T_AREFS T_CALDACS T_CHANNEL T_VALUE T_NUMBER T_STRING
241 %type <ival> T_NUMBER
242 %type <sval> T_STRING
249 fprintf(stderr, "input error on line %i\n", @1.first_line );
256 | hash_element ',' hash
259 hash_element: T_DRIVER_NAME T_ASSIGN T_STRING
261 if( priv(parse_arg)->parsed_file->driver_name != NULL ) YYABORT;
262 priv(parse_arg)->parsed_file->driver_name = strdup( $3 );
264 | T_BOARD_NAME T_ASSIGN T_STRING
266 if( priv(parse_arg)->parsed_file->board_name != NULL ) YYABORT;
267 priv(parse_arg)->parsed_file->board_name = strdup( $3 );
269 | T_CALIBRATIONS T_ASSIGN '[' calibrations_array ']'
272 calibrations_array: /* empty */
273 | '{' calibration_setting '}'
274 | '{' calibration_setting '}' ',' calibrations_array
277 calibration_setting: /* empty */ { priv(parse_arg)->cal_index++; }
278 | calibration_setting_element { priv(parse_arg)->cal_index++; }
279 | calibration_setting_element ',' calibration_setting
282 calibration_setting_element: T_SUBDEVICE T_ASSIGN T_NUMBER
284 comedi_calibration_setting_t *setting;
285 setting = current_setting( parse_arg );
286 if( setting == NULL ) YYABORT;
287 setting->subdevice = $3;
289 | T_CHANNELS T_ASSIGN '[' channels_array ']'
290 | T_RANGES T_ASSIGN '[' ranges_array ']'
291 | T_AREFS T_ASSIGN '[' arefs_array ']'
292 | T_CALDACS T_ASSIGN '[' caldacs_array ']'
295 channels_array: /* empty */
297 | channel ',' channels_array
300 channel: T_NUMBER { add_channel( parse_arg, $1 ); }
303 ranges_array: /* empty */
305 | range ',' ranges_array
308 range: T_NUMBER { add_range( parse_arg, $1 ); }
311 arefs_array: /* empty */
313 | aref ',' arefs_array
316 aref: T_NUMBER { add_aref( parse_arg, $1 ); }
319 caldacs_array: /* empty */
321 | '{' caldac '}' ',' caldacs_array
324 caldac: /* empty */ { add_caldac( parse_arg, priv(parse_arg)->caldac ); }
325 | caldac_element { add_caldac( parse_arg, priv(parse_arg)->caldac ); }
326 | caldac_element ',' caldac
329 caldac_element: T_SUBDEVICE T_ASSIGN T_NUMBER { priv(parse_arg)->caldac.subdevice = $3; }
330 | T_CHANNEL T_ASSIGN T_NUMBER { priv(parse_arg)->caldac.channel = $3; }
331 | T_VALUE T_ASSIGN T_NUMBER { priv(parse_arg)->caldac.value = $3; }
336 void calib_yyerror(char *s)
338 fprintf(stderr, "%s\n", s);