#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "defines.h"
#include "fsm_arg.h"
#include "util.h"
#include "fsm.h"
#include "fsm_var.h"
#include "vsignal.h"
#include "expr.h"
#include "vector.h"
#include "statement.h"
#include "link.h"
#include "param.h"
#include "obfuscate.h"
Functions | |
static expression * | fsm_arg_parse_state (char **arg, char *funit_name) |
void | fsm_arg_parse (const char *arg) |
Parses specified -F argument for FSM information. | |
static expression * | fsm_arg_parse_value (char **str, const func_unit *funit) |
static void | fsm_arg_parse_trans (expression *expr, fsm *table, const func_unit *funit) |
void | fsm_arg_parse_attr (attr_param *ap, int line, const func_unit *funit, bool exclude) |
Parses specified attribute argument for FSM information. | |
Variables | |
int | curr_expr_id |
char | user_msg [USER_MSG_LENGTH] |
void fsm_arg_parse | ( | const char * | arg | ) |
Parses specified -F argument for FSM information.
anonymous | Throw |
Parses specified argument string for FSM information. If the FSM information is considered legal, returns TRUE; otherwise, returns FALSE.
arg | Command-line argument following -F specifier |
References Catch_anonymous, FALSE, FATAL, free_safe, fsm_arg_parse_state(), fsm_var_add(), print_output(), PROFILE, PROFILE_END, strdup_safe, Throw, and Try.
Referenced by score_parse_args().
00247 { PROFILE(FSM_ARG_PARSE); 00248 00249 char* tmp = strdup_safe( arg ); /* Temporary copy of given argument */ 00250 char* ptr = tmp; /* Pointer to current character in arg */ 00251 expression* in_state; /* Pointer to input state expression */ 00252 expression* out_state; /* Pointer to output state expression */ 00253 00254 Try { 00255 00256 while( (*ptr != '\0') && (*ptr != '=') ) { 00257 ptr++; 00258 } 00259 00260 if( *ptr == '\0' ) { 00261 00262 print_output( "Option -F must specify a module/task/function/named block and one or two variables. See \"covered score -h\" for more information.", 00263 FATAL, __FILE__, __LINE__ ); 00264 Throw 0; 00265 00266 } else { 00267 00268 *ptr = '\0'; 00269 ptr++; 00270 00271 if( (in_state = fsm_arg_parse_state( &ptr, tmp )) != NULL ) { 00272 00273 if( *ptr == ',' ) { 00274 00275 ptr++; 00276 00277 if( (out_state = fsm_arg_parse_state( &ptr, tmp )) != NULL ) { 00278 (void)fsm_var_add( arg, 0, in_state, out_state, NULL, FALSE ); 00279 } else { 00280 print_output( "Illegal FSM command-line output state", FATAL, __FILE__, __LINE__ ); 00281 Throw 0; 00282 } 00283 00284 } else { 00285 00286 /* Copy the current expression */ 00287 (void)fsm_var_add( arg, 0, in_state, in_state, NULL, FALSE ); 00288 00289 } 00290 00291 } else { 00292 00293 print_output( "Illegal FSM command-line input state", FATAL, __FILE__, __LINE__ ); 00294 Throw 0; 00295 00296 } 00297 00298 } 00299 00300 } Catch_anonymous { 00301 free_safe( tmp, (strlen( arg ) + 1) ); 00302 Throw 0; 00303 } 00304 00305 /* Deallocate temporary memory */ 00306 free_safe( tmp, (strlen( arg ) + 1) ); 00307 00308 PROFILE_END; 00309 00310 }
void fsm_arg_parse_attr | ( | attr_param * | ap, | |
int | line, | |||
const func_unit * | funit, | |||
bool | exclude | |||
) |
Parses specified attribute argument for FSM information.
anonymous | Throw Throw Throw Throw Throw Throw Throw Throw fsm_arg_parse_trans |
Parses the specified attribute parameter for validity and updates FSM structure accordingly.
ap | Pointer to attribute parameter list | |
line | First line of attribute | |
funit | Pointer to functional unit containing this attribute | |
exclude | If TRUE, sets the exclude bits in the FSM |
References Catch_anonymous, ESUPPL_STATIC_BASE, attr_param_s::expr, FALSE, FATAL, func_unit_s::filename, free_safe, fsm_arg_parse_state(), fsm_arg_parse_trans(), func_unit_s::fsm_head, fsm_link_find(), fsm_var_add(), func_unit_s::name, attr_param_s::name, obf_file, obf_sig, attr_param_s::prev, print_output(), PROFILE, PROFILE_END, expression_s::suppl, fsm_link_s::table, Throw, TRUE, Try, user_msg, USER_MSG_LENGTH, expression_s::value, and vector_to_string().
Referenced by attribute_parse().
00597 { PROFILE(FSM_ARG_PARSE_ATTR); 00598 00599 attr_param* curr; /* Pointer to current attribute parameter in list */ 00600 fsm_link* fsml = NULL; /* Pointer to found FSM structure */ 00601 int index = 1; /* Current index number in list */ 00602 bool ignore = FALSE; /* Set to TRUE if we should ignore this attribute */ 00603 expression* in_state = NULL; /* Pointer to input state */ 00604 expression* out_state = NULL; /* Pointer to output state */ 00605 char* str; /* Temporary holder for string value */ 00606 char* tmp; /* Temporary holder for string value */ 00607 00608 curr = ap; 00609 while( (curr != NULL) && !ignore ) { 00610 00611 /* This name is the name of the FSM structure to update */ 00612 if( index == 1 ) { 00613 if( curr->expr != NULL ) { 00614 ignore = TRUE; 00615 } else { 00616 fsml = fsm_link_find( curr->name, funit->fsm_head ); 00617 } 00618 } else if( (index == 2) && (strcmp( curr->name, "is" ) == 0) && (curr->expr != NULL) ) { 00619 if( fsml == NULL ) { 00620 int slen; 00621 tmp = str = vector_to_string( curr->expr->value, ESUPPL_STATIC_BASE( curr->expr->suppl ), FALSE, 0 ); 00622 slen = strlen( tmp ); 00623 Try { 00624 if( (in_state = fsm_arg_parse_state( &str, funit->name )) == NULL ) { 00625 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Illegal input state expression (%s), file: %s", str, obf_file( funit->filename ) ); 00626 assert( rv < USER_MSG_LENGTH ); 00627 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00628 Throw 0; 00629 } 00630 } Catch_anonymous { 00631 free_safe( tmp, (slen + 1) ); 00632 Throw 0; 00633 } 00634 free_safe( tmp, (slen + 1) ); 00635 } else { 00636 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Input state specified after output state for this FSM has already been specified, file: %s", 00637 obf_file( funit->filename ) ); 00638 assert( rv < USER_MSG_LENGTH ); 00639 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00640 Throw 0; 00641 } 00642 } else if( (index == 2) && (strcmp( curr->name, "os" ) == 0) && (curr->expr != NULL) ) { 00643 if( fsml == NULL ) { 00644 int slen; 00645 tmp = str = vector_to_string( curr->expr->value, ESUPPL_STATIC_BASE( curr->expr->suppl ), FALSE, 0 ); 00646 slen = strlen( tmp ); 00647 Try { 00648 if( (out_state = fsm_arg_parse_state( &str, funit->name )) == NULL ) { 00649 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Illegal output state expression (%s), file: %s", str, obf_file( funit->filename ) ); 00650 assert( rv < USER_MSG_LENGTH ); 00651 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00652 Throw 0; 00653 } else { 00654 (void)fsm_var_add( funit->name, line, out_state, out_state, curr->name, exclude ); 00655 fsml = fsm_link_find( curr->name, funit->fsm_head ); 00656 } 00657 } Catch_anonymous { 00658 free_safe( tmp, (slen + 1) ); 00659 Throw 0; 00660 } 00661 free_safe( tmp, (slen + 1) ); 00662 } else { 00663 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Output state specified after output state for this FSM has already been specified, file: %s", 00664 obf_file( funit->filename ) ); 00665 assert( rv < USER_MSG_LENGTH ); 00666 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00667 Throw 0; 00668 } 00669 } else if( (index == 3) && (strcmp( curr->name, "os" ) == 0) && (out_state == NULL) && 00670 (in_state != NULL) && (curr->expr != NULL) ) { 00671 if( fsml == NULL ) { 00672 int slen; 00673 tmp = str = vector_to_string( curr->expr->value, ESUPPL_STATIC_BASE( curr->expr->suppl ), FALSE, 0 ); 00674 slen = strlen( tmp ); 00675 Try { 00676 if( (out_state = fsm_arg_parse_state( &str, funit->name )) == NULL ) { 00677 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Illegal output state expression (%s), file: %s", str, obf_file( funit->filename ) ); 00678 assert( rv < USER_MSG_LENGTH ); 00679 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00680 Throw 0; 00681 } else { 00682 (void)fsm_var_add( funit->name, line, in_state, out_state, curr->name, exclude ); 00683 fsml = fsm_link_find( curr->name, funit->fsm_head ); 00684 } 00685 } Catch_anonymous { 00686 free_safe( tmp, (slen + 1) ); 00687 Throw 0; 00688 } 00689 free_safe( tmp, (slen + 1) ); 00690 } else { 00691 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Output state specified after output state for this FSM has already been specified, file: %s", 00692 obf_file( funit->filename ) ); 00693 assert( rv < USER_MSG_LENGTH ); 00694 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00695 Throw 0; 00696 } 00697 } else if( (index > 1) && (strncmp( curr->name, "trans", 5 ) == 0) && (curr->expr != NULL) ) { 00698 if( fsml == NULL ) { 00699 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Attribute FSM name (%s) has not been previously created, file: %s", 00700 obf_sig( curr->name ), obf_file( funit->filename ) ); 00701 assert( rv < USER_MSG_LENGTH ); 00702 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00703 Throw 0; 00704 } else { 00705 fsm_arg_parse_trans( curr->expr, fsml->table, funit ); 00706 } 00707 } else { 00708 unsigned int rv; 00709 tmp = vector_to_string( curr->expr->value, ESUPPL_STATIC_BASE( curr->expr->suppl ), FALSE, 0 ); 00710 rv = snprintf( user_msg, USER_MSG_LENGTH, "Invalid covered_fsm attribute parameter (%s=%s), file: %s", 00711 curr->name, tmp, obf_file( funit->filename ) ); 00712 assert( rv < USER_MSG_LENGTH ); 00713 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00714 free_safe( tmp, (strlen( tmp ) + 1) ); 00715 Throw 0; 00716 } 00717 00718 /* We need to work backwards in attribute parameter lists */ 00719 curr = curr->prev; 00720 index++; 00721 00722 } 00723 00724 PROFILE_END; 00725 00726 }
static expression* fsm_arg_parse_state | ( | char ** | arg, | |
char * | funit_name | |||
) | [static] |
anonymous | fsm_var_bind_add fsm_var_bind_add fsm_var_bind_add fsm_var_bind_add fsm_var_bind_add Throw Throw expression_create expression_create expression_create expression_create expression_create expression_create expression_create expression_create expression_create expression_create expression_create expression_create expression_create expression_create |
Parses the specified argument value for all information regarding a state variable expression.
arg | Pointer to argument to parse | |
funit_name | Name of functional unit that this expression belongs to |
References Catch_anonymous, curr_expr_id, vsignal_s::dim, EXP_OP_CONCAT, EXP_OP_LIST, EXP_OP_MBIT_NEG, EXP_OP_MBIT_POS, EXP_OP_MBIT_SEL, EXP_OP_SBIT_SEL, EXP_OP_SIG, EXP_OP_STATIC, expression_create(), expression_dealloc(), FALSE, fsm_var_bind_add(), fsm_var_stmt_add(), dim_range_s::lsb, vsignal_s::name, statement_s::next_false, statement_s::next_true, statement_s::part, ssuppl_u::part, PROFILE, PROFILE_END, SSUPPL_TYPE_IMPLICIT, SSUPPL_TYPE_IMPLICIT_NEG, SSUPPL_TYPE_IMPLICIT_POS, statement_create(), statement_s::suppl, vsignal_s::suppl, Throw, TRUE, Try, ssuppl_u::type, expression_s::value, vsignal_s::value, VDATA_UL, vector_create(), vector_dealloc(), vector_from_int(), vsignal_dealloc(), vsignal_from_string(), VTYPE_VAL, and vector_s::width.
Referenced by fsm_arg_parse(), and fsm_arg_parse_attr().
00057 { PROFILE(FSM_ARG_PARSE_STATE); 00058 00059 bool error = FALSE; /* Specifies if a parsing error has been found */ 00060 vsignal* sig; /* Pointer to read-in signal */ 00061 expression* expl = NULL; /* Pointer to left expression */ 00062 expression* expr = NULL; /* Pointer to right expression */ 00063 expression* expt = NULL; /* Pointer to temporary expression */ 00064 statement* stmt; /* Pointer to statement containing top expression */ 00065 exp_op_type op; /* Type of operation to decode for this signal */ 00066 00067 /* 00068 If we are a concatenation, parse arguments of concatenation as signal names 00069 in a comma-separated list. 00070 */ 00071 if( **arg == '{' ) { 00072 00073 /* Get first state */ 00074 while( (**arg != '}') && !error ) { 00075 if( ((expl != NULL) && (**arg == ',')) || (**arg == '{') ) { 00076 (*arg)++; 00077 } 00078 if( (sig = vsignal_from_string( arg )) != NULL ) { 00079 00080 Try { 00081 00082 if( sig->value->width == 0 ) { 00083 00084 expr = expression_create( NULL, NULL, EXP_OP_SIG, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00085 curr_expr_id++; 00086 fsm_var_bind_add( sig->name, expr, funit_name ); 00087 00088 } else if( sig->value->width == 1 ) { 00089 00090 expr = expression_create( NULL, NULL, EXP_OP_STATIC, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00091 curr_expr_id++; 00092 vector_dealloc( expr->value ); 00093 expr->value = vector_create( 32, VTYPE_VAL, VDATA_UL, TRUE ); 00094 (void)vector_from_int( expr->value, sig->dim[0].lsb ); 00095 00096 expr = expression_create( NULL, expr, EXP_OP_SBIT_SEL, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00097 curr_expr_id++; 00098 fsm_var_bind_add( sig->name, expr, funit_name ); 00099 00100 } else { 00101 00102 expt = expression_create( NULL, NULL, EXP_OP_STATIC, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00103 curr_expr_id++; 00104 vector_dealloc( expt->value ); 00105 expt->value = vector_create( 32, VTYPE_VAL, VDATA_UL, TRUE ); 00106 (void)vector_from_int( expt->value, sig->dim[0].lsb ); 00107 00108 expr = expression_create( NULL, NULL, EXP_OP_STATIC, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00109 curr_expr_id++; 00110 vector_dealloc( expr->value ); 00111 expr->value = vector_create( 32, VTYPE_VAL, VDATA_UL, TRUE ); 00112 (void)vector_from_int( expr->value, ((sig->value->width - 1) + sig->dim[0].lsb) ); 00113 00114 switch( sig->suppl.part.type ) { 00115 case SSUPPL_TYPE_IMPLICIT : op = EXP_OP_MBIT_SEL; break; 00116 case SSUPPL_TYPE_IMPLICIT_POS : op = EXP_OP_MBIT_POS; break; 00117 case SSUPPL_TYPE_IMPLICIT_NEG : op = EXP_OP_MBIT_NEG; break; 00118 default : assert( 0 ); break; 00119 } 00120 expr = expression_create( expt, expr, op, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00121 curr_expr_id++; 00122 fsm_var_bind_add( sig->name, expr, funit_name ); 00123 00124 } 00125 00126 if( expl != NULL ) { 00127 expl = expression_create( expr, expl, EXP_OP_LIST, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00128 curr_expr_id++; 00129 } else { 00130 expl = expr; 00131 } 00132 00133 } Catch_anonymous { 00134 vsignal_dealloc( sig ); 00135 expression_dealloc( expr, FALSE ); 00136 Throw 0; 00137 } 00138 00139 /* Deallocate signal */ 00140 vsignal_dealloc( sig ); 00141 00142 } else { 00143 expression_dealloc( expl, FALSE ); 00144 error = TRUE; 00145 } 00146 } 00147 if( !error ) { 00148 (*arg)++; 00149 expl = expression_create( expl, NULL, EXP_OP_CONCAT, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00150 curr_expr_id++; 00151 } 00152 00153 } else { 00154 00155 if( (sig = vsignal_from_string( arg )) != NULL ) { 00156 00157 Try { 00158 00159 if( sig->value->width == 0 ) { 00160 00161 expl = expression_create( NULL, NULL, EXP_OP_SIG, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00162 curr_expr_id++; 00163 00164 } else if( sig->value->width == 1 ) { 00165 00166 expr = expression_create( NULL, NULL, EXP_OP_STATIC, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00167 curr_expr_id++; 00168 vector_dealloc( expr->value ); 00169 expr->value = vector_create( 32, VTYPE_VAL, VDATA_UL, TRUE ); 00170 (void)vector_from_int( expr->value, sig->dim[0].lsb ); 00171 00172 expl = expression_create( NULL, expr, EXP_OP_SBIT_SEL, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00173 curr_expr_id++; 00174 00175 } else { 00176 00177 expt = expression_create( NULL, NULL, EXP_OP_STATIC, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00178 curr_expr_id++; 00179 vector_dealloc( expt->value ); 00180 expt->value = vector_create( 32, VTYPE_VAL, VDATA_UL, TRUE ); 00181 (void)vector_from_int( expt->value, sig->dim[0].lsb ); 00182 00183 expr = expression_create( NULL, NULL, EXP_OP_STATIC, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00184 curr_expr_id++; 00185 vector_dealloc( expr->value ); 00186 expr->value = vector_create( 32, VTYPE_VAL, VDATA_UL, TRUE ); 00187 (void)vector_from_int( expr->value, ((sig->value->width - 1) + sig->dim[0].lsb) ); 00188 00189 switch( sig->suppl.part.type ) { 00190 case SSUPPL_TYPE_IMPLICIT : op = EXP_OP_MBIT_SEL; break; 00191 case SSUPPL_TYPE_IMPLICIT_POS : op = EXP_OP_MBIT_POS; break; 00192 case SSUPPL_TYPE_IMPLICIT_NEG : op = EXP_OP_MBIT_NEG; break; 00193 default : assert( 0 ); break; 00194 } 00195 00196 expl = expression_create( expt, expr, op, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00197 curr_expr_id++; 00198 00199 } 00200 00201 /* Add signal name and expression to FSM var binding list */ 00202 fsm_var_bind_add( sig->name, expl, funit_name ); 00203 00204 } Catch_anonymous { 00205 vsignal_dealloc( sig ); 00206 expression_dealloc( expl, FALSE ); 00207 Throw 0; 00208 } 00209 00210 /* Deallocate signal */ 00211 vsignal_dealloc( sig ); 00212 00213 } else { 00214 error = TRUE; 00215 } 00216 00217 } 00218 00219 /* Create statement for top-level expression, this statement will work like a continuous assignment */ 00220 if( !error ) { 00221 stmt = statement_create( expl, NULL, 0 ); 00222 stmt->suppl.part.head = 1; 00223 stmt->suppl.part.stop_true = 1; 00224 stmt->suppl.part.stop_false = 1; 00225 stmt->suppl.part.cont = 1; 00226 stmt->next_true = stmt; 00227 stmt->next_false = stmt; 00228 fsm_var_stmt_add( stmt, funit_name ); 00229 } else { 00230 expl = NULL; 00231 } 00232 00233 PROFILE_END; 00234 00235 return( expl ); 00236 00237 }
static void fsm_arg_parse_trans | ( | expression * | expr, | |
fsm * | table, | |||
const func_unit * | funit | |||
) | [static] |
anonymous | Throw |
expr | Pointer to expression containing string value in vector value array | |
table | Pointer to FSM table to add the transition arcs to | |
funit | Pointer to the functional unit that contains the specified FSM |
References Catch_anonymous, ESUPPL_STATIC_BASE, FALSE, FATAL, func_unit_s::filename, free_safe, fsm_add_arc(), fsm_arg_parse_value(), expression_s::line, obf_file, print_output(), PROFILE, PROFILE_END, expression_s::suppl, Throw, Try, user_msg, USER_MSG_LENGTH, expression_s::value, and vector_to_string().
Referenced by fsm_arg_parse_attr().
00527 { PROFILE(FSM_ARG_PARSE_TRANS); 00528 00529 expression* from_state; /* Pointer to from_state value of transition */ 00530 expression* to_state; /* Pointer to to_state value of transition */ 00531 char* str; /* String version of expression value */ 00532 char* tmp; /* Temporary pointer to string */ 00533 00534 assert( expr != NULL ); 00535 00536 /* Convert expression value to a string */ 00537 tmp = str = vector_to_string( expr->value, ESUPPL_STATIC_BASE( expr->suppl ), FALSE, 0 ); 00538 00539 Try { 00540 00541 if( (from_state = fsm_arg_parse_value( &str, funit )) == NULL ) { 00542 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Left-hand side FSM transition value must be a constant value or parameter, line: %d, file: %s", 00543 expr->line, obf_file( funit->filename ) ); 00544 assert( rv < USER_MSG_LENGTH ); 00545 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00546 Throw 0; 00547 } else { 00548 00549 if( (str[0] != '-') || (str[1] != '>') ) { 00550 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "FSM transition values must contain the string '->' between them, line: %d, file: %s", 00551 expr->line, obf_file( funit->filename ) ); 00552 assert( rv < USER_MSG_LENGTH ); 00553 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00554 Throw 0; 00555 } else { 00556 str += 2; 00557 } 00558 00559 if( (to_state = fsm_arg_parse_value( &str, funit )) == NULL ) { 00560 unsigned int rv = snprintf( user_msg, USER_MSG_LENGTH, "Right-hand side FSM transition value must be a constant value or parameter, line: %d, file: %s", 00561 expr->line, obf_file( funit->filename ) ); 00562 assert( rv < USER_MSG_LENGTH ); 00563 print_output( user_msg, FATAL, __FILE__, __LINE__ ); 00564 Throw 0; 00565 } else { 00566 00567 /* Add both expressions to FSM arc list */ 00568 fsm_add_arc( table, from_state, to_state ); 00569 00570 } 00571 00572 } 00573 00574 } Catch_anonymous { 00575 free_safe( tmp, (strlen( tmp ) + 1) ); 00576 Throw 0; 00577 } 00578 00579 /* Deallocate string */ 00580 free_safe( tmp, (strlen( tmp ) + 1) ); 00581 00582 PROFILE_END; 00583 00584 }
static expression* fsm_arg_parse_value | ( | char ** | str, | |
const func_unit * | funit | |||
) | [static] |
anonymous | Throw expression_create expression_create expression_create expression_create expression_create expression_create expression_create expression_create expression_create expression_create expression_create expression_create expression_create |
Parses specified string value for a parameter or constant value. If the string is parsed correctly, a new expression is created to hold the contents of the parsed value and is returned to the calling function. If the string is not parsed correctly, a value of NULL is returned to the calling function.
str | Pointer to string containing parameter or constant value | |
funit | Pointer to functional unit containing this FSM |
References Catch_anonymous, curr_expr_id, mod_parm_s::exp_head, exp_link_add(), EXP_OP_PARAM, EXP_OP_PARAM_MBIT, EXP_OP_PARAM_MBIT_NEG, EXP_OP_PARAM_MBIT_POS, EXP_OP_PARAM_SBIT, EXP_OP_STATIC, mod_parm_s::exp_tail, expression_create(), expression_dealloc(), FALSE, mod_parm_find(), func_unit_s::param_head, PROFILE, PROFILE_END, Throw, TRUE, Try, expression_s::value, VDATA_UL, vector_create(), vector_dealloc(), vector_from_int(), vector_from_string(), and VTYPE_VAL.
Referenced by fsm_arg_parse_trans().
00328 { PROFILE(FSM_ARG_PARSE_VALUE); 00329 00330 expression* expr = NULL; /* Pointer to expression containing state value */ 00331 expression* left; /* Left child expression */ 00332 expression* right = NULL; /* Right child expression */ 00333 vector* vec; /* Pointer to newly allocated vector value */ 00334 int base; /* Base of parsed string value */ 00335 char str_val[256]; /* String version of value parsed */ 00336 int msb; /* Most-significant bit position of parameter */ 00337 int lsb; /* Least-significant bit position of parameter */ 00338 int chars_read; /* Number of characters read from sscanf() */ 00339 mod_parm* mparm; /* Pointer to module parameter found */ 00340 00341 vector_from_string( str, FALSE, &vec, &base ); 00342 00343 if( vec != NULL ) { 00344 00345 /* This value represents a static value, handle as such */ 00346 Try { 00347 expr = expression_create( NULL, NULL, EXP_OP_STATIC, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00348 } Catch_anonymous { 00349 vector_dealloc( vec ); 00350 Throw 0; 00351 } 00352 curr_expr_id++; 00353 00354 vector_dealloc( expr->value ); 00355 expr->value = vec; 00356 00357 } else { 00358 00359 /* This value should be a parameter value, parse it */ 00360 if( sscanf( *str, "%[a-zA-Z0-9_]\[%d:%d]%n", str_val, &msb, &lsb, &chars_read ) == 3 ) { 00361 *str = *str + chars_read; 00362 if( (mparm = mod_parm_find( str_val, funit->param_head )) != NULL ) { 00363 00364 /* Generate left child expression */ 00365 left = expression_create( NULL, NULL, EXP_OP_STATIC, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00366 curr_expr_id++; 00367 vector_dealloc( left->value ); 00368 left->value = vector_create( 32, VTYPE_VAL, VDATA_UL, TRUE ); 00369 (void)vector_from_int( left->value, msb ); 00370 00371 /* Generate right child expression */ 00372 Try { 00373 right = expression_create( NULL, NULL, EXP_OP_STATIC, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00374 } Catch_anonymous { 00375 expression_dealloc( left, FALSE ); 00376 Throw 0; 00377 } 00378 curr_expr_id++; 00379 vector_dealloc( right->value ); 00380 right->value = vector_create( 32, VTYPE_VAL, VDATA_UL, TRUE ); 00381 (void)vector_from_int( right->value, lsb ); 00382 00383 /* Generate multi-bit parameter expression */ 00384 Try { 00385 expr = expression_create( right, left, EXP_OP_PARAM_MBIT, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00386 } Catch_anonymous { 00387 expression_dealloc( left, FALSE ); 00388 expression_dealloc( right, FALSE ); 00389 Throw 0; 00390 } 00391 curr_expr_id++; 00392 exp_link_add( expr, &(mparm->exp_head), &(mparm->exp_tail) ); 00393 00394 } 00395 } else if( sscanf( *str, "%[a-zA-Z0-9_]\[%d+:%d]%n", str_val, &msb, &lsb, &chars_read ) == 3 ) { 00396 *str = *str + chars_read; 00397 if( (mparm = mod_parm_find( str_val, funit->param_head )) != NULL ) { 00398 00399 /* Generate left child expression */ 00400 left = expression_create( NULL, NULL, EXP_OP_STATIC, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00401 curr_expr_id++; 00402 vector_dealloc( left->value ); 00403 left->value = vector_create( 32, VTYPE_VAL, VDATA_UL, TRUE ); 00404 (void)vector_from_int( left->value, msb ); 00405 00406 /* Generate right child expression */ 00407 Try { 00408 right = expression_create( NULL, NULL, EXP_OP_STATIC, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00409 } Catch_anonymous { 00410 expression_dealloc( left, FALSE ); 00411 Throw 0; 00412 } 00413 curr_expr_id++; 00414 vector_dealloc( right->value ); 00415 right->value = vector_create( 32, VTYPE_VAL, VDATA_UL, TRUE ); 00416 (void)vector_from_int( right->value, lsb ); 00417 00418 /* Generate variable positive multi-bit parameter expression */ 00419 Try { 00420 expr = expression_create( right, left, EXP_OP_PARAM_MBIT_POS, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00421 } Catch_anonymous { 00422 expression_dealloc( left, FALSE ); 00423 expression_dealloc( right, FALSE ); 00424 Throw 0; 00425 } 00426 curr_expr_id++; 00427 exp_link_add( expr, &(mparm->exp_head), &(mparm->exp_tail) ); 00428 00429 } 00430 } else if( sscanf( *str, "%[a-zA-Z0-9_]\[%d-:%d]%n", str_val, &msb, &lsb, &chars_read ) == 3 ) { 00431 *str = *str + chars_read; 00432 if( (mparm = mod_parm_find( str_val, funit->param_head )) != NULL ) { 00433 00434 /* Generate left child expression */ 00435 left = expression_create( NULL, NULL, EXP_OP_STATIC, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00436 curr_expr_id++; 00437 vector_dealloc( left->value ); 00438 left->value = vector_create( 32, VTYPE_VAL, VDATA_UL, TRUE ); 00439 (void)vector_from_int( left->value, msb ); 00440 00441 /* Generate right child expression */ 00442 Try { 00443 right = expression_create( NULL, NULL, EXP_OP_STATIC, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00444 } Catch_anonymous { 00445 expression_dealloc( left, FALSE ); 00446 Throw 0; 00447 } 00448 curr_expr_id++; 00449 vector_dealloc( right->value ); 00450 right->value = vector_create( 32, VTYPE_VAL, VDATA_UL, TRUE ); 00451 (void)vector_from_int( right->value, lsb ); 00452 00453 /* Generate variable positive multi-bit parameter expression */ 00454 Try { 00455 expr = expression_create( right, left, EXP_OP_PARAM_MBIT_NEG, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00456 } Catch_anonymous { 00457 expression_dealloc( left, FALSE ); 00458 expression_dealloc( right, FALSE ); 00459 Throw 0; 00460 } 00461 curr_expr_id++; 00462 exp_link_add( expr, &(mparm->exp_head), &(mparm->exp_tail) ); 00463 00464 } 00465 } else if( sscanf( *str, "%[a-zA-Z0-9_]\[%d]%n", str_val, &lsb, &chars_read ) == 2 ) { 00466 *str = *str + chars_read; 00467 if( (mparm = mod_parm_find( str_val, funit->param_head )) != NULL ) { 00468 00469 /* Generate left child expression */ 00470 left = expression_create( NULL, NULL, EXP_OP_STATIC, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00471 curr_expr_id++; 00472 vector_dealloc( left->value ); 00473 left->value = vector_create( 32, VTYPE_VAL, VDATA_UL, TRUE ); 00474 (void)vector_from_int( left->value, lsb ); 00475 00476 /* Generate single-bit parameter expression */ 00477 Try { 00478 expr = expression_create( NULL, left, EXP_OP_PARAM_SBIT, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00479 } Catch_anonymous { 00480 expression_dealloc( left, FALSE ); 00481 Throw 0; 00482 } 00483 curr_expr_id++; 00484 exp_link_add( expr, &(mparm->exp_head), &(mparm->exp_tail) ); 00485 00486 } 00487 } else if( sscanf( *str, "%[a-zA-Z0-9_]%n", str_val, &chars_read ) == 1 ) { 00488 *str = *str + chars_read; 00489 if( (mparm = mod_parm_find( str_val, funit->param_head )) != NULL ) { 00490 00491 /* Generate parameter expression */ 00492 expr = expression_create( NULL, NULL, EXP_OP_PARAM, FALSE, curr_expr_id, 0, 0, 0, FALSE ); 00493 curr_expr_id++; 00494 exp_link_add( expr, &(mparm->exp_head), &(mparm->exp_tail) ); 00495 00496 } 00497 } else { 00498 expr = NULL; 00499 } 00500 00501 } 00502 00503 PROFILE_END; 00504 00505 return( expr ); 00506 00507 }
int curr_expr_id |
This static value contains the current expression ID number to use for the next expression found, it is incremented by one when an expression is found. This allows us to have a unique expression ID for each expression (since expressions have no intrinsic names).
char user_msg[USER_MSG_LENGTH] |
Holds some output that will be displayed via the print_output command. This is created globally so that memory does not need to be reallocated for each function that wishes to use it.