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 } |