Doxygen Source Code Documentation
mri_symbolize.c File Reference
#include "mrilib.h"Go to the source code of this file.
Functions | |
| floatvecvec * | SYM_expand_ranges (int nlast, int nrang, SYM_irange *rang, char *str) |
Function Documentation
|
||||||||||||||||||||
|
Expand a string like "Fred 2*Jed -Ned[1..3]" into a float vector. Each SYM_irange struct has 4 fields
Definition at line 15 of file mri_symbolize.c. References floatvec::ar, calloc, ENTRY, free, floatvecvec::fvar, SYM_irange::gbot, KILL_floatvec, malloc, MCW_get_intlist(), MCW_intlist_allow_negative(), name, floatvec::nar, SYM_irange::nbot, NI_decode_string_list(), NI_delete_str_array, SYM_irange::ntop, NI_str_array::num, floatvecvec::nvec, RETURN, NI_str_array::str, and strtod(). Referenced by read_glt_matrix().
00016 {
00017 floatvec *fv ;
00018 floatvecvec *fvv=NULL ;
00019 int rr , ii , ss , gg, *qlist , nvec=0 , iv ;
00020 NI_str_array *sar ;
00021 char qname[64] , *qstr , *qpt , *qls ;
00022 float fac ;
00023
00024 ENTRY("SYM_expand_ranges") ;
00025
00026 if( nlast < 0 ) RETURN(NULL) ; /* bad input */
00027
00028 /* check if have anything to scan for */
00029
00030 if( nrang < 1 || rang == NULL || str == NULL || *str == '\0' ) RETURN(NULL) ;
00031
00032 /* check if input line is a comment */
00033
00034 for( ii=0 ; str[ii] != '\0' && isspace(str[ii]) ; ii++ ) ; /*nada*/
00035
00036 if( str[ii] == '\0' || /* all blank */
00037 str[ii] == '#' || /* starts with "#" */
00038 (str[ii] == '/' && str[ii+1] == '/') /* starts with "//" */
00039 ) RETURN(NULL) ;
00040
00041 fv = (floatvec *)malloc(sizeof(floatvec)) ; /* create empty output */
00042 fv->nar = nlast+1 ;
00043 fv->ar = (float *)calloc(sizeof(float),nlast+1) ;
00044
00045 /* break input string into separate chunks */
00046
00047 sar = NI_decode_string_list( str , "~" ) ;
00048 if( sar == NULL ){
00049 fvv = (floatvecvec *)malloc(sizeof(floatvecvec)) ;
00050 fvv->nvec = 1 ;
00051 fvv->fvar = fv ;
00052 RETURN(fvv) ;
00053 }
00054
00055 /* scan each chunk */
00056
00057 for( ss=0 ; ss < sar->num ; ss++ ){
00058 qstr = sar->str[ss] ;
00059 if( qstr == NULL || *qstr == '\0' ) continue ; /* bad entry? */
00060 if( *qstr == '#' || /* comment ends line */
00061 (*qstr == '/' && *(qstr+1) == '/') ) break ;
00062
00063 qstr = strdup(sar->str[ss]) ; /* duplicate for surgery */
00064 qls = strchr(qstr,'[') ; /* find and decode "[...]" subscripts */
00065 qlist = NULL ; /* if they are present, that is */
00066 if( qls != NULL ){
00067 *qls = '\0' ; /* cut string off at '[' subscripts */
00068 qls++ ; /* will scan for intlist starting here */
00069 }
00070
00071 qpt = strchr(qstr,'*') ; /* find and decode factor in front */
00072 if( qpt != NULL ){ /* if it is present, that is */
00073 fac = (float)strtod(qstr,NULL) ;
00074 if( fac == 0.0 && *qstr != '0' ) fac = 1.0 ;
00075 qpt++ ;
00076 } else if( *qstr == '+' ){ /* "+" is same as "+1.0*" */
00077 qpt = qstr+1 ; fac = 1.0 ;
00078 } else if( *qstr == '-' ){ /* "-" is same as "-1.0*" */
00079 qpt = qstr+1 ; fac = -1.0 ;
00080 } else { /* default is "+" */
00081 qpt = qstr ; fac = 1.0 ;
00082 }
00083
00084 for( rr=0 ; rr < nrang ; rr++ ) /* match name in list */
00085 if( strcmp(qpt,rang[rr].name) == 0 ) break ;
00086 if( rr == nrang ){ /* no match!? */
00087 fprintf(stderr,"** ERROR: can't match symbolic name '%s'\n",qpt) ;
00088 free((void *)qstr) ; continue ;
00089 }
00090 /* now scan for intlist, if present */
00091 if( qls != NULL ){
00092 MCW_intlist_allow_negative( (rang[rr].nbot < 0) ) ;
00093 qlist = MCW_get_intlist( rang[rr].ntop+1 , qls ) ;
00094
00095 if( qlist != NULL && *qls == '[' ){ /** [[...]] type of subscript **/
00096 if( nvec == 0 ){
00097 nvec = qlist[0] ;
00098 fvv = (floatvecvec *)malloc(sizeof(floatvecvec)) ;
00099 fvv->nvec = nvec ;
00100 fvv->fvar = (floatvec *)calloc(sizeof(floatvec),nvec) ;
00101 for( iv=0 ; iv < nvec ; iv++ ){
00102 fvv->fvar[iv].nar = nlast+1 ;
00103 fvv->fvar[iv].ar = (float *)calloc(sizeof(float),nlast+1) ;
00104 }
00105 } else if( qlist[0] != nvec ){
00106 fprintf(stderr,"** ERROR: mismatch in use of -gltsym [[...]]: '%s'\n",
00107 sar->str[ss] ) ;
00108 free((void *)qlist) ; free((void *)qstr) ;
00109 continue ;
00110 }
00111 for( iv=0 ; iv < nvec ; iv++ ){
00112 gg = qlist[iv+1] - rang[rr].nbot + rang[rr].gbot ;
00113 if( gg >= 0 && gg <= nlast ) fvv->fvar[iv].ar[gg] = fac ;
00114 }
00115 free((void *)qlist) ; free((void *)qstr) ;
00116 continue ; /** skip to next one, since this was special **/
00117 }
00118 }
00119 /* make up a fake list, if needed */
00120 if( qlist == NULL ){
00121 qlist = (int *)malloc(sizeof(int)*(rang[rr].ntop-rang[rr].nbot+2)) ;
00122 qlist[0] = rang[rr].ntop-rang[rr].nbot+1 ;
00123 for( ii=0 ; ii < qlist[0] ; ii++ ) qlist[ii+1] = rang[rr].nbot+ii ;
00124 }
00125 /* insert values into output list */
00126
00127 for( ii=0 ; ii < qlist[0] ; ii++ ){
00128 if( qlist[ii+1] < rang[rr].nbot || qlist[ii+1] > rang[rr].ntop ){
00129 fprintf(stderr,"** ERROR: subscript %s[%d] out of range %d..%d\n",
00130 rang[rr].name , qlist[ii+1] , rang[rr].nbot,rang[rr].ntop ) ;
00131 continue ;
00132 }
00133 gg = qlist[ii+1] - rang[rr].nbot + rang[rr].gbot ;
00134 if( gg >= 0 && gg <= nlast ) fv->ar[gg] = fac ;
00135 }
00136
00137 free((void *)qlist) ; free((void *)qstr) ;
00138 }
00139 MCW_intlist_allow_negative(0) ;
00140
00141 NI_delete_str_array(sar);
00142
00143 /* if had no [[...]] subscripts, only have 1 vector for output */
00144
00145 if( nvec == 0 ){
00146 fvv = (floatvecvec *)malloc(sizeof(floatvecvec)) ;
00147 fvv->nvec = 1 ;
00148 fvv->fvar = fv ;
00149 } else { /* have multiple outputs */
00150 for( iv=0 ; iv < nvec ; iv++ ){
00151 for( gg=0 ; gg <= nlast ; gg++ ){
00152 if( fvv->fvar[iv].ar[gg] == 0.0f ) fvv->fvar[iv].ar[gg] = fv->ar[gg] ;
00153 }
00154 }
00155 KILL_floatvec(fv) ;
00156 }
00157
00158 RETURN(fvv) ;
00159 }
|