%option noyywrap
%option nounput
+%option yylineno
+%option reentrant
%{
lib/calib_lex.l
code for parsing calibration file, generated by flex
- Copyright (C) 2003 Frank Mori Hess <fmhess@users.sourceforge.net
+ Copyright (C) 2003 Frank Mori Hess <fmhess@users.sourceforge.net>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
%%
-%{
- calib_llocp->first_line = 1;
-%}
-
-<STRING,INITIAL>\n { calib_llocp->first_line++; }
+<STRING,INITIAL>\n
"#" { BEGIN(COMMENT); }
-<COMMENT>\n { calib_llocp->first_line++; BEGIN(INITIAL); }
+<COMMENT>\n {BEGIN(INITIAL); }
<COMMENT>.
\" { BEGIN(STRING); }
<STRING>[^\"]*\" {
- if( strlen( calib_yytext ) > 0 )
- calib_yytext[ strlen( calib_yytext ) - 1 ] = 0;
- calib_lvalp->sval = calib_yytext;
+ if(strlen(calib_yyget_text(yyscanner)) > 0)
+ calib_yyget_text(yyscanner)[strlen(calib_yyget_text(yyscanner)) - 1] = 0;
+ calib_lvalp->sval = calib_yyget_text(yyscanner);
BEGIN(INITIAL);
return ( T_STRING );
}
caldacs { return ( T_CALDACS ); }
channel { return ( T_CHANNEL ); }
value { return ( T_VALUE ); }
+coefficients {return (T_COEFFICIENTS);}
+expansion_origin {return (T_EXPANSION_ORIGIN);}
+softcal_to_phys {return T_SOFTCAL_TO_PHYS;}
+softcal_from_phys {return T_SOFTCAL_FROM_PHYS;}
=> { return ( T_ASSIGN ); };
-(0[xX])?(00)?[0-9a-fA-F]+ { calib_lvalp->ival = strtol( calib_yytext, NULL, 0 );
+(0[xX])?(00)?[0-9a-fA-F]+ {calib_lvalp->ival = strtol(calib_yyget_text(yyscanner), NULL, 0);
return( T_NUMBER ); }
+[0-9]+\.*[0-9]* { calib_lvalp->dval = strtod(calib_yyget_text(yyscanner), 0);
+ return( T_FLOAT ); }
+
+[0-9]*\.*[0-9]+ { calib_lvalp->dval = strtod(calib_yyget_text(yyscanner), 0);
+ return( T_FLOAT ); }
+
[ \t]
-. { return( calib_yytext[0] ); }
+. {return(calib_yyget_text(yyscanner)[0]);}
%%
#include <string.h>
#include <stdlib.h>
#include "calib_yacc.h"
+#include "calib_lex.h"
#define YYERROR_VERBOSE
#define YYPARSE_PARAM parse_arg
+#define YYLEX_PARAM priv(YYPARSE_PARAM)->yyscanner
+
+enum polynomial_direction
+{
+ POLYNOMIAL_TO_PHYS,
+ POLYNOMIAL_FROM_PHYS
+};
typedef struct
{
+ yyscan_t yyscanner;
comedi_calibration_t *parsed_file;
comedi_caldac_t caldac;
int cal_index;
+ enum polynomial_direction polynomial_direction;
+ unsigned num_coefficients;
+ comedi_polynomial_t polynomial;
} calib_yyparse_private_t;
YY_DECL;
setting->caldacs = NULL;
setting->num_caldacs = 0;
}
+ if(setting->soft_calibration.to_phys)
+ {
+ free(setting->soft_calibration.to_phys);
+ setting->soft_calibration.to_phys = NULL;
+ }
+ if(setting->soft_calibration.from_phys)
+ {
+ free(setting->soft_calibration.from_phys);
+ setting->soft_calibration.from_phys = NULL;
+ }
}
static void free_settings( comedi_calibration_t *file_contents )
return 0;
}
+static int add_polynomial(calib_yyparse_private_t *priv)
+{
+ comedi_calibration_setting_t *setting;
+
+ setting = current_setting( priv );
+ if( setting == NULL ) return -1;
+ if(priv->num_coefficients < 1) return -1;
+ if(priv->polynomial_direction == POLYNOMIAL_TO_PHYS)
+ {
+ if(setting->soft_calibration.to_phys) return -1;
+ setting->soft_calibration.to_phys = malloc(sizeof(comedi_polynomial_t));
+ *setting->soft_calibration.to_phys = priv->polynomial;
+ }else
+ {
+ if(setting->soft_calibration.from_phys) return -1;
+ setting->soft_calibration.from_phys = malloc(sizeof(comedi_polynomial_t));
+ *setting->soft_calibration.from_phys = priv->polynomial;
+ }
+ return 0;
+}
+
static comedi_calibration_t* alloc_calib_parse( void )
{
comedi_calibration_t *file_contents;
}
free_settings( file_contents );
free( file_contents );
- file_contents = NULL;
}
EXPORT_ALIAS_DEFAULT(_comedi_parse_calibration_file,comedi_parse_calibration_file,0.7.20);
FILE *file;
if( cal_file_path == NULL ) return NULL;
-
+
priv.parsed_file = alloc_calib_parse();
if( priv.parsed_file == NULL ) return NULL;
priv.cal_index = 0;
COMEDILIB_DEBUG( 3, "failed to open file\n" );
return NULL;
}
- calib_yyrestart( file );
+ calib_yylex_init(&priv.yyscanner);
+ calib_yyrestart(file, priv.yyscanner);
if( calib_yyparse( &priv ) )
{
comedi_cleanup_calibration( priv.parsed_file );
priv.parsed_file = NULL;
}
+ calib_yylex_destroy(priv.yyscanner);
fclose( file );
return priv.parsed_file;
}
%union
{
int ival;
+ double dval;
char *sval;
}
%token T_DRIVER_NAME T_BOARD_NAME T_CALIBRATIONS T_SUBDEVICE T_CHANNELS
%token T_RANGES T_AREFS T_CALDACS T_CHANNEL T_VALUE T_NUMBER T_STRING
-%token T_ASSIGN
+%token T_COEFFICIENTS T_EXPANSION_ORIGIN T_SOFTCAL_TO_PHYS T_SOFTCAL_FROM_PHYS
+%token T_ASSIGN T_FLOAT
%type <ival> T_NUMBER
%type <sval> T_STRING
+%type <dval> T_FLOAT
%%
| T_RANGES T_ASSIGN '[' ranges_array ']'
| T_AREFS T_ASSIGN '[' arefs_array ']'
| T_CALDACS T_ASSIGN '[' caldacs_array ']'
+ | T_SOFTCAL_TO_PHYS T_ASSIGN '{' polynomial '}'
+ {
+ priv(parse_arg)->polynomial_direction = POLYNOMIAL_TO_PHYS;
+ }
+ | T_SOFTCAL_FROM_PHYS T_ASSIGN '{' polynomial '}'
+ {
+ priv(parse_arg)->polynomial_direction = POLYNOMIAL_FROM_PHYS;
+ }
;
channels_array: /* empty */
| T_VALUE T_ASSIGN T_NUMBER { priv(parse_arg)->caldac.value = $3; }
;
+ polynomial: /* empty */ { add_polynomial(parse_arg);}
+ | polynomial_element { add_polynomial(parse_arg);}
+ | polynomial_element ',' polynomial
+ ;
+
+ polynomial_element: T_COEFFICIENTS T_ASSIGN '[' coefficient_array ']' {priv(parse_arg)->num_coefficients = 0;}
+ | T_EXPANSION_ORIGIN T_ASSIGN expansion_origin
+ ;
+
+ coefficient_array: /* empty */
+ | coefficient
+ | coefficient ',' coefficient_array
+ ;
+
+ coefficient: T_FLOAT
+ {
+ if(priv(parse_arg)->num_coefficients >= COMEDI_MAX_NUM_POLYNOMIAL_COEFFICIENTS)
+ {
+ fprintf(stderr, "too many coefficients for polynomial on line %i ,\n", @1.first_line );
+ fprintf(stderr, "max is %i .\n", COMEDI_MAX_NUM_POLYNOMIAL_COEFFICIENTS);
+ YYABORT;
+ }
+ priv(parse_arg)->polynomial.order = priv(parse_arg)->num_coefficients;
+ priv(parse_arg)->polynomial.coefficients[priv(parse_arg)->num_coefficients++] = $1;
+ }
+ ;
+
+ expansion_origin: T_FLOAT
+ {
+ priv(parse_arg)->polynomial.expansion_origin = $1;
+ }
+ ;
+
%%
void calib_yyerror(char *s)