1 
2 #define DEBUG_3
3 #ifdef DEBUG_1
4    #define DEBUG_2
5    #define DEBUG_3
6 #endif
7 
8 /* Header FILES */
9 
10 #include "SUMA_suma.h"
11 #include "../thd_brainormalize.h"
12 
13 /* CODE */
14 
15 
16 /*!
17    \brief Returns the time value in msec from a time string 'tm'
18    (if no unit follows number in tm, units are assumed to be in seconds)
19 */
SUMA_ParseTime(char * tm)20 double SUMA_ParseTime(char *tm)
21 {
22    static char FuncName[]={"SUMA_ParseTime"};
23    double slp;
24    char *dur=NULL;
25    int nc;
26    char un='\0';
27 
28    SUMA_ENTRY;
29 
30    if (!tm || !(nc = strlen(tm))) SUMA_RETURN(-1.0);
31    dur = SUMA_copy_string(tm);
32 
33    if (SUMA_iswordin_ci(dur, "ms") == 1) { un = 'm'; dur[nc-2] = '\0'; }
34    else if (SUMA_iswordin_ci(dur, "msec") == 1) { un = 'm'; dur[nc-4] = '\0'; }
35    else if (SUMA_iswordin_ci(dur, "millisec") == 1) { un = 'm'; dur[nc-8] = '\0'; }
36    else if (SUMA_iswordin_ci(dur, "mseconds") == 1) { un = 'm'; dur[nc-8] = '\0'; }
37    else if (SUMA_iswordin_ci(dur, "milliseconds") == 1) { un = 'm'; dur[nc-12] = '\0'; }
38    else if (SUMA_iswordin_ci(dur, "s") == 1) { un = 's'; dur[nc-1] = '\0'; }
39    else if (SUMA_iswordin_ci(dur, "sec") == 1) { un = 's'; dur[nc-3] = '\0'; }
40    else if (SUMA_iswordin_ci(dur, "seconds") == 1) { un = 's'; dur[nc-7] = '\0'; }
41    else { un = 's'; }
42    slp = atof(dur); if (un != 'm') slp *= 1000.0;
43 
44    SUMA_free(dur); dur = NULL;
45    SUMA_RETURN(slp);
46 }
47 
48 /*!
49    \brief Returns the code for the next command (at the tail of the list).
50    CommandCode =  SUMA_GetListNextCommand (list);
51    \param list (DList *) pointer to doubly linked list
52    \return CommandCode (SUMA_ENGINE_CODE) code for next command. The next command is at the head of the list.
53 
54    Note that the list is not modified.
55 
56    This function replaces the obsolete SUMA_GetNextCommand
57 */
SUMA_GetListNextCommand(DList * list)58 SUMA_ENGINE_CODE SUMA_GetListNextCommand (DList *list)
59 {
60    static char FuncName[]={"SUMA_GetListNextCommand"};
61    DListElmt *next;
62    SUMA_EngineData *ED = NULL;
63 
64    SUMA_ENTRY;
65 
66    if (!dlist_size(list)) {
67       SUMA_RETURN (SE_Empty);
68    }
69 
70    next = (DListElmt *)dlist_head(list);
71    ED = (SUMA_EngineData *)(next->data);
72    SUMA_RETURN (ED->CommandCode);
73 
74 }
75 
76 
77 /*!**
78 File : SUMA_ParseCommands.c
79 \author Ziad Saad
80 Date : Tue Feb 5 10:39:02 EST 2002
81 
82 Purpose :
83    obtain the next command Scom from the string of commands S
84 
85 
86 Usage :
87       Ret = SUMA_GetNextCommand (char *S, char d, char term, char *Scom);
88 
89 
90 Input paramters :
91 \param  S (char *) : String containing commands like "Initialize|ShowSurf|LightsON~"
92 \param  d (char)  : character delimiting multiple commands ('|' in this example)
93 \param  term (char) : character terminating entire command ('~' in this example)
94 \param  Scom (char *): Null terminated string that will contain latest command (LightsON) in this example
95                      S will be returned "Initialize|ShowSurf~"
96 
97 Returns :
98 \return   code of the command as defined for SUMA_ENGINE_CODE
99 
100 NOTE:  OBSOLETE, use SUMA_GetListNextCommand
101 
102 
103 ***/
SUMA_GetNextCommand(char * S,char d,char term,char * Scom)104 int SUMA_GetNextCommand (char *S, char d, char term, char *Scom)
105 {/*SUMA_GetNextCommand*/
106    static char FuncName[]={"SUMA_GetNextCommand"};
107    int i=0, iBegin, iStop;
108 
109    SUMA_ENTRY;
110 
111    fprintf (SUMA_STDERR, "Error %s: This function is now obsolete. Must use SUMA_GetListNextCommand instead.\n", FuncName);
112    SUMA_RETURN (NOPE);
113 
114    iStop = strlen(S)-1;
115 
116    /*fprintf(stdout,"%s %c %c\n", S, S[iStop], term);  */
117    if (S[iStop] != term) {
118       fprintf (stderr, "%s Error: Command poorly terminated!\n\a", FuncName);
119       SUMA_RETURN (0);
120    }
121    /* Make sure character just before term is not d */
122    if (S[iStop-1] == d) {
123       S[iStop] = '\0';
124       iStop -= 1;
125       S[iStop] = term;
126    }
127 
128    /* search for command delimiter */
129    iBegin = iStop -1;
130    while (iBegin > -1 && S[iBegin]!= d) --iBegin;
131    ++iBegin;
132 
133    /* copy command to Scom*/
134    for (i=0; i< iStop - iBegin; ++i)  {
135       /*fprintf(stdout,"%d %c\n", iBegin+i, S[iBegin+i]);*/
136       Scom[i] = S[iBegin+i];
137       S[iBegin+i] = '\0'; /*for esthetics */}
138 
139    /* seal strings with terminators */
140    Scom[iStop-iBegin] = '\0';
141    if (iBegin > 0) {
142       S[iBegin-1] = term;
143       iStop = iBegin-1;
144    }
145    else {
146       S[iBegin] = term;
147       iStop = iBegin;
148 
149    }
150 
151    /*get the code of the command*/
152    SUMA_RETURN (SUMA_CommandCode(Scom));
153 
154 }/*SUMA_GetNextCommand*/
155 
SUMA_CommandCode(char * Scom)156 int SUMA_CommandCode(char *Scom)
157 {
158    static char FuncName[]={"SUMA_CommandCode"};
159 
160    SUMA_ENTRY;
161 
162    if (!Scom) SUMA_RETURN(SE_BadCode);
163 
164    if (!strlen(Scom)) SUMA_RETURN (SE_Empty);
165    if (strcmp(Scom,"~") == 0) SUMA_RETURN (SE_Empty);
166 
167    /*fprintf(stdout,"Looking for %s\n", Scom);*/
168    if (!strcmp(Scom,"SetLookAt")) SUMA_RETURN(SE_SetLookAt);
169    if (!strcmp(Scom,"SetLookFrom")) SUMA_RETURN(SE_SetLookFrom);
170    if (!strcmp(Scom,"Redisplay")) SUMA_RETURN(SE_Redisplay);
171    if (!strcmp(Scom,"RedisplayNow")) SUMA_RETURN(SE_RedisplayNow);
172    if (!strcmp(Scom,"Redisplay_AllVisible"))
173       SUMA_RETURN(SE_Redisplay_AllVisible);
174    if (!strcmp(Scom,"SetNodeColor")) SUMA_RETURN (SE_SetNodeColor);
175    if (!strcmp(Scom,"FlipLight0Pos"))   SUMA_RETURN(SE_FlipLight0Pos);
176    if (!strcmp(Scom,"GetNearestNode"))   SUMA_RETURN (SE_GetNearestNode);
177    if (!strcmp(Scom,"SetLookAtNode"))   SUMA_RETURN (SE_SetLookAtNode);
178    if (!strcmp(Scom,"SetRotMatrix"))   SUMA_RETURN (SE_SetRotMatrix);
179    if (!strcmp(Scom,"SetCrossHair"))   SUMA_RETURN (SE_SetCrossHair);
180    if (!strcmp(Scom,"ToggleCrossHair"))   SUMA_RETURN (SE_ToggleCrossHair);
181    if (!strcmp(Scom,"HighlightNodes"))   SUMA_RETURN (SE_HighlightNodes);
182    if (!strcmp(Scom,"ToggleShowSelectedNode"))
183       SUMA_RETURN (SE_ToggleShowSelectedNode);
184    if (!strcmp(Scom,"SetSelectedNode"))   SUMA_RETURN (SE_SetSelectedNode);
185    if (!strcmp(Scom,"SetSelectedFaceSet"))   SUMA_RETURN (SE_SetSelectedFaceSet);
186    if (!strcmp(Scom,"ToggleShowSelectedFaceSet"))
187       SUMA_RETURN (SE_ToggleShowSelectedFaceSet);
188    if (!strcmp(Scom,"ToggleConnected")) SUMA_RETURN (SE_ToggleConnected);
189    if (!strcmp(Scom,"StartListening")) SUMA_RETURN(SE_StartListening);
190    if (!strcmp(Scom,"SetAfniCrossHair")) SUMA_RETURN (SE_SetAfniCrossHair);
191    if (!strcmp(Scom,"SetGICORnode")) SUMA_RETURN (SE_SetGICORnode);
192    if (!strcmp(Scom,"SetForceAfniSurf")) SUMA_RETURN (SE_SetForceAfniSurf);
193    if (!strcmp(Scom,"CloseStream4All")) SUMA_RETURN (SE_CloseStream4All);
194    if (!strcmp(Scom,"SetAfniSurf")) SUMA_RETURN (SE_SetAfniSurf);
195    if (!strcmp(Scom,"SetAfniThisSurf")) SUMA_RETURN (SE_SetAfniThisSurf);
196    if (!strcmp(Scom,"SetAfniSurfList")) SUMA_RETURN (SE_SetAfniSurfList);
197    if (!strcmp(Scom,"SetAfniMask")) SUMA_RETURN (SE_SetAfniMask);
198    if (!strcmp(Scom,"BindCrossHair")) SUMA_RETURN(SE_BindCrossHair);
199    if (!strcmp(Scom,"ToggleForeground")) SUMA_RETURN (SE_ToggleForeground);
200    if (!strcmp(Scom,"ToggleBackground")) SUMA_RETURN (SE_ToggleBackground);
201    if (!strcmp(Scom,"FOVreset")) SUMA_RETURN (SE_FOVreset);
202    if (!strcmp(Scom,"ResetOpenGLState")) SUMA_RETURN (SE_ResetOpenGLState);
203    if (!strcmp(Scom,"LockCrossHair")) SUMA_RETURN(SE_LockCrossHair);
204    if (!strcmp(Scom,"Home")) SUMA_RETURN (SE_Home);
205    if (!strcmp(Scom,"Home_AllVisible")) SUMA_RETURN (SE_Home_AllVisible);
206    if (!strcmp(Scom,"ToggleLockAllCrossHair"))
207       SUMA_RETURN(SE_ToggleLockAllCrossHair);
208    if (!strcmp(Scom,"SetLockAllCrossHair")) SUMA_RETURN(SE_SetLockAllCrossHair);
209    if (!strcmp(Scom,"ToggleLockView")) SUMA_RETURN(SE_ToggleLockView);
210    if (!strcmp(Scom,"ToggleLockAllViews")) SUMA_RETURN(SE_ToggleLockAllViews);
211    if (!strcmp(Scom,"Load_Group")) SUMA_RETURN(SE_Load_Group);
212    if (!strcmp(Scom,"Help")) SUMA_RETURN(SE_Help);
213    if (!strcmp(Scom,"Help_Xform")) SUMA_RETURN(SE_Help_Xform);
214    if (!strcmp(Scom,"Help_Cmap")) SUMA_RETURN(SE_Help_Cmap);
215    if (!strcmp(Scom,"Help_Plot")) SUMA_RETURN(SE_Help_Plot);
216    if (!strcmp(Scom,"Whereami")) SUMA_RETURN(SE_Whereami);
217    if (!strcmp(Scom,"UpdateLog")) SUMA_RETURN(SE_UpdateLog);
218    if (!strcmp(Scom,"Log")) SUMA_RETURN(SE_Log);
219    if (!strcmp(Scom,"SetRenderMode")) SUMA_RETURN(SE_SetRenderMode);
220    if (!strcmp(Scom,"SetTransMode")) SUMA_RETURN(SE_SetTransMode);
221    if (!strcmp(Scom,"SetATransMode")) SUMA_RETURN(SE_SetATransMode);
222    if (!strcmp(Scom,"OpenDrawROI")) SUMA_RETURN(SE_OpenDrawROI);
223    if (!strcmp(Scom,"RedisplayNow_AllVisible"))
224       SUMA_RETURN(SE_RedisplayNow_AllVisible);
225    if (!strcmp(Scom,"RedisplayNow_AllOtherVisible"))
226       SUMA_RETURN(SE_RedisplayNow_AllOtherVisible);
227    if (!strcmp(Scom,"SetLight0Pos")) SUMA_RETURN(SE_SetLight0Pos);
228    if (!strcmp(Scom,"OpenColFileSelection"))
229       SUMA_RETURN(SE_OpenColFileSelection);
230    if (!strcmp(Scom,"OpenDsetFileSelection"))
231       SUMA_RETURN(SE_OpenDsetFileSelection);
232    if (!strcmp(Scom,"OpenMaskFile"))
233       SUMA_RETURN(SE_OpenMaskFile);
234    if (!strcmp(Scom,"OpenMaskFileSelection"))
235       SUMA_RETURN(SE_OpenMaskFileSelection);
236    if (!strcmp(Scom,"SaveMaskFileSelection"))
237       SUMA_RETURN(SE_SaveMaskFileSelection);
238    if (!strcmp(Scom,"OpenCmapFileSelection"))
239       SUMA_RETURN(SE_OpenCmapFileSelection);
240    if (!strcmp(Scom,"SaveDrawnROIFileSelection"))
241       SUMA_RETURN(SE_SaveDrawnROIFileSelection);
242    if (!strcmp(Scom,"SaveXformOptsFileSelection"))
243       SUMA_RETURN(SE_SaveXformOptsFileSelection);
244    if (!strcmp(Scom,"OpenDrawnROIFileSelection"))
245       SUMA_RETURN(SE_OpenDrawnROIFileSelection);
246    if (!strcmp(Scom,"OpenXformOrtFileFileSelection"))
247       SUMA_RETURN(SE_OpenXformOrtFileFileSelection);
248    if (!strcmp(Scom,"SendColorMapToAfni")) SUMA_RETURN(SE_SendColorMapToAfni);
249    if (!strcmp(Scom,"SaveSOFileSelection")) SUMA_RETURN(SE_SaveSOFileSelection);
250    if (!strcmp(Scom,"SetSOinFocus")) SUMA_RETURN(SE_SetSOinFocus);
251    if (!strcmp(Scom,"LoadViewFileSelection"))
252       SUMA_RETURN(SE_LoadViewFileSelection);
253    if (!strcmp(Scom,"SaveViewFileSelection"))
254       SUMA_RETURN(SE_SaveViewFileSelection);
255    if (!strcmp(Scom,"LoadSegDO")) SUMA_RETURN(SE_LoadSegDO);
256    if (!strcmp(Scom,"SetClip")) SUMA_RETURN(SE_SetClip);
257    if (!strcmp(Scom,"load_dset")) SUMA_RETURN(SE_OpenDsetFile);
258    if (!strcmp(Scom,"load_col")) SUMA_RETURN(SE_OpenColFile);
259    if (!strcmp(Scom,"surf_cont")) SUMA_RETURN(SE_SetSurfCont);
260    if (!strcmp(Scom,"object_cont")) SUMA_RETURN(SE_SetObjectCont);
261    if (!strcmp(Scom,"viewer_cont")) SUMA_RETURN(SE_SetViewerCont);
262    if (!strcmp(Scom,"recorder_cont")) SUMA_RETURN(SE_SetRecorderCont);
263    if (!strcmp(Scom,"SetDsetViewMode")) SUMA_RETURN(SE_SetDsetViewMode);
264    if (!strcmp(Scom,"SetDsetFont")) SUMA_RETURN(SE_SetDsetFont);
265    if (!strcmp(Scom,"SetDsetNodeRad")) SUMA_RETURN(SE_SetDsetNodeRad);
266    if (!strcmp(Scom,"SetDsetThrough")) SUMA_RETURN(SE_SetDsetThrough);
267    if (!strcmp(Scom,"SetDsetEdgeThick")) SUMA_RETURN(SE_SetDsetEdgeThick);
268    if (!strcmp(Scom,"SetDsetEdgeStip")) SUMA_RETURN(SE_SetDsetEdgeStip);
269    if (!strcmp(Scom,"SetTractStyle")) SUMA_RETURN(SE_SetTractStyle);
270    if (!strcmp(Scom,"SetDsetAlphaVal")) SUMA_RETURN(SE_SetDsetAlphaVal);
271    if (!strcmp(Scom,"SetDsetNodeCol")) SUMA_RETURN(SE_SetDsetNodeCol);
272    if (!strcmp(Scom,"SetDsetTxtShad")) SUMA_RETURN(SE_SetDsetTxtShad);
273    if (!strcmp(Scom,"SetDsetGmatBord")) SUMA_RETURN(SE_SetDsetGmatBord);
274    if (!strcmp(Scom,"SetTractMask")) SUMA_RETURN(SE_SetTractMask);
275    /*if (!strcmp(Scom,"")) SUMA_RETURN(SE_);*/
276    /* Last one is Bad Code */
277    SUMA_RETURN (SE_BadCode);
278 }
279 
280 
SUMA_niCommandCode(char * Scom)281 SUMA_NI_COMMAND_CODE SUMA_niCommandCode(char *Scom)
282 {
283    static char FuncName[]={"SUMA_niCommandCode"};
284 
285    SUMA_ENTRY;
286 
287    if (!Scom) SUMA_RETURN(SE_BadCode);
288 
289    if (!strlen(Scom)) SUMA_RETURN (SE_niEmpty);
290    if (strcmp(Scom,"~") == 0) SUMA_RETURN (SE_niEmpty);
291 
292    /*fprintf(stdout,"Looking for %s\n", Scom);*/
293    if (!strcmp(Scom,"surf_cont")) SUMA_RETURN(SE_niSetSurfCont);
294    if (!strcmp(Scom,"object_cont")) SUMA_RETURN(SE_niSetObjectCont);
295    if (!strcmp(Scom,"viewer_cont")) SUMA_RETURN(SE_niSetViewerCont);
296    if (!strcmp(Scom,"recorder_cont")) SUMA_RETURN(SE_niSetRecorderCont);
297    if (!strcmp(Scom,"kill_suma")) SUMA_RETURN(SE_niKillSuma);
298    if (!strcmp(Scom,"get_label")) SUMA_RETURN(SE_GetLabel);
299    /*if (!strcmp(Scom,"")) SUMA_RETURN(SE_ni);*/
300 
301    /* Last one is Bad Code */
302    SUMA_RETURN (SE_niBadCode);
303 
304 }
305 
SUMA_ColMixModeString(SUMA_COL_MIX_MODE mode)306 const char *SUMA_ColMixModeString (SUMA_COL_MIX_MODE mode)
307 {
308    static char FuncName[]={"SUMA_ColMixModeString"};
309 
310    SUMA_ENTRY;
311 
312    switch (mode) {
313       case SUMA_BAD_MODE:
314          SUMA_RETURN("BadMode");
315       case SUMA_ORIG_MIX_MODE:
316          SUMA_RETURN("ORIG");
317       case SUMA_4AML:
318          SUMA_RETURN("MOD1");
319       default:
320          SUMA_RETURN("VeryBadMode");
321    }
322 
323 }
324 
SUMA_DomainKinships_String(SUMA_DOMAIN_KINSHIPS code)325 const char *SUMA_DomainKinships_String (SUMA_DOMAIN_KINSHIPS code)
326 {
327    static char FuncName[]={"SUMA_DomainKinships_String"};
328 
329    SUMA_ENTRY;
330 
331    switch (code) {
332       case SUMA_DOMAINS_ERROR:
333          SUMA_RETURN("Code Error");
334       case SUMA_DOMAINS_NOT_RELATED:
335          SUMA_RETURN("Surfaces domains not related");
336       case SUMA_SO1_is_SO2:
337          SUMA_RETURN("Surfaces are the same (identical idcodes)");
338       case SUMA_SO1_is_LDPSO2:
339          SUMA_RETURN("Surface 1 is the local domain parent of Surface 2");
340       case SUMA_SO2_is_LDPSO1:
341          SUMA_RETURN("Surface 2 is the local domain parent of Surface 1");
342       case SUMA_NUCELAR_FAMILY:
343          SUMA_RETURN("Flag for nuclear family flag limit");
344       case SUMA_LDPSO1_is_LDPSO2:
345          SUMA_RETURN("Surfaces have same domain grandparent");
346       case SUMA_SO1_is_GPSO2:
347          SUMA_RETURN("Surface 1 is the domain grandparent of Surface 2");
348       case SUMA_SO2_is_GPSO1:
349          SUMA_RETURN("Surface 2 is the domain grandparent of Surface 1");
350       case SUMA_GPSO1_is_GPSO2:
351          SUMA_RETURN("Surfaces have the same domain grandparent.");
352       case SUMA_N_NODE_SAME:
353          SUMA_RETURN("Surfaces have the same number of nodes.");
354       default:
355          SUMA_RETURN("Should not see this");
356    }
357 
358    SUMA_RETURN("Should not see this either");
359 }
360 /*!
361    \brief Transforms a command code into a string for human consumption
362    const char *SUMA_CommandString (SUMA_ENGINE_CODE code);
363 
364 */
SUMA_CommandString(SUMA_ENGINE_CODE code)365 const char *SUMA_CommandString (SUMA_ENGINE_CODE code)
366 {
367    static char FuncName[]={"SUMA_CommandString"};
368 
369    SUMA_ENTRY;
370 
371    switch (code) {
372       case SE_SetLookAt:
373          SUMA_RETURN("SetLookAt");
374       case SE_SetLookFrom:
375          SUMA_RETURN("SetLookFrom");
376       case SE_Redisplay:
377          SUMA_RETURN("Redisplay");
378       case SE_RedisplayNow:
379          SUMA_RETURN("RedisplayNow");
380       case SE_Redisplay_AllVisible:
381          SUMA_RETURN("Redisplay_AllVisible");
382       case SE_SetNodeColor:
383          SUMA_RETURN("SetNodeColor");
384       case SE_FlipLight0Pos:
385          SUMA_RETURN("FlipLight0Pos");
386       case SE_GetNearestNode:
387          SUMA_RETURN("GetNearestNode");
388       case SE_SetLookAtNode:
389          SUMA_RETURN("SetLookAtNode");
390       case SE_SetRotMatrix:
391          SUMA_RETURN("SetRotMatrix");
392       case SE_SetCrossHair:
393          SUMA_RETURN("SetCrossHair");
394       case SE_ToggleCrossHair:
395          SUMA_RETURN("ToggleCrossHair");
396       case SE_HighlightNodes:
397          SUMA_RETURN("HighlightNodes");
398       case SE_ToggleShowSelectedNode:
399          SUMA_RETURN("ToggleShowSelectedNode");
400       case SE_SetSelectedNode:
401          SUMA_RETURN("SetSelectedNode");
402       case SE_SetSelectedFaceSet:
403          SUMA_RETURN("SetSelectedFaceSet");
404       case SE_ToggleShowSelectedFaceSet:
405          SUMA_RETURN("ToggleShowSelectedFaceSet");
406       case SE_ToggleConnected:
407          SUMA_RETURN("ToggleConnected");
408       case SE_StartListening:
409          SUMA_RETURN("StartListening");
410       case SE_SetAfniCrossHair:
411          SUMA_RETURN("SetAfniCrossHair");
412       case SE_SetGICORnode:
413          SUMA_RETURN("SetGICORnode");
414       case SE_SetForceAfniSurf:
415          SUMA_RETURN("SetForceAfniSurf");
416       case SE_CloseStream4All:
417          SUMA_RETURN("CloseStream4All");
418       case SE_SetAfniThisSurf:
419          SUMA_RETURN("SetAfniThisSurf");
420       case SE_SetAfniSurf:
421          SUMA_RETURN("SetAfniSurf");
422       case SE_SetAfniMask:
423          SUMA_RETURN("SetAfniMask");
424       case SE_SetAfniSurfList:
425          SUMA_RETURN("SetAfniSurfList");
426       case SE_BindCrossHair:
427          SUMA_RETURN("BindCrossHair");
428       case SE_ToggleForeground:
429          SUMA_RETURN("ToggleForeground");
430       case SE_ToggleBackground:
431          SUMA_RETURN("ToggleBackground");
432       case SE_FOVreset:
433          SUMA_RETURN("FOVreset");
434       case SE_ResetOpenGLState:
435          SUMA_RETURN("ResetOpenGLState");
436       case SE_LockCrossHair:
437          SUMA_RETURN("LockCrossHair");
438       case SE_Home:
439          SUMA_RETURN("Home");
440       case SE_Home_AllVisible:
441          SUMA_RETURN("Home_AllVisible");
442       case SE_Empty:
443          SUMA_RETURN("Empty");
444       case SE_ToggleLockAllCrossHair:
445          SUMA_RETURN("ToggleLockAllCrossHair");
446       case SE_SetLockAllCrossHair:
447          SUMA_RETURN("SetLockAllCrossHair");
448       case SE_ToggleLockView:
449          SUMA_RETURN("ToggleLockView");
450       case SE_ToggleLockAllViews:
451          SUMA_RETURN("ToggleLockAllViews");
452       case SE_Load_Group:
453          SUMA_RETURN("Load_Group");
454       case SE_Help:
455          SUMA_RETURN("Help");
456       case SE_Help_Xform:
457          SUMA_RETURN("Help_Xform");
458       case SE_Help_Cmap:
459          SUMA_RETURN("Help_Cmap");
460       case SE_Help_Plot:
461          SUMA_RETURN("Help_Plot");
462       case SE_Whereami:
463          SUMA_RETURN("Whereami");
464       case SE_UpdateLog:
465          SUMA_RETURN("UpdateLog");
466       case SE_Log:
467          SUMA_RETURN("Log");
468       case SE_SetRenderMode:
469          SUMA_RETURN("SetRenderMode");
470       case SE_SetTransMode:
471          SUMA_RETURN("SetTransMode");
472       case SE_SetATransMode:
473          SUMA_RETURN("SetATransMode");
474       case SE_OpenDrawROI:
475          SUMA_RETURN("OpenDrawROI");
476       case SE_RedisplayNow_AllVisible:
477          SUMA_RETURN("RedisplayNow_AllVisible");
478       case SE_RedisplayNow_AllOtherVisible:
479          SUMA_RETURN("RedisplayNow_AllOtherVisible");
480       case SE_SetLight0Pos:
481          SUMA_RETURN("SetLight0Pos");
482       case SE_OpenColFileSelection:
483          SUMA_RETURN("OpenColFileSelection");
484       case SE_OpenDsetFileSelection:
485          SUMA_RETURN("OpenDsetFileSelection");
486       case SE_OpenMaskFileSelection:
487          SUMA_RETURN("OpenMaskFileSelection");
488       case SE_OpenMaskFile:
489          SUMA_RETURN("OpenMaskFile");
490       case SE_SaveMaskFileSelection:
491          SUMA_RETURN("SaveMaskFileSelection");
492       case SE_OpenCmapFileSelection:
493          SUMA_RETURN("OpenCmapFileSelection");
494       case SE_SaveXformOptsFileSelection:
495          SUMA_RETURN("SaveXformOptsFileSelection");
496       case SE_SaveDrawnROIFileSelection:
497          SUMA_RETURN("SaveDrawnROIFileSelection");
498       case SE_OpenXformOrtFileFileSelection:
499          SUMA_RETURN("OpenXformOrtFileFileSelection");
500       case SE_OpenDrawnROIFileSelection:
501          SUMA_RETURN("OpenDrawnROIFileSelection");
502       case SE_SendColorMapToAfni:
503          SUMA_RETURN("SendColorMapToAfni");
504       case SE_SaveSOFileSelection:
505          SUMA_RETURN("SaveSOFileSelection");
506       case SE_SetSOinFocus:
507          SUMA_RETURN("SetSOinFocus");
508       case SE_LoadViewFileSelection:
509          SUMA_RETURN("LoadViewFileSelection");
510       case SE_SaveViewFileSelection:
511          SUMA_RETURN("SaveViewFileSelection");
512       case SE_LoadSegDO:
513          SUMA_RETURN("LoadSegDO");
514       case SE_SetClip:
515          SUMA_RETURN("SetClip");
516       case SE_OpenColFile:
517          SUMA_RETURN("load_col");
518       case SE_OpenDsetFile:
519          SUMA_RETURN("load_dset");
520       case SE_SetSurfCont:
521          SUMA_RETURN("surf_cont");
522       case SE_SetObjectCont:
523          SUMA_RETURN("object_cont");
524       case SE_SetViewerCont:
525          SUMA_RETURN("viewer_cont");
526       case SE_SetRecorderCont:
527          SUMA_RETURN("recorder_cont");
528       case SE_SetDsetViewMode:
529          SUMA_RETURN("SetDsetViewMode");
530       case SE_SetDsetFont:
531          SUMA_RETURN("SetDsetFont");
532       case SE_SetDsetNodeRad:
533          SUMA_RETURN("SetDsetNodeRad");
534       case SE_SetDsetThrough:
535          SUMA_RETURN("SetDsetThrough");
536       case SE_SetDsetEdgeStip:
537          SUMA_RETURN("SetDsetEdgeStip");
538       case SE_SetTractStyle:
539          SUMA_RETURN("SetTractStyle");
540       case SE_SetDsetAlphaVal:
541          SUMA_RETURN("SetDsetAlphaVal");
542       case SE_SetDsetEdgeThick:
543          SUMA_RETURN("SetDsetEdgeThick");
544       case SE_SetDsetNodeCol:
545          SUMA_RETURN("SetDsetNodeCol");
546       case SE_SetDsetTxtShad:
547          SUMA_RETURN("SetDsetTxtShad");
548       case SE_SetDsetGmatBord:
549          SUMA_RETURN("SetDsetGmatBord");
550       /*case SE_:
551          SUMA_RETURN("");      */
552       default:
553          SUMA_RETURN ("BadCode");
554    }
555 }
SUMA_niCommandString(SUMA_NI_COMMAND_CODE code)556 const char *SUMA_niCommandString (SUMA_NI_COMMAND_CODE code)
557 {
558    static char FuncName[]={"SUMA_niCommandString"};
559 
560    SUMA_ENTRY;
561 
562    switch (code) {
563      case SE_niEmpty:
564          SUMA_RETURN("Empty");
565       case SE_niSetSurfCont:
566          SUMA_RETURN("surf_cont");
567       case SE_niSetObjectCont:
568          SUMA_RETURN("object_cont");
569       case SE_niSetViewerCont:
570          SUMA_RETURN("viewer_cont");
571       case SE_niSetRecorderCont:
572          SUMA_RETURN("recorder_cont");
573       case SE_niKillSuma:
574          SUMA_RETURN("kill_suma");
575       /*case SE_ni:
576          SUMA_RETURN("");      */
577       default:
578          SUMA_RETURN ("BadCode");
579    }
580 }
581 
582 /*!
583    \brief Returns the name (string) of a surface format
584 */
SUMA_SurfaceFormatString(SUMA_SO_File_Format ff)585 const char * SUMA_SurfaceFormatString (SUMA_SO_File_Format ff)
586 {
587    static char FuncName[]={"SUMA_SurfaceFormatString"};
588 
589    SUMA_ENTRY;
590    switch (ff) {
591       case SUMA_FF_NOT_SPECIFIED:
592          SUMA_RETURN("NotSpecified");
593          break;
594       case SUMA_ASCII:
595          SUMA_RETURN("ASCII");
596          break;
597       case SUMA_BINARY:
598          SUMA_RETURN("BINARY");
599          break;
600       case SUMA_BINARY_BE:
601          SUMA_RETURN("BINARY_BE");
602          break;
603       case SUMA_BINARY_LE:
604          SUMA_RETURN("BINARY_LE");
605          break;
606       case SUMA_XML_SURF:
607          SUMA_RETURN("XML_SURF");
608          break;
609       case SUMA_XML_ASCII_SURF:
610          SUMA_RETURN("XML_ASCII_SURF");
611          break;
612       case SUMA_XML_B64_SURF:
613          SUMA_RETURN("XML_B64_SURF");
614          break;
615       case SUMA_XML_B64GZ_SURF:
616          SUMA_RETURN("XML_B64GZ_SURF");
617          break;
618       case SUMA_FF_ERROR:
619          SUMA_RETURN ("Error");
620       default:
621          SUMA_RETURN ("Error");
622    }
623 }
624 /*!
625    \brief Returns the code for a surface's file format
626 */
SUMA_SurfaceFormatCode(char * cd)627 SUMA_SO_File_Format SUMA_SurfaceFormatCode (char *cd)
628 {
629    static char FuncName[]={"SUMA_SurfaceFormatCode"};
630 
631    SUMA_ENTRY;
632 
633    if (!cd) { SUMA_RETURN(SUMA_FF_ERROR); }
634 
635    if (!strcmp(cd, "NotSpecified")) {
636       SUMA_RETURN(SUMA_FF_NOT_SPECIFIED );
637    }
638    if (!strcmp(cd, "ASCII")) {
639       SUMA_RETURN(SUMA_ASCII );
640    }
641    if (!strcmp(cd, "BINARY")) {
642       SUMA_RETURN( SUMA_BINARY);
643    }
644    if (!strcmp(cd, "BINARY_BE")) {
645       SUMA_RETURN( SUMA_BINARY_BE);
646    }
647    if (!strcmp(cd, "BINARY_LE")) {
648       SUMA_RETURN( SUMA_BINARY_LE);
649    }
650    if (!strcmp(cd, "XML_SURF")) {
651       SUMA_RETURN( SUMA_XML_SURF);
652    }
653    if (!strcmp(cd, "XML_ASCII_SURF")) {
654       SUMA_RETURN( SUMA_XML_ASCII_SURF);
655    }
656    if (!strcmp(cd, "XML_B64_SURF")) {
657       SUMA_RETURN( SUMA_XML_B64_SURF);
658    }
659    if (!strcmp(cd, "XML_B64GZ_SURF")) {
660       SUMA_RETURN(SUMA_XML_B64GZ_SURF);
661    }
662    if (!strcmp(cd, "Error")) {
663       SUMA_RETURN( SUMA_FF_ERROR);
664    }
665 
666    SUMA_RETURN( SUMA_FF_ERROR);
667 }
668 /*!
669    \brief Returns the name (string) of a surface type
670 */
SUMA_SurfaceTypeString(SUMA_SO_File_Type tp)671 const char * SUMA_SurfaceTypeString (SUMA_SO_File_Type tp)
672 {
673    static char FuncName[]={"SUMA_SurfaceTypeString"};
674 
675    SUMA_ENTRY;
676    switch (tp) {
677       case SUMA_FT_NOT_SPECIFIED:
678          SUMA_RETURN("NotSpecified");
679          break;
680       case SUMA_FREE_SURFER:
681       case SUMA_FREE_SURFER_PATCH:
682          SUMA_RETURN("FreeSurfer");
683          break;
684       case SUMA_SUREFIT:
685          SUMA_RETURN("SureFit");
686          break;
687       case SUMA_INVENTOR_GENERIC:
688          SUMA_RETURN("GenericInventor");
689          break;
690       case SUMA_PLY:
691          SUMA_RETURN("Ply");
692          break;
693       case SUMA_STL:
694          SUMA_RETURN("STL");
695          break;
696       case SUMA_MNI_OBJ:
697          SUMA_RETURN("MNI");
698          break;
699       case SUMA_BRAIN_VOYAGER:
700          SUMA_RETURN("BrainVoyager");
701          break;
702       case SUMA_BYU:
703          SUMA_RETURN("BYU");
704          break;
705       case SUMA_GIFTI:
706          SUMA_RETURN("GIFTI");
707          break;
708       case SUMA_VEC:
709          SUMA_RETURN("1D");
710          break;
711       case SUMA_OPENDX_MESH:
712          SUMA_RETURN("OpenDX");
713          break;
714       case SUMA_OBJ_MESH:
715          SUMA_RETURN("OBJ");
716          break;
717       case SUMA_PREDEFINED:
718          SUMA_RETURN("Predefined");
719          break;
720       case SUMA_FT_ERROR:
721          SUMA_RETURN("Error");
722       default:
723          SUMA_RETURN ("Error");
724    }
725 }
726 
727 /*!
728    \brief Returns the code for a surface's file type
729 */
SUMA_SurfaceTypeCode(char * cd)730 SUMA_SO_File_Type SUMA_SurfaceTypeCode (char *cd)
731 {
732    static char FuncName[]={"SUMA_SurfaceTypeCode"};
733 
734    SUMA_ENTRY;
735 
736    if (!cd) { SUMA_RETURN(SUMA_FT_ERROR); }
737 
738    if (!strcmp(cd, "NotSpecified")) {
739       SUMA_RETURN(SUMA_FT_NOT_SPECIFIED );
740    }
741    if (  !strcmp(cd, "FreeSurfer") || !strcmp(cd, "FS") ||
742          !strcmp(cd, "fs")) {
743       SUMA_RETURN( SUMA_FREE_SURFER);
744    }
745    if (!strcmp(cd, "SureFit") || !strcmp(cd, "SF") ||
746        !strcmp(cd, "sf")) {
747       SUMA_RETURN( SUMA_SUREFIT);
748    }
749    if (  !strcmp(cd, "GenericInventor") || !strcmp(cd, "INV") ||
750          !strcmp(cd, "inv")) {
751       SUMA_RETURN(SUMA_INVENTOR_GENERIC );
752    }
753    if (  !strcmp(cd, "Ply") || !strcmp(cd, "PLY") ||
754          !strcmp(cd, "ply")) {
755       SUMA_RETURN( SUMA_PLY);
756    }
757    if (  !strcmp(cd, "Stl") || !strcmp(cd, "STL") ||
758          !strcmp(cd, "stl")) {
759       SUMA_RETURN( SUMA_STL);
760    }
761    if (  !strcmp(cd, "Mni") || !strcmp(cd, "MNI") ||
762          !strcmp(cd, "mni")) {
763       SUMA_RETURN( SUMA_MNI_OBJ);
764    }
765    if (  !strcmp(cd, "DX") || !strcmp(cd, "dx") ||
766          !strcmp(cd, "OpenDX") || !strcmp(cd, "opendx")) {
767       SUMA_RETURN( SUMA_OPENDX_MESH);
768    }
769    if (  !strcmp(cd, "OBJ") || !strcmp(cd, "obj") ) {
770       SUMA_RETURN( SUMA_OBJ_MESH);
771    }
772    if (  !strcmp(cd, "Predefined") || !strcmp(cd, "PREDEFINED") ||
773          !strcmp(cd, "pre") || !strcmp(cd, "Pre")) {
774       SUMA_RETURN( SUMA_PREDEFINED);
775    }
776    if (  !strcmp(cd, "BrainVoyager") || !strcmp(cd, "BV") ||
777          !strcmp(cd, "bv")) {
778       SUMA_RETURN( SUMA_BRAIN_VOYAGER);
779    }
780    if (  !strcmp(cd, "BYU") || !strcmp(cd, "Byu") ||
781          !strcmp(cd, "byu")) {
782       SUMA_RETURN( SUMA_BYU);
783    }
784    if (  !strcmp(cd, "GIFTI") || !strcmp(cd, "Gifti") || !strcmp(cd, "gifti") ||
785          !strcmp(cd, "gii") || !strcmp(cd, "GII")) {
786       SUMA_RETURN( SUMA_GIFTI);
787    }
788    if (!strcmp(cd, "1D") || !strcmp(cd, "VEC") || !strcmp(cd, "1d")) {
789       SUMA_RETURN(SUMA_VEC );
790    }
791    if (!strcmp(cd, "Error")) {
792       SUMA_RETURN(SUMA_FT_ERROR );
793    }
794    /* if (!strcmp(cd, "")) { SUMA_RETURN( ); } */
795    SUMA_RETURN(SUMA_FT_ERROR);
796 
797 }
798 
SUMA_DO_DrawMaskCode2Name_human(SUMA_DO_DRAW_MASK dd)799 char *SUMA_DO_DrawMaskCode2Name_human(SUMA_DO_DRAW_MASK dd) {
800    switch(dd) {
801       case SDODM_Error:
802          return("err");
803       case SDODM_All:
804          return("All DOs");
805       case SDODM_n3CrossHair:
806          return("node + 3 Neighb. Layers");
807       case SDODM_n2CrossHair:
808          return("node + 2 Neighb. Layers");
809       case SDODM_n1CrossHair:
810          return("node + 1 Neighb. Layer");
811       case SDODM_n0CrossHair:
812          return("node");
813       case SDODM_Hide:
814          return("no DOs");
815       case SDODM_N_DO_DrawMasks:
816          return("Number of mask modes");
817       default:
818          return("errerrerr");
819    }
820 }
821 
SUMA_DO_DrawMaskCode2Name(SUMA_DO_DRAW_MASK dd)822 char *SUMA_DO_DrawMaskCode2Name(SUMA_DO_DRAW_MASK dd) {
823    switch(dd) {
824       case SDODM_Error:
825          return("err");
826       case SDODM_All:
827          return("all");
828       case SDODM_n3CrossHair:
829          return("node+3");
830       case SDODM_n2CrossHair:
831          return("node+2");
832       case SDODM_n1CrossHair:
833          return("node+1");
834       case SDODM_n0CrossHair:
835          return("node");
836       case SDODM_Hide:
837          return("nothing");
838       case SDODM_N_DO_DrawMasks:
839          return("n_mask_modes");
840       default:
841          return("errerrerr");
842    }
843 }
844 
SUMA_DO_DrawMaskName2Code(char * name)845 SUMA_DO_DRAW_MASK SUMA_DO_DrawMaskName2Code (char *name) {
846    if (!name) return(SDODM_Error);
847    if (!strcmp(name,"err")) return(SDODM_Error);
848    if (!strcmp(name,"all") || !strcmp(name,"All DOs")) return(SDODM_All);
849    if (!strcmp(name,"node+3") || !strcmp(name,"node + 3 Neighb. Layers"))
850       return(SDODM_n3CrossHair);
851    if (!strcmp(name,"node+2") || !strcmp(name,"node + 2 Neighb. Layers"))
852       return(SDODM_n2CrossHair);
853    if (!strcmp(name,"node+1") || !strcmp(name,"node + 1 Neighb. Layer"))
854       return(SDODM_n1CrossHair);
855    if (!strcmp(name,"node")) return(SDODM_n0CrossHair);
856    if (!strcmp(name,"nothing") || !strcmp(name,"no DOs")) return(SDODM_Hide);
857    if (!strcmp(name,"n_mask_modes") || !strcmp(name,"Number of mask modes"))
858       return(SDODM_N_DO_DrawMasks);
859    return(SDODM_Error);
860 }
861 
862 /*!**
863 
864 Purpose :
865    Append or prepend command Scom to S
866 
867 
868 Usage :
869       Ret =  SUMA_RegisterCommand(char *S, char d, char term, char *Scom, SUMA_Boolean Prepend);
870 
871 
872 Input paramters :
873 \param  S (char *) : String containing commands like "Initialize|ShowSurf~" MUST BE NULL TERMINATED
874 \param  d (char)  : character delimiting multiple commands ('|' in this example)
875 \param  term (char) : character terminating entire command ('~' in this example)
876 \param  Scom (char *): Null terminated string that will contain latest command (LightsON) in this example
877                      S will be returned "Initialize|ShowSurf/LightsON~" if Prepend is YUP
878                      S will be returned "LightsON|Initialize|ShowSurf" is Prepend if NOPE
879 \param Prepend (SUMA_Boolean): append or prepend command
880 
881 Returns :
882 \return   NOPE for failure, YUP success
883 
884 NOTE: OBSOLETE, use  SUMA_RegisterEngineListCommand
885 
886 
887 ***/
SUMA_RegisterCommand(char * S,char d,char term,char * Scom,SUMA_Boolean Prepend)888 SUMA_Boolean SUMA_RegisterCommand (char *S, char d, char term, char *Scom, SUMA_Boolean Prepend)
889 {   int i, iStop, iorig, iStopNew, nCom;
890    static char FuncName[]={"SUMA_RegisterCommand"};
891 
892    SUMA_ENTRY;
893 
894    fprintf (SUMA_STDERR, "Error %s: This function is now obsolete. Must use SUMA_RegisterCommand instead.\n", FuncName);
895    SUMA_RETURN (NOPE);
896 
897    iStop = strlen(S)-1;
898 
899    nCom = strlen(Scom);
900    /*fprintf (stdout,"Scom->%s<-, length %d\n", Scom, nCom);*/
901    if (strlen(Scom) + iStop + 2 > SUMA_MAX_COMMAND_LENGTH ) {
902       fprintf (stderr, "%s Error: Resultant command longer than SUMA_MAX_COMMAND_LENGTH!\n\a", FuncName);
903       SUMA_RETURN (NOPE);
904    }
905    if (S[iStop] != term) {
906       fprintf (stderr, "%s Error: S improperly terminated!\n\a", FuncName);
907       SUMA_RETURN (NOPE);
908    }
909    if (!Prepend) {
910       /* add a delimiter */
911       if (S[iStop-1] != d) {
912          S[iStop] = d;
913          iStop += 1;
914       }
915       /*append the command */
916       for (i=0; i <nCom; ++i) {
917          S[iStop+i] = Scom[i];
918       }
919       iStop += nCom;
920       S[iStop] = term;
921       S[iStop+1] = '\0';
922       SUMA_RETURN (YUP);
923    } else {
924       /* move old string forward*/
925       iStopNew = iStop+nCom+1;
926       S[iStopNew+1] = '\0';
927       iorig = 0;
928       while (iorig <= iStop) {
929          S[iStopNew-iorig] = S[iStop-iorig];
930          ++iorig;
931       }
932       S[iStopNew-iorig] = d;
933 
934       /*add new one */
935       for (i=0; i < nCom; ++i) {
936          S[i] = Scom[i];
937       }
938       iStop = iStopNew;
939       SUMA_RETURN (YUP);
940    }
941 }
942 
943 /*!
944    \brief translates SUMA_ENGINE_FIELD_CODE to string
945 */
SUMA_EngineFieldString(SUMA_ENGINE_FIELD_CODE i)946 const char* SUMA_EngineFieldString (SUMA_ENGINE_FIELD_CODE i)
947 {
948    static char FuncName[]={"SUMA_EngineFieldString"};
949 
950    SUMA_ENTRY;
951 
952    switch (i) {
953       case (SEF_fm):
954          SUMA_RETURN ("fm");
955          break;
956       case (SEF_im):
957          SUMA_RETURN ("im");
958          break;
959       case (SEF_ivec):
960          SUMA_RETURN ("ivec");
961          break;
962       case (SEF_fvec):
963          SUMA_RETURN ("fvec");
964          break;
965       case (SEF_fv3):
966          SUMA_RETURN ("fv3");
967          break;
968       case (SEF_iv3):
969          SUMA_RETURN ("iv3");
970          break;
971       case (SEF_fv15):
972          SUMA_RETURN ("fv15");
973          break;
974       case (SEF_iv15):
975          SUMA_RETURN ("iv15");
976          break;
977       case (SEF_iv200):
978          SUMA_RETURN ("iv200");
979          break;
980       case (SEF_fv200):
981          SUMA_RETURN ("fv200");
982          break;
983       case (SEF_i):
984          SUMA_RETURN ("i");
985          break;
986       case (SEF_f):
987          SUMA_RETURN ("f");
988          break;
989       case (SEF_s):
990          SUMA_RETURN ("s");
991          break;
992       case (SEF_vp):
993          SUMA_RETURN ("vp");
994          break;
995       case (SEF_cp):
996          SUMA_RETURN ("cp");
997          break;
998       case (SEF_fp):
999          SUMA_RETURN ("fp");
1000          break;
1001       case (SEF_ip):
1002          SUMA_RETURN ("ip");
1003          break;
1004       case (SEF_ngr):
1005          SUMA_RETURN ("ngr");
1006          break;
1007       case (SEF_nel):
1008          SUMA_RETURN ("nel");
1009          break;
1010       default:
1011          SUMA_RETURN ("Unknown");
1012          break;
1013 
1014    }
1015 
1016 }
1017 
SUMA_EngineFieldCode(char * Scom)1018 SUMA_ENGINE_FIELD_CODE SUMA_EngineFieldCode(char *Scom)
1019 {
1020    static char FuncName[]={"SUMA_EngineFieldCode"};
1021 
1022    SUMA_ENTRY;
1023 
1024    if (!strlen(Scom)) SUMA_RETURN (SEF_Empty);
1025 
1026    /*fprintf(stdout,"Looking for %s\n", Scom);*/
1027    if (!strcmp(Scom,"fm")) SUMA_RETURN(SEF_fm);
1028    if (!strcmp(Scom,"im")) SUMA_RETURN(SEF_im);
1029    if (!strcmp(Scom,"fvec")) SUMA_RETURN(SEF_fvec);
1030    if (!strcmp(Scom,"ivec")) SUMA_RETURN(SEF_ivec);
1031    if (!strcmp(Scom,"fv3")) SUMA_RETURN(SEF_fv3);
1032    if (!strcmp(Scom,"iv3")) SUMA_RETURN(SEF_iv3);
1033    if (!strcmp(Scom,"fv15")) SUMA_RETURN(SEF_fv15);
1034    if (!strcmp(Scom,"iv15")) SUMA_RETURN(SEF_iv15);
1035    if (!strcmp(Scom,"fv200")) SUMA_RETURN(SEF_fv200);
1036    if (!strcmp(Scom,"iv200")) SUMA_RETURN(SEF_iv200);
1037    if (!strcmp(Scom,"i")) SUMA_RETURN(SEF_i);
1038    if (!strcmp(Scom,"f")) SUMA_RETURN (SEF_f);
1039    if (!strcmp(Scom,"s")) SUMA_RETURN (SEF_s);
1040    if (!strcmp(Scom,"vp")) SUMA_RETURN (SEF_vp); /* void pointer */
1041    if (!strcmp(Scom,"fp")) SUMA_RETURN(SEF_fp);
1042    if (!strcmp(Scom,"cp")) SUMA_RETURN(SEF_cp);
1043    if (!strcmp(Scom,"ip")) SUMA_RETURN(SEF_ip);
1044    if (!strcmp(Scom,"ngr")) SUMA_RETURN(SEF_ngr);
1045    if (!strcmp(Scom,"nel")) SUMA_RETURN(SEF_nel);
1046    /*if (!strcmp(Scom,"")) SUMA_RETURN(SEF_);*/
1047 
1048    /* Last one is Bad Code */
1049    SUMA_RETURN (SEF_BadCode);
1050 
1051 }
1052 
SUMA_EngineSourceCode(char * Scom)1053 int SUMA_EngineSourceCode (char *Scom)
1054 {
1055    static char FuncName[]={"SUMA_EngineSourceCode"};
1056 
1057    SUMA_ENTRY;
1058 
1059    if (!strlen(Scom)) SUMA_RETURN (SES_Empty);
1060    if (!strcmp(Scom,"suma")) SUMA_RETURN(SES_Suma);
1061    if (!strcmp(Scom,"afni")) SUMA_RETURN(SES_Afni);
1062    if (!strcmp(Scom,"suma_widget")) SUMA_RETURN(SES_SumaWidget);
1063    if (!strcmp(Scom,"suma_from_afni")) SUMA_RETURN(SES_SumaFromAfni);
1064    if (!strcmp(Scom,"suma_from_any")) SUMA_RETURN(SES_SumaFromAny);
1065    if (!strcmp(Scom,"unknown")) SUMA_RETURN(SES_Unknown);
1066 
1067    /* got here? Unknown */
1068    SUMA_RETURN (SES_Unknown);
1069 }
1070 
SUMA_EngineSourceString(char * Scom,int i)1071 void SUMA_EngineSourceString (char *Scom, int i)
1072 {
1073    static char FuncName[]={"SUMA_EngineSourceString"};
1074 
1075    SUMA_ENTRY;
1076 
1077    switch (i) {
1078       case SES_Empty:
1079          Scom[0]='\0';
1080          break;
1081       case SES_Suma:
1082          sprintf(Scom,"suma");
1083          break;
1084       case SES_Afni:
1085          sprintf(Scom, "afni");
1086          break;
1087       case SES_SumaWidget:
1088          sprintf(Scom, "suma_widget");
1089          break;
1090       case SES_SumaFromAfni:
1091          sprintf(Scom, "suma_from_afni");
1092          break;
1093       case SES_SumaFromAny:
1094          sprintf(Scom, "suma_from_any");
1095          break;
1096       case SES_Unknown:
1097          sprintf(Scom, "unknown");
1098          break;
1099       default:
1100          sprintf(Scom, "Undetermined flag");
1101          break;
1102    }
1103    SUMA_RETURNe;
1104 }
1105 
1106 /*!
1107 \brief Appends a new message to the list of SUMA messages, making sure
1108 the number of messages does not exceed SUMA_MAX_MESSAGES
1109 Ans = SUMA_RegisterMessage (  list, Message, Source, Type, Action );
1110 
1111 \param list (DList *) pointer to doubly linked list of messages
1112 \param Message (char *) null terminated message
1113 \param Source (char *) null terminated source of message
1114 \param Type (SUMA_MESSAGE_TYPES) Type of message to spit out
1115 \param Action (SUMA_MESSAGE_ACTION) Action to perform with message
1116 \return  YUP/NOPE, success/failure
1117 
1118 */
SUMA_RegisterMessage(DList * list,char * Message,char * Source,SUMA_MESSAGE_TYPES Type,SUMA_MESSAGE_ACTION Action)1119 SUMA_Boolean SUMA_RegisterMessage ( DList *list, char *Message,
1120                                     char *Source, SUMA_MESSAGE_TYPES Type,
1121                                     SUMA_MESSAGE_ACTION Action)
1122 {
1123    static char FuncName[]={"SUMA_RegisterMessage"};
1124    SUMA_MessageData *MD = NULL;
1125    SUMA_Boolean TryLogWindow = NOPE;
1126    int i=0, TrimTheFat=0;
1127    SUMA_Boolean LocalHead = NOPE;
1128 
1129    SUMA_ENTRY;
1130 
1131    if (!list) {
1132       fprintf (SUMA_STDERR, "Warning %s: list has not been initialized.\n"
1133                             "Nothing done.\n", FuncName);
1134       SUMA_RETURN (YUP);
1135    }
1136 
1137    /* allocate and initialize element */
1138    MD = (SUMA_MessageData *) SUMA_calloc(1,sizeof(SUMA_MessageData));
1139    if (!MD) {
1140       fprintf (SUMA_STDERR, "Error %s: Failed to allocate.\n", FuncName);
1141       SUMA_RETURN (NOPE);
1142    }
1143 
1144    MD->Message = SUMA_copy_string(Message);
1145    MD->Source = SUMA_copy_string(Source);
1146    MD->Type = Type;
1147    MD->Action = Action;
1148 
1149    SUMA_LH("Have %s %s", MD->Source, MD->Message);
1150    /* add element at end */
1151    if (dlist_ins_next (list, dlist_tail(list), (void *)MD) < 0) {
1152        fprintf (SUMA_STDERR,
1153                 "Error %s: Failed to insert message:\n%s from %s in list.\n",
1154          FuncName, MD->Message, MD->Source);
1155        SUMA_RETURN(NOPE);
1156    }
1157 
1158    /* make sure size of list is < SUMA_MAX_MESSAGES */
1159    TrimTheFat = list->size - SUMA_MAX_MESSAGES;
1160    if ( TrimTheFat > 0) {
1161       for (i=0; i < TrimTheFat; ++i) {
1162          /* remove the head */
1163          if (!SUMA_ReleaseMessageListElement (list, dlist_head(list))) {
1164             fprintf (SUMA_STDERR,
1165                      "Error %s: Failed in SUMA_ReleaseMessageListElement.\n",
1166                      FuncName);
1167             SUMA_RETURN (NOPE);
1168          }
1169       }
1170    }
1171 
1172    /* Decide on what to do with new element */
1173    switch (MD->Action) {
1174       case SMA_Nothing:
1175          break;
1176       case SMA_Log:
1177          TryLogWindow = YUP;
1178          break;
1179       case SMA_LogAndPopup:
1180          TryLogWindow = YUP;
1181          if(SUMA_isEnv("SUMA_SHOWPOPUPS","y"))
1182             SUMA_PopUpMessage (MD);
1183          break;
1184       default:
1185          break;
1186 
1187    }
1188 
1189    if (TryLogWindow) {
1190       DList *Elist=NULL;
1191       SUMA_EngineData *ED=NULL;
1192 
1193       Elist = SUMA_CreateList();
1194       SUMA_REGISTER_HEAD_COMMAND_NO_DATA(Elist, SE_UpdateLog, SES_Suma, NULL);
1195 
1196       if (!SUMA_Engine (&Elist)) {
1197          fprintf(SUMA_STDERR, "Error %s: SUMA_Engine call failed.\n", FuncName);
1198          SUMA_RETURN (NOPE);
1199       }
1200    }
1201 
1202 
1203    SUMA_RETURN (YUP);
1204 }
1205 
1206 /*!
1207    \brief forms a string out of all the messages in the Message list
1208 
1209 */
SUMA_BuildMessageLog(DList * ML)1210 char *SUMA_BuildMessageLog (DList *ML)
1211 {
1212    static char FuncName[]={"SUMA_BuildMessageLog"};
1213    char *s=NULL;
1214    SUMA_STRING *SS = NULL;
1215    SUMA_MessageData *MD=NULL;
1216    DListElmt *CurElmt=NULL;
1217 
1218    SUMA_ENTRY;
1219 
1220 
1221    if (!ML->size) { /* Nothing */
1222       SUMA_RETURN (NULL);
1223    }
1224 
1225    SS = SUMA_StringAppend (NULL, NULL);
1226 
1227    if (!(CurElmt = dlist_head(ML))) {
1228       SUMA_RETURN (NULL);
1229    }
1230    do {
1231       MD = (SUMA_MessageData *)CurElmt->data;
1232       s = SUMA_FormatMessage (MD);
1233       SS = SUMA_StringAppend (SS, s);
1234       SUMA_free(s); s = NULL;
1235       if (MD->Type != SMT_Text)
1236          SS = SUMA_StringAppend (SS, "---------------------\n");
1237    } while ((CurElmt = dlist_next(CurElmt)));
1238 
1239    /* clean SS */
1240    SS = SUMA_StringAppend (SS, NULL);
1241    /* copy s pointer and free SS */
1242    s = SS->s;
1243    SUMA_free(SS);
1244 
1245    SUMA_RETURN (s);
1246 
1247 }
1248 /*!
1249 \brief Adds a new element to the list of commands for SUMA_Engine.
1250 NewElement = SUMA_RegisterEngineListCommand (   list,  EngineData,
1251                                                 FldCode, FldValp,
1252                                                 SourceCode, SourcePointer, PassByPointer,
1253                                                 InsertAt, Element);
1254 
1255 \param list (DList *) pointer to doubly linked list of engine commands.
1256 \param EngineData (SUMA_EngineData *) a properly initialized pointer to EngineData structure.
1257 \param FldCode (SUMA_ENGINE_FIELD_CODE) code of field in EngineData structure to be filled.
1258 \param FldValp (void *) pointer to value that is to be placed in FldCode field of EngineData.
1259 \param SourceCode (SUMA_ENGINE_SOURCE) code of source issuing command.
1260 \param SourcePointer (void *) pointer to data structure of source issuing command.
1261    I use this as a pointer to the calling surface viewer structure, but you can use it for anyting you please as long
1262    as SUMA_Engine knows what to do with it. Send NULL for none.
1263 \param PassByPointer (SUMA_Boolean) flag (YUP/NOPE), if YUP then assignment is done at the pointer level (EngineData->Fld = FldValp)
1264        if NOPE then space is allocated for Fld and values are copied from FldValp[i][j] to EngineData->Fld[i][j]
1265 \param InsertAt (SUMA_ENGINE_INSERT_LOCATION) Determines where to insert the next element in the list.
1266        SEI_Head : Insert at head of list (prepend)
1267        SEI_Tail : Insert at tail of list (append)
1268        SEI_Before : Insert before Element
1269        SEI_After : Insert after Element
1270        SEI_In : Inset in Element
1271 \param Element (DListElmt *) Element relative to which the insertion is made. NULL should be used with SEI_Head and SEI_Tail
1272 
1273 \return NewElement (DListElmt *) The new element inserted into the list.
1274                                     NewElement = Element if SEI_In is used for InsertAt.
1275                                     NULL is returned if the function fails.
1276 
1277 
1278 \sa SUMA_InitializeEngineListData
1279 
1280 -PassByPointer option is only useful when dealing with fields that are/can be dynamically allocated like fm and fi.
1281 For fields like fv3 or iv15 then assignments are done by value and not pointers.
1282 -You cannot set the value of a field unless the destination for the pre-existing data in that field has been reached
1283 -When passing by value for fields requiring allocation, like fm or fi, you must be sure that EngineData->N_cols and
1284 EngineData->N_rows are set correctly before you call the function.
1285 
1286 -NOTE: If a Command requires that mutliple fields be filled, you can call this function repeatedly with the same
1287 fields except FldCode, FldValp, SourcePointer and InsertAt should be SEI_In and Element should be the pointer
1288 returned in the previous call for  SUMA_RegisterEngineListCommand.
1289 
1290 */
SUMA_RegisterEngineListCommand(DList * list,SUMA_EngineData * EngineData,SUMA_ENGINE_FIELD_CODE Fld,void * FldValp,SUMA_ENGINE_SOURCE Src,void * Srcp,SUMA_Boolean PassByPointer,SUMA_ENGINE_INSERT_LOCATION InsertAt,DListElmt * Element)1291 DListElmt * SUMA_RegisterEngineListCommand (
1292                DList *list, SUMA_EngineData * EngineData,
1293                SUMA_ENGINE_FIELD_CODE Fld, void *FldValp,
1294                SUMA_ENGINE_SOURCE Src, void *Srcp, SUMA_Boolean PassByPointer,
1295                SUMA_ENGINE_INSERT_LOCATION InsertAt, DListElmt *Element)
1296 {
1297    SUMA_ENGINE_CODE Dest=SES_Empty;
1298    static char FuncName[]={"SUMA_RegisterEngineListCommand"};
1299    SUMA_Boolean  Refill = NOPE;
1300    DListElmt *tail=NULL, *head=NULL, *NewElement=NULL;
1301    SUMA_EngineData * Old_ED=NULL;
1302    SUMA_IVEC *ivec=NULL;
1303    SUMA_FVEC *fvec=NULL;
1304    SUMA_Boolean LocalHead = NOPE;
1305 
1306    SUMA_ENTRY;
1307 
1308    if (PassByPointer) {
1309       if (Fld != SEF_im && Fld != SEF_fm && Fld != SEF_ivec && Fld != SEF_fvec) {
1310          SUMA_SL_Err("Cannot use PassByPointer except with SEF_im || "
1311                      "SEF_fm || SEF_ivec || SEF_fvec");
1312          SUMA_RETURN (NULL);
1313       }
1314    }
1315 
1316    if (!list) {
1317       SUMA_T_Err("list has not been initialized.");
1318       SUMA_RETURN (NULL);
1319    }
1320 
1321    if (InsertAt == SEI_In) {
1322       /* adding fields to EngineData, check for errors */
1323       Refill = YUP;
1324       /* Src and Srcp should be the same as before */
1325       if (!Element) {
1326          SUMA_SL_Err("NULL element with SEI_In");
1327          SUMA_RETURN(NULL);
1328       }
1329       Old_ED = (SUMA_EngineData *)Element->data;
1330       if (Old_ED != EngineData) {
1331          SUMA_S_Err(
1332             "EngineData is different from initializing call for Element.");
1333          SUMA_RETURN (NULL);
1334       }
1335       if (Old_ED->Src != Src) {
1336          SUMA_S_Err("Src is different from initializing call for Element.");
1337          SUMA_RETURN (NULL);
1338       }
1339       if (Old_ED->Srcp != Srcp) {
1340          SUMA_S_Err("Srcp is different from initializing call for Element.");
1341          SUMA_RETURN (NULL);
1342       }
1343       if (Old_ED->CommandCode != EngineData->CommandCode) {
1344          SUMA_S_Err("CommandCode is different in EngineData from the one"
1345                     " initializing call for Element.");
1346          SUMA_RETURN (NULL);
1347       }
1348 
1349    } else Refill = NOPE;
1350 
1351    Dest = EngineData->CommandCode;
1352 
1353    if (!Refill) {
1354       /* make sure Destination is good and wholesome*/
1355       switch (Dest) {
1356          case SE_BadCode:
1357             fprintf (SUMA_STDERR, "Error in %s: Bad code string.\n", FuncName);
1358             SUMA_RETURN (NULL);
1359             break;
1360          case SE_Empty:
1361             fprintf (SUMA_STDERR, "Error in %s: Empty code string.\n", FuncName);
1362             SUMA_RETURN (NULL);
1363             break;
1364          default:
1365             break;
1366       }
1367 
1368       /* make sure that Srcp is empty or the same as in EngineData */
1369       if (EngineData->Srcp != NULL) {
1370          if (EngineData->Srcp != Srcp) {
1371             fprintf (SUMA_STDERR, "Error %s: Attempting to assign a Srcp to a structure that has a different Srcp.\n", FuncName);
1372             SUMA_RETURN (NULL);
1373          }
1374       }
1375 
1376       EngineData->Srcp = Srcp;
1377       EngineData->Src = Src;
1378    }
1379 
1380    if (LocalHead) fprintf(SUMA_STDOUT, "%s: Registering %s for %s\n", FuncName, SUMA_EngineFieldString(Fld), SUMA_CommandString (Dest));
1381 
1382    switch (Fld) { /* switch Fld */
1383       case SEF_Empty:
1384          break;
1385       case SEF_fm:
1386          if (EngineData->fm_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
1387             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->fm_Dest);
1388             SUMA_RETURN (NULL);
1389          }
1390          /* space available*/
1391          if (PassByPointer) {
1392             /* pass the pointer */
1393             EngineData->fm = (float **)FldValp;
1394             EngineData->fm_LocalAlloc = NOPE; /* allocation not done by Engine functions */
1395          }
1396          else { /* pass by value */
1397             if (EngineData->fm != NULL) {
1398                fprintf(SUMA_STDERR, "Error %s: Passing by value and EngineData->fm is not NULL. Clean up your act.\n", FuncName);
1399                SUMA_RETURN(NULL);
1400             }
1401             if (!EngineData->N_rows || !EngineData->N_cols) {
1402                fprintf(SUMA_STDERR, "Error %s: EngineData->N_rows or EngineData->N_cols is 0.\n", FuncName);
1403                SUMA_RETURN(NULL);
1404             }
1405             EngineData->fm = (float **)SUMA_allocate2D(EngineData->N_rows, EngineData->N_cols, sizeof(float));
1406             if (EngineData->fm == NULL) {
1407                fprintf(SUMA_STDERR, "Error %s: Failed to allocate fm.\n", FuncName);
1408                SUMA_RETURN(NULL);
1409             }
1410             EngineData->fm_LocalAlloc = YUP; /* allocation done by Engine functions, this can be freed*/
1411             {/* copy the data */
1412                float **fm;
1413                int i, j;
1414                fm = (float **)FldValp;
1415                for (i=0; i < EngineData->N_rows; ++i) {
1416                   for (j=0; j < EngineData->N_cols; ++j)
1417                      EngineData->fm[i][j] = fm[i][j];
1418                }
1419             }/* copy the data */
1420          }/* pass by value */
1421          /* set the new destination*/
1422          EngineData->fm_Dest = Dest;
1423          EngineData->fm_Source = Src;
1424          break;
1425       case SEF_im:
1426          if (EngineData->im_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
1427             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->im_Dest);
1428             SUMA_RETURN (NULL);
1429          }
1430          /* space available*/
1431          if (PassByPointer) {
1432             /* pass the pointer */
1433             EngineData->im = (int **)FldValp;
1434             EngineData->im_LocalAlloc = NOPE; /* allocation not done by Engine functions */
1435          }   else { /* pass by value */
1436             if (EngineData->im != NULL) {
1437                fprintf(SUMA_STDERR, "Error %s: Passing by value and EngineData->im is not NULL. Clean up your act.\n", FuncName);
1438                SUMA_RETURN(NULL);
1439             }
1440             if (!EngineData->N_rows || !EngineData->N_cols) {
1441                fprintf(SUMA_STDERR, "Error %s: EngineData->N_rows or EngineData->N_cols is 0.\n", FuncName);
1442                SUMA_RETURN(NULL);
1443             }
1444             EngineData->im = (int **)SUMA_allocate2D(EngineData->N_rows, EngineData->N_cols, sizeof(int));
1445             if (EngineData->im == NULL) {
1446                fprintf(SUMA_STDERR, "Error %s: Failed to allocate im.\n", FuncName);
1447                SUMA_RETURN(NULL);
1448             }
1449             EngineData->im_LocalAlloc = YUP; /* allocation done by Engine functions, this can be freed*/
1450             {/* copy the data */
1451                int **im;
1452                int i, j;
1453                im = (int **)FldValp;
1454                for (i=0; i < EngineData->N_rows; ++i) {
1455                   for (j=0; j < EngineData->N_cols; ++j)
1456                      EngineData->im[i][j] = im[i][j];
1457                }
1458             }/* copy the data */
1459          }/* pass by value */
1460          /* set the new destination*/
1461          EngineData->im_Dest = Dest;
1462          EngineData->im_Source = Src;
1463          break;
1464 
1465       case SEF_ivec:
1466          if (EngineData->ivec_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
1467             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->ivec_Dest);
1468             SUMA_RETURN (NULL);
1469          }
1470          ivec = (SUMA_IVEC *)FldValp;
1471          /* space available*/
1472          if (PassByPointer) {
1473             EngineData->ivec = ivec;
1474             EngineData->ivec_LocalAlloc = NOPE;
1475          } else {
1476             if (EngineData->fvec != NULL) {
1477                fprintf(SUMA_STDERR, "Error %s: Passing by value and EngineData->fvec is not NULL. Clean up your act.\n", FuncName);
1478                SUMA_RETURN(NULL);
1479             }
1480             if (ivec->n <= 0 && ivec->v) {
1481                fprintf(SUMA_STDERR, "Error %s: ivec->n <= 0 while ivec->v is not NULL. Clean up your act.\n", FuncName);
1482                SUMA_RETURN(NULL);
1483             }
1484             EngineData->ivec_LocalAlloc = YUP;
1485             EngineData->ivec = (SUMA_IVEC*)SUMA_malloc(sizeof(SUMA_IVEC));
1486             EngineData->ivec->v = (int *)SUMA_malloc(ivec->n * sizeof(int));
1487             if (!EngineData->ivec->v)  {
1488                SUMA_SL_Crit("Failed to allocate");
1489                SUMA_RETURN(NULL);
1490             }
1491             SUMA_COPY_VEC(ivec->v, EngineData->ivec->v, ivec->n, int, int);
1492             EngineData->ivec->n = ivec->n;
1493          }
1494          /* set the new destination*/
1495          EngineData->ivec_Dest = Dest;
1496          EngineData->ivec_Source = Src;
1497          break;
1498 
1499      case SEF_fvec:
1500          if (EngineData->fvec_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
1501             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->fvec_Dest);
1502             SUMA_RETURN (NULL);
1503          }
1504          fvec = (SUMA_FVEC *)FldValp;
1505          /* space available*/
1506          if (PassByPointer) {
1507             EngineData->fvec = fvec;
1508             EngineData->fvec_LocalAlloc = NOPE;
1509          } else {
1510             if (EngineData->fvec != NULL) {
1511                fprintf(SUMA_STDERR, "Error %s: Passing by value and EngineData->fvec is not NULL. Clean up your act.\n", FuncName);
1512                SUMA_RETURN(NULL);
1513             }
1514             if (fvec->n <= 0 && fvec->v) {
1515                fprintf(SUMA_STDERR, "Error %s: fvec->n <= 0 while fvec->v is not NULL. Clean up your act.\n", FuncName);
1516                SUMA_RETURN(NULL);
1517             }
1518             EngineData->fvec_LocalAlloc = YUP;
1519             EngineData->fvec = (SUMA_FVEC*)SUMA_malloc(sizeof(SUMA_FVEC));
1520             EngineData->fvec->v = (float *)SUMA_malloc(fvec->n * sizeof(float));
1521             if (!EngineData->fvec->v)  {
1522                SUMA_SL_Crit("Failed to allocate");
1523                SUMA_RETURN(NULL);
1524             }
1525             SUMA_COPY_VEC(fvec->v, EngineData->fvec->v, fvec->n, float, float);
1526             EngineData->fvec->n = fvec->n;
1527          }
1528          /* set the new destination*/
1529          EngineData->fvec_Dest = Dest;
1530          EngineData->fvec_Source = Src;
1531          break;
1532 
1533       case SEF_i:
1534          if (EngineData->i_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
1535             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->i_Dest);
1536             SUMA_RETURN (NULL);
1537          }
1538          { /* assign by value */
1539             int *it;
1540             it = (int*)FldValp;
1541             EngineData->i = *it;
1542          }
1543          EngineData->i_Dest = Dest;
1544          EngineData->i_Source = Src;
1545          break;
1546 
1547       case SEF_f:
1548          if (EngineData->f_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
1549             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->f_Dest);
1550             SUMA_RETURN (NULL);
1551          }
1552          { /* assign by value */
1553             float *ft;
1554             ft = (float*)FldValp;
1555             EngineData->f = *ft;
1556          }
1557          EngineData->f_Dest = Dest;
1558          EngineData->f_Source = Src;
1559          break;
1560 
1561       case SEF_fv3:
1562          if (EngineData->fv3_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
1563             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->fv3_Dest);
1564             SUMA_RETURN (NULL);
1565          }
1566          { /* assign by value */
1567             float *fvt;
1568             int kt;
1569             fvt = (float*)FldValp;
1570             for (kt=0; kt < 3; ++kt) EngineData->fv3[kt] = fvt[kt];
1571          }
1572          EngineData->fv3_Dest = Dest;
1573          EngineData->fv3_Source = Src;
1574          break;
1575 
1576       case SEF_fv15:
1577          if (EngineData->fv15_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
1578             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->fv15_Dest);
1579             SUMA_RETURN (NULL);
1580          }
1581          { /* assign by value */
1582             float *fvt;
1583             int kt;
1584             fvt = (float*)FldValp;
1585             for (kt=0; kt < 15; ++kt) EngineData->fv15[kt] = fvt[kt];
1586          }
1587          EngineData->fv15_Dest = Dest;
1588          EngineData->fv15_Source = Src;
1589          break;
1590 
1591       case SEF_fv200:
1592          if (EngineData->fv200_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
1593             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->fv200_Dest);
1594             SUMA_RETURN (NULL);
1595          }
1596          { /* assign by value */
1597             float *fvt;
1598             int kt;
1599             fvt = (float*)FldValp;
1600             for (kt=0; kt < 200; ++kt) EngineData->fv200[kt] = fvt[kt];
1601          }
1602          EngineData->fv200_Dest = Dest;
1603          EngineData->fv200_Source = Src;
1604          break;
1605 
1606       case SEF_iv3:
1607          if (EngineData->iv3_Dest != SEF_Empty) {  /* Make sure the data in
1608                                                 this field in not predestined */
1609             fprintf(SUMA_STDERR,
1610                     "Error %s: field %d has a preset destination (%d).\n",
1611                     FuncName, Fld, EngineData->iv3_Dest);
1612             SUMA_RETURN (NULL);
1613          }
1614          { /* assign by value */
1615             int *ivt;
1616             int kt;
1617             ivt = (int*)FldValp;
1618             for (kt=0; kt < 3; ++kt) EngineData->iv3[kt] = ivt[kt];
1619          }
1620          EngineData->iv3_Dest = Dest;
1621          EngineData->iv3_Source = Src;
1622          break;
1623 
1624       case SEF_iv15:
1625          if (EngineData->iv15_Dest != SEF_Empty) { /* Make sure the data in this
1626                                                       field in not predestined */
1627             fprintf( SUMA_STDERR,
1628                      "Error %s: field %d has a preset destination (%d).\n",
1629                      FuncName, Fld, EngineData->iv15_Dest);
1630             SUMA_RETURN (NULL);
1631          }
1632          { /* assign by value */
1633             int *ivt;
1634             int kt;
1635             ivt = (int*)FldValp;
1636             for (kt=0; kt < 15; ++kt) EngineData->iv15[kt] = ivt[kt];
1637          }
1638          EngineData->iv15_Dest = Dest;
1639          EngineData->iv15_Source = Src;
1640          break;
1641 
1642       case SEF_iv200:
1643          if (EngineData->iv200_Dest != SEF_Empty) { /* Make sure the data in this                                                      field in not predestined */
1644             fprintf( SUMA_STDERR,
1645                      "Error %s: field %d has a preset destination (%d).\n",
1646                      FuncName, Fld, EngineData->iv200_Dest);
1647             SUMA_RETURN (NULL);
1648          }
1649          { /* assign by value */
1650             int *ivt;
1651             int kt;
1652             ivt = (int*)FldValp;
1653             for (kt=0; kt < 200; ++kt) EngineData->iv200[kt] = ivt[kt];
1654          }
1655          EngineData->iv200_Dest = Dest;
1656          EngineData->iv200_Source = Src;
1657          break;
1658 
1659      case SEF_s:
1660          if (EngineData->s_Dest != SEF_Empty) { /* Make sure the data in this
1661                                                    field in not predestined */
1662             fprintf( SUMA_STDERR,
1663                      "Error %s: field %d has a preset destination (%d).\n",
1664                      FuncName, Fld, EngineData->s_Dest);
1665             SUMA_RETURN (NULL);
1666          }
1667          { /* assign by value */
1668             char *st;
1669             st = (char*)FldValp;
1670             if (!st) {
1671                EngineData->s[0]='\0';
1672             } else {
1673                if (strlen(st) < SUMA_MAX_STRING_LENGTH) {
1674                   sprintf(EngineData->s,"%s", st);
1675                } else {
1676                   fprintf(SUMA_STDERR,
1677          "Error %s: string in FldValp is longer than SUMA_MAX_STRING_LENGTH.\n",
1678                      FuncName);
1679                   SUMA_RETURN (NULL);
1680                }
1681             }
1682          }
1683          EngineData->s_Dest = Dest;
1684          EngineData->s_Source = Src;
1685          break;
1686 
1687       case SEF_vp:
1688          if (EngineData->vp_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
1689             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->vp_Dest);
1690             SUMA_RETURN (NULL);
1691          }
1692          EngineData->vp = (void *)FldValp;
1693          EngineData->vp_Dest = Dest;
1694          EngineData->vp_Source = Src;
1695          break;
1696 
1697       case SEF_ip:
1698          if (EngineData->ip_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
1699             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->ip_Dest);
1700             SUMA_RETURN (NULL);
1701          }
1702          EngineData->ip = (int *)FldValp;
1703          EngineData->ip_Dest = Dest;
1704          break;
1705 
1706       case SEF_fp:
1707          if (EngineData->fp_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
1708             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->fp_Dest);
1709             SUMA_RETURN (NULL);
1710          }
1711          EngineData->fp = (float *)FldValp;
1712          EngineData->fp_Dest = Dest;
1713          break;
1714 
1715       case SEF_cp:
1716          if (EngineData->cp_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
1717             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->cp_Dest);
1718             SUMA_RETURN (NULL);
1719          }
1720          EngineData->cp = (char *)FldValp;
1721          EngineData->cp_Dest = Dest;
1722          break;
1723 
1724       case SEF_ngr:
1725          if (EngineData->ngr_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
1726             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->ngr_Dest);
1727             SUMA_RETURN (NULL);
1728          }
1729          EngineData->ngr = (NI_group *)FldValp;
1730          EngineData->ngr_Dest = Dest;
1731          break;
1732 
1733       case SEF_nel:
1734          if (EngineData->nel_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
1735             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->nel_Dest);
1736             SUMA_RETURN (NULL);
1737          }
1738          EngineData->nel = (NI_element *)FldValp;
1739          EngineData->nel_Dest = Dest;
1740          break;
1741 
1742       default:
1743          fprintf(SUMA_STDERR, "Error %s: Not setup for field %d yet.\n", FuncName, Fld);
1744          SUMA_RETURN (NULL);
1745          break;
1746    }/* switch Fld */
1747 
1748    /* Now EngineData is filled up, add an element (if not present already) to the list with EngineData */
1749    switch (InsertAt) {
1750       case SEI_In:
1751          if (LocalHead) fprintf (SUMA_STDERR, "%s: Element already in list.\n", FuncName);
1752          NewElement = Element;
1753          break;
1754       case SEI_Tail:
1755          if (LocalHead) fprintf (SUMA_STDERR, "%s: Inserting new element at end of list \n", FuncName);
1756          if (dlist_ins_next (list, dlist_tail(list), (void *)EngineData) < 0) {
1757             fprintf (SUMA_STDERR, "Error %s: Failed to insert element in list.\n", FuncName);
1758             SUMA_RETURN(NULL);
1759          }
1760          NewElement = dlist_tail(list);
1761          break;
1762       case SEI_Head:
1763          if (LocalHead) fprintf (SUMA_STDERR, "%s: Inserting new element at beginning of list \n", FuncName);
1764          if (dlist_ins_prev (list, dlist_head(list), (void *)EngineData) < 0) {
1765             fprintf (SUMA_STDERR, "Error %s: Failed to insert element in list.\n", FuncName);
1766             SUMA_RETURN(NULL);
1767          }
1768          NewElement = dlist_head(list);
1769          break;
1770       case SEI_Before:
1771          if (LocalHead) fprintf (SUMA_STDERR, "%s: Inserting new element before specified element.\n", FuncName);
1772          if (!Element) fprintf (SUMA_STDERR, "Error %s: NULL Element!\n", FuncName);
1773          if (dlist_ins_prev (list, Element, (void *)EngineData) < 0) {
1774             fprintf (SUMA_STDERR, "Error %s: Failed to insert element in list.\n", FuncName);
1775             SUMA_RETURN(NULL);
1776          }
1777          NewElement = Element->prev;
1778          if (!NewElement) {
1779             fprintf (SUMA_STDERR, "Error %s: No previous element. List size %d", FuncName, dlist_size(list));
1780             SUMA_RETURN(NULL);
1781          }
1782          break;
1783       case SEI_After:
1784          if (LocalHead) fprintf (SUMA_STDERR, "%s: Inserting new element after specified element.\n", FuncName);
1785          if (!Element) fprintf (SUMA_STDERR, "Error %s: NULL Element!\n", FuncName);
1786          if (dlist_ins_next (list, Element, (void *)EngineData) < 0) {
1787             fprintf (SUMA_STDERR, "Error %s: Failed to insert element in list.\n", FuncName);
1788             SUMA_RETURN(NULL);
1789          }
1790          NewElement = Element->next;
1791          if (!NewElement) {
1792             fprintf (SUMA_STDERR, "Error %s: No next element. List size %d", FuncName, dlist_size(list));
1793             SUMA_RETURN(NULL);
1794          }
1795          break;
1796       case SEI_WTSDS:
1797       case SEI_BadLoc:
1798       default:
1799          fprintf (SUMA_STDERR, "Error %s: Bad insertion location!\n", FuncName);
1800          SUMA_RETURN(NULL);
1801          break;
1802 
1803    }
1804 
1805    SUMA_RETURN (NewElement);
1806 }
1807 
1808 /*!
1809 SUMA_Boolean SUMA_RegisterEngineData (SUMA_EngineData *ED, char *Fldname, void *FldValp, char *DestName, char *SourceName, SUMA_Boolean PassByPointer)
1810 \param ED (SUMA_EngineData *) pointer to EngineData structure
1811 \param Fldname (char *) Field name
1812 \param FldValp (void *) Pointer to the value that is to be placed in Fldname
1813 \param DestName (char *) Name of EngineCommand that the data in Fldname is destined to
1814 \param PassByPointer (SUMA_Boolean) flag (YUP/NOPE), if YUP then assignment is done at the pointer level (ED->Fld = FldValp)
1815                         if NOPE then space is allocated for Fldname and values are copied from FldValp[i][j] to ED->Fld[i][j]
1816 
1817 \ret YUP/NOPE
1818 
1819 +PassByPointer option is only useful when dealing with fields that are/can be dynamically allocated like fm and fi. For fields like fv3 or iv15 then assignments are done by value and not pointers.
1820 +You cannot set the value of a field unless the destination for the pre-existing data in that field has been reached
1821 +When passing by value for fields requiring allocation, like fm or fi, you must be sure that ED->N_cols and ED->N_rows are
1822 set correctly before you call the function.
1823 
1824 \sa SUMA_EngineDataFieldCode
1825 \sa SUMA_ReleaseEngineData
1826 \sa SUMA_InitializeEngineData
1827 \sa SUMA_FreeEngineData
1828 \sa EngineData
1829 \sa SUMA_define.h
1830 
1831 NOTE: OBSOLETE, use SUMA_RegisterEngineListCommand
1832 */
1833 
SUMA_RegisterEngineData(SUMA_EngineData * ED,char * Fldname,void * FldValp,char * DestName,char * SourceName,SUMA_Boolean PassByPointer)1834 SUMA_Boolean SUMA_RegisterEngineData (SUMA_EngineData *ED, char *Fldname, void *FldValp, char *DestName, char *SourceName, SUMA_Boolean PassByPointer)
1835 { /* SUMA_RegisterEngineData*/
1836    int Dest, Fld, Src;
1837    static char FuncName[]={"SUMA_RegisterEngineData"};
1838 
1839    SUMA_ENTRY;
1840 
1841    fprintf (SUMA_STDERR, "Error %s: This function is now obsolete. Must use SUMA_RegisterEngineListCommand instead.\n", FuncName);
1842    SUMA_RETURN (NOPE);
1843 
1844    Dest = SUMA_CommandCode((char *)DestName);
1845    Fld = SUMA_EngineFieldCode((char *)Fldname);
1846    Src = SUMA_EngineSourceCode ((char *)SourceName);
1847 
1848    /* make sure Destination is good and wholesome*/
1849    switch (Dest) {
1850       case SE_BadCode:
1851          fprintf (SUMA_STDERR, "Error in %s: Bad code string.\n", FuncName);
1852          SUMA_RETURN (NOPE);
1853          break;
1854       case SE_Empty:
1855          fprintf (SUMA_STDERR, "Error in %s: Empty code string.\n", FuncName);
1856          SUMA_RETURN (NOPE);
1857          break;
1858       default:
1859          break;
1860    }
1861 
1862    /*fprintf(SUMA_STDOUT, "%s: Registering %s for %s\n", FuncName, Fldname, DestName);*/
1863 
1864    switch (Fld) { /* switch Fld */
1865       case SEF_fm:
1866          if (ED->fm_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
1867             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->fm_Dest);
1868             SUMA_RETURN (NOPE);
1869          }
1870          /* space available*/
1871          if (PassByPointer) {
1872             /* pass the pointer */
1873             ED->fm = (float **)FldValp;
1874             ED->fm_LocalAlloc = NOPE; /* allocation not done by Engine functions */
1875          }
1876          else { /* pass by value */
1877             if (ED->fm != NULL) {
1878                fprintf(SUMA_STDERR, "Error %s: Passing by value and ED->fm is not NULL. Clean up your act.\n", FuncName);
1879                SUMA_RETURN(NOPE);
1880             }
1881             if (!ED->N_rows || !ED->N_cols) {
1882                fprintf(SUMA_STDERR, "Error %s: ED->N_rows or ED->N_cols is 0.\n", FuncName);
1883                SUMA_RETURN(NOPE);
1884             }
1885             ED->fm = (float **)SUMA_allocate2D(ED->N_rows, ED->N_cols, sizeof(float));
1886             if (ED->fm == NULL) {
1887                fprintf(SUMA_STDERR, "Error %s: Failed to allocate fm.\n", FuncName);
1888                SUMA_RETURN(NOPE);
1889             }
1890             ED->fm_LocalAlloc = YUP; /* allocation done by Engine functions, this can be freed*/
1891             {/* copy the data */
1892                float **fm;
1893                int i, j;
1894                fm = (float **)FldValp;
1895                for (i=0; i < ED->N_rows; ++i) {
1896                   for (j=0; j < ED->N_cols; ++j)
1897                      ED->fm[i][j] = fm[i][j];
1898                }
1899             }/* copy the data */
1900          }/* pass by value */
1901          /* set the new destination*/
1902          ED->fm_Dest = Dest;
1903          ED->fm_Source = Src;
1904          SUMA_RETURN (YUP);
1905          break;
1906       case SEF_im:
1907          if (ED->im_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
1908             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->im_Dest);
1909             SUMA_RETURN (NOPE);
1910          }
1911          /* space available*/
1912          if (PassByPointer) {
1913             /* pass the pointer */
1914             ED->im = (int **)FldValp;
1915             ED->im_LocalAlloc = NOPE; /* allocation not done by Engine functions */
1916          }   else { /* pass by value */
1917             if (ED->im != NULL) {
1918                fprintf(SUMA_STDERR, "Error %s: Passing by value and ED->im is not NULL. Clean up your act.\n", FuncName);
1919                SUMA_RETURN(NOPE);
1920             }
1921             if (!ED->N_rows || !ED->N_cols) {
1922                fprintf(SUMA_STDERR, "Error %s: ED->N_rows or ED->N_cols is 0.\n", FuncName);
1923                SUMA_RETURN(NOPE);
1924             }
1925             ED->im = (int **)SUMA_allocate2D(ED->N_rows, ED->N_cols, sizeof(int));
1926             if (ED->im == NULL) {
1927                fprintf(SUMA_STDERR, "Error %s: Failed to allocate im.\n", FuncName);
1928                SUMA_RETURN(NOPE);
1929             }
1930             ED->im_LocalAlloc = YUP; /* allocation done by Engine functions, this can be freed*/
1931             {/* copy the data */
1932                int **im;
1933                int i, j;
1934                im = (int **)FldValp;
1935                for (i=0; i < ED->N_rows; ++i) {
1936                   for (j=0; j < ED->N_cols; ++j)
1937                      ED->im[i][j] = im[i][j];
1938                }
1939             }/* copy the data */
1940          }/* pass by value */
1941          /* set the new destination*/
1942          ED->im_Dest = Dest;
1943          ED->im_Source = Src;
1944          SUMA_RETURN (YUP);
1945          break;
1946 
1947       case SEF_i:
1948          if (ED->i_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
1949             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->i_Dest);
1950             SUMA_RETURN (NOPE);
1951          }
1952          { /* assign by value */
1953             int *it;
1954             it = (int*)FldValp;
1955             ED->i = *it;
1956          }
1957          ED->i_Dest = Dest;
1958          ED->i_Source = Src;
1959          SUMA_RETURN (YUP);
1960          break;
1961 
1962       case SEF_f:
1963          if (ED->f_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
1964             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->f_Dest);
1965             SUMA_RETURN (NOPE);
1966          }
1967          { /* assign by value */
1968             float *ft;
1969             ft = (float*)FldValp;
1970             ED->f = *ft;
1971          }
1972          ED->f_Dest = Dest;
1973          ED->f_Source = Src;
1974          SUMA_RETURN (YUP);
1975          break;
1976 
1977       case SEF_fv3:
1978          if (ED->fv3_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
1979             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->fv3_Dest);
1980             SUMA_RETURN (NOPE);
1981          }
1982          { /* assign by value */
1983             float *fvt;
1984             int kt;
1985             fvt = (float*)FldValp;
1986             for (kt=0; kt < 3; ++kt) ED->fv3[kt] = fvt[kt];
1987          }
1988          ED->fv3_Dest = Dest;
1989          ED->fv3_Source = Src;
1990          SUMA_RETURN (YUP);
1991          break;
1992 
1993       case SEF_fv15:
1994          if (ED->fv15_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
1995             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->fv15_Dest);
1996             SUMA_RETURN (NOPE);
1997          }
1998          { /* assign by value */
1999             float *fvt;
2000             int kt;
2001             fvt = (float*)FldValp;
2002             for (kt=0; kt < 15; ++kt) ED->fv15[kt] = fvt[kt];
2003          }
2004          ED->fv15_Dest = Dest;
2005          ED->fv15_Source = Src;
2006          SUMA_RETURN (YUP);
2007          break;
2008 
2009       case SEF_fv200:
2010          if (ED->fv200_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
2011             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->fv200_Dest);
2012             SUMA_RETURN (NOPE);
2013          }
2014          { /* assign by value */
2015             float *fvt;
2016             int kt;
2017             fvt = (float*)FldValp;
2018             for (kt=0; kt < 200; ++kt) ED->fv200[kt] = fvt[kt];
2019          }
2020          ED->fv200_Dest = Dest;
2021          ED->fv200_Source = Src;
2022          SUMA_RETURN (YUP);
2023          break;
2024 
2025       case SEF_iv3:
2026          if (ED->iv3_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
2027             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->iv3_Dest);
2028             SUMA_RETURN (NOPE);
2029          }
2030          { /* assign by value */
2031             int *ivt;
2032             int kt;
2033             ivt = (int*)FldValp;
2034             for (kt=0; kt < 3; ++kt) ED->iv3[kt] = ivt[kt];
2035          }
2036          ED->iv3_Dest = Dest;
2037          ED->iv3_Source = Src;
2038          SUMA_RETURN (YUP);
2039          break;
2040 
2041       case SEF_iv15:
2042          if (ED->iv15_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
2043             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->iv15_Dest);
2044             SUMA_RETURN (NOPE);
2045          }
2046          { /* assign by value */
2047             int *ivt;
2048             int kt;
2049             ivt = (int*)FldValp;
2050             for (kt=0; kt < 15; ++kt) ED->iv15[kt] = ivt[kt];
2051          }
2052          ED->iv15_Dest = Dest;
2053          ED->iv15_Source = Src;
2054          SUMA_RETURN (YUP);
2055          break;
2056 
2057       case SEF_iv200:
2058          if (ED->iv200_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
2059             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->iv200_Dest);
2060             SUMA_RETURN (NOPE);
2061          }
2062          { /* assign by value */
2063             int *ivt;
2064             int kt;
2065             ivt = (int*)FldValp;
2066             for (kt=0; kt < 200; ++kt) ED->iv200[kt] = ivt[kt];
2067          }
2068          ED->iv200_Dest = Dest;
2069          ED->iv200_Source = Src;
2070          SUMA_RETURN (YUP);
2071          break;
2072 
2073       case SEF_s:
2074          if (ED->s_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
2075             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->s_Dest);
2076             SUMA_RETURN (NOPE);
2077          }
2078          { /* assign by value */
2079             char *st;
2080             st = (char*)FldValp;
2081             if (!st) {
2082                ED->s[0]='\0';
2083             } else {
2084                if (strlen(st) < SUMA_MAX_STRING_LENGTH) {
2085                   sprintf(ED->s,"%s", st);
2086                } else {
2087                   fprintf(SUMA_STDERR,
2088          "Error %s: string in FldValp is longer than SUMA_MAX_STRING_LENGTH.\n",
2089                           FuncName);
2090                   SUMA_RETURN (NOPE);
2091                }
2092             }
2093          }
2094          ED->s_Dest = Dest;
2095          ED->s_Source = Src;
2096          SUMA_RETURN (YUP);
2097          break;
2098 
2099       case SEF_vp:
2100          if (ED->vp_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
2101             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->vp_Dest);
2102             SUMA_RETURN (NOPE);
2103          }
2104          ED->vp = (void *)FldValp;
2105          ED->vp_Dest = Dest;
2106          ED->vp_Source = Src;
2107          SUMA_RETURN (YUP);
2108          break;
2109 
2110       case SEF_ip:
2111          if (ED->ip_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
2112             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->ip_Dest);
2113             SUMA_RETURN (NOPE);
2114          }
2115          ED->ip = (int *)FldValp;
2116          ED->ip_Dest = Dest;
2117          SUMA_RETURN (YUP);
2118          break;
2119 
2120       case SEF_fp:
2121          if (ED->fp_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
2122             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->fp_Dest);
2123             SUMA_RETURN (NOPE);
2124          }
2125          ED->fp = (float *)FldValp;
2126          ED->fp_Dest = Dest;
2127          SUMA_RETURN (YUP);
2128          break;
2129 
2130       case SEF_cp:
2131          if (ED->cp_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
2132             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->cp_Dest);
2133             SUMA_RETURN (NOPE);
2134          }
2135          ED->cp = (char *)FldValp;
2136          ED->cp_Dest = Dest;
2137          SUMA_RETURN (YUP);
2138          break;
2139 
2140       case SEF_ngr:
2141          if (ED->ngr_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
2142             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->ngr_Dest);
2143             SUMA_RETURN (NOPE);
2144          }
2145          ED->ngr = (NI_group *)FldValp;
2146          ED->ngr_Dest = Dest;
2147          ED->ngr_Source = Src;
2148          SUMA_RETURN (YUP);
2149          break;
2150 
2151       case SEF_nel:
2152          if (ED->nel_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
2153             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->nel_Dest);
2154             SUMA_RETURN (NOPE);
2155          }
2156          ED->nel = (NI_element *)FldValp;
2157          ED->nel_Dest = Dest;
2158          ED->nel_Source = Src;
2159          SUMA_RETURN (YUP);
2160          break;
2161 
2162       default:
2163          fprintf(SUMA_STDERR, "Error %s: Not setup for field %s yet.\n", FuncName, Fldname);
2164          SUMA_RETURN (NOPE);
2165          break;
2166    }/* switch Fld */
2167 
2168 
2169 }/* SUMA_RegisterEngineData*/
2170 
2171 /*!
2172    \brief allocate and initialize the data structure for EngineData
2173    SUMA_EngineData *SUMA_InitializeEngineListData (SUMA_ENGINE_CODE CommandCode);
2174    \param CommandCode (SUMA_ENGINE_CODE) command code to store in Engine data structure
2175    \return ED (SUMA_EngineData *) Pointer to empty engine data structure with the field ED->CommandCode set to CommandCode
2176       NULL if function failed.
2177 
2178 */
SUMA_InitializeEngineListData(SUMA_ENGINE_CODE CommandCode)2179 SUMA_EngineData *SUMA_InitializeEngineListData (SUMA_ENGINE_CODE CommandCode)
2180 {
2181    static char FuncName[]={"SUMA_InitializeEngineListData"};
2182    SUMA_EngineData *ED=NULL;
2183    int i;
2184 
2185    SUMA_ENTRY;
2186 
2187    if (CommandCode <= SE_Empty || CommandCode >= SE_BadCode) {
2188       fprintf(SUMA_STDERR,"Error %s: Bad command code.\n", FuncName);
2189       SUMA_RETURN (NULL);
2190    }
2191 
2192    ED = SUMA_calloc(1,sizeof(SUMA_EngineData));
2193    if (!ED) {
2194       fprintf(SUMA_STDERR,"Error %s: Failed to allocate for ED.\n", FuncName);
2195       SUMA_RETURN (NULL);
2196    }
2197 
2198    ED->CommandCode = CommandCode;
2199    ED->Srcp = NULL;
2200    ED->fm = NULL;
2201    ED->fm_LocalAlloc = NOPE;
2202    ED->im = NULL;
2203    ED->im_LocalAlloc = NOPE;
2204    ED->N_rows = 0;
2205    ED->N_cols = 0;
2206    ED->ivec = NULL;
2207    ED->fvec = NULL;
2208    ED->ivec_LocalAlloc = NOPE;
2209    ED->fvec_LocalAlloc = NOPE;
2210    ED->i = 0;
2211    ED->f = 0.0;
2212    ED->iv3[0] = ED->iv3[1] = ED->iv3[2] = 0;
2213    ED->fv3[0] = ED->fv3[1] = ED->fv3[2] = 0.0;
2214    for (i=0; i < 15; ++i) {
2215       ED->fv15[i] = 0.0;
2216       ED->iv15[i] = 0;
2217    }
2218    for (i=0; i < 200; ++i) {
2219       ED->fv200[i] = 0.0;
2220       ED->iv200[i] = 0;
2221    }
2222    sprintf(ED->s,"NOTHING");
2223 
2224    ED->vp = NULL;
2225    ED->ngr = NULL;
2226    ED->nel = NULL;
2227    ED->fm_Dest = ED->im_Dest = ED->i_Dest = ED->f_Dest = ED->iv3_Dest = ED->fv3_Dest = \
2228    ED->fv15_Dest = ED->iv15_Dest = ED->fv200_Dest = ED->iv200_Dest = ED->s_Dest = ED->vp_Dest = ED->ip_Dest = ED->fp_Dest = \
2229    ED->cp_Dest = ED->ivec_Dest = ED->fvec_Dest = ED->ngr_Dest = ED->nel_Dest = SE_Empty;
2230 
2231    ED->fm_Source = ED->im_Source = ED->i_Source = ED->f_Source = ED->iv3_Source = ED->fv3_Source = \
2232    ED->fv15_Source = ED->iv15_Source = ED->fv200_Source = ED->iv200_Source = ED->s_Source = ED->vp_Source = \
2233    ED->ivec_Source = ED->fvec_Source = ED->ngr_Source = ED->nel_Source = SES_Empty;
2234 
2235    SUMA_RETURN (ED);
2236 
2237 }
2238 
2239 
2240 /*!
2241    Free an action stack data structure
2242    -frees AS_data->ActionData by calling destructor function
2243    -frees AS_data
2244 */
SUMA_FreeActionStackData(void * asdata)2245 void SUMA_FreeActionStackData(void *asdata)
2246 {
2247    static char FuncName[]={"SUMA_FreeActionStackData"};
2248    SUMA_ACTION_STACK_DATA *AS_data=NULL;
2249    SUMA_Boolean LocalHead = NOPE;
2250 
2251    SUMA_ENTRY;
2252 
2253    AS_data=(SUMA_ACTION_STACK_DATA *)asdata;
2254    if (AS_data) {
2255       if (LocalHead) fprintf (SUMA_STDERR, "%s: Destroying Action Stack Data \n", FuncName);
2256       /* first you want to free the Action Data */
2257       AS_data->ActionDataDestructor(AS_data->ActionData);
2258 
2259       /* Now you can free the Action Stucture Data */
2260       SUMA_free(AS_data);
2261    }
2262 
2263    SUMA_RETURNe;
2264 }
2265 
2266 /*!
2267    Releases an action stack data structure
2268    -frees AS_data->ActionData WITHOUT calling destructor function
2269    -frees AS_data
2270 */
SUMA_ReleaseActionStackData(void * asdata)2271 void SUMA_ReleaseActionStackData (void *asdata)
2272 {
2273    static char FuncName[]={"SUMA_ReleaseActionStackData"};
2274    SUMA_ACTION_STACK_DATA *AS_data=NULL;
2275    SUMA_Boolean LocalHead = NOPE;
2276 
2277    SUMA_ENTRY;
2278 
2279    AS_data=(SUMA_ACTION_STACK_DATA *)asdata;
2280    if (AS_data) {
2281       if (LocalHead) fprintf (SUMA_STDERR, "%s: Releasing Action Stack Data structure\n", FuncName);
2282       /* first you want to free the Action Data */
2283       if (AS_data->ActionData) SUMA_free(AS_data->ActionData);
2284 
2285       /* Now you can free the Action Stucture Data */
2286       SUMA_free(AS_data);
2287    }
2288 
2289    SUMA_RETURNe;
2290 }
2291 /*!
2292    \brief free a message structure and any allocated space in its fields
2293 
2294    \param Hv (void *) pointer to Message structure.
2295             It is type cast to void* to suit the standard list manipulation routines.
2296 */
SUMA_FreeMessageListData(void * Hv)2297 void SUMA_FreeMessageListData(void *Hv)
2298 {
2299    static char FuncName[]={"SUMA_FreeMessageListData"};
2300    SUMA_MessageData *H = NULL;
2301 
2302    SUMA_ENTRY;
2303 
2304    H = (SUMA_MessageData *)Hv;
2305 
2306    if (!H) {
2307       fprintf(SUMA_STDERR,"Warning %s: H is null, nothing to do!\n", FuncName);
2308       SUMA_RETURNe;
2309    }
2310 
2311 #if 1   /* Message and Source are never allocated and should not be freed. */
2312         /*                                            2003 June 19 [rickr] */
2313         /* Message and Source are now allocated */
2314         /*                 2003 June 23 [zsaad] */
2315    if (H->Message) SUMA_free(H->Message);
2316    if (H->Source) SUMA_free(H->Source);
2317 #endif
2318 
2319    if (H) SUMA_free(H);
2320 
2321    SUMA_RETURNe;
2322 }
2323 
2324 /*!
2325    \brief free an engine data structure and any allocated space in its fields
2326    SUMA_FreeEngineListData (EDv);
2327 
2328    \param EDv (void *) pointer to EngineData structure.
2329             It is type cast to void* to suit the standard list manipulation routines.
2330 
2331 if space for im or fm has been dynamically allocated in SUMA_RegisterEngineListCommand()
2332 it is released.
2333 
2334 */
SUMA_FreeEngineListData(void * EDv)2335 void SUMA_FreeEngineListData(void *EDv)
2336 {
2337    static char FuncName[]={"SUMA_FreeEngineListData"};
2338    SUMA_EngineData *ED = NULL;
2339 
2340    SUMA_ENTRY;
2341 
2342    ED = (SUMA_EngineData *)EDv;
2343 
2344    if (ED == NULL) {
2345       fprintf(SUMA_STDERR,"Warning %s: ED is null, nothing to do!\n", FuncName);
2346       SUMA_RETURNe;
2347    }
2348 
2349    /* check on Dynamic Memory Allocations needs */
2350    if (ED->fm_LocalAlloc) {
2351       if (!ED->N_rows || !ED->N_cols) {
2352          fprintf(SUMA_STDERR,"Error %s: N_rows or N_cols are 0.\n\a", FuncName);
2353          SUMA_RETURNe;
2354       }
2355       if (ED->fm == NULL) {
2356          fprintf(SUMA_STDERR,"Error %s: ED->fm is NULL, not good here.\n\a", FuncName);
2357          SUMA_RETURNe;
2358       }
2359       /* OK, free ED->fm */
2360       SUMA_free2D((char **)ED->fm, ED->N_rows);
2361    }
2362 
2363    if (ED->im_LocalAlloc) {
2364       if (!ED->N_rows || !ED->N_cols) {
2365          fprintf(SUMA_STDERR,"Error %s: N_rows or N_cols are 0.\n\a", FuncName);
2366          SUMA_RETURNe;
2367       }
2368       if (ED->im == NULL) {
2369          fprintf(SUMA_STDERR,"Error %s: ED->im is NULL, not good here.\n\a", FuncName);
2370          SUMA_RETURNe;
2371       }
2372       /* OK, free ED->im */
2373       SUMA_free2D((char **)ED->im, ED->N_rows);
2374    }
2375 
2376    /* good deal, flush ED */
2377    SUMA_free(ED);
2378    SUMA_RETURNe;
2379 }
2380 
2381 /*!
2382 SUMA_Boolean SUMA_FreeEngineData (SUMA_EngineData *ED)
2383 
2384 free memory allocated for ED in SUMA_InitializeEngineData
2385 
2386 \param ED (SUMA_EngineData *) pointer to SUMA_EngineData
2387 
2388 \ret YUP/NOPE
2389 
2390 if space for im or fm has been dynamically allocated in SUMA_RegisterEngineData
2391 it is released. ED itself is not freed
2392 
2393 OBSOLETE: Use SUMA_FreeEngineListData
2394 
2395 */
SUMA_FreeEngineData(SUMA_EngineData * ED)2396 SUMA_Boolean SUMA_FreeEngineData (SUMA_EngineData *ED)
2397 {
2398    static char FuncName[]={"SUMA_FreeEngineData"};
2399 
2400    SUMA_ENTRY;
2401 
2402    fprintf (SUMA_STDERR, "Error %s: This function is now obsolete. Must use SUMA_FreeEngineListData instead.\n", FuncName);
2403    SUMA_RETURN (NOPE);
2404 
2405    if (ED == NULL) {
2406       fprintf(SUMA_STDERR,"Error %s: ED is null, nothing to do!\n", FuncName);
2407       SUMA_RETURN (NOPE);
2408    }
2409 
2410    /* check on Dynamic Memory Allocations needs */
2411    if (ED->fm_LocalAlloc) {
2412       if (!ED->N_rows || !ED->N_cols) {
2413          fprintf(SUMA_STDERR,"Error %s: N_rows or N_cols are 0.\n", FuncName);
2414          SUMA_RETURN (NOPE);
2415       }
2416       if (ED->fm == NULL) {
2417          fprintf(SUMA_STDERR,"Error %s: ED->fm is NULL, not good here.\n", FuncName);
2418          SUMA_RETURN (NOPE);
2419       }
2420       /* OK, free ED->fm */
2421       SUMA_free2D((char **)ED->fm, ED->N_rows);
2422    }
2423 
2424    if (ED->im_LocalAlloc) {
2425       if (!ED->N_rows || !ED->N_cols) {
2426          fprintf(SUMA_STDERR,"Error %s: N_rows or N_cols are 0.\n", FuncName);
2427          SUMA_RETURN (NOPE);
2428       }
2429       if (ED->im == NULL) {
2430          fprintf(SUMA_STDERR,"Error %s: ED->im is NULL, not good here.\n", FuncName);
2431          SUMA_RETURN (NOPE);
2432       }
2433       /* OK, free ED->im */
2434       SUMA_free2D((char **)ED->im, ED->N_rows);
2435    }
2436 
2437    /* good deal, DO NOT flush ED in case it was not dynamically allocated*/
2438    SUMA_RETURN (YUP);
2439 }
2440 
2441 /*!
2442    \brief removes an element from the list, frees the data structure associated with the removed element
2443    ans = SUMA_ReleaseEngineListElement (list, element)
2444    \param list (DList *)
2445    \param element (DListElmt *)
2446    \return (YUP/NOPE), success, failure
2447 
2448    - The list is not destroyed if no elements remain in it,
2449    you should check for that after this function returns.
2450 */
SUMA_ReleaseEngineListElement(DList * list,DListElmt * element)2451 SUMA_Boolean SUMA_ReleaseEngineListElement (DList *list, DListElmt *element)
2452 {
2453    static char FuncName[]={"SUMA_ReleaseEngineListElement"};
2454    void *ED=NULL;
2455 
2456    SUMA_ENTRY;
2457    if (!element) {
2458       SUMA_SL_Err("Null element");
2459       SUMA_RETURN (NOPE);
2460    }
2461    if (dlist_remove (list, element, &ED) < 0) {
2462       fprintf (SUMA_STDERR, "Error %s: Failed to remove element from list.\n", FuncName);
2463       SUMA_RETURN (NOPE);
2464    }
2465    if (ED) { /* had an if (!ED) here..... */
2466       SUMA_FreeEngineListData((SUMA_EngineData *)ED);
2467    }
2468 
2469    SUMA_RETURN (YUP);
2470 }
2471 
2472 /*!
2473    \brief removes an element from the list, frees the data structure associated with the removed element
2474    ans = SUMA_ReleaseMessageListElement (list, element)
2475    \param list (DList *)
2476    \param element (DListElmt *)
2477    \return (YUP/NOPE), success, failure
2478 
2479    - The list is not destroyed if no elements remain in it,
2480    you should check for that after this function returns.
2481 */
SUMA_ReleaseMessageListElement(DList * list,DListElmt * element)2482 SUMA_Boolean SUMA_ReleaseMessageListElement (DList *list, DListElmt *element)
2483 {
2484    static char FuncName[]={"SUMA_ReleaseMessageListElement"};
2485    void *H=NULL;
2486 
2487    SUMA_ENTRY;
2488 
2489    if (dlist_remove (list, element, &H) < 0) {
2490       fprintf (SUMA_STDERR, "Error %s: Failed to remove element from list.\n", FuncName);
2491       SUMA_RETURN (NOPE);
2492    }
2493    if (H) {/* had an if (!H) here..... */
2494       SUMA_FreeMessageListData((SUMA_MessageData *)H);
2495    }
2496 
2497    SUMA_RETURN (YUP);
2498 }
2499 
2500 
2501 /*!
2502    \brief destroys a list IF IT IS EMPTY !
2503    list = SUMA_DestroyList (list);
2504 
2505    \param list (DList *)
2506    \return ans (DList *) NULL if function succeeds, list if function fails
2507 
2508    ++ list is also freed (Jan. 29 04)
2509    \sa SUMA_EmptyDestroyList
2510 */
SUMA_DestroyList(DList * list)2511 DList * SUMA_DestroyList (DList *list)
2512 {
2513    static char FuncName[]={"SUMA_DestroyList"};
2514 
2515    SUMA_ENTRY;
2516 
2517    if (list->size) {
2518       fprintf (SUMA_STDERR,
2519                "Error %s: list still contains elements.\n", FuncName);
2520       SUMA_RETURN (list);
2521    }
2522 
2523    dlist_destroy(list);
2524    if (list) SUMA_free(list);
2525    SUMA_RETURN (NULL);
2526 }
2527 
2528 /*!
2529    \brief destroys a list even if it is not empty
2530    list = SUMA_DestroyList (list);
2531 
2532    \param list (DList *)
2533    \return ans (DList *) NULL always
2534    ++ list is also freed (Jan. 29 04)
2535    \sa SUMA_DestroyList
2536 */
SUMA_EmptyDestroyList(DList * list)2537 DList * SUMA_EmptyDestroyList (DList *list)
2538 {
2539    static char FuncName[]={"SUMA_EmptyDestroyList"};
2540 
2541    SUMA_ENTRY;
2542 
2543    dlist_destroy(list);
2544    if (list) SUMA_free(list);
2545    SUMA_RETURN (NULL);
2546 }
2547 
2548 /*!
2549    \brief creates a list for the Action Stack
2550    list = SUMA_CreateActionStack ();
2551    \return list (DList *) pointer to doubly linked list
2552             NULL if function fails
2553 
2554 */
SUMA_CreateActionStack(void)2555 DList *SUMA_CreateActionStack (void)
2556 {
2557    static char FuncName[]={"SUMA_CreateActionStack"};
2558    DList *list=NULL;
2559 
2560    SUMA_ENTRY;
2561 
2562    list = (DList *)calloc(1,sizeof(DList));
2563    if (!list) {
2564       fprintf (SUMA_STDERR, "Error %s: Failed to allocate for list.\n", FuncName);
2565       SUMA_RETURN(NULL);
2566    }
2567 
2568    /*
2569       Do not use: dlist_init(list, SUMA_FreeActionStackData);
2570       You do not want to destroy data stored inside the ActionStack because
2571       the data is used elsewhere. Destruction of ActionStackData should
2572       only be done when a stack element is above the new Do element and will
2573       therefore never be used again. */
2574 
2575    dlist_init(list, SUMA_ReleaseActionStackData);
2576 
2577    SUMA_RETURN (list);
2578 }
2579 
2580 /*!
2581    \brief destroys the Action Stack
2582    ans = SUMA_DestroyActionStack (DList *AS);
2583 
2584    \returns NULL
2585 
2586 */
SUMA_EmptyDestroyActionStack(DList * AS)2587 DList *SUMA_EmptyDestroyActionStack (DList *AS)
2588 {
2589    static char FuncName[]={"SUMA_DestroyActionStack"};
2590 
2591    SUMA_ENTRY;
2592 
2593    dlist_destroy(AS); SUMA_free(AS); AS = NULL;
2594 
2595    SUMA_RETURN (NULL);
2596 }
2597 
2598 /*!
2599    \brief creates a list for the message list
2600    list = SUMA_CreateMessageList ();
2601    \return list (DList *) pointer to doubly linked list
2602             NULL if function fails
2603 
2604             DO not use common field variables here.
2605 */
SUMA_CreateMessageList(void)2606 DList *SUMA_CreateMessageList (void)
2607 {
2608    static char FuncName[]={"SUMA_CreateMessageList"};
2609    DList *list=NULL;
2610 
2611 
2612    list = (DList *)calloc(1,sizeof(DList));
2613    if (!list) {
2614       fprintf (SUMA_STDERR, "Error %s: Failed to allocate for list.\n", FuncName);
2615       return (NULL);
2616    }
2617 
2618    dlist_init(list, SUMA_FreeMessageListData);
2619 
2620    return (list);
2621 }
2622 
2623 /*!
2624    \brief creates a list for SUMA_Engine
2625    list = SUMA_CreateList ();
2626    \return list (DList *) pointer to doubly linked list
2627             NULL if function fails
2628 */
SUMA_CreateList(void)2629 DList *SUMA_CreateList (void)
2630 {
2631    static char FuncName[]={"SUMA_CreateList"};
2632    DList *list=NULL;
2633 
2634    SUMA_ENTRY;
2635 
2636    list = (DList *)SUMA_calloc(1,sizeof(DList));
2637    if (!list) {
2638       fprintf (SUMA_STDERR, "Error %s: Failed to allocate for list.\n", FuncName);
2639       SUMA_RETURN (NULL);
2640    }
2641 
2642    dlist_init(list, SUMA_FreeEngineListData);
2643 
2644    SUMA_RETURN (list);
2645 }
2646 
2647 /*!
2648 SUMA_Boolean SUMA_ReleaseEngineData (SUMA_EngineData *ED, char *Location)
2649 
2650 This function releases data fields that were destined to Location
2651 
2652 \param ED (SUMA_EngineData *) pointer to Engine data structure
2653 \param Location (char *) location in SUMA_Engine, from which the function was called (one of the commands in SUMA_Engine)
2654 
2655 \ret YUP/NOPE
2656 
2657 Memory is freed for fm and im only if their assignment in SUMA_RegisterEngineData was done by value
2658 
2659 \sa SUMA_EngineDataFieldCode
2660 \sa SUMA_ReleaseEngineData
2661 \sa SUMA_InitializeEngineData
2662 \sa SUMA_FreeEngineData
2663 \sa EngineData
2664 \sa SUMA_define.h
2665 \sa SUMA_RegisterEngineData
2666 
2667 OBSOLETE: Use SUMA_ReleaseEngineListElement
2668 */
SUMA_ReleaseEngineData(SUMA_EngineData * ED,char * Location)2669 SUMA_Boolean SUMA_ReleaseEngineData (SUMA_EngineData *ED, char *Location)
2670 {/* SUMA_ReleaseEngineData*/
2671    static char FuncName[]={"SUMA_ReleaseEngineData"};
2672    int Loc;
2673 
2674    SUMA_ENTRY;
2675 
2676    fprintf (SUMA_STDERR, "Error %s: This function is now obsolete. Must use SUMA_ReleaseEngineListElement instead.\n", FuncName);
2677    SUMA_RETURN (NOPE);
2678 
2679    /* search through all fields and clear (or release) all those who should be */
2680    Loc = SUMA_CommandCode((char *)Location);
2681 
2682    /* make sure Destination is good and wholesome*/
2683    switch (Loc) {
2684       case SE_BadCode:
2685          fprintf (SUMA_STDERR, "Error in %s: Bad code string.\n", FuncName);
2686          SUMA_RETURN (NOPE);
2687          break;
2688       case SE_Empty:
2689          fprintf (SUMA_STDERR, "Error in %s: Empty code string.\n", FuncName);
2690          SUMA_RETURN (NOPE);
2691          break;
2692       default:
2693          break;
2694    }
2695 
2696    /*fprintf(SUMA_STDOUT,"%s : Releasing location %s\n", FuncName, Location);*/
2697    /* go through all the fields*/
2698    /* fm */
2699    if (ED->fm_Dest == Loc) {
2700       /* needs to be released */
2701       if (ED->fm_LocalAlloc) { /* locally allocated */
2702          /* must be freed */
2703          if (!ED->N_rows || !ED->N_cols) {
2704             fprintf (SUMA_STDERR, "Error in %s: ED->N_rows or ED->N_cols is 0 .\n", FuncName);
2705             SUMA_RETURN (NOPE);
2706          }
2707          if (ED->fm == NULL) {
2708             fprintf (SUMA_STDERR, "Error in %s: fm is null already. This should not be .\n", FuncName);
2709             SUMA_RETURN (NOPE);
2710          }
2711          SUMA_free2D((char **)ED->fm, ED->N_rows);
2712          ED->N_rows = ED->N_cols = 0;
2713          ED->fm = NULL;
2714          ED->fm_Dest = SE_Empty;
2715          ED->fm_Source = SES_Empty;
2716       } /* locally allocated */ else { /* passed by pointer */
2717          ED->fm = NULL;
2718          ED->N_rows = ED->N_cols = 0;
2719          ED->fm_Dest = SE_Empty;
2720          ED->fm_Source = SES_Empty;
2721       }/* passed by pointer */
2722    }
2723 
2724    /*im*/
2725    if (ED->im_Dest == Loc) {
2726       /* needs to be released */
2727       if (ED->im_LocalAlloc) { /* locally allocated */
2728          /* must be freed */
2729          if (!ED->N_rows || !ED->N_cols) {
2730             fprintf (SUMA_STDERR, "Error in %s: ED->N_rows or ED->N_cols is 0 .\n", FuncName);
2731             SUMA_RETURN (NOPE);
2732          }
2733          if (ED->im == NULL) {
2734             fprintf (SUMA_STDERR, "Error in %s: im is null already. This should not be .\n", FuncName);
2735             SUMA_RETURN (NOPE);
2736          }
2737          SUMA_free2D((char **)ED->im, ED->N_rows);
2738          ED->N_rows = ED->N_cols = 0;
2739          ED->im = NULL;
2740          ED->im_Dest = SE_Empty;
2741          ED->im_Source = SES_Empty;
2742       } /* locally allocated */ else { /* passed by pointer */
2743          ED->im = NULL;
2744          ED->N_rows = ED->N_cols = 0;
2745          ED->im_Dest = SE_Empty;
2746          ED->im_Source = SES_Empty;
2747       }/* passed by pointer */
2748    }
2749 
2750    /* ivec */
2751    if (ED->ivec_Dest == Loc) {
2752       /* needs to be released */
2753       if (ED->ivec_LocalAlloc) { /* locally allocated */
2754          /* must be freed */
2755          if (!ED->ivec) {
2756             fprintf (SUMA_STDERR, "Error %s: NULL ivec, why?\n", FuncName);
2757             SUMA_RETURN (NOPE);
2758          }
2759          if (ED->ivec->n > 0 && !ED->ivec->v) {
2760             fprintf (SUMA_STDERR, "Error %s: ED->ivec->n >= 0 && ED->ivec->v = NULL.\n", FuncName);
2761             SUMA_RETURN (NOPE);
2762          }
2763          if (ED->ivec->v == NULL) {
2764             fprintf (SUMA_STDERR, "Error in %s: v is null already. This should not be .\n", FuncName);
2765             SUMA_RETURN (NOPE);
2766          }
2767          if (ED->ivec->v) SUMA_free(ED->ivec->v);
2768          if (ED->ivec) SUMA_free(ED->ivec);
2769          ED->ivec = NULL;
2770          ED->ivec_Dest = SE_Empty;
2771          ED->ivec_Source = SES_Empty;
2772       } /* locally allocated */ else { /* passed by pointer */
2773          ED->ivec = NULL;
2774          ED->ivec_Dest = SE_Empty;
2775          ED->ivec_Source = SES_Empty;
2776       }/* passed by pointer */
2777    }
2778 
2779    /* fvec */
2780    if (ED->fvec_Dest == Loc) {
2781       /* needs to be released */
2782       if (ED->fvec_LocalAlloc) { /* locally allocated */
2783          /* must be freed */
2784          if (!ED->fvec) {
2785             fprintf (SUMA_STDERR, "Error %s: NULL fvec, why?\n", FuncName);
2786             SUMA_RETURN (NOPE);
2787          }
2788          if (ED->fvec->n > 0 && !ED->fvec->v) {
2789             fprintf (SUMA_STDERR, "Error %s: ED->fvec->n >= 0 && ED->fvec->v = NULL.\n", FuncName);
2790             SUMA_RETURN (NOPE);
2791          }
2792          if (ED->fvec->v == NULL) {
2793             fprintf (SUMA_STDERR, "Error in %s: v is null already. This should not be .\n", FuncName);
2794             SUMA_RETURN (NOPE);
2795          }
2796          if (ED->fvec->v) SUMA_free(ED->fvec->v);
2797          if (ED->fvec) SUMA_free(ED->fvec);
2798          ED->fvec = NULL;
2799          ED->fvec_Dest = SE_Empty;
2800          ED->fvec_Source = SES_Empty;
2801       } /* locally allocated */ else { /* passed by pointer */
2802          ED->fvec = NULL;
2803          ED->fvec_Dest = SE_Empty;
2804          ED->fvec_Source = SES_Empty;
2805       }/* passed by pointer */
2806    }
2807 
2808   /* i */
2809    if (ED->i_Dest == Loc) {
2810       ED->i_Dest = SE_Empty;
2811       ED->i_Source = SES_Empty;
2812    }
2813 
2814    /* iv3 */
2815    if (ED->iv3_Dest == Loc) {
2816       ED->iv3_Dest = SE_Empty;
2817       ED->iv3_Source = SES_Empty;
2818    }
2819 
2820    /* iv15 */
2821    if (ED->iv15_Dest == Loc) {
2822       ED->iv15_Dest = SE_Empty;
2823       ED->iv15_Source = SES_Empty;
2824    }
2825 
2826    /* iv200 */
2827    if (ED->iv200_Dest == Loc) {
2828       ED->iv200_Dest = SE_Empty;
2829       ED->iv200_Source = SES_Empty;
2830    }
2831 
2832    /* f */
2833    if (ED->f_Dest == Loc) {
2834       ED->f_Dest = SE_Empty;
2835       ED->f_Source = SES_Empty;
2836    }
2837 
2838    /* fv3 */
2839    if (ED->fv3_Dest == Loc) {
2840       ED->fv3_Dest = SE_Empty;
2841       ED->fv3_Source = SES_Empty;
2842    }
2843 
2844    /* fv15 */
2845    if (ED->fv15_Dest == Loc) {
2846       ED->fv15_Dest = SE_Empty;
2847       ED->fv15_Source = SES_Empty;
2848    }
2849 
2850    /* fv200 */
2851    if (ED->fv200_Dest == Loc) {
2852       ED->fv200_Dest = SE_Empty;
2853       ED->fv200_Source = SES_Empty;
2854    }
2855 
2856    /*s*/
2857    if (ED->s_Dest == Loc) {
2858       ED->s_Dest = SE_Empty;
2859       ED->s_Source = SES_Empty;
2860    }
2861 
2862    /* vp */
2863    if (ED->vp_Dest == Loc) {
2864       ED->vp_Dest = SE_Empty;
2865       ED->vp_Source = SES_Empty;
2866    }
2867 
2868    /* cp */
2869    if (ED->cp_Dest == Loc) {
2870       ED->cp_Dest = SE_Empty;
2871    }
2872 
2873    /* ip */
2874    if (ED->ip_Dest == Loc) {
2875       ED->ip_Dest = SE_Empty;
2876    }
2877 
2878    /* fp */
2879    if (ED->fp_Dest == Loc) {
2880       ED->fp_Dest = SE_Empty;
2881    }
2882    /* SUMA_RETURN, tout va bien */
2883    SUMA_RETURN (YUP);
2884 }
2885 
2886 /*!
2887    \brief Writes the commands to be executed in list
2888           SUMA_ShowList (list, Out);
2889    \param list (DList *) Pointer to list
2890    \param Out (FILE *) pointer to output stream, if NULL then Out is stdout
2891    \return (void)
2892 
2893 */
SUMA_ShowList(DList * list,FILE * Out)2894 void SUMA_ShowList (DList *list, FILE *Out)
2895 {
2896    static char FuncName[]={"SUMA_ShowList"};
2897    DListElmt *NE;
2898    SUMA_EngineData *ED;
2899 
2900    SUMA_ENTRY;
2901 
2902    if (!Out) Out = stdout;
2903 
2904    if (!list) {
2905       fprintf (Out,"%s: NULL List.\n", FuncName);
2906       SUMA_RETURNe;
2907    }
2908 
2909    if (!list->size) {
2910       fprintf (Out,"%s: Empty List.\n", FuncName);
2911       SUMA_RETURNe;
2912    }
2913 
2914    fprintf (Out,"%s: List of %d elements.\n\t", FuncName, list->size);
2915    do{
2916       NE = dlist_head(list);
2917       ED = (SUMA_EngineData *) NE->data;
2918       if (!ED) {
2919          fprintf (Out, "NULL-This should not be | ");
2920       } else {
2921          fprintf (Out, "%s | ", SUMA_CommandString (ED->CommandCode));
2922       }
2923    } while (!dlist_is_tail(NE));
2924 
2925    fprintf (Out,"\n");
2926 
2927    SUMA_RETURNe;
2928 }
2929 
2930 /*!
2931    \brief looks for words in str to guess what surface type
2932    is being mentioned
2933    at times you're better off with
2934    SUMA_GuessSurfFormatFromExtension_core and/or
2935    SUMA_GuessSurfFormatFromExtension
2936 */
SUMA_guess_surftype_argv(char * str)2937 SUMA_SO_File_Type SUMA_guess_surftype_argv(char *str)
2938 {
2939    static char FuncName[]={"SUMA_guess_surftype_argv"};
2940    SUMA_SO_File_Type tp=SUMA_FT_NOT_SPECIFIED;
2941 
2942    SUMA_ENTRY;
2943    if (  SUMA_iswordin_ci(str, "FreeSurfer") == 1 ||
2944          SUMA_iswordin_ci(str, "fs") == 1 ) {
2945       SUMA_RETURN( SUMA_FREE_SURFER );
2946    }
2947    if (  SUMA_iswordin_ci(str, "SureFit")  == 1 ||
2948          SUMA_iswordin_ci(str, "sf") == 1  ||
2949          SUMA_iswordin_ci(str, "caret") == 1 )
2950       SUMA_RETURN( SUMA_SUREFIT );
2951    if (  SUMA_iswordin_ci(str, "Inventor")  == 1 ||
2952          SUMA_iswordin_ci(str, "iv") == 1  ||
2953          SUMA_iswordin_ci(str, "inv") == 1 )
2954       SUMA_RETURN( SUMA_INVENTOR_GENERIC );
2955    if (SUMA_iswordin_ci(str, "dx")  == 1 )
2956       SUMA_RETURN( SUMA_OPENDX_MESH );
2957    if (SUMA_iswordin_ci(str, "obj")  == 1 )
2958       SUMA_RETURN( SUMA_OBJ_MESH );
2959    if (SUMA_iswordin_ci(str, "pre")  == 1 )
2960       SUMA_RETURN( SUMA_PREDEFINED );
2961    if (SUMA_iswordin_ci(str, "ply")  == 1 )
2962       SUMA_RETURN( SUMA_PLY );
2963    if (SUMA_iswordin_ci(str, "stl")  == 1 )
2964       SUMA_RETURN( SUMA_STL );
2965    if (SUMA_iswordin_ci(str, "mni")  == 1 )
2966       SUMA_RETURN( SUMA_MNI_OBJ );
2967    if (  SUMA_iswordin_ci(str, "vec")  == 1 ||
2968          SUMA_iswordin_ci(str, "1d") == 1   )
2969       SUMA_RETURN( SUMA_VEC );
2970    if (SUMA_iswordin_ci(str, "BrainVoyager") == 1  ||
2971          SUMA_iswordin_ci(str, "bv") == 1 )
2972       SUMA_RETURN( SUMA_BRAIN_VOYAGER );
2973    if (SUMA_iswordin_ci(str, "BYU") == 1  )
2974       SUMA_RETURN( SUMA_BYU );
2975    if (  SUMA_iswordin_ci(str, "GIFTI") == 1  ||
2976          SUMA_iswordin_ci(str, "GII") == 1  )
2977       SUMA_RETURN( SUMA_GIFTI );
2978    if (SUMA_iswordin_ci(str, "cmap")  == 1 )
2979       SUMA_RETURN( SUMA_CMAP_SO );
2980 
2981    SUMA_RETURN(tp);
2982 }
2983 
2984 /*!
2985    \brief Surface Type from extension
2986    \param Name (char *) name
2987    \return Type SUMA_SO_File_Type
2988    Bad name for function, should be ...SurfTypeFromExte...
2989 */
SUMA_GuessSurfFormatFromExtension_core(char * Name,char ** pdspec,char ** pdsv,char ** pdsname)2990 SUMA_SO_File_Type SUMA_GuessSurfFormatFromExtension_core(char *Name,
2991                                     char **pdspec, char **pdsv, char **pdsname)
2992 {
2993    static char FuncName[]={"SUMA_GuessSurfFormatFromExtension_core"};
2994    SUMA_SO_File_Type form=SUMA_FT_NOT_SPECIFIED;
2995    int tp=0;
2996    char *pname=NULL;
2997 
2998    SUMA_ENTRY;
2999    if (!Name) { SUMA_RETURN(form); }
3000    if (pdsname && *pdsname) {
3001       SUMA_S_Err("Bad init for pdsname");
3002       SUMA_RETURN(form);
3003    }
3004    if ( (tp = SUMA_is_predefined_SO_name(Name, NULL,
3005                                           pdspec, pdsv, &pname)) ) {
3006       /* fprintf(stderr,"tp=%d\n", tp); */
3007       switch(tp) {
3008          case 1:
3009          case 2:
3010             if (pdsname) *pdsname=pname;
3011             else SUMA_ifree(pname);
3012             SUMA_RETURN(SUMA_PREDEFINED);
3013             break;
3014          case 3:
3015             /* Spec file, not for here */
3016             break;
3017          case 4: /* pre-existing template file */
3018             Name = pname; /* format TBD below */
3019             break;
3020       }
3021    }
3022 
3023    if (  SUMA_isExtension(Name, ".1D.coord") ||
3024          SUMA_isExtension(Name, ".1D.topo")) form = SUMA_VEC;
3025    else if (  SUMA_isExtension(Name, ".1D") ) form = SUMA_VEC;
3026    else if (  SUMA_isExtension(Name, ".asc")) form = SUMA_FREE_SURFER;
3027    else if (  SUMA_isExtension(Name, ".topo") ||
3028          SUMA_isExtension(Name, ".coord") ) form = SUMA_SUREFIT;
3029    else if (  SUMA_isExtension(Name, ".iv") ) form = SUMA_INVENTOR_GENERIC;
3030    else if (  SUMA_isExtension(Name, ".dx")) form = SUMA_OPENDX_MESH;
3031    else if (  SUMA_isExtension(Name, ".obj")) form = SUMA_OBJ_MESH;
3032    else if (  SUMA_isExtension(Name, ".stl")) form = SUMA_STL;
3033    else if (  SUMA_isExtension(Name, ".ply")) form = SUMA_PLY;
3034    else if (  SUMA_isExtension(Name, ".obj")) form = SUMA_MNI_OBJ;
3035    else if (  SUMA_isExtension(Name, ".srf")) form = SUMA_BRAIN_VOYAGER;
3036    else if (  SUMA_isExtension(Name, ".gii")) form = SUMA_GIFTI;
3037    else if (  SUMA_isExtension(Name, ".byu") ||
3038          SUMA_isExtension(Name, ".g") ||
3039          SUMA_isExtension(Name, ".go")) form =  SUMA_BYU;
3040    else if (  SUMA_isExtension(Name, ".cmap")) form = SUMA_CMAP_SO;
3041 
3042    if (pdsname) *pdsname=pname;
3043    else SUMA_ifree(pname);
3044 
3045    SUMA_RETURN(form);
3046 }
3047 
SUMA_GuessSurfFormatFromExtension(char * Name,char * fallbackname)3048 SUMA_SO_File_Type SUMA_GuessSurfFormatFromExtension(
3049    char *Name,
3050    char *fallbackname)
3051 {
3052    static char FuncName[]={"SUMA_GuessSurfFormatFromExtension"};
3053    SUMA_SO_File_Type form=SUMA_FT_NOT_SPECIFIED;
3054 
3055    SUMA_ENTRY;
3056 
3057    if (!Name && fallbackname) {Name = fallbackname;}
3058    form = SUMA_GuessSurfFormatFromExtension_core(Name, NULL, NULL, NULL);
3059 
3060    if (form <= SUMA_NO_DSET_FORMAT && fallbackname && Name != fallbackname ) {
3061       /* try with fallback */
3062       form = SUMA_GuessSurfFormatFromExtension_core(fallbackname,
3063                                                     NULL, NULL, NULL);
3064    }
3065 
3066    SUMA_RETURN(form);
3067 }
3068 
3069 
3070 
3071 /*!
3072    \brief a function to allocate and initialize the option structure
3073    that is to be used by most programs.
3074 
3075    This is probably the least elegant function. Do not change initialization values
3076    because they might affect different programs in various ways.
3077    Some options are very specific to an application, others are common to many
3078 
3079    \sa SUMA_Free_Generic_Prog_Options_Struct
3080    \sa SUMA_GENERIC_PROG_OPTIONS_STRUCT
3081 */
SUMA_Alloc_Generic_Prog_Options_Struct(void)3082 SUMA_GENERIC_PROG_OPTIONS_STRUCT * SUMA_Alloc_Generic_Prog_Options_Struct(void)
3083 {
3084    static char FuncName[]={"SUMA_Alloc_Generic_Prog_Options_Struct"};
3085    int i;
3086    SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt = NULL;
3087 
3088    SUMA_ENTRY;
3089 
3090    Opt = (SUMA_GENERIC_PROG_OPTIONS_STRUCT *)
3091             SUMA_calloc(1,sizeof(SUMA_GENERIC_PROG_OPTIONS_STRUCT));
3092    Opt->SpatNormDxyz = 0.0;
3093    Opt->spec_file = NULL;
3094    Opt->surftype = NULL;
3095    Opt->out_vol_prefix = NULL;
3096    Opt->out_vol_view[0]='\0';
3097    Opt->out_vol_exists = -1;
3098    Opt->out_grid_prefix = NULL;
3099    Opt->out_grid_view[0]='\0';
3100    Opt->out_grid_exists = -1;
3101    Opt->in_vol_prefix = NULL;
3102    Opt->in_vol_view[0]='\0';
3103    Opt->in_vol_exists = -1;
3104    Opt->out_prefix = NULL;
3105    Opt->oform = SUMA_NO_DSET_FORMAT;
3106    Opt->sv_name = NULL;
3107    Opt->N_surf = -1;
3108    Opt->in_name = NULL;
3109    for (i=0; i<SUMA_GENERIC_PROG_MAX_IN_NAME; ++i) { Opt->in_namev[i] = NULL; }
3110    Opt->n_in_namev = 0;
3111    Opt->cmask = NULL;
3112    Opt->MaskMode = SUMA_ISO_UNDEFINED;
3113    for (i=0; i<SUMA_GENERIC_PROG_MAX_SURF; ++i) { Opt->surf_names[i] = NULL; }
3114    Opt->in_vol = NULL;
3115    Opt->nvox = -1;
3116    Opt->ninmask = -1;
3117    Opt->mcfv = NULL;
3118    Opt->debug = 0;
3119    Opt->v0 = 0.0;
3120    Opt->v1 = 0.0;
3121    Opt->dvec = NULL;
3122    Opt->fvec = NULL; Opt->n_fvec=-1; Opt->fvec_dim=-1;
3123    Opt->SurfFileType = SUMA_PLY;
3124    Opt->SurfFileFormat = SUMA_ASCII;
3125    Opt->xform = SUMA_ISO_XFORM_UNDEFINED;
3126    Opt->obj_type = -1;
3127    Opt->obj_type_res = -1;
3128    Opt->XYZ = NULL;
3129    Opt->in_1D = NULL;
3130    Opt->N_XYZ = 0;
3131    Opt->Zt = 0.0;
3132    Opt->ExpFrac = 0.0;
3133    Opt->N_it = 0;
3134    Opt->Icold = 0;
3135    Opt->NodeDbg = -1;
3136    Opt->t2 = Opt->t98 = Opt->t = Opt->tm = -1;
3137    Opt->r = 0;
3138    Opt->d1 = 0;
3139    Opt->su1 = 0;
3140    Opt->UseNew = 0.0;
3141    Opt->d4 = 0;
3142    Opt->ztv = NULL;
3143    Opt->Kill98 = 0;
3144    Opt->NoEyes = 0;
3145    Opt->NNsmooth = 0;
3146    Opt->smootheach = 0;
3147    Opt->avoid_vent = 0;
3148    Opt->smooth_end = 0;
3149    Opt->fix_winding = 0;
3150    Opt->k98mask = NULL;
3151    Opt->k98maskcnt = 0;
3152    Opt->dbg_eyenodes = NULL;
3153    Opt->travstp = 0.0;
3154    Opt->Stop = NULL;
3155    Opt->MaxIntIter = 0;
3156    Opt->UseExpansion = 0;
3157    Opt->PercInt = 0;
3158    Opt->UseSkull = 0;
3159    Opt->send_hull = 0;
3160    Opt->bot_lztclip = 0.0; /* 0.5 is OK but causes too much leakage below cerebellum in most dsets, 0.65 seems better. 0 if you do not want to use it*/
3161    Opt->var_lzt = 0.0; /* a flag at the moment, set it to 1 to cause shirnk fac to vary during iterations. Helps escape certain large
3162                            chunks of CSF just below the brain */
3163    Opt->DemoPause = 0;
3164    Opt->DoSpatNorm = 0;
3165    Opt->WriteSpatNorm = 0;
3166    Opt->fillhole = -1;
3167    Opt->iset = NULL;
3168    Opt->SpatShift[0] = Opt->SpatShift[1] = Opt->SpatShift[2] = 0.0;
3169    Opt->OrigSpatNormedSet = NULL;
3170    Opt->in_edvol = NULL;
3171    Opt->blur_fwhm = 0.0;
3172    Opt->iset_hand = 0;
3173    Opt->shrink_bias_name = NULL;
3174    Opt->shrink_bias = NULL;
3175    Opt->specie = HUMAN;
3176 
3177    Opt->NearestNode = 0;
3178    Opt->NearestTriangle = 0;
3179    Opt->DistanceToMesh = 0;
3180    Opt->ProjectionOnMesh = 0;
3181    Opt->Data = 0;
3182 
3183    Opt->in_nodeindices = NULL;
3184 
3185    Opt->popt = NULL;
3186 
3187    Opt->emask = NULL;
3188    Opt->fatemask = NULL;
3189    Opt->Use_emask = 0;
3190    Opt->PushToEdge = 0;
3191 
3192    Opt->nmask = NULL;
3193 
3194    Opt->Brain_Contour = NULL;
3195    Opt->Brain_Hull = NULL;
3196    Opt->Skull_Outer = NULL;
3197    Opt->Skull_Inner = NULL;
3198 
3199    Opt->UseThisBrain = NULL; /* do not free, argv[.] copy */
3200    Opt->UseThisBrainHull = NULL; /* do not free, argv[.] copy */
3201    Opt->UseThisSkullOuter = NULL; /* do not free, argv[.] copy */
3202    Opt->unit_sphere_name = NULL; /* do not free, argv[.] copy */
3203    Opt->bases_prefix = NULL; /* do not free, argv[.] copy */
3204    Opt->SurfaceCoil = 0;
3205 
3206    Opt->com = NULL;
3207    Opt->N_com = 0;
3208 
3209    Opt->s = NULL;
3210 
3211    Opt->ps = NULL; /* just a holder */
3212    SUMA_RETURN(Opt);
3213 }
3214 
SUMA_Free_Generic_Prog_Options_Struct(SUMA_GENERIC_PROG_OPTIONS_STRUCT * Opt)3215 SUMA_GENERIC_PROG_OPTIONS_STRUCT * SUMA_Free_Generic_Prog_Options_Struct(SUMA_GENERIC_PROG_OPTIONS_STRUCT *Opt)
3216 {
3217    static char FuncName[]={"SUMA_Free_Generic_Prog_Options_Struct"};
3218    int i;
3219    SUMA_ENTRY;
3220 
3221    if (!Opt) SUMA_RETURN(NULL);
3222 
3223    Opt->ps = NULL; /* DO NOT FREE THIS ONE HERE */
3224    if (Opt->OrigSpatNormedSet && Opt->OrigSpatNormedSet != Opt->in_vol) {
3225       DSET_delete(Opt->OrigSpatNormedSet); Opt->OrigSpatNormedSet = NULL;
3226    } else Opt->OrigSpatNormedSet = NULL;
3227 
3228    if (Opt->dbg_eyenodes) fclose(Opt->dbg_eyenodes); Opt->dbg_eyenodes = NULL;
3229    if (Opt->k98mask) SUMA_free(Opt->k98mask); Opt->k98mask = NULL;
3230    if (Opt->Stop) SUMA_free(Opt->Stop); Opt->Stop = NULL;
3231    if (Opt->dvec) SUMA_free(Opt->dvec); Opt->dvec = NULL;
3232    if (Opt->fvec) SUMA_free(Opt->fvec); Opt->fvec = NULL;
3233    if (Opt->mcfv) {SUMA_free(Opt->mcfv); Opt->mcfv = NULL;}
3234    if (Opt->in_vol) { DSET_delete( Opt->in_vol); Opt->in_vol = NULL;}
3235    if (Opt->out_prefix) SUMA_free(Opt->out_prefix); Opt->out_prefix = NULL;
3236    if (Opt->out_vol_prefix) SUMA_free(Opt->out_vol_prefix);
3237                                                 Opt->out_vol_prefix = NULL;
3238    if (Opt->in_vol_prefix) SUMA_free(Opt->in_vol_prefix);
3239                                                    Opt->in_vol_prefix = NULL;
3240    if (Opt->out_grid_prefix) SUMA_free(Opt->out_grid_prefix);
3241                                                 Opt->out_grid_prefix = NULL;
3242    if (Opt->XYZ) SUMA_free(Opt->XYZ); Opt->XYZ = NULL;
3243    if (Opt->ztv) SUMA_free(Opt->ztv); Opt->ztv = NULL;
3244    if (Opt->shrink_bias) SUMA_free(Opt->shrink_bias);
3245                                              Opt->shrink_bias = NULL;
3246    if (Opt->shrink_bias_name) SUMA_free(Opt->shrink_bias_name);
3247                                              Opt->shrink_bias_name = NULL;
3248    if (Opt->popt) Opt->popt = NULL; /* freeing, if needed for this structure
3249                                        should be done elsewhere*/
3250    if (Opt->emask) SUMA_free(Opt->emask); Opt->emask = NULL;
3251    if (Opt->fatemask) SUMA_free(Opt->fatemask); Opt->fatemask = NULL;
3252    if (Opt->nmask) SUMA_free(Opt->nmask); Opt->nmask = NULL;
3253    if (Opt->Brain_Contour)  SUMA_free(Opt->Brain_Contour);
3254                                              Opt->Brain_Contour= NULL;
3255    if (Opt->Brain_Hull)  SUMA_free(Opt->Brain_Hull); Opt->Brain_Hull= NULL;
3256    if (Opt->Skull_Outer)  SUMA_free(Opt->Skull_Outer); Opt->Skull_Outer= NULL;
3257    if (Opt->Skull_Inner)  SUMA_free(Opt->Skull_Inner); Opt->Skull_Inner= NULL;
3258    if (Opt->com) {
3259       for (i=0; i<Opt->N_com; ++i) if (Opt->com[i]) SUMA_free(Opt->com[i]);
3260       SUMA_free(Opt->com);
3261    }
3262    if (Opt->s) {
3263       SUMA_free(Opt->s); Opt->s=NULL;
3264    }
3265    if (Opt) SUMA_free(Opt);
3266 
3267    SUMA_RETURN(NULL);
3268 
3269 }
SUMA_CreateGenericArgParse(char * optflags)3270 SUMA_GENERIC_ARGV_PARSE *SUMA_CreateGenericArgParse(char *optflags)
3271 {
3272    static char FuncName[]={"SUMA_CreateGenericArgParse"};
3273    SUMA_GENERIC_ARGV_PARSE *ps=NULL;
3274    int i;
3275    SUMA_ENTRY;
3276 
3277    ps = (SUMA_GENERIC_ARGV_PARSE*)
3278             SUMA_calloc(1,sizeof(SUMA_GENERIC_ARGV_PARSE));
3279    ps->cmask = NULL;
3280    ps->nmaskname = NULL;
3281    ps->bmaskname = NULL;
3282 
3283    ps->cmap = NULL;
3284    ps->cmapfile = NULL;
3285    ps->cmapdb = NULL;
3286 
3287    ps->cs = NULL;
3288 
3289    for (i=0;i<SUMA_MAX_SURF_ON_COMMAND; ++i) {
3290       ps->t_surfnames[i]   =  ps->t_surftopo[i] =
3291                               ps->t_surfpath[i] =
3292                               ps->t_surfprefix[i] =
3293                               ps->t_state[i] = NULL;
3294       ps->t_N_surfnames = 0;
3295       ps->t_FF[i] = SUMA_FF_NOT_SPECIFIED;
3296       ps->t_FT[i] = SUMA_FT_NOT_SPECIFIED;
3297       ps->t_anatomical[i] = NOPE;
3298       ps->i_surfnames[i]   =  ps->i_surftopo[i] =
3299                               ps->i_surfpath[i] =
3300                               ps->i_surfprefix[i] =
3301                               ps->i_state[i] =
3302                               ps->i_group[i] = NULL;
3303       ps->i_N_surfnames = 0;
3304       ps->i_FF[i] = SUMA_FF_NOT_SPECIFIED;
3305       ps->i_FT[i] = SUMA_FT_NOT_SPECIFIED;
3306       ps->i_anatomical[i] = NOPE;
3307       ps->ipar_surfnames[i]   =  ps->ipar_surftopo[i] =
3308                                  ps->ipar_surfpath[i] =
3309                                  ps->ipar_surfprefix[i] =
3310                                  ps->ipar_state[i] =
3311                                  ps->ipar_group[i] = NULL;
3312       ps->ipar_N_surfnames = 0;
3313       ps->ipar_FF[i] = SUMA_FF_NOT_SPECIFIED;
3314       ps->ipar_FT[i] = SUMA_FT_NOT_SPECIFIED;
3315       ps->ipar_anatomical[i] = NOPE;
3316       ps->o_surfnames[i]   =  ps->o_surftopo[i] =
3317                               ps->o_surfpath[i] =
3318                               ps->o_surfprefix[i] =
3319                               ps->o_state[i] =
3320                               ps->o_group[i] = NULL;
3321       ps->o_N_surfnames = 0;
3322       ps->o_FF[i] = SUMA_FF_NOT_SPECIFIED;
3323       ps->o_FT[i] = SUMA_FT_NOT_SPECIFIED;
3324       ps->o_anatomical[i] = NOPE;
3325       ps->s_surfnames[i]   =  ps->s_surfprefix[i] =
3326                               ps->s_surfpath[i] = NULL;
3327       ps->s_N_surfnames = 0;
3328       ps->spec_names[i] = NULL;
3329       ps->N_spec_names = 0;
3330       ps->sv[i] = NULL; ps->N_sv = 0;
3331       ps->vp[i] = NULL; ps->N_vp = 0;
3332 
3333       ps->hverb = 0;
3334    }
3335 
3336    ps->N_dsetname = 0;
3337    for (i=0; i<SUMA_MAX_DSET_ON_COMMAND; ++i) {
3338       ps->dsetname[i]=NULL;
3339    }
3340 
3341    ps->N_DO = 0;
3342    for (i=0; i<SUMA_MAX_DO_ON_COMMAND; ++i) {
3343       ps->DO_name[i]=NULL;
3344       ps->DO_type[i] = NOT_SET_type;
3345    }
3346 
3347    for (i=0; i< SUMA_N_ARGS_MAX; ++i) {
3348       ps->arg_checked[i] = 0;
3349    }
3350    ps->N_args = 0;
3351 
3352    if (SUMA_iswordin(optflags,"-t;"))
3353       ps->accept_t = 1; else ps->accept_t = 0;
3354    if (SUMA_iswordin(optflags,"-i;"))
3355       ps->accept_i = 1; else ps->accept_i = 0;
3356    if (SUMA_iswordin(optflags,"-ipar;"))
3357       ps->accept_ipar = 1; else ps->accept_ipar = 0;
3358    if (SUMA_iswordin(optflags,"-s;"))
3359       ps->accept_s = 1; else ps->accept_s = 0;
3360    if (SUMA_iswordin(optflags,"-o;"))
3361       ps->accept_o = 1; else ps->accept_o = 0;
3362    if (SUMA_iswordin(optflags,"-spec;"))
3363       ps->accept_spec = 1; else ps->accept_spec = 0;
3364    if (SUMA_iswordin(optflags,"-sv;"))
3365       ps->accept_sv = 1; else ps->accept_sv = 0;
3366    if (SUMA_iswordin(optflags,"-talk;"))
3367       ps->accept_talk_suma = 1; else ps->accept_talk_suma = 0;
3368    if (SUMA_iswordin(optflags,"-m;")||SUMA_iswordin(optflags,"-mask;"))
3369       ps->accept_mask = 1; else ps->accept_mask = 0;
3370    if (SUMA_iswordin(optflags,"-dset;")||SUMA_iswordin(optflags,"-d;"))
3371       ps->accept_dset = 1; else ps->accept_dset = 0;
3372    if (SUMA_iswordin(optflags,"-do;")||SUMA_iswordin(optflags,"-d;"))
3373       ps->accept_do = 1; else ps->accept_do = 0;
3374    if (SUMA_iswordin(optflags,"-cmap;"))
3375       ps->accept_cmap = 1; else ps->accept_cmap = 0;
3376 
3377    ps->check_input_surf = 1;
3378    SUMA_RETURN(ps);
3379 }
3380 
SUMA_FreeGenericArgParse(SUMA_GENERIC_ARGV_PARSE * ps)3381 SUMA_GENERIC_ARGV_PARSE *SUMA_FreeGenericArgParse(SUMA_GENERIC_ARGV_PARSE *ps)
3382 {
3383    static char FuncName[]={"SUMA_FreeGenericArgParse"};
3384    int i;
3385    SUMA_ENTRY;
3386 
3387    if (ps) {
3388       for (i=0; i<SUMA_MAX_SURF_ON_COMMAND; ++i) {
3389          if (ps->t_surfnames[i])
3390             SUMA_free(ps->t_surfnames[i]); ps->t_surfnames[i]= NULL;
3391          if (ps->t_surftopo[i])
3392             SUMA_free(ps->t_surftopo[i]); ps->t_surftopo[i]= NULL;
3393          if (ps->t_surfpath[i])
3394             SUMA_free(ps->t_surfpath[i]); ps->t_surfpath[i]= NULL;
3395          if (ps->t_surfprefix[i])
3396             SUMA_free(ps->t_surfprefix[i]);ps->t_surfprefix[i] = NULL;
3397          if (ps->t_state[i]) SUMA_free(ps->t_state[i]);ps->t_state[i] = NULL;
3398          if (ps->i_surfnames[i])
3399             SUMA_free(ps->i_surfnames[i]); ps->i_surfnames[i]= NULL;
3400          if (ps->i_surftopo[i])
3401             SUMA_free(ps->i_surftopo[i]); ps->i_surftopo[i]= NULL;
3402          if (ps->i_surfpath[i])
3403             SUMA_free(ps->i_surfpath[i]); ps->i_surfpath[i]= NULL;
3404          if (ps->i_surfprefix[i])
3405             SUMA_free(ps->i_surfprefix[i]);ps->i_surfprefix[i] = NULL;
3406          if (ps->i_state[i]) SUMA_free(ps->i_state[i]);ps->i_state[i] = NULL;
3407          if (ps->ipar_surfnames[i])
3408             SUMA_free(ps->ipar_surfnames[i]); ps->ipar_surfnames[i]= NULL;
3409          if (ps->ipar_surftopo[i])
3410             SUMA_free(ps->ipar_surftopo[i]); ps->ipar_surftopo[i]= NULL;
3411          if (ps->ipar_surfpath[i])
3412             SUMA_free(ps->ipar_surfpath[i]); ps->ipar_surfpath[i]= NULL;
3413          if (ps->ipar_surfprefix[i])
3414             SUMA_free(ps->ipar_surfprefix[i]);ps->ipar_surfprefix[i] = NULL;
3415          if (ps->ipar_state[i])
3416             SUMA_free(ps->ipar_state[i]);ps->ipar_state[i] = NULL;
3417          if (ps->o_surfnames[i])
3418             SUMA_free(ps->o_surfnames[i]); ps->o_surfnames[i]= NULL;
3419          if (ps->o_surftopo[i])
3420             SUMA_free(ps->o_surftopo[i]); ps->o_surftopo[i]= NULL;
3421          if (ps->o_surfpath[i])
3422             SUMA_free(ps->o_surfpath[i]); ps->o_surfpath[i]= NULL;
3423          if (ps->o_surfprefix[i])
3424             SUMA_free(ps->o_surfprefix[i]);   ps->o_surfprefix[i] = NULL;
3425          if (ps->o_state[i]) SUMA_free(ps->o_state[i]);ps->o_state[i] = NULL;
3426          if (ps->s_surfnames[i])
3427             SUMA_free(ps->s_surfnames[i]); ps->s_surfnames[i]= NULL;
3428          if (ps->s_surfprefix[i])
3429             SUMA_free(ps->s_surfprefix[i]);ps->s_surfprefix[i] = NULL;
3430          if (ps->s_surfpath[i])
3431             SUMA_free(ps->s_surfpath[i]); ps->s_surfpath[i]= NULL;
3432          if (ps->spec_names[i])
3433             SUMA_free(ps->spec_names[i]); ps->spec_names[i] = NULL;
3434          if (ps->sv[i]) SUMA_free(ps->sv[i]); ps->sv[i] = NULL;
3435          if (ps->vp[i]) SUMA_free(ps->vp[i]); ps->vp[i] = NULL;
3436       }
3437       for (i=0; i<SUMA_MAX_DSET_ON_COMMAND; ++i) {
3438          if (ps->dsetname[i]) SUMA_free(ps->dsetname[i]); ps->dsetname[i]=NULL;
3439       }
3440       for (i=0; i<SUMA_MAX_DO_ON_COMMAND; ++i) {
3441          if (ps->DO_name[i]) SUMA_free(ps->DO_name[i]); ps->DO_name[i]=NULL;
3442       }
3443       if (ps->nmaskname) SUMA_free(ps->nmaskname); ps->nmaskname = NULL;
3444       if (ps->bmaskname) SUMA_free(ps->nmaskname); ps->nmaskname = NULL;
3445       if (ps->cmask) SUMA_free(ps->cmask); ps->cmask = NULL;
3446       if (ps->cmap) SUMA_free(ps->cmap); ps->cmap = NULL;
3447       if (ps->cmapdb) SUMA_free(ps->cmapdb); ps->cmapdb = NULL;
3448       if (ps->cmapfile) SUMA_free(ps->cmapfile); ps->cmapfile = NULL;
3449 
3450       if (ps->cs) SUMA_Free_CommSrtuct(ps->cs); ps->cs = NULL;
3451       SUMA_free(ps); ps = NULL;
3452    }
3453    SUMA_RETURN(NULL);
3454 }
3455 
SUMA_help_IO_Args(SUMA_GENERIC_ARGV_PARSE * opt)3456 char *SUMA_help_IO_Args(SUMA_GENERIC_ARGV_PARSE *opt)
3457 {
3458    static char FuncName[]={"SUMA_help_IO_Args"};
3459    char *s=NULL, *st = NULL;
3460    SUMA_STRING *SS = NULL;
3461 
3462    SUMA_ENTRY;
3463    SS = SUMA_StringAppend (NULL, NULL);
3464 
3465 
3466    if (opt->accept_do) {
3467       SS = SUMA_StringAppend (SS,
3468 " Specifying displayable objects:\n"
3469 "    -cdset CDSET: Load and display a CIFTI dataset\n"
3470 "    -gdset GDSET: Load and display a graph dataset\n"
3471 "    -tract TRACT: Load and display a tractography dataset\n"
3472 "    -vol VOL: Load and display a volume\n"
3473       );
3474    }
3475 
3476    if (opt->accept_i) {
3477       SS = SUMA_StringAppend_va (SS,
3478 " Specifying input surfaces using -i or -i_TYPE options: \n"
3479 "    -i_TYPE inSurf specifies the input surface,\n"
3480 "            TYPE is one of the following:\n"
3481 "       fs: FreeSurfer surface. \n"
3482 "           If surface name has .asc it is assumed to be\n"
3483 "           in ASCII format. Otherwise it is assumed to be\n"
3484 "           in BINARY_BE (Big Endian) format.\n"
3485 "           Patches in Binary format cannot be read at the moment.\n"
3486 "       sf: SureFit surface. \n"
3487 "           You must specify the .coord followed by the .topo file.\n"
3488 "       vec (or 1D): Simple ascii matrix format. \n"
3489 "            You must specify the coord (NodeList) file followed by \n"
3490 "            the topo (FaceSetList) file.\n"
3491 "            coord contains 3 floats per line, representing \n"
3492 "            X Y Z vertex coordinates.\n"
3493 "            topo contains 3 ints per line, representing \n"
3494 "            v1 v2 v3 triangle vertices.\n"
3495 "       ply: PLY format, ascii or binary.\n"
3496 "            Only vertex and triangulation info is preserved.\n"
3497 "       stl: STL format, ascii or binary.\n"
3498 "            This format of no use for much of the surface-based\n"
3499 "            analyses. Objects are defined as a soup of triangles\n"
3500 "            with no information about which edges they share. STL is only\n"
3501 "            useful for taking surface models to some 3D printing \n"
3502 "            software.\n"
3503 "       mni: MNI .obj format, ascii only.\n"
3504 "            Only vertex, triangulation, and node normals info is preserved.\n"
3505 "       byu: BYU format, ascii.\n"
3506 "            Polygons with more than 3 edges are turned into\n"
3507 "            triangles.\n"
3508 "       bv: BrainVoyager format. \n"
3509 "           Only vertex and triangulation info is preserved.\n"
3510 "       dx: OpenDX ascii mesh format.\n"
3511 "           Only vertex and triangulation info is preserved.\n"
3512 "           Requires presence of 3 objects, the one of class \n"
3513 "           'field' should contain 2 components 'positions'\n"
3514 "           and 'connections' that point to the two objects\n"
3515 "           containing node coordinates and topology, respectively.\n"
3516 "       gii: GIFTI XML surface format.\n"
3517 "       obj: OBJ file format for triangular meshes only. The following\n"
3518 "            primitives are preserved: v (vertices), \f (faces, triangles\n"
3519 "            only), and p (points)\n"
3520 " Note that if the surface filename has the proper extension, \n"
3521 " it is enough to use the -i option and let the programs guess\n"
3522 " the type from the extension.\n"
3523 "\n"
3524 " You can also specify multiple surfaces after -i option. This makes\n"
3525 " it possible to use wildcards on the command line for reading in a bunch\n"
3526 " of surfaces at once.\n"
3527 "\n"
3528 "     -onestate: Make all -i_* surfaces have the same state, i.e.\n"
3529 "                they all appear at the same time in the viewer.\n"
3530 "                By default, each -i_* surface has its own state. \n"
3531 "                For -onestate to take effect, it must precede all -i\n"
3532 "                options with on the command line. \n"
3533 "     -anatomical: Label all -i surfaces as anatomically correct.\n"
3534 "                Again, this option should precede the -i_* options.\n"
3535 "\n"
3536 " More variants for option -i:\n"
3537 "-----------------------------\n"
3538 " You can also load standard-mesh spheres that are formed in memory\n"
3539 " with the following notation\n"
3540 "     -i ldNUM:  Where NUM is the parameter controlling\n"
3541 "                the mesh density exactly as the parameter -ld linDepth\n"
3542 "                does in CreateIcosahedron. For example: \n"
3543 "                    suma -i ld60\n"
3544 "                create on the fly a surface that is identical to the\n"
3545 "                one produced by: CreateIcosahedron -ld 60 -tosphere\n"
3546 "     -i rdNUM: Same as -i ldNUM but with NUM specifying the equivalent\n"
3547 "               of parameter -rd recDepth in CreateIcosahedron.\n"
3548 "\n"
3549 " To keep the option confusing enough, you can also use -i to load\n"
3550 " template surfaces. For example:\n"
3551 "           suma -i lh:MNI_N27:ld60:smoothwm \n"
3552 " will load the left hemisphere smoothwm surface for template MNI_N27 \n"
3553 " at standard mesh density ld60.\n"
3554 " The string following -i is formatted thusly:\n"
3555 "     HEMI:TEMPLATE:DENSITY:SURF where:\n"
3556 "     HEMI specifies a hemisphere. Choose from 'l', 'r', 'lh' or 'rh'.\n"
3557 "          You must specify a hemisphere with option -i because it is \n"
3558 "          supposed to load one surface at a time. \n"
3559 "          You can load multiple surfaces with -spec which also supports \n"
3560 "          these features.\n"
3561 "     TEMPLATE: Specify the template name. For now, choose from MNI_N27 if\n"
3562 "               you want to use the FreeSurfer reconstructed surfaces from\n"
3563 "               the MNI_N27 volume, or TT_N27\n"
3564 "               Those templates must be installed under this directory:\n"
3565 "                 %s\n"
3566 "               If you have no surface templates there, download\n"
3567 "                 https://afni.nimh.nih.gov/pub/dist/tgz/suma_MNI_N27.tgz\n"
3568 "               and/or\n"
3569 "                 https://afni.nimh.nih.gov/pub/dist/tgz/suma_TT_N27.tgz\n"
3570 "               and/or\n"
3571 "                 https://afni.nimh.nih.gov/pub/dist/tgz/suma_MNI152_2009.tgz\n"
3572 "               and untar them under directory %s\n"
3573 "     DENSITY: Use if you want to load standard-mesh versions of the template\n"
3574 "              surfaces. Note that only ld20, ld60, ld120, and ld141 are in\n"
3575 "              the current distributed templates. You can create other \n"
3576 "              densities if you wish with MapIcosahedron, but follow the\n"
3577 "              same naming convention to enable SUMA to find them.\n"
3578 "     SURF: Which surface do you want. The string matching is partial, as long\n"
3579 "           as the match is unique. \n"
3580 "           So for example something like: suma -i l:MNI_N27:ld60:smooth\n"
3581 "           is more than enough to get you the ld60 MNI_N27 left hemisphere\n"
3582 "           smoothwm surface.\n"
3583 "     The order in which you specify HEMI, TEMPLATE, DENSITY, and SURF, does\n"
3584 "     not matter.\n"
3585 "     For template surfaces, the -sv option is provided automatically, so you\n"
3586 "     can have SUMA talking to AFNI with something like:\n"
3587 "             suma -i l:MNI_N27:ld60:smooth &\n"
3588 "             afni -niml %s/suma_MNI_N27 \n"
3589 "\n",
3590       THD_datadir(1), THD_datadir(1), THD_datadir(0));
3591    }
3592    if (opt->accept_ipar) {
3593       SS = SUMA_StringAppend (SS,
3594 "    -ipar_TYPE ParentSurf specifies the parent surface. Only used\n"
3595 "            when -o_fsp is used, see -o_TYPE options.\n"
3596       );
3597    }
3598 
3599    if (opt->accept_t) {
3600       SS = SUMA_StringAppend (SS,
3601 " Specifying surfaces using -t* options: \n"
3602 "   -tn TYPE NAME: specify surface type and name.\n"
3603 "                  See below for help on the parameters.\n"
3604 "   -tsn TYPE STATE NAME: specify surface type state and name.\n"
3605 "        TYPE: Choose from the following (case sensitive):\n"
3606 "           1D: 1D format\n"
3607 "           FS: FreeSurfer ascii format\n"
3608 "           PLY: ply format\n"
3609 "           MNI: MNI obj ascii format\n"
3610 "           BYU: byu format\n"
3611 "           SF: Caret/SureFit format\n"
3612 "           BV: BrainVoyager format\n"
3613 "           GII: GIFTI format\n"
3614 "        NAME: Name of surface file. \n"
3615 "           For SF and 1D formats, NAME is composed of two names\n"
3616 "           the coord file followed by the topo file\n"
3617 "        STATE: State of the surface.\n"
3618 "           Default is S1, S2.... for each surface.\n"
3619       );
3620    }
3621 
3622 
3623    if (opt->accept_sv) {
3624       SS = SUMA_StringAppend (SS,
3625 " Specifying a Surface Volume:\n"
3626 "    -sv SurfaceVolume [VolParam for sf surfaces]\n"
3627 "       If you supply a surface volume, the coordinates of the input surface.\n"
3628 "        are modified to SUMA's convention and aligned with SurfaceVolume.\n"
3629 "        You must also specify a VolParam file for SureFit surfaces.\n"
3630       );
3631    }
3632 
3633    if (opt->accept_spec) {
3634       char *ss = SUMA_help_SPEC_symbolic();
3635       SS = SUMA_StringAppend_va (SS,
3636 " Specifying a surface specification (spec) file:\n"
3637 "    -spec SPEC: specify the name of the SPEC file.\n"
3638 "%s\n",
3639    ss
3640       );
3641       SUMA_ifree(ss);
3642    }
3643 
3644    if (opt->accept_s) {
3645       SS = SUMA_StringAppend (SS,
3646 " Specifying a surface using -surf_? method:\n"
3647 "    -surf_A SURFACE: specify the name of the first\n"
3648 "            surface to load. If the program requires\n"
3649 "            or allows multiple surfaces, use -surf_B\n"
3650 "            ... -surf_Z .\n"
3651 "            You need not use _A if only one surface is\n"
3652 "            expected.\n"
3653 "            SURFACE is the name of the surface as specified\n"
3654 "            in the SPEC file. The use of -surf_ option \n"
3655 "            requires the use of -spec option.\n"
3656 
3657       );
3658    }
3659 
3660    if (opt->accept_o) {
3661       SS = SUMA_StringAppend (SS,
3662 " Specifying output surfaces using -o or -o_TYPE options: \n"
3663 "    -o_TYPE outSurf specifies the output surface, \n"
3664 "            TYPE is one of the following:\n"
3665 "       fs: FreeSurfer ascii surface. \n"
3666 "       fsp: FeeSurfer ascii patch surface. \n"
3667 "            In addition to outSurf, you need to specify\n"
3668 "            the name of the parent surface for the patch.\n"
3669 "            using the -ipar_TYPE option.\n"
3670 "            This option is only for ConvertSurface \n"
3671 "       sf: SureFit surface. \n"
3672 "           For most programs, you are expected to specify prefix:\n"
3673 "           i.e. -o_sf brain. In some programs, you are allowed to \n"
3674 "           specify both .coord and .topo file names: \n"
3675 "           i.e. -o_sf XYZ.coord TRI.topo\n"
3676 "           The program will determine your choice by examining \n"
3677 "           the first character of the second parameter following\n"
3678 "           -o_sf. If that character is a '-' then you have supplied\n"
3679 "           a prefix and the program will generate the coord and topo names.\n"
3680 "       vec (or 1D): Simple ascii matrix format. \n"
3681 "            For most programs, you are expected to specify prefix:\n"
3682 "            i.e. -o_1D brain. In some programs, you are allowed to \n"
3683 "            specify both coord and topo file names: \n"
3684 "            i.e. -o_1D brain.1D.coord brain.1D.topo\n"
3685 "            coord contains 3 floats per line, representing \n"
3686 "            X Y Z vertex coordinates.\n"
3687 "            topo contains 3 ints per line, representing \n"
3688 "            v1 v2 v3 triangle vertices.\n"
3689 "       ply: PLY format, ascii or binary.\n"
3690 "       stl: STL format, ascii or binary (see also STL under option -i_TYPE).\n"
3691 "       byu: BYU format, ascii or binary.\n"
3692 "       mni: MNI obj format, ascii only.\n"
3693 "       gii: GIFTI format, ascii.\n"
3694 "            You can also enforce the encoding of data arrays\n"
3695 "            by using gii_asc, gii_b64, or gii_b64gz for \n"
3696 "            ASCII, Base64, or Base64 Gzipped. \n"
3697 "            If AFNI_NIML_TEXT_DATA environment variable is set to YES, the\n"
3698 "            the default encoding is ASCII, otherwise it is Base64.\n"
3699 "       obj: No support for writing OBJ format exists yet.\n"
3700 " Note that if the surface filename has the proper extension, \n"
3701 " it is enough to use the -o option and let the programs guess\n"
3702 " the type from the extension.\n"      );
3703    }
3704 
3705    if (opt->accept_dset) {
3706       st = SUMA_help_dset();
3707       SS = SUMA_StringAppend_va (SS,
3708                   "\n"
3709                   "%s"
3710                   "\n",
3711                   st
3712       );
3713       SUMA_free(st); st = NULL;
3714    }
3715 
3716    if (opt->accept_mask) {
3717       st = SUMA_help_mask();
3718       SS = SUMA_StringAppend_va (SS,
3719                   "\n"
3720                   "%s"
3721                   "\n",
3722                   st
3723       );
3724       SUMA_free(st); st = NULL;
3725    }
3726 
3727    if (opt->accept_cmap) {
3728       st = SUMA_help_cmap();
3729       SS = SUMA_StringAppend_va (SS,
3730                   "\n"
3731                   "%s"
3732                   "\n",
3733                   st
3734       );
3735       SUMA_free(st); st = NULL;
3736    }
3737 
3738    if (opt->accept_talk_suma) {
3739       st = SUMA_help_talk();
3740       SS = SUMA_StringAppend_va (SS,
3741                   "\n"
3742                   "%s"
3743                   "\n",
3744                   st
3745       );
3746       SUMA_free(st); st = NULL;
3747    }
3748 
3749    SUMA_SS2S(SS, s);
3750 
3751    SUMA_RETURN(s);
3752 
3753 }
3754 
SUMA_isOutputFormatFromArg(char * argi,SUMA_DSET_FORMAT * oform)3755 SUMA_Boolean SUMA_isOutputFormatFromArg(char *argi, SUMA_DSET_FORMAT *oform)
3756 {
3757    static char FuncName[]={"SUMA_isOutputFormatFromArg"};
3758    SUMA_DSET_FORMAT oforml = SUMA_NO_DSET_FORMAT;
3759    int sgn = 0;
3760    SUMA_Boolean isformat=NOPE;
3761 
3762    SUMA_ENTRY;
3763 
3764    isformat = SUMA_isIOFormatFromArg(argi, &oforml, &sgn);
3765    if (isformat && sgn > 0) {/* that is output */
3766       *oform = oforml;
3767       SUMA_RETURN(YUP);
3768    }
3769 
3770    SUMA_RETURN(NOPE);
3771 }
SUMA_isInputFormatFromArg(char * argi,SUMA_DSET_FORMAT * oform)3772 SUMA_Boolean SUMA_isInputFormatFromArg(char *argi, SUMA_DSET_FORMAT *oform)
3773 {
3774    static char FuncName[]={"SUMA_isInputFormatFromArg"};
3775    SUMA_DSET_FORMAT oforml = SUMA_NO_DSET_FORMAT;
3776    int sgn = 0;
3777    SUMA_Boolean isformat=NOPE;
3778 
3779    SUMA_ENTRY;
3780 
3781    isformat = SUMA_isIOFormatFromArg(argi, &oforml, &sgn);
3782    if (isformat && sgn < 0) {/* that is input */
3783       *oform = oforml;
3784       SUMA_RETURN(YUP);
3785    }
3786 
3787    SUMA_RETURN(NOPE);
3788 }
SUMA_isFormatFromArg(char * argi,SUMA_DSET_FORMAT * oform)3789 SUMA_Boolean SUMA_isFormatFromArg(char *argi, SUMA_DSET_FORMAT *oform)
3790 {
3791    static char FuncName[]={"SUMA_isFormatFromArg"};
3792    SUMA_DSET_FORMAT oforml = SUMA_NO_DSET_FORMAT;
3793    int sgn = 0;
3794    SUMA_Boolean isformat=NOPE;
3795 
3796    SUMA_ENTRY;
3797 
3798    isformat = SUMA_isIOFormatFromArg(argi, &oforml, &sgn);
3799    if (isformat) {/* that is input */
3800       *oform = oforml;
3801       SUMA_RETURN(YUP);
3802    }
3803 
3804    SUMA_RETURN(NOPE);
3805 }
3806 
SUMA_isIOFormatFromArg(char * argi,SUMA_DSET_FORMAT * oformp,int * io)3807 SUMA_Boolean SUMA_isIOFormatFromArg(char *argi, SUMA_DSET_FORMAT *oformp,
3808                                     int *io)
3809 {
3810    static char FuncName[]={"SUMA_isIOFormatFromArg"};
3811    SUMA_Boolean brk = NOPE;
3812    char *arg=NULL;
3813    int sgn=0;
3814    SUMA_DSET_FORMAT oform = SUMA_NO_DSET_FORMAT;
3815    SUMA_Boolean LocalHead = NOPE;
3816 
3817    SUMA_ENTRY;
3818 
3819    if (!argi) SUMA_RETURN(NOPE);
3820 
3821 
3822    if (  !strncmp(argi,"-o_",3) ||
3823          !strncmp(argi,"-O_",3)) {
3824          arg = SUMA_copy_string(argi+3);
3825       sgn = 1;
3826    } else if (!strncmp(argi,"-i_",3) ||
3827          !strncmp(argi,"-I_",3)) {
3828             arg = SUMA_copy_string(argi+3);
3829       sgn = -1;
3830    } else {
3831       arg = SUMA_copy_string(argi);
3832       sgn = 0;
3833    }
3834    SUMA_TO_LOWER(arg);
3835    SUMA_LHv("%s-->%s\n", argi, arg);
3836 
3837    oform = SUMA_FormatFromFormString(arg);
3838    if (oform != SUMA_ERROR_DSET_FORMAT) {
3839       if (*oformp && *oformp != SUMA_NO_DSET_FORMAT) {
3840          SUMA_SL_Warn("output type already specified.");
3841       }
3842    }
3843 
3844    if (io) *io = sgn;
3845 
3846    if (oformp && oform != SUMA_ERROR_DSET_FORMAT
3847               && oform != SUMA_NO_DSET_FORMAT) {
3848       *oformp = oform;
3849       SUMA_LHv("Returning %s with oform=%d, sgn %d\n", arg, oform, sgn);
3850       SUMA_free(arg); arg=NULL;
3851       SUMA_RETURN(YUP);
3852    } else {
3853       SUMA_LHv("Returning %s without touching oform, sgn = %d\n", arg, sgn);
3854       SUMA_free(arg); arg=NULL;
3855       SUMA_RETURN(NOPE);
3856    }
3857 
3858 }
3859 
SUMA_setenv_option(char * s)3860 int SUMA_setenv_option(char *s)
3861 {
3862    static char FuncName[]={"SUMA_setenv_option"};
3863    char *aval=NULL, lhs[64]={""}, rhs[256]={""};
3864    int closed=0;
3865    SUMA_Boolean LocalHead = NOPE;
3866 
3867    SUMA_ENTRY;
3868 
3869    if (!s) {
3870       SUMA_S_Err("NULL input");
3871       SUMA_RETURN(0);
3872    }
3873    if (s[0] != '\'' && s[0] != '\"') {
3874       SUMA_S_Errv("You must enclose env expression with ' or \" quotes\n"
3875                   "Have >>%s<<\n", s);
3876       SUMA_RETURN(0);
3877    }
3878 
3879    aval = SUMA_copy_quoted(s,NULL,'\0','\0', 1, 0, &closed);
3880    if (!aval) {
3881       SUMA_S_Err("Failed to get env value");
3882       SUMA_RETURN(0);
3883    }
3884    if (!closed) {
3885       SUMA_S_Errv("You must enclose env expression with ' or \" quotes\n"
3886                   "Have unterminated %s\n", aval);
3887       SUMA_free(aval); aval=NULL;
3888       SUMA_RETURN(0);
3889    }
3890    SUMA_LHv("Got >%s<\n", aval);
3891    if (SUMA_ParseLHS_RHS (aval, lhs, rhs)) {
3892       strcpy(aval,lhs) ; strcat(aval,"=") ; strcat(aval,rhs) ;
3893       SUMA_LHv("PUTENV: %s\n", aval);
3894       putenv(aval); /* DO NOT FREE aval! */
3895    } else {
3896       SUMA_S_Errv("Failed to parse >%s<\n", s);
3897    }
3898 
3899    SUMA_RETURN(1);
3900 }
3901 
3902 /*!
3903    A function to parse command line arguments and return a convenient
3904    structure that can be used by various programs for surface specifications
3905 
3906    I hope and pray that this will not be a can of worms.
3907 */
SUMA_Parse_IO_Args(int argc,char * argv[],char * optflags)3908 SUMA_GENERIC_ARGV_PARSE *SUMA_Parse_IO_Args (int argc, char *argv[],
3909                                              char *optflags)
3910 {
3911    static char FuncName[]={"SUMA_Parse_IO_Args"};
3912    int i, kar, ind, N_name, MoreInput =0;
3913    SUMA_Boolean brk = NOPE;
3914    SUMA_GENERIC_ARGV_PARSE *ps=NULL;
3915    SUMA_Boolean LocalHead = NOPE;
3916 
3917    SUMA_ENTRY;
3918 
3919    if (argc >= SUMA_N_ARGS_MAX) {
3920       SUMA_S_Err("Number of arguments exceeds SUMA's parsing limit.");
3921       SUMA_RETURN(NULL);
3922    }
3923 
3924    ps = SUMA_CreateGenericArgParse(optflags);
3925    if (!ps) {
3926       SUMA_S_Err("Failed to create parse structure.");
3927       SUMA_RETURN(NULL);
3928    }
3929    ps->N_args = argc;
3930    ps->N_DO = 0;
3931    ps->cs = SUMA_Create_CommSrtuct();
3932    kar = 1;
3933    brk = NOPE;
3934    while (kar < argc) { /* loop accross command ine options */
3935       /* envs */
3936       if (!brk) {
3937          if (!strcmp(argv[kar],"-setenv")) {
3938             ps->arg_checked[kar]=1; kar ++;
3939             if (kar >= argc)  {
3940                fprintf (SUMA_STDERR, "need quoted env string after %s \n",
3941                                      argv[kar-1]);
3942                exit (1);
3943             }
3944             if (!SUMA_setenv_option(argv[kar])) {
3945                exit(1);
3946             }
3947             ps->arg_checked[kar]=1;
3948             brk = YUP;
3949          }
3950       }
3951       /* allow for users to set cmap */
3952       if (!brk && ps->accept_cmap) {
3953          if (!brk && (  (strcmp(argv[kar], "-cmap") == 0) ||
3954                         (strcmp(argv[kar], "-cmapfile") == 0)  ) ) {
3955             if (ps->cmap || ps->cmapfile) {
3956                fprintf (SUMA_STDERR,"Cmap already set to %s\n"
3957                                     "Option %s is redundant\n",
3958                                     ps->cmap, argv[kar]);
3959                exit(1);
3960             }
3961             ps->arg_checked[kar]=1; kar ++;
3962             if (kar >= argc)  {
3963                fprintf (SUMA_STDERR, "need 1 argument after %s \n",
3964                                      argv[kar-1]);
3965                exit (1);
3966             }
3967             /* put the flags up */
3968             if (strcmp(argv[kar], "-cmap") == 0) {
3969                ps->cmap = SUMA_copy_string(argv[kar]);
3970             } else {
3971                SUMA_DSET_FORMAT form;
3972                SUMA_COLOR_MAP *Cmap=NULL;
3973                SUMA_PARSED_NAME * pn=NULL;
3974 
3975                if (!SUMA_filexists(argv[kar])) {
3976                   fprintf (SUMA_STDERR,"cmap file %s not found\n",
3977                                        argv[kar]);
3978                   exit(1);
3979                }
3980 
3981                /* take a stab at the format */
3982                form = SUMA_GuessFormatFromExtension(argv[kar], NULL);
3983 
3984                /* load the baby */
3985                Cmap = NULL;
3986                switch (form) {
3987                   case  SUMA_1D:
3988                      Cmap = SUMA_Read_Color_Map_1D (argv[kar]);
3989                      if (Cmap == NULL) {
3990                         fprintf (SUMA_STDERR,"Could not load colormap %s.\n",
3991                                              argv[kar]);
3992                      }
3993                      break;
3994                   case SUMA_ASCII_NIML:
3995                   case SUMA_BINARY_NIML:
3996                   case SUMA_NIML:
3997                      fprintf (SUMA_STDERR,
3998                               "Not ready for this cmap format yet.\n");
3999                      break;
4000                   default:
4001                      fprintf (SUMA_STDERR,  "Cmap format not recognized.\n"
4002                                     "I won't try to guess.\n"
4003                                     "Do use the proper extension.\n");
4004                      break;
4005                }
4006                if (!Cmap) exit(1);
4007 
4008                /* have Cmap, add to dbase */
4009 
4010                /* remove path from name for pretty purposes */
4011                pn = SUMA_ParseFname(Cmap->Name, NULL);
4012                SUMA_STRING_REPLACE(Cmap->Name, pn->FileName_NoExt);
4013                SUMA_Free_Parsed_Name(pn); pn = NULL;
4014                if (  !SUMAg_CF->scm &&
4015                      !(SUMAg_CF->scm = SUMA_Build_Color_maps())) {
4016                   fprintf (SUMA_STDERR, "Failed to build color maps.\n");
4017                   exit(1);
4018                }
4019                SUMAg_CF->scm->CMv =
4020                   SUMA_Add_ColorMap (Cmap, SUMAg_CF->scm->CMv,
4021                                      &(SUMAg_CF->scm->N_maps));
4022                ps->cmapfile = SUMA_copy_string(argv[kar]);
4023                ps->cmap = SUMA_copy_string(Cmap->Name);
4024             }
4025             ps->arg_checked[kar]=1;
4026             brk = YUP;
4027 
4028          }
4029          if (!brk && (  (strcmp(argv[kar], "-cmapdb") == 0) ) ) {
4030             if (ps->cmapdb) {
4031                fprintf (SUMA_STDERR,"Cmapdb already set to %s\n",
4032                                     ps->cmapdb);
4033                exit(1);
4034             }
4035             ps->arg_checked[kar]=1; kar ++;
4036             if (kar >= argc)  {
4037                fprintf (SUMA_STDERR, "need 1 argument after %s \n",
4038                                      argv[kar]);
4039                exit (1);
4040             }
4041             if (!SUMA_filexists(argv[kar])) {
4042                fprintf (SUMA_STDERR,"cmapdb file %s not found\n",
4043                                     argv[kar]);
4044                exit(1);
4045             }
4046             ps->cmapdb = SUMA_copy_string(argv[kar]);
4047             /* load the database */
4048             if (  !SUMAg_CF->scm &&
4049                      !(SUMAg_CF->scm = SUMA_Build_Color_maps())) {
4050                   fprintf (SUMA_STDERR, "Failed to build color maps.\n");
4051                   exit(1);
4052             }
4053             if (SUMA_AFNI_Extract_Colors ( ps->cmapdb, SUMAg_CF->scm ) < 0) {
4054                fprintf (SUMA_STDERR,
4055                         "Failed to read %s color database file.\n",
4056                         ps->cmapdb);
4057                exit(1);
4058             }
4059             ps->arg_checked[kar]=1;
4060             brk = YUP;
4061          }
4062       }
4063       if (!brk && ps->accept_mask) {
4064          if (!brk && (strcmp(argv[kar], "-n_mask") == 0)) {
4065             ps->arg_checked[kar]=1; kar ++;
4066             if (kar >= argc)  {
4067                fprintf (SUMA_STDERR, "need 1 argument after -n_mask \n");
4068                exit (1);
4069             }
4070             ps->nmaskname = SUMA_copy_string(argv[kar]);
4071             ps->arg_checked[kar]=1;
4072             brk = YUP;
4073          }
4074          if (!brk && (strcmp(argv[kar], "-cmask") == 0 ||
4075                       strcmp(argv[kar], "-c_mask") == 0)) {
4076             ps->arg_checked[kar]=1; kar ++;
4077             if (kar >= argc)  {
4078                fprintf (SUMA_STDERR, "need 1 argument after -c_mask \n");
4079                exit (1);
4080             }
4081             ps->cmask = SUMA_copy_string(argv[kar]);
4082             ps->arg_checked[kar]=1;
4083             brk = YUP;
4084          }
4085          if (!brk && (strcmp(argv[kar], "-b_mask") == 0)) {
4086              ps->arg_checked[kar]=1; kar ++;
4087             if (kar >= argc)  {
4088                fprintf (SUMA_STDERR, "need 1 argument after -b_mask \n");
4089                exit (1);
4090             }
4091             ps->bmaskname = SUMA_copy_string(argv[kar]);
4092             ps->arg_checked[kar]=1;
4093             brk = YUP;
4094          }
4095       }
4096       if (!brk && ps->accept_dset) {
4097         if (!brk && (strcmp(argv[kar], "-input") == 0)) {
4098             if (kar+1 >= argc)  {
4099                fprintf (SUMA_STDERR, "need 1 argument after -input \n");
4100                exit (1);
4101             }
4102             ps->N_dsetname = 0;
4103             do {
4104                ps->arg_checked[kar]=1; ++kar;
4105                /* do we have a - as the first char ? */
4106                if (argv[kar][0] == '-') {
4107                   fprintf (SUMA_STDERR,
4108                            "no option should directly follow -input \n");
4109                   exit (1);
4110                }
4111                if (ps->N_dsetname+1 < SUMA_MAX_DSET_ON_COMMAND) {
4112                   ps->dsetname[ps->N_dsetname] = SUMA_copy_string(argv[kar]);
4113                   SUMA_LHv("Got %s\n", ps->dsetname[ps->N_dsetname]);
4114                   ++ps->N_dsetname;
4115                } else {
4116                   SUMA_S_Errv("Too many dsets on command line.\n"
4117                               "Maximum of %d is allowed.\n",
4118                               SUMA_MAX_DSET_ON_COMMAND);
4119                   exit (1);
4120                }
4121                ps->arg_checked[kar]=1;
4122                if (kar+1>= argc || argv[kar+1][0] == '-') {
4123                   SUMA_LH("No more input"); MoreInput = 0; }
4124                else { SUMA_LH("More input"); MoreInput = 1; }
4125             } while (MoreInput);
4126             brk = YUP;
4127         }
4128       }
4129       if (!brk && ps->accept_do) {
4130         if (!brk &&
4131                (  (strcmp(argv[kar], "-tract") == 0) ||
4132                   (strcmp(argv[kar], "-gdset") == 0) ||
4133                   (strcmp(argv[kar], "-vol") == 0)   ||
4134                   (strcmp(argv[kar], "-cdset") == 0) ||
4135                   (strcmp(argv[kar], "-mask") == 0) )) {
4136             if (kar+1 >= argc)  {
4137                fprintf (SUMA_STDERR,
4138                      "need 1 argument after -tract/-cdset/-gdset/-vol/-mask \n");
4139                exit (1);
4140             }
4141             do {
4142                ps->arg_checked[kar]=1; ++kar;
4143                /* do we have a - as the first char ? */
4144                if (argv[kar][0] == '-') {
4145                   fprintf (SUMA_STDERR,
4146               "no option should directly follow -tract/-cdset/-gdset/-vol \n");
4147                   exit (1);
4148                }
4149                if (ps->N_DO+1 < SUMA_MAX_DO_ON_COMMAND) {
4150                   ps->DO_name[ps->N_DO] = SUMA_copy_string(argv[kar]);
4151                           if ((strcmp(argv[kar-1], "-tract") == 0)) {
4152                      ps->DO_type[ps->N_DO] = TRACT_type;
4153                   }  else if ((strcmp(argv[kar-1], "-gdset") == 0)) {
4154                      ps->DO_type[ps->N_DO] = GDSET_type;
4155                   }  else if ((strcmp(argv[kar-1], "-cdset") == 0)) {
4156                      ps->DO_type[ps->N_DO] = CDOM_type;
4157                   }  else if ((strcmp(argv[kar-1], "-vol") == 0)) {
4158                      ps->DO_type[ps->N_DO] = VO_type;
4159                   } else if ((strcmp(argv[kar-1], "-mask") == 0)) {
4160                      ps->DO_type[ps->N_DO] = MASK_type;
4161                   } else {
4162                      SUMA_S_Errv("Not set to handle type%s\n",argv[kar-1]);
4163                      exit(1);
4164                   }
4165                   SUMA_LHv("Got %s, type %d (%s)\n",
4166                            ps->DO_name[ps->N_DO], ps->DO_type[ps->N_DO],
4167                      SUMA_ObjectTypeCode2ObjectTypeName(ps->DO_type[ps->N_DO]));
4168                   ++ps->N_DO;
4169                } else {
4170                   SUMA_S_Errv("Too many displayable objects on command line.\n"
4171                               "Maximum of %d is allowed.\n",
4172                               SUMA_MAX_DO_ON_COMMAND);
4173                   exit (1);
4174                }
4175                ps->arg_checked[kar]=1;
4176                if (kar+1>= argc || argv[kar+1][0] == '-') {
4177                   SUMA_LH("No more input"); MoreInput = 0; }
4178                else { SUMA_LH("More input"); MoreInput = 1; }
4179             } while (MoreInput);
4180             brk = YUP;
4181         }
4182       }
4183 
4184 
4185       if (!brk && ps->accept_talk_suma) {
4186          if (!brk && (strcmp(argv[kar], "-talk_suma") == 0)) {
4187             ps->arg_checked[kar]=1;
4188             ps->cs->talk_suma = 1;
4189             brk = YUP;
4190          }
4191 
4192          if (!brk && (strcmp(argv[kar], "-feed_afni") == 0)) {
4193             ps->arg_checked[kar]=1;
4194             ps->cs->Feed2Afni = 1;
4195             brk = YUP;
4196          }
4197 
4198          if (!brk && strcmp(argv[kar], "-send_kth") == 0)
4199          {
4200             ps->arg_checked[kar]=1;
4201             kar ++; ps->arg_checked[kar]=1;
4202             if (kar >= argc)  {
4203                SUMA_S_Err("need argument after -send_kth \n");
4204                exit (1);
4205             }
4206             ps->cs->kth = atoi(argv[kar]);
4207             if (ps->cs->kth <= 0) {
4208                fprintf (SUMA_STDERR,
4209                         "Bad value (%d) for send_kth\n", ps->cs->kth);
4210                exit (1);
4211             }
4212 
4213             brk = YUP;
4214          }
4215 
4216          if (!brk && strcmp(argv[kar], "-ni_text") == 0)
4217          {
4218             ps->arg_checked[kar]=1;
4219             ps->cs->comm_NI_mode = NI_TEXT_MODE;
4220             brk = YUP;
4221          }
4222 
4223          if (!brk && strcmp(argv[kar], "-ni_binary") == 0)
4224          {
4225             ps->arg_checked[kar]=1;
4226             ps->cs->comm_NI_mode = NI_BINARY_MODE;
4227             brk = YUP;
4228          }
4229 
4230          if (!brk && strcmp(argv[kar], "-sh") == 0)
4231          {
4232             ps->arg_checked[kar]=1;
4233             kar ++; ps->arg_checked[kar]=1;
4234             if (kar >= argc)  {
4235                SUMA_S_Err("need argument after -sh \n");
4236                exit (1);
4237             }
4238             if (strcmp(argv[kar],"localhost") != 0) {
4239                ps->cs->suma_host_name = SUMA_copy_string(argv[kar]);
4240             }else {
4241               SUMA_S_Note ("localhost is the default for -sh\n"
4242                            "No need to specify it.\n");
4243             }
4244 
4245             brk = YUP;
4246          }
4247 
4248          if (!brk && strcmp(argv[kar], "-ah") == 0)
4249          {
4250             ps->arg_checked[kar]=1;
4251             kar ++; ps->arg_checked[kar]=1;
4252             if (kar >= argc)  {
4253                SUMA_S_Err("need argument after -ah \n");
4254                exit (1);
4255             }
4256             if (strcmp(argv[kar],"localhost") != 0) {
4257                ps->cs->afni_host_name = SUMA_copy_string(argv[kar]);
4258             }else {
4259               SUMA_S_Note ("localhost is the default for -ah\n"
4260                            "No need to specify it.\n");
4261             }
4262 
4263             brk = YUP;
4264          }
4265 
4266 
4267          if (!brk && strcmp(argv[kar], "-refresh_rate") == 0)
4268          {
4269             ps->arg_checked[kar]=1;
4270             kar ++; ps->arg_checked[kar]=1;
4271             if (kar >= argc)  {
4272                SUMA_S_Err("need argument after -refresh_rate \n");
4273                exit (1);
4274             }
4275             ps->cs->rps = atof(argv[kar]);
4276             if (ps->cs->rps <= 0) {
4277                SUMA_S_Errv("Bad value (%f) for refresh_rate\n", ps->cs->rps);
4278                exit (1);
4279             }
4280 
4281             brk = YUP;
4282          }
4283 
4284       }
4285 
4286       if (!brk && ps->accept_sv) {
4287          if (!brk && (strcmp(argv[kar], "-sv") == 0)) {
4288             ps->arg_checked[kar]=1;
4289             kar ++; ps->arg_checked[kar]=1;
4290             if (kar >= argc)  {
4291                SUMA_S_Err("need 1 or 2 arguments after -sv ");
4292                exit (1);
4293             }
4294             if (ps->N_sv >= SUMA_MAX_SURF_ON_COMMAND) {
4295                SUMA_S_Err("Exceeding maximum number of allowed sv files...");
4296                exit(1);
4297             }
4298             ps->sv[ps->N_sv] = SUMA_copy_string(argv[kar]);
4299             /* is there a volparam option ?*/
4300             if (kar+1 < argc) {
4301                /* maybe a volparam file */
4302                if (argv[kar+1][0] == '-') { /* NOPE*/
4303                } else {
4304                   kar ++; ps->arg_checked[kar]=1;
4305                   ps->vp[ps->N_vp] = SUMA_copy_string(argv[kar]);
4306                   ++ps->N_vp;
4307                }
4308             }
4309             ++ps->N_sv;
4310             brk = YUP;
4311          }
4312       }
4313       if (!brk && (ps->accept_spec || ps->accept_s)) {
4314          char *pdspec=NULL, *pdsv=NULL;
4315          if (!brk && (strcmp(argv[kar], "-spec") == 0)) {
4316             ps->arg_checked[kar]=1;
4317             kar ++; ps->arg_checked[kar]=1;
4318             if (kar >= argc)  {
4319                SUMA_S_Err( "need argument after -spec ");
4320                exit (1);
4321             }
4322             if (ps->N_spec_names >= SUMA_MAX_SURF_ON_COMMAND) {
4323                SUMA_SL_Err("Exceeding maximum number of allowed spec files...");
4324                exit(1);
4325             }
4326             if (SUMA_GuessSurfFormatFromExtension_core(argv[kar+1],
4327                                        &pdspec, &pdsv, NULL) == 3) {
4328                ps->spec_names[ps->N_spec_names] = pdspec; pdspec = NULL;
4329                ++ps->N_spec_names;
4330                ps->sv[ps->N_sv] = pdsv; pdsv = NULL;
4331                ++ps->N_vp;
4332             } else {
4333                ps->spec_names[ps->N_spec_names] = SUMA_copy_string(argv[kar]);
4334                ++ps->N_spec_names;
4335             }
4336             SUMA_ifree(pdspec); SUMA_ifree(pdsv);
4337             brk = YUP;
4338          }
4339 
4340       }
4341       if (!brk && ps->accept_s) {
4342          if (!brk
4343                && (strlen(argv[kar])==7 )
4344                && (strncmp(argv[kar], "-surf_", 6) == 0)) {
4345             ps->arg_checked[kar]=1;
4346             if (kar + 1>= argc)  {
4347                SUMA_S_Err( "need argument after -surf_X SURF_NAME \n");
4348                exit (1);
4349             }
4350             ind = argv[kar][6] - 'A';
4351             if (ind < 0 || ind >= ('Z'-'A')) {
4352                fprintf (SUMA_STDERR,
4353                   "Error %s:\n -surf_X SURF_NAME option (%s)is out of range.\n"
4354                   "Only %d surfaces are allowed. \n"
4355                   "Must start with surf_A for first surface.\n",
4356                         FuncName, argv[kar], ('Z'-'A'));
4357                exit (1);
4358             }
4359             if (ps->s_surfnames[ind]) {
4360                SUMA_S_Errv("It looks like %s has been used already.\n",
4361                            argv[kar]);
4362                exit(1);
4363             }
4364             kar ++;
4365             ps->arg_checked[kar]=1;
4366             if (ps->s_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
4367                SUMA_SL_Err("Exceeding maximum number of allowed surfaces...");
4368                exit(1);
4369             }
4370             ps->s_surfnames[ind] = SUMA_copy_string(argv[kar]);
4371 
4372             ++ps->s_N_surfnames;
4373             brk = YUP;
4374          }
4375          if (!brk && (strcmp(argv[kar], "-surf") == 0)) {
4376             ps->arg_checked[kar]=1;
4377             if (kar + 1>= argc)  {
4378                SUMA_S_Err( "need argument after -surf SURF_NAME \n");
4379                exit (1);
4380             }
4381             ind = 0;
4382 
4383             kar ++;
4384             ps->arg_checked[kar]=1;
4385             if (ps->s_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
4386                SUMA_SL_Err("Exceeding maximum number of allowed surfaces...");
4387                exit(1);
4388             }
4389             if (ps->s_surfnames[ps->s_N_surfnames+ind]) {
4390                SUMA_SL_Err("surface (A) already specified.");
4391                exit(1);
4392             }
4393             ps->s_surfnames[ps->s_N_surfnames+ind] = SUMA_copy_string(argv[kar]);
4394             ++ps->s_N_surfnames;
4395             brk = YUP;
4396          }
4397       }
4398       if (!brk && (strcmp(argv[kar], "-anatomical")==0 )) {
4399          ps->arg_checked[kar]=1;
4400          ps->anatomical = 1;
4401          brk = YUP;
4402       }
4403 
4404       if (!brk && ps->accept_i) { /* just check on onestate */
4405          if (( !strcmp(argv[kar], "-onestate") )) {
4406             ps->arg_checked[kar]=1;
4407             ps->onestate = 1;
4408             brk = YUP;
4409          }
4410       }
4411 
4412      // Verbose mode
4413      if (( !strcmp(argv[kar], "-clippingPlaneVerbose") )) {
4414         SUMAg_CF->clippingPlaneVerbose = 1;
4415      }
4416 
4417 
4418       if (!brk && ps->accept_i) {
4419          char *tmp_i = NULL;
4420          char *pdspec=NULL, *pdsname=NULL, *pdsv=NULL;
4421          int skar = kar+1; /* Argument index for surface names(s).
4422                              Also, get drunk in arabic */
4423          int readmore = 0, advance_kar=0;
4424          do {
4425             if (strcmp(argv[kar], "-i_") == 0 || strcmp(argv[kar], "-i") == 0) {
4426                if (skar >= argc)  {
4427                   SUMA_S_Err( "need argument after -i_ ");
4428                   exit (1);
4429                }
4430                SUMA_LH("Checking %s, readmore = %d", argv[skar], readmore);
4431                switch(SUMA_GuessSurfFormatFromExtension_core(argv[skar],
4432                                           &pdspec, &pdsv, &pdsname)) {
4433                   case SUMA_FREE_SURFER:
4434                   case SUMA_FREE_SURFER_PATCH:
4435                      tmp_i = SUMA_copy_string("-i_fs");
4436                      break;
4437                   case SUMA_SUREFIT:
4438                      tmp_i = SUMA_copy_string("-i_sf");
4439                      break;
4440                   case SUMA_INVENTOR_GENERIC:
4441                      tmp_i = SUMA_copy_string("-i_iv");
4442                      break;
4443                   case SUMA_STL:
4444                      tmp_i = SUMA_copy_string("-i_stl");
4445                      break;
4446                   case SUMA_PLY:
4447                      tmp_i = SUMA_copy_string("-i_ply");
4448                      break;
4449                   case SUMA_MNI_OBJ:
4450                      tmp_i = SUMA_copy_string("-i_mni");
4451                      break;
4452                   case SUMA_VEC:
4453                      tmp_i = SUMA_copy_string("-i_1d");
4454                      break;
4455                   case SUMA_BRAIN_VOYAGER:
4456                      tmp_i = SUMA_copy_string("-i_bv");
4457                      break;
4458                   case SUMA_OPENDX_MESH:
4459                      tmp_i = SUMA_copy_string("-i_dx");
4460                      break;
4461                   case SUMA_OBJ_MESH:
4462                      tmp_i = SUMA_copy_string("-i_obj");
4463                      break;
4464                   case SUMA_BYU:
4465                      tmp_i = SUMA_copy_string("-i_byu");
4466                      break;
4467                   case SUMA_GIFTI:
4468                      tmp_i = SUMA_copy_string("-i_gii");
4469                      break;
4470                   case SUMA_CMAP_SO:
4471                      break;
4472                   case SUMA_PREDEFINED:
4473                      tmp_i = SUMA_copy_string("-i_pre");
4474                      break;
4475                   default:
4476                      tmp_i = SUMA_copy_string(argv[kar]);
4477                      break;
4478                }
4479             } else {
4480                tmp_i = SUMA_copy_string(argv[kar]);
4481             }
4482             SUMA_LHv(
4483                "accept_i %d (argv[%d]=%s), brk = %d, tmp_i=%s, pdsname=%s\n",
4484                 ps->accept_i, kar, argv[kar], brk, tmp_i,
4485                 SUMA_CHECK_NULL_STR(pdsname));
4486             if (!brk && ( (strcmp(tmp_i, "-i_bv") == 0) ||
4487                         (strcmp(tmp_i, "-i_BV") == 0) ) ) {
4488                ps->arg_checked[kar]=1;
4489                ps->arg_checked[skar]=1;
4490                if (skar >= argc)  {
4491                   SUMA_S_Err( "need argument after -i_bv ");
4492                   exit (1);
4493                }
4494                if (ps->i_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
4495                   SUMA_SL_Err("Exceeding maximum number of allowed surfaces...");
4496                   exit(1);
4497                }
4498                if (pdsname) {
4499                   ps->i_surfnames[ps->i_N_surfnames] = pdsname; pdsname = NULL;
4500                } else {
4501                   ps->i_surfnames[ps->i_N_surfnames] =
4502                                                    SUMA_copy_string(argv[skar]);
4503                }
4504                if (pdsv) {
4505                   ps->sv[ps->i_N_surfnames] = pdsv; pdsv = NULL;
4506                }
4507                ps->i_FT[ps->i_N_surfnames] = SUMA_BRAIN_VOYAGER;
4508                ps->i_FF[ps->i_N_surfnames] = SUMA_BINARY;
4509                ++ps->i_N_surfnames;
4510                brk = YUP;
4511             }
4512             if (!brk && ( (strcmp(tmp_i, "-i_byu") == 0) ||
4513                            (strcmp(tmp_i, "-i_BYU") == 0) ) ) {
4514                ps->arg_checked[kar]=1;
4515                ps->arg_checked[skar]=1;
4516                if (skar >= argc)  {
4517                   SUMA_S_Err( "need argument after -i_byu ");
4518                   exit (1);
4519                }
4520                if (ps->i_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
4521                   SUMA_SL_Err("Exceeding maximum number of allowed surfaces...");
4522                   exit(1);
4523                }
4524                if (pdsname) {
4525                   ps->i_surfnames[ps->i_N_surfnames] = pdsname; pdsname = NULL;
4526                } else {
4527                   ps->i_surfnames[ps->i_N_surfnames] =
4528                                                    SUMA_copy_string(argv[skar]);
4529                }
4530                if (pdsv) {
4531                   ps->sv[ps->i_N_surfnames] = pdsv; pdsv = NULL;
4532                }
4533                ps->i_FT[ps->i_N_surfnames] = SUMA_BYU;
4534                ps->i_FF[ps->i_N_surfnames] = SUMA_ASCII;
4535                ++ps->i_N_surfnames;
4536                brk = YUP;
4537             }
4538             if (  !brk &&
4539                   (  (strcmp(tmp_i, "-i_gii") == 0) ||
4540                      (strcmp(tmp_i, "-i_GII") == 0) ) ) {
4541                ps->arg_checked[kar]=1;
4542                ps->arg_checked[skar]=1;
4543                if (skar >= argc)  {
4544                   SUMA_S_Err( "need argument after -i_gii ");
4545                   exit (1);
4546                }
4547                if (ps->i_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
4548                   SUMA_SL_Err("Exceeding maximum number of allowed surfaces...");
4549                   exit(1);
4550                }
4551                if (pdsname) {
4552                   ps->i_surfnames[ps->i_N_surfnames] = pdsname; pdsname = NULL;
4553                } else {
4554                   ps->i_surfnames[ps->i_N_surfnames] =
4555                                                    SUMA_copy_string(argv[skar]);
4556                }
4557                if (pdsv) {
4558                   ps->sv[ps->i_N_surfnames] = pdsv; pdsv = NULL;
4559                }
4560                ps->i_FT[ps->i_N_surfnames] = SUMA_GIFTI;
4561                ps->i_FF[ps->i_N_surfnames] = SUMA_XML_SURF;
4562                ++ps->i_N_surfnames;
4563                brk = YUP;
4564             }
4565             if (!brk && ( (strcmp(tmp_i, "-i_fs") == 0) ||
4566                            (strcmp(tmp_i, "-i_FS") == 0)) ) {
4567                ps->arg_checked[kar]=1;
4568                ps->arg_checked[skar]=1;
4569                if (skar >= argc)  {
4570                   SUMA_S_Err( "need argument after -i_fs ");
4571                   exit (1);
4572                }
4573                if (ps->i_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
4574                   SUMA_SL_Err("Exceeding maximum number of allowed surfaces...");
4575                   exit(1);
4576                }
4577                if (pdsname) {
4578                   ps->i_surfnames[ps->i_N_surfnames] = pdsname; pdsname = NULL;
4579                } else {
4580                   ps->i_surfnames[ps->i_N_surfnames] =
4581                                                    SUMA_copy_string(argv[skar]);
4582                }
4583                if (pdsv) {
4584                   ps->sv[ps->i_N_surfnames] = pdsv; pdsv = NULL;
4585                }
4586                ps->i_FT[ps->i_N_surfnames] = SUMA_FREE_SURFER;
4587                if (SUMA_isExtension(ps->i_surfnames[ps->i_N_surfnames], ".asc"))
4588                   ps->i_FF[ps->i_N_surfnames] = SUMA_ASCII;
4589                else
4590                   ps->i_FF[ps->i_N_surfnames] = SUMA_BINARY_BE;
4591                ++ps->i_N_surfnames;
4592                brk = YUP;
4593             }
4594 
4595             if (!brk && (  (strcmp(tmp_i, "-i_sf") == 0) ||
4596                            (strcmp(tmp_i, "-i_SF") == 0)) ){
4597                ps->arg_checked[kar]=1;
4598                ps->arg_checked[skar]=1;
4599                if (skar+1 >= argc)  {
4600                   SUMA_S_Err( "need 2 arguments after -i_sf");
4601                   exit (1);
4602                }
4603                if (ps->i_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
4604                   SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
4605                   exit(1);
4606                }
4607                if (!SUMA_isExtension(argv[skar], ".topo")) {
4608                   ps->i_surfnames[ps->i_N_surfnames] =
4609                      SUMA_copy_string(argv[skar]);
4610                   skar ++; ps->arg_checked[skar]=1;
4611                   ps->i_surftopo[ps->i_N_surfnames] =
4612                      SUMA_copy_string(argv[skar]);
4613                } else {
4614                   ps->i_surftopo[ps->i_N_surfnames] =
4615                         SUMA_copy_string(argv[skar]);
4616                   skar ++; ps->arg_checked[skar]=1;
4617                   ps->i_surfnames[ps->i_N_surfnames] =
4618                      SUMA_copy_string(argv[skar]);
4619                }
4620                ps->i_FT[ps->i_N_surfnames] = SUMA_SUREFIT;
4621                ps->i_FF[ps->i_N_surfnames] = SUMA_ASCII;
4622                ++ps->i_N_surfnames;
4623                brk = YUP;
4624             }
4625 
4626             if (  !brk &&
4627                   (  (strcmp(tmp_i, "-i_vec") == 0) ||
4628                      (strcmp(tmp_i, "-i_1d") == 0) ||
4629                      (strcmp(tmp_i, "-i_VEC") == 0) ||
4630                      (strcmp(tmp_i, "-i_1D") == 0) ) ) {
4631                ps->arg_checked[kar]=1;
4632                ps->arg_checked[skar]=1;
4633                if (skar+1 >= argc)  {
4634                   SUMA_S_Err( "need 2 argument after -i_vec or -i_1d");
4635                   exit (1);
4636                }
4637                if (ps->i_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
4638                   SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
4639                   exit(1);
4640                }
4641                if (pdsname) {
4642                   SUMA_S_Err("Cannot load template surfs of 1D or VEC format");
4643                }
4644                if (!SUMA_isExtension(argv[skar], ".topo")) {
4645                   ps->i_surfnames[ps->i_N_surfnames] =
4646                                                    SUMA_copy_string(argv[skar]);
4647                   skar ++; ps->arg_checked[skar]=1;
4648                   ps->i_surftopo[ps->i_N_surfnames] =
4649                                                    SUMA_copy_string(argv[skar]);
4650                } else {
4651                   ps->i_surftopo[ps->i_N_surfnames] =
4652                                                    SUMA_copy_string(argv[skar]);
4653                   skar ++; ps->arg_checked[skar]=1;
4654                   ps->i_surfnames[ps->i_N_surfnames] =
4655                                                    SUMA_copy_string(argv[skar]);
4656                }
4657                ps->i_FT[ps->i_N_surfnames] = SUMA_VEC;
4658                ps->i_FF[ps->i_N_surfnames] = SUMA_ASCII;
4659                ++ps->i_N_surfnames;
4660                brk = YUP;
4661             }
4662 
4663             if (!brk && (  (strcmp(tmp_i, "-i_stl") == 0) ||
4664                            (strcmp(tmp_i, "-i_Stl") == 0)
4665                            || (strcmp(tmp_i, "-i_STL") == 0))) {
4666                ps->arg_checked[kar]=1;
4667                ps->arg_checked[skar]=1;
4668                if (skar >= argc)  {
4669                   SUMA_S_Err( "need argument after -i_stl ");
4670                   exit (1);
4671                }
4672                if (ps->i_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
4673                   SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
4674                   exit(1);
4675                }
4676                if (pdsname) {
4677                   ps->i_surfnames[ps->i_N_surfnames] = pdsname; pdsname = NULL;
4678                } else {
4679                   ps->i_surfnames[ps->i_N_surfnames] =
4680                                                 SUMA_copy_string(argv[skar]);
4681                }
4682                if (pdsv) {
4683                   ps->sv[ps->i_N_surfnames] = pdsv; pdsv = NULL;
4684                }
4685                ps->i_FT[ps->i_N_surfnames] = SUMA_STL;
4686                ps->i_FF[ps->i_N_surfnames] = SUMA_FF_NOT_SPECIFIED;
4687                ++ps->i_N_surfnames;
4688                brk = YUP;
4689             }
4690 
4691             if (!brk && (  (strcmp(tmp_i, "-i_ply") == 0) ||
4692                            (strcmp(tmp_i, "-i_Ply") == 0)
4693                            || (strcmp(tmp_i, "-i_PLY") == 0))) {
4694                ps->arg_checked[kar]=1;
4695                ps->arg_checked[skar]=1;
4696                if (skar >= argc)  {
4697                   SUMA_S_Err( "need argument after -i_ply ");
4698                   exit (1);
4699                }
4700                if (ps->i_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
4701                   SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
4702                   exit(1);
4703                }
4704                if (pdsname) {
4705                   ps->i_surfnames[ps->i_N_surfnames] = pdsname; pdsname = NULL;
4706                } else {
4707                   ps->i_surfnames[ps->i_N_surfnames] =
4708                                                 SUMA_copy_string(argv[skar]);
4709                }
4710                if (pdsv) {
4711                   ps->sv[ps->i_N_surfnames] = pdsv; pdsv = NULL;
4712                }
4713                ps->i_FT[ps->i_N_surfnames] = SUMA_PLY;
4714                ps->i_FF[ps->i_N_surfnames] = SUMA_FF_NOT_SPECIFIED;
4715                ++ps->i_N_surfnames;
4716                brk = YUP;
4717             }
4718             if (!brk && (  (strcmp(tmp_i, "-i_mni") == 0) ||
4719                            (strcmp(tmp_i, "-i_Mni") == 0)
4720                            || (strcmp(tmp_i, "-i_MNI") == 0))) {
4721                ps->arg_checked[kar]=1;
4722                ps->arg_checked[skar]=1;
4723                if (skar >= argc)  {
4724                   SUMA_S_Err( "need argument after -i_mni ");
4725                   exit (1);
4726                }
4727                if (ps->i_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
4728                   SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
4729                   exit(1);
4730                }
4731                if (pdsname) {
4732                   ps->i_surfnames[ps->i_N_surfnames] = pdsname; pdsname = NULL;
4733                } else {
4734                   ps->i_surfnames[ps->i_N_surfnames] =
4735                                                    SUMA_copy_string(argv[skar]);
4736                }
4737                if (pdsv) {
4738                   ps->sv[ps->i_N_surfnames] = pdsv; pdsv = NULL;
4739                }
4740                ps->i_FT[ps->i_N_surfnames] = SUMA_MNI_OBJ;
4741                ps->i_FF[ps->i_N_surfnames] = SUMA_ASCII;
4742                ++ps->i_N_surfnames;
4743                brk = YUP;
4744             }
4745             if (!brk && (  (strcmp(tmp_i, "-i_DX") == 0) ||
4746                            (strcmp(tmp_i, "-i_dx") == 0)
4747                         || (strcmp(tmp_i, "-i_Dx") == 0))) {
4748                ps->arg_checked[kar]=1;
4749                ps->arg_checked[skar]=1;
4750                if (skar >= argc)  {
4751                   SUMA_S_Err( "need argument after -i_dx ");
4752                   exit (1);
4753                }
4754                if (ps->i_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
4755                   SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
4756                   exit(1);
4757                }
4758                if (pdsname) {
4759                   ps->i_surfnames[ps->i_N_surfnames] = pdsname; pdsname = NULL;
4760                } else {
4761                   ps->i_surfnames[ps->i_N_surfnames] =
4762                                                    SUMA_copy_string(argv[skar]);
4763                }
4764                if (pdsv) {
4765                   ps->sv[ps->i_N_surfnames] = pdsv; pdsv = NULL;
4766                }
4767                ps->i_FT[ps->i_N_surfnames] = SUMA_OPENDX_MESH;
4768                ps->i_FF[ps->i_N_surfnames] = SUMA_ASCII;
4769                ++ps->i_N_surfnames;
4770                brk = YUP;
4771             }
4772             if (!brk && (  (strcmp(tmp_i, "-i_OBJ") == 0) ||
4773                            (strcmp(tmp_i, "-i_obj") == 0)
4774                         || (strcmp(tmp_i, "-i_Obj") == 0))) {
4775                ps->arg_checked[kar]=1;
4776                ps->arg_checked[skar]=1;
4777                if (skar >= argc)  {
4778                   SUMA_S_Err( "need argument after -i_obj ");
4779                   exit (1);
4780                }
4781                if (ps->i_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
4782                   SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
4783                   exit(1);
4784                }
4785                if (pdsname) {
4786                   ps->i_surfnames[ps->i_N_surfnames] = pdsname; pdsname = NULL;
4787                } else {
4788                   ps->i_surfnames[ps->i_N_surfnames] =
4789                                                    SUMA_copy_string(argv[skar]);
4790                }
4791                if (pdsv) {
4792                   ps->sv[ps->i_N_surfnames] = pdsv; pdsv = NULL;
4793                }
4794                ps->i_FT[ps->i_N_surfnames] = SUMA_OBJ_MESH;
4795                ps->i_FF[ps->i_N_surfnames] = SUMA_ASCII;
4796                ++ps->i_N_surfnames;
4797                brk = YUP;
4798             }
4799             if (!brk && (  (strcmp(tmp_i, "-i_PRE") == 0) ||
4800                            (strcmp(tmp_i, "-i_pre") == 0)
4801                         || (strcmp(tmp_i, "-i_Pre") == 0))) {
4802                ps->arg_checked[kar]=1;
4803                ps->arg_checked[skar]=1;
4804                if (skar >= argc)  {
4805                   SUMA_S_Err( "need argument after -i_pre ");
4806                   exit (1);
4807                }
4808                if (ps->i_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
4809                   SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
4810                   exit(1);
4811                }
4812                if (pdsname) {
4813                   SUMA_S_Err("Cannot load template surfs of predefined format");
4814                }
4815                ps->i_surfnames[ps->i_N_surfnames] = SUMA_copy_string(argv[skar]);
4816                ps->i_FT[ps->i_N_surfnames] = SUMA_PREDEFINED;
4817                ps->i_FF[ps->i_N_surfnames] = SUMA_ASCII;
4818                ++ps->i_N_surfnames;
4819                brk = YUP;
4820             }
4821             if (!brk && (  (strcmp(tmp_i, "-i_iv") == 0) ||
4822                            (strcmp(tmp_i, "-i_IV") == 0) )) {
4823                ps->arg_checked[kar]=1;
4824                ps->arg_checked[skar]=1;
4825                if (skar >= argc)  {
4826                   SUMA_S_Err( "need argument after -i_iv ");
4827                   exit (1);
4828                }
4829                if (ps->i_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
4830                   SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
4831                   exit(1);
4832                }
4833                if (pdsname) {
4834                   ps->i_surfnames[ps->i_N_surfnames] = pdsname; pdsname = NULL;
4835                } else {
4836                   ps->i_surfnames[ps->i_N_surfnames] =
4837                                                    SUMA_copy_string(argv[skar]);
4838                }
4839                if (pdsv) {
4840                   ps->sv[ps->i_N_surfnames] = pdsv; pdsv = NULL;
4841                }
4842                ps->i_FT[ps->i_N_surfnames] = SUMA_INVENTOR_GENERIC;
4843                ps->i_FF[ps->i_N_surfnames] = SUMA_ASCII;
4844                ++ps->i_N_surfnames;
4845                brk = YUP;
4846             }
4847             if (brk) {advance_kar = 1; }
4848             if (skar+1 < argc && argv[skar+1][0] != '-' &&
4849                 SUMA_IS_LOADABLE_SO_NAME(argv[skar+1])) {
4850                /* Looks like we have another surface there */
4851                SUMA_LH("Looks like %s is another surface",argv[skar+1]);
4852                skar = skar+1; readmore = 1; brk = NOPE;
4853             } else readmore = 0;
4854             if (tmp_i) SUMA_free(tmp_i); tmp_i=NULL;
4855             SUMA_ifree(pdsname); SUMA_ifree(pdsv); SUMA_ifree(pdspec);
4856             SUMA_LH("Readmore now %d", readmore);
4857          } while (readmore);
4858          if (advance_kar) kar = skar;
4859       }
4860 
4861       if (!brk && ps->accept_ipar) {
4862          if (!brk && ( (strcmp(argv[kar], "-ipar_bv") == 0) ||                                           (strcmp(argv[kar], "-ipar_BV") == 0) ) ) {
4863             ps->arg_checked[kar]=1;
4864             kar ++; ps->arg_checked[kar]=1;
4865             if (kar >= argc)  {
4866                SUMA_S_Err( "need argument after -ipar_bv ");
4867                exit (1);
4868             }
4869             if (ps->ipar_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
4870                SUMA_SL_Err("Exceeding maximum number of allowed surfaces...");
4871                exit(1);
4872             }
4873             ps->ipar_surfnames[ps->ipar_N_surfnames] =
4874                                        SUMA_copy_string(argv[kar]);
4875             ps->ipar_FT[ps->ipar_N_surfnames] = SUMA_BRAIN_VOYAGER;
4876             ps->ipar_FF[ps->ipar_N_surfnames] = SUMA_BINARY;
4877             ++ps->ipar_N_surfnames;
4878             brk = YUP;
4879          }
4880 
4881          if (!brk && (  (strcmp(argv[kar], "-ipar_byu") == 0) ||
4882                         (strcmp(argv[kar], "-ipar_BYU") == 0) ) ) {
4883             ps->arg_checked[kar]=1;
4884             kar ++; ps->arg_checked[kar]=1;
4885             if (kar >= argc)  {
4886                SUMA_S_Err( "need argument after -ipar_byu ");
4887                exit (1);
4888             }
4889             if (ps->ipar_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
4890                SUMA_SL_Err("Exceeding maximum number of allowed surfaces...");
4891                exit(1);
4892             }
4893             ps->ipar_surfnames[ps->ipar_N_surfnames] =
4894                                     SUMA_copy_string(argv[kar]);
4895             ps->ipar_FT[ps->ipar_N_surfnames] = SUMA_BYU;
4896             ps->ipar_FF[ps->ipar_N_surfnames] = SUMA_ASCII;
4897             ++ps->ipar_N_surfnames;
4898             brk = YUP;
4899          }
4900 
4901          if (  !brk &&
4902                (  (strcmp(argv[kar], "-ipar_gii") == 0) ||
4903                   (strcmp(argv[kar], "-ipar_GII") == 0)  ) ) {
4904             ps->arg_checked[kar]=1;
4905             kar ++; ps->arg_checked[kar]=1;
4906             if (kar >= argc)  {
4907                SUMA_S_Err( "need argument after -ipar_gii ");
4908                exit (1);
4909             }
4910             if (ps->ipar_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
4911                SUMA_SL_Err("Exceeding maximum number of allowed surfaces...");
4912                exit(1);
4913             }
4914             ps->ipar_surfnames[ps->ipar_N_surfnames] =
4915                                              SUMA_copy_string(argv[kar]);
4916             ps->ipar_FT[ps->ipar_N_surfnames] = SUMA_GIFTI;
4917             ps->ipar_FF[ps->ipar_N_surfnames] = SUMA_XML_SURF;
4918             ++ps->ipar_N_surfnames;
4919             brk = YUP;
4920          }
4921 
4922          if (!brk && (  (strcmp(argv[kar], "-ipar_fs") == 0) ||
4923                         (strcmp(argv[kar], "-ipar_FS") == 0)) ) {
4924             ps->arg_checked[kar]=1;
4925             kar ++; ps->arg_checked[kar]=1;
4926             if (kar >= argc)  {
4927                SUMA_S_Err( "need argument after -ipar_fs ");
4928                exit (1);
4929             }
4930             if (ps->ipar_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
4931                SUMA_SL_Err("Exceeding maximum number of allowed surfaces...");
4932                exit(1);
4933             }
4934             ps->ipar_surfnames[ps->ipar_N_surfnames] =
4935                                        SUMA_copy_string(argv[kar]);
4936             ps->ipar_FT[ps->ipar_N_surfnames] = SUMA_FREE_SURFER;
4937             if (SUMA_isExtension(ps->ipar_surfnames[ps->ipar_N_surfnames],
4938                                  ".asc"))
4939                ps->ipar_FF[ps->ipar_N_surfnames] = SUMA_ASCII;
4940             else
4941                ps->ipar_FF[ps->ipar_N_surfnames] = SUMA_BINARY_BE;
4942             ++ps->ipar_N_surfnames;
4943             brk = YUP;
4944          }
4945 
4946          if (!brk && (  (strcmp(argv[kar], "-ipar_sf") == 0) ||
4947                         (strcmp(argv[kar], "-ipar_SF") == 0)) ){
4948             ps->arg_checked[kar]=1;
4949             kar ++; ps->arg_checked[kar]=1;
4950             if (kar+1 >= argc)  {
4951                SUMA_S_Err( "need 2 arguments after -ipar_sf");
4952                exit (1);
4953             }
4954             if (ps->ipar_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
4955                SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
4956                exit(1);
4957             }
4958             if (!SUMA_isExtension(argv[kar], ".topo")) {
4959                ps->ipar_surfnames[ps->ipar_N_surfnames] =
4960                   SUMA_copy_string(argv[kar]);
4961                kar ++; ps->arg_checked[kar]=1;
4962                ps->ipar_surftopo[ps->ipar_N_surfnames] =
4963                   SUMA_copy_string(argv[kar]);
4964             } else {
4965                ps->ipar_surftopo[ps->ipar_N_surfnames] =
4966                   SUMA_copy_string(argv[kar]);
4967                kar ++; ps->arg_checked[kar]=1;
4968                ps->ipar_surfnames[ps->ipar_N_surfnames] =
4969                   SUMA_copy_string(argv[kar]);
4970             }
4971             ps->ipar_FT[ps->ipar_N_surfnames] = SUMA_SUREFIT;
4972             ps->ipar_FF[ps->ipar_N_surfnames] = SUMA_ASCII;
4973             ++ps->ipar_N_surfnames;
4974             brk = YUP;
4975          }
4976 
4977          if (!brk && (  (strcmp(argv[kar], "-ipar_vec") == 0) ||
4978                         (strcmp(argv[kar], "-ipar_1d") == 0) ||
4979                         (strcmp(argv[kar], "-ipar_VEC") == 0) ||
4980                         (strcmp(argv[kar], "-ipar_1D") == 0) ) ) {
4981             ps->arg_checked[kar]=1;
4982             kar ++; ps->arg_checked[kar]=1;
4983             if (kar+1 >= argc)  {
4984                SUMA_S_Err( "need 2 argument after -ipar_vec or -ipar_1d");
4985                exit (1);
4986             }
4987             if (ps->ipar_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
4988                SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
4989                exit(1);
4990             }
4991         if (!SUMA_isExtension(argv[kar], ".topo")) {
4992             ps->ipar_surfnames[ps->ipar_N_surfnames] =
4993                SUMA_copy_string(argv[kar]);
4994             kar ++; ps->arg_checked[kar]=1;
4995             ps->ipar_surftopo[ps->ipar_N_surfnames] =
4996                SUMA_copy_string(argv[kar]);
4997          } else {
4998             ps->ipar_surftopo[ps->ipar_N_surfnames] =
4999                SUMA_copy_string(argv[kar]);
5000             kar ++; ps->arg_checked[kar]=1;
5001             ps->ipar_surfnames[ps->ipar_N_surfnames] =
5002                SUMA_copy_string(argv[kar]);
5003          }
5004             ps->ipar_FT[ps->ipar_N_surfnames] = SUMA_VEC;
5005             ps->ipar_FF[ps->ipar_N_surfnames] = SUMA_ASCII;
5006             ++ps->ipar_N_surfnames;
5007             brk = YUP;
5008          }
5009 
5010          if (!brk && (  (strcmp(argv[kar], "-ipar_stl") == 0) ||
5011                         (strcmp(argv[kar], "-ipar_Stl") == 0) ||
5012                         (strcmp(argv[kar], "-ipar_STL") == 0))) {
5013             ps->arg_checked[kar]=1;
5014             kar ++; ps->arg_checked[kar]=1;
5015             if (kar >= argc)  {
5016                SUMA_S_Err( "need argument after -ipar_stl ");
5017                exit (1);
5018             }
5019             if (ps->ipar_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
5020                SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
5021                exit(1);
5022             }
5023             ps->ipar_surfnames[ps->ipar_N_surfnames] =
5024                                        SUMA_copy_string(argv[kar]);
5025             ps->ipar_FT[ps->ipar_N_surfnames] = SUMA_STL;
5026             ps->ipar_FF[ps->ipar_N_surfnames] = SUMA_FF_NOT_SPECIFIED;
5027             ++ps->ipar_N_surfnames;
5028             brk = YUP;
5029          }
5030          if (!brk && (  (strcmp(argv[kar], "-ipar_ply") == 0) ||
5031                         (strcmp(argv[kar], "-ipar_Ply") == 0) ||
5032                         (strcmp(argv[kar], "-ipar_PLY") == 0))) {
5033             ps->arg_checked[kar]=1;
5034             kar ++; ps->arg_checked[kar]=1;
5035             if (kar >= argc)  {
5036                SUMA_S_Err( "need argument after -ipar_ply ");
5037                exit (1);
5038             }
5039             if (ps->ipar_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
5040                SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
5041                exit(1);
5042             }
5043             ps->ipar_surfnames[ps->ipar_N_surfnames] =
5044                                        SUMA_copy_string(argv[kar]);
5045             ps->ipar_FT[ps->ipar_N_surfnames] = SUMA_PLY;
5046             ps->ipar_FF[ps->ipar_N_surfnames] = SUMA_FF_NOT_SPECIFIED;
5047             ++ps->ipar_N_surfnames;
5048             brk = YUP;
5049          }
5050          if (!brk && (  (strcmp(argv[kar], "-ipar_mni") == 0) ||
5051                         (strcmp(argv[kar], "-ipar_Mni") == 0) ||
5052                         (strcmp(argv[kar], "-ipar_MNI") == 0))) {
5053             ps->arg_checked[kar]=1;
5054             kar ++; ps->arg_checked[kar]=1;
5055             if (kar >= argc)  {
5056                SUMA_S_Err( "need argument after -ipar_mni ");
5057                exit (1);
5058             }
5059             if (ps->ipar_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
5060                SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
5061                exit(1);
5062             }
5063             ps->ipar_surfnames[ps->ipar_N_surfnames] =
5064                                        SUMA_copy_string(argv[kar]);
5065             ps->ipar_FT[ps->ipar_N_surfnames] = SUMA_MNI_OBJ;
5066             ps->ipar_FF[ps->ipar_N_surfnames] = SUMA_ASCII;
5067             ++ps->ipar_N_surfnames;
5068             brk = YUP;
5069          }
5070          if (!brk && (  (strcmp(argv[kar], "-ipar_DX") == 0) ||
5071                         (strcmp(argv[kar], "-ipar_dx") == 0) ||
5072                         (strcmp(argv[kar], "-ipar_Dx") == 0))) {
5073             ps->arg_checked[kar]=1;
5074             kar ++; ps->arg_checked[kar]=1;
5075             if (kar >= argc)  {
5076                SUMA_S_Err( "need argument after -ipar_dx ");
5077                exit (1);
5078             }
5079             if (ps->ipar_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
5080                SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
5081                exit(1);
5082             }
5083             ps->ipar_surfnames[ps->ipar_N_surfnames] =
5084                                        SUMA_copy_string(argv[kar]);
5085             ps->ipar_FT[ps->ipar_N_surfnames] = SUMA_OPENDX_MESH;
5086             ps->ipar_FF[ps->ipar_N_surfnames] = SUMA_ASCII;
5087             ++ps->ipar_N_surfnames;
5088             brk = YUP;
5089          }
5090          if (!brk && (  (strcmp(argv[kar], "-ipar_OBJ") == 0) ||
5091                         (strcmp(argv[kar], "-ipar_obj") == 0) ||
5092                         (strcmp(argv[kar], "-ipar_Obj") == 0))) {
5093             ps->arg_checked[kar]=1;
5094             kar ++; ps->arg_checked[kar]=1;
5095             if (kar >= argc)  {
5096                SUMA_S_Err( "need argument after -ipar_dx ");
5097                exit (1);
5098             }
5099             if (ps->ipar_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
5100                SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
5101                exit(1);
5102             }
5103             ps->ipar_surfnames[ps->ipar_N_surfnames] =
5104                                        SUMA_copy_string(argv[kar]);
5105             ps->ipar_FT[ps->ipar_N_surfnames] = SUMA_OBJ_MESH;
5106             ps->ipar_FF[ps->ipar_N_surfnames] = SUMA_ASCII;
5107             ++ps->ipar_N_surfnames;
5108             brk = YUP;
5109          }
5110          if (!brk && (  (strcmp(argv[kar], "-ipar_iv") == 0) ||
5111                         (strcmp(argv[kar], "-ipar_IV") == 0) )) {
5112             ps->arg_checked[kar]=1;
5113             kar ++; ps->arg_checked[kar]=1;
5114             if (kar >= argc)  {
5115                SUMA_S_Err( "need argument after -ipar_iv ");
5116                exit (1);
5117             }
5118             if (ps->ipar_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
5119                SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
5120                exit(1);
5121             }
5122             ps->ipar_surfnames[ps->ipar_N_surfnames] =
5123                                        SUMA_copy_string(argv[kar]);
5124             ps->ipar_FT[ps->ipar_N_surfnames] = SUMA_INVENTOR_GENERIC;
5125             ps->ipar_FF[ps->ipar_N_surfnames] = SUMA_ASCII;
5126             ++ps->ipar_N_surfnames;
5127             brk = YUP;
5128          }
5129       }
5130 
5131       if (!brk && ps->accept_t) {
5132          if (!brk && (strcmp(argv[kar], "-tn") == 0)) {
5133             ps->arg_checked[kar]=1;
5134             kar ++; ps->arg_checked[kar]=1;
5135             if (kar >= argc)  {
5136                SUMA_S_Err( "Type argument must follow -tn ");
5137                exit (1);
5138             }
5139             if (ps->t_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
5140                SUMA_SL_Err("Exceeding maximum number of allowed surfaces...");
5141                exit(1);
5142             }
5143             /* get the type */
5144             ps->t_FT[ps->t_N_surfnames] = SUMA_SurfaceTypeCode(argv[kar]);
5145             if (  ps->t_FT[ps->t_N_surfnames] == SUMA_FT_ERROR ||
5146                   ps->t_FT[ps->t_N_surfnames] == SUMA_FT_NOT_SPECIFIED) {
5147                fprintf (SUMA_STDERR, "%s is a bad file type.\n", argv[kar]);
5148                exit(1);
5149             }
5150             /* get the name */
5151             if (  ps->t_FT[ps->t_N_surfnames] == SUMA_SUREFIT ||
5152                   ps->t_FT[ps->t_N_surfnames] == SUMA_VEC) N_name = 2;
5153             else N_name = 1;
5154             if (kar+N_name >= argc)  {
5155                fprintf (SUMA_STDERR, "need %d elements for NAME \n", N_name);
5156                exit (1);
5157             }
5158             kar ++; ps->arg_checked[kar]=1;
5159             if (!SUMA_isExtension(argv[kar], ".topo")) {
5160                ps->t_surfnames[ps->t_N_surfnames] = SUMA_copy_string(argv[kar]);
5161                if (N_name == 2) {
5162                   kar ++; ps->arg_checked[kar]=1;
5163                   ps->t_surftopo[ps->t_N_surfnames] =
5164                      SUMA_copy_string(argv[kar]);
5165                }
5166             } else {
5167                if (N_name == 1) {
5168                   ps->t_surfnames[ps->t_N_surfnames] =
5169                      SUMA_Extension(argv[kar], ".topo", YUP);
5170                } else {
5171                   ps->t_surftopo[ps->t_N_surfnames] =
5172                      SUMA_copy_string(argv[kar]);
5173                   kar ++; ps->arg_checked[kar]=1;
5174                   ps->t_surfnames[ps->t_N_surfnames] =
5175                      SUMA_copy_string(argv[kar]);
5176                }
5177             }
5178 
5179             ++ps->t_N_surfnames;
5180             brk = YUP;
5181          }
5182 
5183          if (!brk && (strcmp(argv[kar], "-tsn") == 0)) {
5184             ps->arg_checked[kar]=1;
5185             kar ++; ps->arg_checked[kar]=1;
5186             if (kar >= argc)  {
5187                fprintf (SUMA_STDERR, "Type argument must follow -tn \n");
5188                exit (1);
5189             }
5190             if (ps->t_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
5191                SUMA_SL_Err("Exceeding maximum number of allowed surfaces...");
5192                exit(1);
5193             }
5194             /* get the type */
5195             ps->t_FT[ps->t_N_surfnames] = SUMA_SurfaceTypeCode(argv[kar]);
5196             if (  ps->t_FT[ps->t_N_surfnames] == SUMA_FT_ERROR ||
5197                   ps->t_FT[ps->t_N_surfnames] == SUMA_FT_NOT_SPECIFIED) {
5198                fprintf (SUMA_STDERR, "%s is a bad file type.\n", argv[kar]);
5199                exit(1);
5200             }
5201             /* get the state */
5202             kar ++; ps->arg_checked[kar]=1;
5203             if (kar >= argc)  {
5204                SUMA_S_Err( "STATE argument must follow TYPE with -tsn ");
5205                exit (1);
5206             }
5207             ps->t_state[ps->t_N_surfnames] = SUMA_copy_string(argv[kar]);
5208 
5209             /* get the name */
5210             if (  ps->t_FT[ps->t_N_surfnames] == SUMA_SUREFIT ||
5211                   ps->t_FT[ps->t_N_surfnames] == SUMA_VEC) N_name = 2;
5212             else N_name = 1;
5213             if (kar+N_name >= argc)  {
5214                fprintf (SUMA_STDERR,
5215                         "Error %s:\nneed %d elements for NAME \n"
5216                         , FuncName, N_name);
5217                exit (1);
5218             }
5219             kar ++; ps->arg_checked[kar]=1;
5220             if (!SUMA_isExtension(argv[kar], ".topo")) {
5221                ps->t_surfnames[ps->t_N_surfnames] =
5222                   SUMA_copy_string(argv[kar]);
5223                if (N_name == 2) {
5224                   kar ++; ps->arg_checked[kar]=1;
5225                   ps->t_surftopo[ps->t_N_surfnames] =
5226                      SUMA_copy_string(argv[kar]);
5227                }
5228             } else {
5229                if (N_name == 1) {
5230                   ps->t_surfnames[ps->t_N_surfnames] =
5231                      SUMA_Extension(argv[kar],".topo", YUP);
5232                } else {
5233                   ps->t_surftopo[ps->t_N_surfnames] =
5234                      SUMA_copy_string(argv[kar]);
5235                   kar ++; ps->arg_checked[kar]=1;
5236                   ps->t_surfnames[ps->t_N_surfnames] =
5237                      SUMA_copy_string(argv[kar]);
5238                }
5239             }
5240             /* get the format */
5241             if (  ps->t_FT[ps->t_N_surfnames] == SUMA_SUREFIT ||
5242                   ps->t_FT[ps->t_N_surfnames] == SUMA_VEC ||
5243                   ps->t_FT[ps->t_N_surfnames] == SUMA_INVENTOR_GENERIC ||
5244                   ps->t_FT[ps->t_N_surfnames] == SUMA_OPENDX_MESH ||
5245                   ps->t_FT[ps->t_N_surfnames] == SUMA_OBJ_MESH ||
5246                   ps->t_FT[ps->t_N_surfnames] == SUMA_BYU )
5247                   ps->t_FF[ps->t_N_surfnames] = SUMA_ASCII;
5248             else if (ps->t_FT[ps->t_N_surfnames] == SUMA_GIFTI )
5249                   ps->t_FF[ps->t_N_surfnames] = SUMA_XML_SURF;
5250             else if (ps->t_FT[ps->t_N_surfnames] == SUMA_PLY)
5251                   ps->t_FF[ps->t_N_surfnames] = SUMA_FF_NOT_SPECIFIED;
5252             else if (ps->t_FT[ps->t_N_surfnames] == SUMA_STL)
5253                   ps->t_FF[ps->t_N_surfnames] = SUMA_FF_NOT_SPECIFIED;
5254             else if (ps->t_FT[ps->t_N_surfnames] == SUMA_MNI_OBJ)
5255                   ps->t_FF[ps->t_N_surfnames] = SUMA_ASCII;
5256             else if (ps->t_FT[ps->t_N_surfnames] == SUMA_BRAIN_VOYAGER)
5257                   ps->t_FF[ps->t_N_surfnames] = SUMA_BINARY;
5258             else if (ps->t_FT[ps->t_N_surfnames] == SUMA_FREE_SURFER) {
5259                if (SUMA_isExtension(ps->t_surfnames[ps->t_N_surfnames], ".asc"))
5260                ps->t_FF[ps->t_N_surfnames] = SUMA_ASCII;
5261             else
5262                ps->t_FF[ps->t_N_surfnames] = SUMA_BINARY_BE;
5263             }
5264 
5265             ++ps->t_N_surfnames;
5266             brk = YUP;
5267          }
5268 
5269       }
5270       if (!brk && ps->accept_o) {
5271          char *tmp_o = NULL;
5272          if (strcmp(argv[kar], "-o_") == 0 || strcmp(argv[kar], "-o") == 0) {
5273             if (kar+1 >= argc)  {
5274                SUMA_S_Err( "need argument after -o_ ");
5275                exit (1);
5276             }
5277             switch(SUMA_GuessSurfFormatFromExtension_core(argv[kar+1],
5278                                                           NULL, NULL, NULL)) {
5279                case SUMA_FREE_SURFER:
5280                case SUMA_FREE_SURFER_PATCH:
5281                   tmp_o = SUMA_copy_string("-o_fs");
5282                   break;
5283                case SUMA_SUREFIT:
5284                   tmp_o = SUMA_copy_string("-o_sf");
5285                   break;
5286                case SUMA_INVENTOR_GENERIC:
5287                   tmp_o = SUMA_copy_string("-o_iv");
5288                   break;
5289                case SUMA_STL:
5290                   tmp_o = SUMA_copy_string("-o_stl");
5291                   break;
5292                case SUMA_PLY:
5293                   tmp_o = SUMA_copy_string("-o_ply");
5294                   break;
5295                case SUMA_MNI_OBJ:
5296                   tmp_o = SUMA_copy_string("-o_mni");
5297                   break;
5298                case SUMA_VEC:
5299                   tmp_o = SUMA_copy_string("-o_1d");
5300                   break;
5301                case SUMA_BRAIN_VOYAGER:
5302                   tmp_o = SUMA_copy_string("-o_bv");
5303                   break;
5304                case SUMA_OPENDX_MESH:
5305                   tmp_o = SUMA_copy_string("-o_dx");
5306                   break;
5307                case SUMA_OBJ_MESH:
5308                   tmp_o = SUMA_copy_string("-o_obj");
5309                   break;
5310                case SUMA_BYU:
5311                   tmp_o = SUMA_copy_string("-o_byu");
5312                   break;
5313                case SUMA_GIFTI:
5314                   tmp_o = SUMA_copy_string("-o_gii");
5315                   break;
5316                case SUMA_CMAP_SO:
5317                   break;
5318                default:
5319                   tmp_o = SUMA_copy_string(argv[kar]);
5320                   break;
5321             }
5322          } else {
5323             tmp_o = SUMA_copy_string(argv[kar]);
5324          }
5325          if (!brk && (  (strcmp(tmp_o, "-o_fs") == 0) ||
5326                         (strcmp(tmp_o, "-o_FS") == 0) ) ) {
5327             ps->arg_checked[kar]=1;
5328             kar ++; ps->arg_checked[kar]=1;
5329             if (kar >= argc)  {
5330                SUMA_S_Err( "need argument after -o_fs ");
5331                exit (1);
5332             }
5333             if (ps->o_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
5334                SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
5335                exit(1);
5336             }
5337             ps->o_surfnames[ps->o_N_surfnames] =
5338                SUMA_RemoveSurfNameExtension(argv[kar], SUMA_FREE_SURFER);
5339             ps->o_FT[ps->o_N_surfnames] = SUMA_FREE_SURFER;
5340             ps->o_FF[ps->o_N_surfnames] = SUMA_ASCII;
5341             ++ps->o_N_surfnames;
5342             brk = YUP;
5343          }
5344 
5345          if (!brk && (  (strcmp(tmp_o, "-o_fsp") == 0) ||
5346                         (strcmp(tmp_o, "-o_FSP") == 0) ) ) {
5347             ps->arg_checked[kar]=1;
5348             kar ++; ps->arg_checked[kar]=1;
5349             if (kar >= argc)  {
5350                SUMA_S_Err( "need argument after -o_fsp ");
5351                exit (1);
5352             }
5353             if (ps->o_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
5354                SUMA_SL_Err("Exceeding maximum number of allowed surfaces...");
5355                exit(1);
5356             }
5357 
5358             ps->o_surfnames[ps->o_N_surfnames] =
5359                SUMA_RemoveSurfNameExtension(argv[kar], SUMA_FREE_SURFER_PATCH);
5360             ps->o_FT[ps->o_N_surfnames] = SUMA_FREE_SURFER_PATCH;
5361             ps->o_FF[ps->o_N_surfnames] = SUMA_BINARY;
5362             ++ps->o_N_surfnames;
5363             brk = YUP;
5364          }
5365 
5366          if (!brk && (  (strcmp(tmp_o, "-o_sf") == 0) ||
5367                         (strcmp(tmp_o, "-o_SF") == 0)) ) {
5368             ps->arg_checked[kar]=1;
5369             kar ++; ps->arg_checked[kar]=1;
5370             if (kar >= argc)  {
5371                SUMA_S_Err( "need 1 or 2 argument after -o_sf ");
5372                exit (1);
5373             }
5374             if (ps->o_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
5375                SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
5376                exit(1);
5377             }
5378             ps->o_surfnames[ps->o_N_surfnames] =
5379                SUMA_RemoveSurfNameExtension(argv[kar], SUMA_SUREFIT);
5380             ps->o_FT[ps->o_N_surfnames] = SUMA_SUREFIT;
5381             ps->o_FF[ps->o_N_surfnames] = SUMA_ASCII;
5382             /* is there another argument ?*/
5383             if (kar+1 < argc)  {
5384                if (argv[kar+1][0] == '-') {
5385                   /* that is an option flag */
5386                   ps->o_surftopo[ps->o_N_surfnames] =
5387                      SUMA_copy_string(ps->o_surfnames[ps->o_N_surfnames]);
5388                } else {
5389                   kar ++; ps->arg_checked[kar]=1;
5390                   ps->o_surftopo[ps->o_N_surfnames] =
5391                      SUMA_RemoveSurfNameExtension(argv[kar], SUMA_SUREFIT);
5392                }
5393             }
5394             ++ps->o_N_surfnames;
5395             brk = YUP;
5396          }
5397 
5398 
5399          if (!brk && (  (strcmp(tmp_o, "-o_vec") == 0) ||
5400                         (strcmp(tmp_o, "-o_1d") == 0)  ||
5401                         (strcmp(tmp_o, "-o_VEC") == 0) ||
5402                         (strcmp(tmp_o, "-o_1D") == 0) ) ) {
5403             ps->arg_checked[kar]=1;
5404             kar ++; ps->arg_checked[kar]=1;
5405             if (kar >= argc)  {
5406                SUMA_S_Err( "need 1 or 2 argument after -o_sf ");
5407                exit (1);
5408             }
5409             if (ps->o_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
5410                SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
5411                exit(1);
5412             }
5413             ps->o_surfnames[ps->o_N_surfnames] =
5414                SUMA_RemoveSurfNameExtension(argv[kar], SUMA_VEC);
5415             ps->o_FT[ps->o_N_surfnames] = SUMA_VEC;
5416             ps->o_FF[ps->o_N_surfnames] = SUMA_ASCII;
5417             /* is there another argument ?*/
5418             if (kar+1 < argc)  {
5419                if (argv[kar+1][0] == '-') {
5420                   /* that is an option flag */
5421                   ps->o_surftopo[ps->o_N_surfnames] =
5422                      SUMA_copy_string(ps->o_surfnames[ps->o_N_surfnames]);
5423                } else {
5424                   kar ++; ps->arg_checked[kar]=1;
5425                   ps->o_surftopo[ps->o_N_surfnames] =
5426                      SUMA_RemoveSurfNameExtension(argv[kar], SUMA_VEC);
5427                }
5428             }
5429             ++ps->o_N_surfnames;
5430             brk = YUP;
5431          }
5432 
5433          if (!brk && (  (strcmp(tmp_o, "-o_dx") == 0) ||
5434                         (strcmp(tmp_o, "-o_DX") == 0)
5435                      || (strcmp(tmp_o, "-o_Dx") == 0)) ) {
5436             ps->arg_checked[kar]=1;
5437             kar ++; ps->arg_checked[kar]=1;
5438             if (kar >= argc)  {
5439                SUMA_S_Err( "need argument after -o_dx \n");
5440                exit (1);
5441             }
5442             if (ps->o_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
5443                SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
5444                exit(1);
5445             }
5446             ps->o_surfnames[ps->o_N_surfnames] =
5447                SUMA_RemoveSurfNameExtension(argv[kar], SUMA_OPENDX_MESH);
5448             ps->o_FT[ps->o_N_surfnames] = SUMA_OPENDX_MESH;
5449             ps->o_FF[ps->o_N_surfnames] = SUMA_ASCII;
5450             ++ps->o_N_surfnames;
5451             brk = YUP;
5452          }
5453          if (!brk && (  (strcmp(tmp_o, "-o_obj") == 0) ||
5454                         (strcmp(tmp_o, "-o_OBJ") == 0)
5455                      || (strcmp(tmp_o, "-o_Obj") == 0)) ) {
5456             ps->arg_checked[kar]=1;
5457             kar ++; ps->arg_checked[kar]=1;
5458             if (kar >= argc)  {
5459                SUMA_S_Err( "need argument after -o_obj \n");
5460                exit (1);
5461             }
5462             if (ps->o_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
5463                SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
5464                exit(1);
5465             }
5466             ps->o_surfnames[ps->o_N_surfnames] =
5467                SUMA_RemoveSurfNameExtension(argv[kar], SUMA_OBJ_MESH);
5468             ps->o_FT[ps->o_N_surfnames] = SUMA_OBJ_MESH;
5469             ps->o_FF[ps->o_N_surfnames] = SUMA_ASCII;
5470             ++ps->o_N_surfnames;
5471             brk = YUP;
5472          }
5473          if (!brk && ( (strcmp(tmp_o, "-o_ply") == 0) ||
5474                         (strcmp(tmp_o, "-o_PLY") == 0)
5475                      || (strcmp(tmp_o, "-o_Ply") == 0)) ) {
5476             ps->arg_checked[kar]=1;
5477             kar ++; ps->arg_checked[kar]=1;
5478             if (kar >= argc)  {
5479                SUMA_S_Err( "need argument after -o_ply \n");
5480                exit (1);
5481             }
5482             if (ps->o_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
5483                SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
5484                exit(1);
5485             }
5486             ps->o_surfnames[ps->o_N_surfnames] =
5487                   SUMA_RemoveSurfNameExtension(argv[kar], SUMA_PLY);
5488             ps->o_FT[ps->o_N_surfnames] = SUMA_PLY;
5489             ps->o_FF[ps->o_N_surfnames] = SUMA_ASCII;
5490             ++ps->o_N_surfnames;
5491             brk = YUP;
5492          }
5493          if (!brk && ( (strcmp(tmp_o, "-o_stl") == 0) ||
5494                         (strcmp(tmp_o, "-o_STL") == 0)
5495                      || (strcmp(tmp_o, "-o_Stl") == 0)) ) {
5496             ps->arg_checked[kar]=1;
5497             kar ++; ps->arg_checked[kar]=1;
5498             if (kar >= argc)  {
5499                SUMA_S_Err( "need argument after -o_stl \n");
5500                exit (1);
5501             }
5502             if (ps->o_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
5503                SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
5504                exit(1);
5505             }
5506             ps->o_surfnames[ps->o_N_surfnames] =
5507                   SUMA_RemoveSurfNameExtension(argv[kar], SUMA_STL);
5508             ps->o_FT[ps->o_N_surfnames] = SUMA_STL;
5509             ps->o_FF[ps->o_N_surfnames] = SUMA_ASCII;
5510             ++ps->o_N_surfnames;
5511             brk = YUP;
5512          }
5513          if (!brk && ( (strcmp(tmp_o, "-o_mni") == 0) ||
5514                         (strcmp(tmp_o, "-o_MNI") == 0)
5515                      || (strcmp(tmp_o, "-o_Mni") == 0)) ) {
5516             ps->arg_checked[kar]=1;
5517             kar ++; ps->arg_checked[kar]=1;
5518             if (kar >= argc)  {
5519                SUMA_S_Err( "need argument after -o_mni \n");
5520                exit (1);
5521             }
5522             if (ps->o_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
5523                SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
5524                exit(1);
5525             }
5526             ps->o_surfnames[ps->o_N_surfnames] =
5527                   SUMA_RemoveSurfNameExtension(argv[kar], SUMA_MNI_OBJ);
5528             ps->o_FT[ps->o_N_surfnames] = SUMA_MNI_OBJ;
5529             ps->o_FF[ps->o_N_surfnames] = SUMA_ASCII;
5530             ++ps->o_N_surfnames;
5531             brk = YUP;
5532          }
5533          if (!brk && (  (strcmp(tmp_o, "-o_byu") == 0) ||
5534                         (strcmp(tmp_o, "-o_BYU") == 0)
5535                      || (strcmp(tmp_o, "-o_Ply") == 0)) ) {
5536             ps->arg_checked[kar]=1;
5537             kar ++; ps->arg_checked[kar]=1;
5538             if (kar >= argc)  {
5539                SUMA_S_Err( "need argument after -o_byu \n");
5540                exit (1);
5541             }
5542             if (ps->o_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
5543                SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
5544                exit(1);
5545             }
5546             ps->o_surfnames[ps->o_N_surfnames] =
5547                         SUMA_RemoveSurfNameExtension(argv[kar], SUMA_BYU);
5548             ps->o_FT[ps->o_N_surfnames] = SUMA_BYU;
5549             ps->o_FF[ps->o_N_surfnames] = SUMA_ASCII;
5550             ++ps->o_N_surfnames;
5551             brk = YUP;
5552          }
5553          if (!brk && (  (strncmp(tmp_o, "-o_gii",6) == 0) ||
5554                         (strncmp(tmp_o, "-o_GII",6) == 0) ||
5555                         (strncmp(tmp_o, "-o_gifti",8) == 0) ||
5556                         (strncmp(tmp_o, "-o_GIFTI",8) == 0) ) ) {
5557             ps->arg_checked[kar]=1;
5558             kar ++; ps->arg_checked[kar]=1;
5559             if (kar >= argc)  {
5560                SUMA_S_Err( "need argument after -o_gii \n");
5561                exit (1);
5562             }
5563             if (ps->o_N_surfnames >= SUMA_MAX_SURF_ON_COMMAND) {
5564                SUMA_S_Err("Exceeding maximum number of allowed surfaces...");
5565                exit(1);
5566             }
5567             ps->o_surfnames[ps->o_N_surfnames] =
5568                         SUMA_RemoveSurfNameExtension(argv[kar], SUMA_GIFTI);
5569             ps->o_FT[ps->o_N_surfnames] = SUMA_GIFTI;
5570             if (SUMA_iswordin_ci(tmp_o,"asc") == 1)
5571                ps->o_FF[ps->o_N_surfnames] = SUMA_XML_ASCII_SURF;
5572             else   if (SUMA_iswordin_ci(tmp_o,"gz") == 1)
5573                ps->o_FF[ps->o_N_surfnames] = SUMA_XML_B64GZ_SURF;
5574             else   if (SUMA_iswordin_ci(tmp_o,"b64") == 1)
5575                ps->o_FF[ps->o_N_surfnames] = SUMA_XML_B64_SURF;
5576             else   ps->o_FF[ps->o_N_surfnames] = SUMA_XML_SURF;
5577             ++ps->o_N_surfnames;
5578             brk = YUP;
5579          }
5580 
5581          if (tmp_o) SUMA_free(tmp_o); tmp_o = NULL;
5582       }
5583 
5584       brk = NOPE;
5585       kar ++;
5586    }
5587 
5588    if (ps->cs->rps > 0) {
5589       ps->cs->nelps = (float)ps->cs->talk_suma * ps->cs->rps;
5590    } else { ps->cs->nelps = (float) ps->cs->talk_suma * -1.0; }
5591 
5592 
5593    SUMA_RETURN(ps);
5594 }
5595