Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

thd_intlist.c

Go to the documentation of this file.
00001 /*****************************************************************************
00002    Major portions of this software are copyrighted by the Medical College
00003    of Wisconsin, 1994-2000, and are released under the Gnu General Public
00004    License, Version 2.  See the file README.Copyright for details.
00005 ******************************************************************************/
00006 
00007 #include "mrilib.h"
00008 
00009 static int allow_negative = 0 ;
00010 
00011 /*! Allow negative indexes in MCW_get_intlist() */
00012 
00013 void MCW_intlist_allow_negative( int iii )   /* 22 Nov 1999 */
00014 {
00015    allow_negative = iii ; return ;
00016 }
00017 
00018 /*! Stopping criterion for MCW_get_intlist() */
00019 
00020 #define ISEND(c) ( (c)==']' || (c)=='}' || (c)=='\0' )
00021 
00022 /*-----------------------------------------------------------------*/
00023 /*! Get an integer list in the range 0..(nvals-1), from the
00024    character string str.  If we call the output pointer fred,
00025    then fred[0] = number of integers in the list (> 0), and
00026         fred[i] = i-th integer in the list for i=1..fred[0].
00027    If on return, fred == NULL or fred[0] == 0, then something is
00028    wrong, and the caller must deal with that.
00029 
00030    Syntax of input string:
00031      - initial '{' or '[' is skipped, if present
00032      - ends when '}' or ']' or end of string is found
00033      - contains entries separated by commas
00034      - entries have one of these forms:
00035        - a single number
00036        - a dollar sign '$', which means nvals-1
00037        - a sequence of consecutive numbers in the form "a..b" or
00038          "a-b", where "a" and "b" are single numbers (or '$')
00039        - a sequence of evenly spaced numbers in the form
00040          "a..b(c)" or "a-b(c)", where "c" encodes the step
00041      - Example:  "[2,7..4,3..9(2)]" decodes to the list
00042          2 7 6 5 4 3 5 7 9
00043      - entries should be in the range 0..nvals-1
00044 -------------------------------------------------------------------*/
00045 
00046 int * MCW_get_intlist( int nvals , char *str )
00047 {
00048    int *subv = NULL ;
00049    int ii , ipos , nout , slen ;
00050    int ibot,itop,istep , nused ;
00051    char *cpt ;
00052 
00053    /* Meaningless input? */
00054 
00055    if( nvals < 1 ) return NULL ;
00056 
00057    /* No selection list? */
00058 
00059    if( str == NULL || str[0] == '\0' ) return NULL ;
00060 
00061    /* skip initial '[' or '{' */
00062 
00063    subv    = (int *) malloc( sizeof(int) * 2 ) ;
00064    subv[0] = nout = 0 ;
00065 
00066    ipos = 0 ;
00067    if( str[ipos] == '[' || str[ipos] == '{' ) ipos++ ;
00068 
00069    /*** loop through each sub-selector until end of input ***/
00070 
00071    slen = strlen(str) ;
00072    while( ipos < slen && !ISEND(str[ipos]) ){
00073 
00074       while( isspace(str[ipos]) ) ipos++ ;   /* skip blanks */
00075       if( ISEND(str[ipos]) ) break ;         /* done */
00076 
00077       /** get starting value **/
00078 
00079       if( str[ipos] == '$' ){  /* special case */
00080          ibot = nvals-1 ; ipos++ ;
00081       } else {                 /* decode an integer */
00082          ibot = strtol( str+ipos , &cpt , 10 ) ;
00083          if( ibot < 0 && !allow_negative ){
00084            fprintf(stderr,"** ERROR: sub-brick index %d is out of range 0..%d\n",
00085                    ibot,nvals-1) ;
00086            free(subv) ; return NULL ;
00087          }
00088          if( ibot >= nvals ){
00089            fprintf(stderr,"** ERROR: sub-brick index %d is out of range 0..%d\n",
00090                    ibot,nvals-1) ;
00091            free(subv) ; return NULL ;
00092          }
00093          nused = (cpt-(str+ipos)) ;
00094          if( ibot == 0 && nused == 0 ){
00095            fprintf(stderr,"** ERROR: sub-brick syntax error '%s'\n",str+ipos) ;
00096            free(subv) ; return NULL ;
00097          }
00098          ipos += nused ;
00099       }
00100 
00101       while( isspace(str[ipos]) ) ipos++ ;   /* skip blanks */
00102 
00103       /** if that's it for this sub-selector, add one value to list **/
00104 
00105       if( str[ipos] == ',' || ISEND(str[ipos]) ){
00106          nout++ ;
00107          subv = (int *) realloc( (char *)subv , sizeof(int) * (nout+1) ) ;
00108          subv[0]    = nout ;
00109          subv[nout] = ibot ;
00110          if( ISEND(str[ipos]) ) break ; /* done */
00111          ipos++ ; continue ;            /* re-start loop at next sub-selector */
00112       }
00113 
00114       /** otherwise, must have '..' or '-' as next inputs **/
00115 
00116       if( str[ipos] == '-' ){
00117          ipos++ ;
00118       } else if( str[ipos] == '.' && str[ipos+1] == '.' ){
00119          ipos++ ; ipos++ ;
00120       } else {
00121          fprintf(stderr,"** ERROR: sub-brick selector syntax is bad: '%s'\n",
00122                  str+ipos) ;
00123          free(subv) ; return NULL ;
00124       }
00125 
00126       /** get ending value for loop now **/
00127 
00128       if( str[ipos] == '$' ){  /* special case */
00129          itop = nvals-1 ; ipos++ ;
00130       } else {                 /* decode an integer */
00131          itop = strtol( str+ipos , &cpt , 10 ) ;
00132          if( itop < 0 && !allow_negative ){
00133            fprintf(stderr,"** ERROR: sub-brick index %d is out of range 0..%d\n",
00134                    itop,nvals-1) ;
00135            free(subv) ; return NULL ;
00136          }
00137          if( itop >= nvals ){
00138            fprintf(stderr,"** ERROR: sub-brick index %d is out of range 0..%d\n",
00139                    itop,nvals-1) ;
00140            free(subv) ; return NULL ;
00141          }
00142          nused = (cpt-(str+ipos)) ;
00143          if( itop == 0 && nused == 0 ){
00144            fprintf(stderr,"** ERROR: sub-brick syntax error '%s'\n",str+ipos) ;
00145            free(subv) ; return NULL ;
00146          }
00147          ipos += nused ;
00148       }
00149 
00150       /** set default loop step **/
00151 
00152       istep = (ibot <= itop) ? 1 : -1 ;
00153 
00154       while( isspace(str[ipos]) ) ipos++ ;                  /* skip blanks */
00155 
00156       /** check if we have a non-default loop step **/
00157 
00158       if( str[ipos] == '(' ){  /* decode an integer */
00159          ipos++ ;
00160          istep = strtol( str+ipos , &cpt , 10 ) ;
00161          if( istep == 0 ){
00162            fprintf(stderr,"** ERROR: sub-brick loop step is 0!\n") ;
00163            free(subv) ; return NULL ;
00164          }
00165          nused = (cpt-(str+ipos)) ;
00166          ipos += nused ;
00167          if( str[ipos] == ')' ) ipos++ ;
00168          if( (ibot-itop)*istep > 0 ){
00169            fprintf(stderr,"** WARNING: sub-brick count '%d..%d(%d)' means nothing!\n",
00170                    ibot,itop,istep ) ;
00171          }
00172       }
00173 
00174       /** add values to output **/
00175 
00176       for( ii=ibot ; (ii-itop)*istep <= 0 ; ii += istep ){
00177          nout++ ;
00178          subv = (int *) realloc( (char *)subv , sizeof(int) * (nout+1) ) ;
00179          subv[0]    = nout ;
00180          subv[nout] = ii ;
00181       }
00182 
00183       /** check if we have a comma to skip over **/
00184 
00185       while( isspace(str[ipos]) ) ipos++ ;                  /* skip blanks */
00186       if( str[ipos] == ',' ) ipos++ ;                       /* skip commas */
00187 
00188    }  /* end of loop through selector string */
00189 
00190    if( subv[0] == 0 ){ free(subv); subv = NULL; }
00191    return subv ;
00192 }
 

Powered by Plone

This site conforms to the following standards: