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  

SUMA_ParseCommands.h

Go to the documentation of this file.
00001 #ifndef SUMA_PARSECOMMANDS_INCLUDED
00002 #define SUMA_PARSECOMMANDS_INCLUDED
00003 
00004 /* structures to be used by most command line programs */
00005 #define SUMA_GENERIC_PROG_MAX_SURF 10  /*!< Maximum number of surfaces allowed*/
00006 typedef struct {
00007    SUMA_SO_File_Type iType;
00008    char *sv_name;
00009    char *surf_names[SUMA_GENERIC_PROG_MAX_SURF];
00010    int N_surf;
00011    char *spec_file;
00012    char *in_name;
00013    char *surftype;
00014    char *out_prefix;   /* this one's dynamically allocated so you'll have to free it yourself */
00015    char *out_vol_prefix; /* this one's dynamically allocated so you'll have to free it yourself */
00016    char out_vol_view[5];
00017    int out_vol_exists;
00018    char *out_grid_prefix; /* this one's dynamically allocated so you'll have to free it yourself */
00019    char out_grid_view[5];
00020    int out_grid_exists;
00021    char *in_vol_prefix; /* this one's dynamically allocated so you'll have to free it yourself */
00022    char in_vol_view[5];
00023    int in_vol_exists;
00024    int MaskMode;
00025    char *cmask;
00026    THD_3dim_dataset *in_vol;
00027    float VolCM[3];   /* input volume's center of mass */
00028    double *mcdatav; /* the dataset that is passed to the marching cube algorithm */
00029    int debug;
00030    int ninmask;
00031    int fix_winding;
00032    float v0;
00033    float v1;
00034    int nvox;
00035    double *dvec;
00036    int obj_type;
00037    int obj_type_res;
00038    int xform;
00039    SUMA_SO_File_Format SurfFileFormat;
00040    SUMA_SO_File_Type SurfFileType;
00041    /* following fields are intended for use in ConvexHull only */
00042    char *in_1D;  /* name of 1D file containing XYZ coords */
00043    float *XYZ; /* a 3*N_XYZ vector of XYZ coordinates. This vector should be freed at the end*/
00044    int N_XYZ;  /* number of points in XYZ */
00045    /* following fields are intended for use in BrainWarp only */
00046    float ExpFrac; /* a fraction (0.01) used to control the rate of expansion of the surface (see su3 variable in SUMA_StretchToFitLeCerveau ) */
00047    float Zt; /* a fraction controlling the separation between brain and non brain, see variable tb in SUMA_StretchToFitLeCerveau ) */
00048    int N_it; /* number of iterations */
00049    int Icold; /* number of Ico subdivisions */
00050    int NodeDbg; /* node to debug */
00051    float t;
00052    float tm;
00053    float t2;
00054    float t98;
00055    float r;
00056    float cog[3];
00057    float d1;
00058    float su1;
00059    float UseNew;
00060    float d4;
00061    float *ztv;
00062    int Kill98;
00063    int NoEyes;
00064    int NNsmooth;
00065    int smootheach;
00066    float avoid_vent;
00067    int smooth_end;
00068    int *k98mask;
00069    int k98maskcnt;
00070    float travstp;
00071    float *Stop;
00072    int MaxIntIter;
00073    int UseExpansion;
00074    float PercInt;
00075    int UseSkull;
00076    float bot_lztclip;
00077    float var_lzt;
00078    int send_hull;
00079    int DemoPause;
00080    int DoSpatNorm;
00081    float SpatNormDxyz;
00082    int WriteSpatNorm;
00083    int fillhole;
00084    THD_3dim_dataset *iset;
00085    FILE *dbg_eyenodes;
00086    float SpatShift[3];
00087    THD_3dim_dataset *OrigSpatNormedSet;   
00088    THD_3dim_dataset *in_edvol;
00089    float blur_fwhm;
00090    int iset_hand;
00091    
00092    int NearestNode;
00093    int NearestTriangle;
00094    int DistanceToMesh;
00095    int ProjectionOnMesh;
00096    int Data;
00097    
00098    char *in_nodeindices;
00099 } SUMA_GENERIC_PROG_OPTIONS_STRUCT;
00100 
00101 #define SUMA_MAX_SURF_ON_COMMAND 100
00102 #define SUMA_N_ARGS_MAX 1000
00103 
00104 typedef struct {
00105    /* spec related input */
00106    char *spec_names[SUMA_MAX_SURF_ON_COMMAND];
00107    int N_spec_names;
00108    
00109    char *s_surfnames[SUMA_MAX_SURF_ON_COMMAND];
00110    char *s_surfprefix[SUMA_MAX_SURF_ON_COMMAND];
00111    char *s_surfpath[SUMA_MAX_SURF_ON_COMMAND];
00112    int s_N_surfnames;
00113    
00114    /* -i_ related input */
00115    char *i_surfnames[SUMA_MAX_SURF_ON_COMMAND];
00116    char *i_surftopo[SUMA_MAX_SURF_ON_COMMAND];
00117    char *i_surfpath[SUMA_MAX_SURF_ON_COMMAND];
00118    char *i_surfprefix[SUMA_MAX_SURF_ON_COMMAND];
00119    char *i_state[SUMA_MAX_SURF_ON_COMMAND];
00120    char *i_group[SUMA_MAX_SURF_ON_COMMAND];
00121    int i_anatomical[SUMA_MAX_SURF_ON_COMMAND];
00122    int i_N_surfnames;
00123    SUMA_SO_File_Format i_FF[SUMA_MAX_SURF_ON_COMMAND];
00124    SUMA_SO_File_Type i_FT[SUMA_MAX_SURF_ON_COMMAND];
00125    
00126    /* -ipar_ related input */
00127    char *ipar_surfnames[SUMA_MAX_SURF_ON_COMMAND];
00128    char *ipar_surftopo[SUMA_MAX_SURF_ON_COMMAND];
00129    char *ipar_surfpath[SUMA_MAX_SURF_ON_COMMAND];
00130    char *ipar_surfprefix[SUMA_MAX_SURF_ON_COMMAND];
00131    char *ipar_state[SUMA_MAX_SURF_ON_COMMAND];
00132    char *ipar_group[SUMA_MAX_SURF_ON_COMMAND];
00133    int ipar_anatomical[SUMA_MAX_SURF_ON_COMMAND];
00134    int ipar_N_surfnames;
00135    SUMA_SO_File_Format ipar_FF[SUMA_MAX_SURF_ON_COMMAND];
00136    SUMA_SO_File_Type ipar_FT[SUMA_MAX_SURF_ON_COMMAND];
00137    
00138    /* -o_related input */
00139    char *o_surfnames[SUMA_MAX_SURF_ON_COMMAND];
00140    char *o_surftopo[SUMA_MAX_SURF_ON_COMMAND];
00141    char *o_surfpath[SUMA_MAX_SURF_ON_COMMAND];
00142    char *o_surfprefix[SUMA_MAX_SURF_ON_COMMAND];
00143    char *o_state[SUMA_MAX_SURF_ON_COMMAND];
00144    char *o_group[SUMA_MAX_SURF_ON_COMMAND];
00145    int o_anatomical[SUMA_MAX_SURF_ON_COMMAND];
00146    int o_N_surfnames;
00147    SUMA_SO_File_Format o_FF[SUMA_MAX_SURF_ON_COMMAND];
00148    SUMA_SO_File_Type o_FT[SUMA_MAX_SURF_ON_COMMAND];
00149    
00150    /* -t_related input */
00151    char *t_surfnames[SUMA_MAX_SURF_ON_COMMAND];
00152    char *t_surftopo[SUMA_MAX_SURF_ON_COMMAND];
00153    char *t_surfpath[SUMA_MAX_SURF_ON_COMMAND];
00154    char *t_surfprefix[SUMA_MAX_SURF_ON_COMMAND];
00155    char *t_state[SUMA_MAX_SURF_ON_COMMAND];
00156    char *t_group[SUMA_MAX_SURF_ON_COMMAND];
00157    int t_anatomical[SUMA_MAX_SURF_ON_COMMAND];
00158    int t_N_surfnames;
00159    SUMA_SO_File_Format t_FF[SUMA_MAX_SURF_ON_COMMAND];
00160    SUMA_SO_File_Type t_FT[SUMA_MAX_SURF_ON_COMMAND];
00161    
00162    byte arg_checked[SUMA_N_ARGS_MAX];
00163    int N_args;
00164    char *sv[SUMA_MAX_SURF_ON_COMMAND];
00165    int N_sv;
00166    char *vp[SUMA_MAX_SURF_ON_COMMAND];
00167    int N_vp;
00168    
00169    /* -talk_suma options */
00170    SUMA_COMM_STRUCT *cs;
00171 
00172    /* flags for what to read */
00173    byte accept_t;
00174    byte accept_s;
00175    byte accept_i;
00176    byte accept_ipar;
00177    byte accept_o;
00178    byte accept_spec;
00179    byte accept_sv;
00180    byte accept_talk_suma;
00181    byte check_input_surf;
00182 } SUMA_GENERIC_ARGV_PARSE;
00183 int  SUMA_GetNextCommand (char *S, char d, char term, char *Scom);
00184 SUMA_Boolean  SUMA_RegisterCommand(char *S, char d, char term, char *Scom, SUMA_Boolean Prepend);
00185 int SUMA_CommandCode(char *Scom);
00186 const char *SUMA_CommandString (SUMA_ENGINE_CODE code);
00187 SUMA_Boolean SUMA_RegisterEngineData (SUMA_EngineData *MTI, char *Fldname, void *FldValp, char *DestName, char *SourceName, SUMA_Boolean PassByPointer);
00188 SUMA_Boolean SUMA_FreeEngineData (SUMA_EngineData *MTI);
00189 SUMA_ENGINE_FIELD_CODE SUMA_EngineFieldCode(char *Scom);
00190 const char *SUMA_EngineFieldString (SUMA_ENGINE_FIELD_CODE i);
00191 SUMA_Boolean SUMA_ReleaseEngineData (SUMA_EngineData *MTI, char *Location);
00192 SUMA_Boolean SUMA_InitializeEngineData (SUMA_EngineData *MTI);
00193 int SUMA_EngineSourceCode (char *Scom);
00194 void SUMA_EngineSourceString (char *Scom, int ses_code);
00195 const char *SUMA_DomainKinships_String (SUMA_DOMAIN_KINSHIPS code);
00196 DList *SUMA_CreateList (void);
00197 SUMA_EngineData *SUMA_InitializeEngineListData (SUMA_ENGINE_CODE CommandCode);
00198 DListElmt * SUMA_RegisterEngineListCommand (DList *list, SUMA_EngineData * EngineData,  
00199                                              SUMA_ENGINE_FIELD_CODE Fld, void *FldValp, 
00200                                              SUMA_ENGINE_SOURCE Src, void *Srcp, SUMA_Boolean PassByPointer, 
00201                                              SUMA_ENGINE_INSERT_LOCATION InsertAt, DListElmt *Element);
00202 SUMA_Boolean SUMA_ReleaseEngineListElement (DList *list, DListElmt *element);
00203 DList * SUMA_DestroyList (DList *list);
00204 DList * SUMA_EmptyDestroyList (DList *list);
00205 void SUMA_FreeEngineListData(void *MTI);
00206 SUMA_ENGINE_CODE SUMA_GetListNextCommand (DList *list);
00207 void SUMA_ShowList (DList *list, FILE *Out);
00208 void SUMA_FreeMessageListData(void *Hv);
00209 SUMA_Boolean SUMA_ReleaseMessageListElement (DList *list, DListElmt *element) ;
00210 DList *SUMA_CreateMessageList (void);
00211 SUMA_Boolean SUMA_RegisterMessage ( DList *list, char *Message, char *Source, SUMA_MESSAGE_TYPES Type, SUMA_MESSAGE_ACTION Action);
00212 char *SUMA_BuildMessageLog (DList *ML);
00213 void SUMA_FreeActionStackData(void *asdata);
00214 DList *SUMA_CreateActionStack (void);
00215 void SUMA_ReleaseActionStackData (void *asdata);
00216 DList *SUMA_EmptyDestroyActionStack (DList *AS);
00217 const char *SUMA_ColMixModeString (SUMA_COL_MIX_MODE mode);
00218 SUMA_SO_File_Type SUMA_SurfaceTypeCode (char *cd);
00219 const char * SUMA_SurfaceTypeString (SUMA_SO_File_Type tp);
00220 SUMA_SO_File_Type SUMA_guess_surftype_argv(char *str);
00221 void *SUMA_strtol_vec(char *op, int nvals, int *nread, SUMA_VARTYPE vtp);
00222 SUMA_GENERIC_ARGV_PARSE *SUMA_CreateGenericArgParse(char *optflags);
00223 SUMA_GENERIC_ARGV_PARSE *SUMA_FreeGenericArgParse(SUMA_GENERIC_ARGV_PARSE *ps);
00224 char *SUMA_help_IO_Args(SUMA_GENERIC_ARGV_PARSE *opt);
00225 SUMA_GENERIC_ARGV_PARSE *SUMA_Parse_IO_Args (int argc, char *argv[], char *optflags);
00226 SUMA_GENERIC_PROG_OPTIONS_STRUCT * SUMA_Alloc_Generic_Prog_Options_Struct(void);
00227 SUMA_GENERIC_PROG_OPTIONS_STRUCT * SUMA_Free_Generic_Prog_Options_Struct(SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt);
00228 void *SUMA_AdvancePastNumbers(char *op, char **opend, SUMA_VARTYPE tp);
00229 
00230 /*!
00231    \brief Macro that adds a command to the head of command list.
00232    SUMA_REGISTER_HEAD_COMMAND_NO_DATA(list, Command, Src, Srcp)
00233 
00234    \param list (DList *) pointer to list 
00235    \param Command (SUMA_ENGINE_CODE) command code
00236    \param Src (SUMA_ENGINE_SOURCE) source of command
00237    \param Srcp (void *) pointer to source pointer. (No need to type cast it yourself, macro will)
00238 
00239    - Expects the variable FuncName (char *) to be defined already (that's the case in all of SUMA's functions)
00240    - No Engine Data can be passed with this macro
00241 
00242 */
00243 #define SUMA_REGISTER_HEAD_COMMAND_NO_DATA(list, Command, Src, Srcp) {\
00244    SUMA_EngineData *ED_macro; \
00245    ED_macro = SUMA_InitializeEngineListData (Command);   \
00246    if (!SUMA_RegisterEngineListCommand (  list, ED_macro, \
00247                                           SEF_Empty, NULL,  \
00248                                           Src, (void *)Srcp, NOPE,   \
00249                                           SEI_Head, NULL)) {   \
00250       fprintf (SUMA_STDERR, "Error %s: Failed to register command.\n", FuncName);   \
00251    }  \
00252 }
00253 
00254 /*!
00255    \brief Macro that adds a command to the tail of command list.
00256    
00257    \sa SUMA_REGISTER_HEAD_COMMAND_NO_DATA
00258 */
00259 #define SUMA_REGISTER_TAIL_COMMAND_NO_DATA(list, Command, Src, Srcp) {\
00260    SUMA_EngineData *ED_macro; \
00261    ED_macro = SUMA_InitializeEngineListData (Command);   \
00262    if (!SUMA_RegisterEngineListCommand (  list, ED_macro, \
00263                                           SEF_Empty, NULL,  \
00264                                           Src, (void *)Srcp, NOPE,   \
00265                                           SEI_Tail, NULL)) {   \
00266       fprintf (SUMA_STDERR, "Error %s: Failed to register command.\n", FuncName);   \
00267    }  \
00268 }
00269 
00270 /*!
00271    \brief Macro that reports an error to the log 
00272 
00273 */
00274 #define SUMA_L_Err(msg) {\
00275    SUMA_RegisterMessage (SUMAg_CF->MessageList, msg, FuncName, SMT_Error, SMA_Log); \
00276 }
00277 /*!
00278    \brief Macro that reports an error to stderr 
00279 
00280 */
00281 #define SUMA_S_Err(msg) {\
00282    fprintf (SUMA_STDERR, "Error %s (%s:%d):\n %s\n", FuncName, __FILE__ , __LINE__, msg);  \
00283 }
00284 /*!
00285    \brief Macro that reports an error to stderr and log 
00286 
00287 */
00288 #define SUMA_SL_Err(msg) {\
00289    SUMA_S_Err(msg);  \
00290    SUMA_L_Err(msg); \
00291 }
00292 /*!
00293    \brief Macro that reports an error to stderr and log and popup
00294 
00295 */
00296 #define SUMA_SLP_Err(msg) {\
00297    SUMA_S_Err(msg);  \
00298    SUMA_RegisterMessage (SUMAg_CF->MessageList, msg, FuncName, SMT_Error, SMA_LogAndPopup); \
00299 }
00300 
00301 /*!
00302    \brief Macro that reports a notice to the log 
00303 
00304 */
00305 #define SUMA_L_Note(msg) {\
00306    SUMA_RegisterMessage (SUMAg_CF->MessageList, msg, FuncName, SMT_Notice, SMA_Log); \
00307 }
00308 /*!
00309    \brief Macro that reports a notice to stderr 
00310 
00311 */
00312 #define SUMA_S_Note(msg) {\
00313    fprintf (SUMA_STDERR, "Notice %s:\n %s\n", FuncName, msg);  \
00314 }
00315 /*!
00316    \brief Macro that reports a notice to stderr and log 
00317 
00318 */
00319 #define SUMA_SL_Note(msg) {\
00320    fprintf (SUMA_STDERR, "Notice %s:\n %s\n", FuncName, msg);  \
00321    SUMA_RegisterMessage (SUMAg_CF->MessageList, msg, FuncName, SMT_Notice, SMA_Log); \
00322 }
00323 /*!
00324    \brief Macro that reports a notice to stderr and log and popup
00325 
00326 */
00327 #define SUMA_SLP_Note(msg) {\
00328    fprintf (SUMA_STDERR, "Notice %s:\n %s\n", FuncName, msg);  \
00329    SUMA_RegisterMessage (SUMAg_CF->MessageList, msg, FuncName, SMT_Notice, SMA_LogAndPopup); \
00330 }
00331 
00332 /*!
00333    \brief Macro that reports a text message to the log 
00334 
00335 */
00336 #define SUMA_L_Text(msg) {\
00337    SUMA_RegisterMessage (SUMAg_CF->MessageList, msg, FuncName, SMT_Text, SMA_Log); \
00338 }
00339 /*!
00340    \brief Macro that reports a text message to stderr 
00341 
00342 */
00343 #define SUMA_S_Text(msg) {\
00344    fprintf (SUMA_STDERR, "%s\n", msg);  \
00345 }
00346 /*!
00347    \brief Macro that reports a text message to stderr and log 
00348 
00349 */
00350 #define SUMA_SL_Text(msg) {\
00351    fprintf (SUMA_STDERR, "%s\n", msg);  \
00352    SUMA_RegisterMessage (SUMAg_CF->MessageList, msg, FuncName, SMT_Text, SMA_Log); \
00353 }
00354 /*!
00355    \brief Macro that reports a text message to stderr and log and popup
00356 
00357 */
00358 #define SUMA_SLP_Text(msg) {\
00359    fprintf (SUMA_STDERR, "%s\n", msg);  \
00360    SUMA_RegisterMessage (SUMAg_CF->MessageList, msg, FuncName, SMT_Text, SMA_LogAndPopup); \
00361 }
00362 
00363 /*!
00364    \brief Macro that reports a warning to the log 
00365 
00366 */
00367 #define SUMA_L_Warn(msg) {\
00368    SUMA_RegisterMessage (SUMAg_CF->MessageList, msg, FuncName, SMT_Warning, SMA_Log); \
00369 }
00370 /*!
00371    \brief Macro that reports a warning to stderr 
00372 
00373 */
00374 #define SUMA_S_Warn(msg) {\
00375    fprintf (SUMA_STDERR, "Warning %s:\n %s\n", FuncName, msg);  \
00376 }
00377 /*!
00378    \brief Macro that reports a warning to stderr and log 
00379 
00380 */
00381 #define SUMA_SL_Warn(msg) {\
00382    fprintf (SUMA_STDERR, "Warning %s:\n %s\n", FuncName, msg);  \
00383    SUMA_RegisterMessage (SUMAg_CF->MessageList, msg, FuncName, SMT_Warning, SMA_Log); \
00384 }
00385 /*!
00386    \brief Macro that reports a warning to stderr and log and popup
00387 
00388 */
00389 #define SUMA_SLP_Warn(msg) {\
00390    fprintf (SUMA_STDERR, "Warning %s:\n %s\n", FuncName, msg);  \
00391    SUMA_RegisterMessage (SUMAg_CF->MessageList, msg, FuncName, SMT_Warning, SMA_LogAndPopup); \
00392 }
00393 
00394 /*!
00395    \brief Macro that reports a critical error to the log 
00396 
00397 */
00398 #define SUMA_L_Crit(msg) {\
00399    SUMA_RegisterMessage (SUMAg_CF->MessageList, msg, FuncName, SMT_Critical, SMA_Log); \
00400 }
00401 /*!
00402    \brief Macro that reports a critical error to stderr 
00403 
00404 */
00405 #define SUMA_S_Crit(msg) {\
00406    fprintf (SUMA_STDERR, "Critical %s:\n %s\n", FuncName, msg);  \
00407 }
00408 /*!
00409    \brief Macro that reports a critical error to stderr and log 
00410 
00411 */
00412 #define SUMA_SL_Crit(msg) {\
00413    fprintf (SUMA_STDERR, "Critical %s:\n %s\n", FuncName, msg);  \
00414    SUMA_RegisterMessage (SUMAg_CF->MessageList, msg, FuncName, SMT_Critical, SMA_Log); \
00415 }
00416 /*!
00417    \brief Macro that reports a critical error to stderr and log and popup
00418 
00419 */
00420 #define SUMA_SLP_Crit(msg) {\
00421    fprintf (SUMA_STDERR, "Critical %s:\n %s\n", FuncName, msg);  \
00422    SUMA_RegisterMessage (SUMAg_CF->MessageList, msg, FuncName, SMT_Critical, SMA_LogAndPopup); \
00423 }
00424 
00425 #define SUMA_BEEP {  \
00426    if (SUMAg_SVv[0].X->TOPLEVEL) XBell (XtDisplay (SUMAg_SVv[0].X->TOPLEVEL), SUMA_BEEP_LENGTH_MS);  \
00427 }
00428 /*!
00429    \brief Macro that reports a message to SUMA_STDERR if LocalHead is set to YUP
00430 */
00431 #define SUMA_LH(msg) {\
00432    if (LocalHead) fprintf (SUMA_STDERR, "%s (%s:%d):\n %s\n", FuncName, __FILE__, __LINE__,msg);  \
00433 }
00434 
00435 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Begin string parsing macros <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
00436 /*! a macro version of C's isspace
00437    returns 1 if charater is considered a blank
00438    \sa SUMA_SKIP_BLANK
00439 */
00440 #define SUMA_IS_BLANK(c) ( ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) == '\v' || (c) == '\f' || (c) == '\r') ? 1 : 0 )
00441 /*!
00442    \brief advances pointer to next non-space, see isspace function for characters I check for.
00443    op must be NULL terminated, if eop is NULL
00444    eop is a limit address not to be reached by op
00445    \sa SUMA_IS_BLANK
00446 */
00447 #define SUMA_SKIP_BLANK(op, eop){  \
00448    while (*op != '\0' && op != eop && SUMA_IS_BLANK(*op)) ++op; \
00449 }
00450 #define SUMA_SKIP_LINE(op, eop){   \
00451    while (*op != '\0' && op != eop && *op != '\n' && *op != '\f' && *op != '\r') ++op; \
00452    SUMA_SKIP_BLANK(op, eop);\
00453 }
00454 #define SUMA_IS_COMMENT_LINE(opor, eop, cc, ans){   \
00455    char *m_op = opor;  \
00456    ans = 0;\
00457    SUMA_SKIP_BLANK(m_op, eop);\
00458    if (*m_op == cc) { ans = 1; } \
00459 }
00460 
00461 
00462 /*!
00463    \brief advance pointer to next blank, skips quoted strings (works with " and ' combos, I hope)
00464    Hello 'djjdk sskjd' Jon
00465    if op[0] is the ' then after the macro, op[0] will be the space
00466    just before Jon
00467    op must be NULL terminated, if eop is NULL
00468    eop is a limit address not to be reached by op
00469 */
00470 #define SUMA_SKIP_TO_NEXT_BLANK(op, eop){  \
00471    char m_quote_open = '\0';   \
00472    while (*op != '\0' && op !=eop && !( !m_quote_open && (*op == ' ' || *op == '\t' || *op == '\n' || *op == '\v' || *op == '\f' || *op == '\r')) ) { \
00473       if (*op == '"' || *op == '\'') {  \
00474          if (!m_quote_open) m_quote_open = *op; \
00475          else if (m_quote_open == *op) m_quote_open = '\0'; \
00476       }  \
00477       ++op; \
00478    }  \
00479 }
00480 
00481 /*!
00482    \brief Find the addresses limiting a section between two blanks, 
00483    Hello   'djjdk sskjd'    Jon
00484    if op is pointing the blank space somewhere after Hello then
00485    op will then point to '
00486    and op2 will point to the first blank after sskjd'
00487    op must be NULL terminated, if eop is NULL
00488    eop is a limit address not to be reached by op
00489 */
00490 #define SUMA_GET_BETWEEN_BLANKS(op, eop, op2){  \
00491    SUMA_SKIP_BLANK(op, eop); /* skip first blanks*/   \
00492    op2 = op;                 /* skip till next blanks */ \
00493    SUMA_SKIP_TO_NEXT_BLANK(op2, eop);  \
00494 }
00495 /*!
00496    \brief advance pointer past a string
00497    \param op (char *) pointer to char array
00498    \param eop (char *) DO not search op past eop (NULL ok if op is NULL terminated)
00499                DO NOT CALL THE MACRO WITH eop SET TO (op+Nchars), i.e. do not do this:
00500                SUMA_ADVANCE_PAST(op,(op+5),attr,Found,Word); to check only 5 chars ahead
00501                if you do so, a part of the if condition (op < eop) will always evaluate to 
00502                true because it is expanded to op < (op+5) !
00503    \param attr (char *) character string searched (NULL terminated)
00504    \Found (int)   0 --> Not found, op is not changed
00505                   1 --> Found, op is set just past the location of attr
00506    \Word (int)    0 --> Search for an exact match of attr, regardless of how its surrounded
00507                   1 --> Make sure attr is surrounded by blanks
00508 */
00509 #define SUMA_ADVANCE_PAST(op,eop,attr,Found,Word){ \
00510    int m_natr = strlen(attr); \
00511    char *m_bop = op;    \
00512    Found = 0;  \
00513    while (op < eop && *op != '\0' && Found < m_natr) { \
00514       if (*op == attr[Found]) {  \
00515          /* found a match, increment match counter */ \
00516          ++Found; \
00517       } else { /* no match, break */   \
00518          Found = 0;  \
00519       }  \
00520       ++op; \
00521       if (Word && Found == m_natr) { /* make sure word is surrounded by blank */\
00522          if ( !(*op == '\0' || op == eop || SUMA_IS_BLANK(*op)) ) { /* character after word is not blank */ \
00523             Found = 0;  /* reset  */ \
00524          } else { /* check for blank after word */ \
00525             char *m_bef = op - m_natr - 1;/* pointer to character before attr */ \
00526             if ( !(m_bef < m_bop || SUMA_IS_BLANK(*m_bef)) ) { /* character before word is not blank */ \
00527                Found = 0;  /* reset */ \
00528             }  \
00529          }  \
00530       }  \
00531    }  \
00532    /* fprintf(SUMA_STDERR,"%s: Searched %d chars.\n", FuncName, op-m_bop);  */\
00533    if (Found != m_natr) { Found = 0; op = m_bop; }/* reset pointer to origin */ \
00534 }
00535 /*!
00536    \brief advance pointer past a next number
00537    \param op (char *) pointer to char array (NULL terminated)
00538    \param num (double) output of strtod function
00539    \Found (int)   0 --> Not found, op is not changed
00540                   1 --> Found, op is set just past the location after number
00541 */
00542 
00543 #define SUMA_ADVANCE_PAST_NUM(op, num, Found){\
00544    char *m_ope=NULL;    \
00545    Found = 0;  \
00546    num = strtod(op, &m_ope); \
00547    if (m_ope > op) { /* something found */ \
00548       Found = 1; \
00549       op = m_ope; \
00550    } else { /* just to be safe */\
00551       num = 0;\
00552    }  \
00553 }
00554 
00555 /*!
00556    \brief copies characters between [op,op2[ into a new NULL terminated string str
00557    str should be freed with SUMA_free
00558 */
00559 #define SUMA_COPY_TO_STRING(op,op2,sval){   \
00560    int m_imax, m_i; \
00561    if (sval) { SUMA_SL_Err("sval must be null when macro is called"); } \
00562    else if (op2 > op) { /* copy the deed */  \
00563       m_imax = op2 - op;   \
00564       if (m_imax > 5000) {   SUMA_SL_Warn("Unexpectedly large field!"); } \
00565       sval = (char *)SUMA_calloc(m_imax + 2, sizeof(char));   \
00566       if (!sval) { SUMA_SL_Crit("Failed To Allocate"); } \
00567       else { for (m_i=0; m_i < m_imax; ++m_i) { sval[m_i] = op[m_i]; } sval[m_imax] = '\0'; }\
00568    }  \
00569 }
00570 
00571 /* >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> End string parsing macros <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< */
00572 
00573 #endif
 

Powered by Plone

This site conforms to the following standards: