Browse Source

bug 2909730

pre-master-46
h_vogt 17 years ago
parent
commit
974585af8c
  1. 3
      ChangeLog
  2. 220
      src/frontend/inpcom.c

3
ChangeLog

@ -1,3 +1,6 @@
2009-12-11 Holger Vogt
* bug 2909730, patch for parsing expressions applied
2009-12-10 Dietmar Warning
* spicelib/parser/inptree.c: omit some debug printf's

220
src/frontend/inpcom.c

@ -2418,12 +2418,15 @@ inp_do_macro_param_replace( int fcn_number, char *params[] )
while ( ( param_ptr = strstr( search_ptr, func_params[fcn_number][i] ) ) ) {
/* make sure actually have the parameter name */
before = *(param_ptr-1);
if (param_ptr == search_ptr) /* no valid 'before' */
before = '\0';
else
before = *(param_ptr-1);
after = *(param_ptr+strlen(func_params[fcn_number][i]));
if ( !(is_arith_char(before) || isspace(before) || before == ',' || before == '=' || (param_ptr-1) < curr_ptr ) ||
!(is_arith_char(after) || isspace(after) || after == ',' || after == '=' || after == '\0' ) ) {
search_ptr = param_ptr + 1;
continue;
search_ptr = param_ptr + 1;
continue;
}
keep = *param_ptr;
@ -2470,120 +2473,127 @@ inp_do_macro_param_replace( int fcn_number, char *params[] )
static char*
inp_expand_macro_in_str( char *str )
{
int i;
char *c;
char *open_paren_ptr, *close_paren_ptr, *fcn_name, *comma_ptr, *params[1000];
char *curr_ptr, *new_str, *macro_str, *curr_str = NULL;
int num_parens, num_params;
char *orig_ptr = str, *search_ptr = str, *orig_str = strdup(str);
char keep;
int i;
char *c;
char *open_paren_ptr, *close_paren_ptr, *fcn_name, *comma_ptr, *params[1000];
char *curr_ptr, *new_str, *macro_str, *curr_str = NULL;
int num_parens, num_params;
char *orig_ptr = str, *search_ptr = str, *orig_str = strdup(str);
char keep;
while ( ( open_paren_ptr = strstr( search_ptr, "(" ) ) ) {
fcn_name = open_paren_ptr;
if ( open_paren_ptr != search_ptr) {
while ( --fcn_name != search_ptr && (isalnum(*fcn_name) || *fcn_name == '_') );
if ( !isalnum(*fcn_name) && *fcn_name != '_' ) fcn_name++;
}
while ( ( open_paren_ptr = strstr( search_ptr, "(" ) ) ) {
fcn_name = open_paren_ptr - 1;
while ( fcn_name != search_ptr && (isalnum(*fcn_name) || *fcn_name == '_') ) fcn_name--;
if ( fcn_name != search_ptr ) fcn_name++;
*open_paren_ptr = '\0';
close_paren_ptr = NULL;
if ( open_paren_ptr != fcn_name ) {
for ( i = 0; i < num_functions; i++ ) {
if ( strcmp( func_names[i], fcn_name ) == 0 ) {
/* find the closing paren */
close_paren_ptr = NULL;
num_parens = 0;
for ( c = open_paren_ptr + 1; *c && *c != '\0'; c++ ) {
if ( *c == '(' ) num_parens++;
if ( *c == ')' ) {
if ( num_parens != 0 ) num_parens--;
else {
close_paren_ptr = c;
break;
}
}
}
if ( close_paren_ptr == NULL ) {
fprintf( stderr, "ERROR: did not find closing parenthesis for function call in str: %s\n", orig_str );
*open_paren_ptr = '\0';
close_paren_ptr = NULL;
search_ptr = open_paren_ptr + 1;
if ( open_paren_ptr != fcn_name ) {
for ( i = 0; i < num_functions; i++ ) {
if ( strcmp( func_names[i], fcn_name ) == 0 ) {
/* find the closing paren */
close_paren_ptr = NULL;
num_parens = 0;
for ( c = open_paren_ptr + 1; *c && *c != '\0'; c++ ) {
if ( *c == '(' ) num_parens++;
if ( *c == ')' ) {
if ( num_parens != 0 ) num_parens--;
else {
close_paren_ptr = c;
break;
}
}
}
if ( close_paren_ptr == NULL ) {
fprintf( stderr, "ERROR: did not find closing parenthesis for function call in str: %s\n", orig_str );
#ifdef HAS_WINDOWS
winmessage("Fatal error in SPICE");
winmessage("Fatal error in SPICE");
#endif
exit( -1 );
}
*close_paren_ptr = '\0';
/* get the parameters */
curr_ptr = open_paren_ptr+1;
while ( isspace(*curr_ptr) ) curr_ptr++;
num_params = 0;
if ( ciprefix( "v(", curr_ptr ) ) {
// look for any commas and change to ' '
char *str_ptr = curr_ptr;
while ( *str_ptr != '\0' && *str_ptr != ')' ) { if ( *str_ptr == ',' || *str_ptr == '(' ) *str_ptr = ' '; str_ptr++; }
if ( *str_ptr == ')' ) *str_ptr = ' ';
}
while ( ( comma_ptr = strstr( curr_ptr, "," ) ) ) {
while ( isspace(*curr_ptr) ) curr_ptr++;
*comma_ptr = '\0';
params[num_params++] = inp_expand_macro_in_str( strdup( curr_ptr ) );
*comma_ptr = ',';
curr_ptr = comma_ptr+1;
}
while ( isspace(*curr_ptr) ) curr_ptr++;
/* get the last parameter */
params[num_params++] = inp_expand_macro_in_str( strdup( curr_ptr ) );
exit( -1 );
}
*close_paren_ptr = '\0';
if ( num_parameters[i] != num_params ) {
fprintf( stderr, "ERROR: parameter mismatch for function call in str: %s\n", orig_ptr );
/* get the parameters */
curr_ptr = open_paren_ptr+1;
while ( isspace(*curr_ptr) ) curr_ptr++;
num_params = 0;
if ( ciprefix( "v(", curr_ptr ) ) {
// look for any commas and change to ' '
char *str_ptr = curr_ptr;
while ( *str_ptr != '\0' && *str_ptr != ')' ) {
if ( *str_ptr == ',' || *str_ptr == '(' ) *str_ptr = ' '; str_ptr++; }
if ( *str_ptr == ')' ) *str_ptr = ' ';
}
num_parens = 0;
for (comma_ptr = curr_ptr; *comma_ptr && *comma_ptr != '\0'; comma_ptr++) {
if (*comma_ptr == ',' && num_parens == 0) {
while ( isspace(*curr_ptr) ) curr_ptr++;
*comma_ptr = '\0';
params[num_params++] = inp_expand_macro_in_str( strdup( curr_ptr ) );
*comma_ptr = ',';
curr_ptr = comma_ptr+1;
}
if ( *comma_ptr == '(' ) num_parens++;
if ( *comma_ptr == ')' ) num_parens--;
}
while ( isspace(*curr_ptr) ) curr_ptr++;
/* get the last parameter */
params[num_params++] = inp_expand_macro_in_str( strdup( curr_ptr ) );
if ( num_parameters[i] != num_params ) {
fprintf( stderr, "ERROR: parameter mismatch for function call in str: %s\n", orig_ptr );
#ifdef HAS_WINDOWS
winmessage("Fatal error in SPICE");
winmessage("Fatal error in SPICE");
#endif
exit( -1 );
}
exit( -1 );
}
macro_str = inp_do_macro_param_replace( i, params );
keep = *fcn_name;
*fcn_name = '\0';
if ( curr_str == NULL ) {
new_str = tmalloc( strlen(str) + strlen(macro_str) + strlen(close_paren_ptr+1) + 3 );
sprintf( new_str, "%s(%s)", str, macro_str );
curr_str = new_str;
} else {
new_str = tmalloc( strlen(curr_str) + strlen(str) + strlen(macro_str) + strlen(close_paren_ptr+1) + 3 );
sprintf( new_str, "%s%s(%s)", curr_str, str, macro_str );
tfree(curr_str);
curr_str = new_str;
}
macro_str = inp_do_macro_param_replace( i, params );
keep = *fcn_name;
*fcn_name = '\0';
if ( curr_str == NULL ) {
new_str = tmalloc( strlen(str) + strlen(macro_str) + strlen(close_paren_ptr+1) + 3 );
sprintf( new_str, "%s(%s)", str, macro_str );
curr_str = new_str;
} else {
new_str = tmalloc( strlen(curr_str) + strlen(str) + strlen(macro_str) + strlen(close_paren_ptr+1) + 3 );
sprintf( new_str, "%s%s(%s)", curr_str, str, macro_str );
tfree(curr_str);
curr_str = new_str;
}
*fcn_name = keep;
*close_paren_ptr = ')';
*fcn_name = keep;
*close_paren_ptr = ')';
search_ptr = str = close_paren_ptr+1;
break;
} /* if strcmp */
} /* for loop over function names */
}
*open_paren_ptr = '(';
search_ptr = str = close_paren_ptr+1;
break;
} /* if strcmp */
} /* for loop over function names */
}
*open_paren_ptr = '(';
search_ptr = open_paren_ptr + 1;
}
}
if ( curr_str == NULL ) {
curr_str = orig_ptr;
}
else {
if ( str != NULL ) {
new_str = tmalloc( strlen(curr_str) + strlen(str) + 1 );
sprintf( new_str, "%s%s", curr_str, str );
tfree(curr_str);
curr_str = new_str;
}
tfree(orig_ptr);
}
if ( curr_str == NULL ) {
curr_str = orig_ptr;
}
else {
if ( str != NULL ) {
new_str = tmalloc( strlen(curr_str) + strlen(str) + 1 );
sprintf( new_str, "%s%s", curr_str, str );
tfree(curr_str);
curr_str = new_str;
}
tfree(orig_ptr);
}
tfree(orig_str);
tfree(orig_str);
return curr_str;
return curr_str;
}
static void

Loading…
Cancel
Save