#include "mrilib.h"
static int nerr=0 ;
int SYM_expand_errcount(void){ return nerr; } /* 03 May 2007 */
/*----------------------------------------------------------------------------*/
/*! Expand a string like "Fred 2*Jed -Ned[1..3]" into a float vector.
Each SYM_irange struct has 4 fields
- name = string that names this field
- nbot,ntop = range of indexes valid for this name (nbot <= ntop, please)
- gbot = global index that maps to nbot
The set of structs in rang[] should collectively span global indexes
from 0..nlast (inclusive). The returned floatvec will have nlast+1 entries.
------------------------------------------------------------------------------*/
floatvecvec * SYM_expand_ranges( int nlast, int nrang, SYM_irange *rang, char *str )
{
floatvec *fv ;
floatvecvec *fvv=NULL ;
int rr , ii , ss , gg, *qlist , nvec=0 , iv ;
NI_str_array *sar ;
char qname[64] , *qstr , *qpt , *qls ;
float fac ;
ENTRY("SYM_expand_ranges") ;
if( nlast < 0 ) RETURN(NULL) ; /* bad input */
/* check if have anything to scan for */
if( nrang < 1 || rang == NULL || str == NULL || *str == '\0' ) RETURN(NULL) ;
/* check if input line is a comment */
for( ii=0 ; str[ii] != '\0' && isspace(str[ii]) ; ii++ ) ; /*nada*/
if( str[ii] == '\0' || /* all blank */
str[ii] == '#' || /* starts with "#" */
(str[ii] == '/' && str[ii+1] == '/') /* starts with "//" */
) RETURN(NULL) ;
fv = (floatvec *)malloc(sizeof(floatvec)) ; /* create empty output */
fv->nar = nlast+1 ;
fv->ar = (float *)calloc(sizeof(float),nlast+1) ;
/* break input string into separate chunks */
sar = NI_decode_string_list( str , "~" ) ;
if( sar == NULL ){
fvv = (floatvecvec *)malloc(sizeof(floatvecvec)) ;
fvv->nvec = 1 ;
fvv->fvar = fv ;
ERROR_message("empty line in -gltsym?") ; nerr++ ;
RETURN(fvv) ;
}
/* scan each chunk */
for( ss=0 ; ss < sar->num ; ss++ ){
qstr = sar->str[ss] ;
if( qstr == NULL || *qstr == '\0' ) continue ; /* bad entry? */
if( *qstr == '#' || /* comment ends line */
(*qstr == '/' && *(qstr+1) == '/') ) break ;
qstr = strdup(sar->str[ss]) ; /* duplicate for surgery */
qls = strchr(qstr,'[') ; /* find and decode "[...]" subscripts */
qlist = NULL ; /* if they are present, that is */
if( qls != NULL ){
*qls = '\0' ; /* cut string off at '[' subscripts */
qls++ ; /* will scan for intlist starting here */
}
qpt = strchr(qstr,'*') ; /* find and decode factor in front */
if( qpt != NULL ){ /* if it is present, that is */
fac = (float)strtod(qstr,NULL) ;
if( fac == 0.0 && *qstr != '0' ) fac = 1.0 ;
qpt++ ;
} else if( *qstr == '+' ){ /* "+" is same as "+1.0*" */
qpt = qstr+1 ; fac = 1.0 ;
} else if( *qstr == '-' ){ /* "-" is same as "-1.0*" */
qpt = qstr+1 ; fac = -1.0 ;
} else { /* default is "+" */
qpt = qstr ; fac = 1.0 ;
}
for( rr=0 ; rr < nrang ; rr++ ) /* match name in list */
if( strcmp(qpt,rang[rr].name) == 0 ) break ;
if( rr == nrang ){ /* no match!? */
ERROR_message("-gltsym: can't match symbolic name '%s'\n",qpt) ;
nerr++ ; free((void *)qstr) ; continue ;
}
/* now scan for intlist, if present */
if( qls != NULL ){
MCW_intlist_allow_negative( (rang[rr].nbot < 0) ) ;
qlist = MCW_get_intlist( rang[rr].ntop+1 , qls ) ;
if( qlist != NULL && *qls == '[' ){ /** [[...]] type of subscript **/
if( nvec == 0 ){
nvec = qlist[0] ;
fvv = (floatvecvec *)malloc(sizeof(floatvecvec)) ;
fvv->nvec = nvec ;
fvv->fvar = (floatvec *)calloc(sizeof(floatvec),nvec) ;
for( iv=0 ; iv < nvec ; iv++ ){
fvv->fvar[iv].nar = nlast+1 ;
fvv->fvar[iv].ar = (float *)calloc(sizeof(float),nlast+1) ;
}
} else if( qlist[0] != nvec ){
ERROR_message("mismatch in use of -gltsym [[...]]: '%s'\n",
sar->str[ss] ) ;
nerr++ ;free((void *)qlist) ; free((void *)qstr) ;
continue ;
}
for( iv=0 ; iv < nvec ; iv++ ){
gg = qlist[iv+1] - rang[rr].nbot + rang[rr].gbot ;
if( gg >= 0 && gg <= nlast ) fvv->fvar[iv].ar[gg] = fac ;
}
free((void *)qlist) ; free((void *)qstr) ;
continue ; /** skip to next one, since this was special **/
}
}
/* make up a fake list, if needed */
if( qlist == NULL ){
qlist = (int *)malloc(sizeof(int)*(rang[rr].ntop-rang[rr].nbot+2)) ;
qlist[0] = rang[rr].ntop-rang[rr].nbot+1 ;
for( ii=0 ; ii < qlist[0] ; ii++ ) qlist[ii+1] = rang[rr].nbot+ii ;
}
/* insert values into output list */
for( ii=0 ; ii < qlist[0] ; ii++ ){
if( qlist[ii+1] < rang[rr].nbot || qlist[ii+1] > rang[rr].ntop ){
ERROR_message("-gltsym subscript %s[%d] out of range %d..%d\n",
rang[rr].name , qlist[ii+1] , rang[rr].nbot,rang[rr].ntop ) ;
nerr++ ; continue ;
}
gg = qlist[ii+1] - rang[rr].nbot + rang[rr].gbot ;
if( gg >= 0 && gg <= nlast ) fv->ar[gg] = fac ;
}
free((void *)qlist) ; free((void *)qstr) ;
}
MCW_intlist_allow_negative(0) ;
NI_delete_str_array(sar);
/* if had no [[...]] subscripts, only have 1 vector for output */
if( nvec == 0 ){
fvv = (floatvecvec *)malloc(sizeof(floatvecvec)) ;
fvv->nvec = 1 ;
fvv->fvar = fv ;
} else { /* have multiple outputs */
for( iv=0 ; iv < nvec ; iv++ ){
for( gg=0 ; gg <= nlast ; gg++ ){
if( fvv->fvar[iv].ar[gg] == 0.0f ) fvv->fvar[iv].ar[gg] = fv->ar[gg] ;
}
}
KILL_floatvec(fv) ;
}
RETURN(fvv) ;
}
syntax highlighted by Code2HTML, v. 0.9.1