Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

SUMA_ParseCommands.c

Go to the documentation of this file.
00001 
00002 #define DEBUG_3
00003 #ifdef DEBUG_1
00004    #define DEBUG_2
00005    #define DEBUG_3
00006 #endif
00007    
00008 /* Header FILES */
00009    
00010 #include "SUMA_suma.h"
00011 
00012 #ifdef STAND_ALONE
00013    SUMA_CommonFields *SUMAg_CF;
00014 #else
00015    extern SUMA_CommonFields *SUMAg_CF; 
00016 #endif
00017 
00018 /* CODE */
00019    
00020 /*!
00021    \brief Returns the code for the next command (at the tail of the list).
00022    CommandCode =  SUMA_GetListNextCommand (list);
00023    \param list (DList *) pointer to doubly linked list
00024    \return CommandCode (SUMA_ENGINE_CODE) code for next command. The next command is at the head of the list.
00025     
00026    Note that the list is not modified.
00027    
00028    This function replaces the obsolete SUMA_GetNextCommand
00029 */
00030 SUMA_ENGINE_CODE SUMA_GetListNextCommand (DList *list)
00031 {
00032    static char FuncName[]={"SUMA_GetListNextCommand"};
00033    DListElmt *next;
00034    SUMA_EngineData *ED = NULL;
00035    
00036    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00037 
00038    if (!dlist_size(list)) {
00039       SUMA_RETURN (SE_Empty);
00040    }
00041    
00042    next = (DListElmt *)dlist_head(list);
00043    ED = (SUMA_EngineData *)(next->data);
00044    SUMA_RETURN (ED->CommandCode);
00045    
00046 } 
00047 
00048    
00049 /*!**
00050 File : SUMA_ParseCommands.c
00051 \author Ziad Saad
00052 Date : Tue Feb 5 10:39:02 EST 2002
00053    
00054 Purpose : 
00055    obtain the next command Scom from the string of commands S
00056    
00057    
00058 Usage : 
00059       Ret = SUMA_GetNextCommand (char *S, char d, char term, char *Scom);
00060    
00061    
00062 Input paramters : 
00063 \param  S (char *) : String containing commands like "Initialize|ShowSurf|LightsON~" 
00064 \param  d (char)  : character delimiting multiple commands ('|' in this example)
00065 \param  term (char) : character terminating entire command ('~' in this example)
00066 \param  Scom (char *): Null terminated string that will contain latest command (LightsON) in this example
00067                      S will be returned "Initialize|ShowSurf~"
00068 
00069 Returns : 
00070 \return   code of the command as defined for SUMA_ENGINE_CODE
00071    
00072 NOTE:  OBSOLETE, use SUMA_GetListNextCommand   
00073       
00074    
00075 ***/
00076 int SUMA_GetNextCommand (char *S, char d, char term, char *Scom)
00077 {/*SUMA_GetNextCommand*/
00078    static char FuncName[]={"SUMA_GetNextCommand"}; 
00079    int i=0, iBegin, iStop;
00080    
00081    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00082 
00083    fprintf (SUMA_STDERR, "Error %s: This function is now obsolete. Must use SUMA_GetListNextCommand instead.\n", FuncName);
00084    SUMA_RETURN (NOPE);
00085 
00086    iStop = strlen(S)-1;
00087    
00088    /*fprintf(stdout,"%s %c %c\n", S, S[iStop], term);  */
00089    if (S[iStop] != term) {
00090       fprintf (stderr, "%s Error: Command poorly terminated!\n\a", FuncName);
00091       SUMA_RETURN (0);
00092    }
00093    /* Make sure character just before term is not d */
00094    if (S[iStop-1] == d) {
00095       S[iStop] = '\0';
00096       iStop -= 1;
00097       S[iStop] = term;
00098    }
00099    
00100    /* search for command delimiter */
00101    iBegin = iStop -1;
00102    while (iBegin > -1 && S[iBegin]!= d) --iBegin;
00103    ++iBegin;
00104    
00105    /* copy command to Scom*/
00106    for (i=0; i< iStop - iBegin; ++i)  {
00107       /*fprintf(stdout,"%d %c\n", iBegin+i, S[iBegin+i]);*/
00108       Scom[i] = S[iBegin+i]; 
00109       S[iBegin+i] = '\0'; /*for esthetics */}
00110    
00111    /* seal strings with terminators */
00112    Scom[iStop-iBegin] = '\0';
00113    if (iBegin > 0) {
00114       S[iBegin-1] = term;
00115       iStop = iBegin-1;
00116    }
00117    else {
00118       S[iBegin] = term;
00119       iStop = iBegin;
00120 
00121    }
00122    
00123    /*get the code of the command*/
00124    SUMA_RETURN (SUMA_CommandCode(Scom));
00125 
00126 }/*SUMA_GetNextCommand*/
00127 
00128 int SUMA_CommandCode(char *Scom)
00129 {   
00130    static char FuncName[]={"SUMA_CommandCode"};
00131    
00132    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00133 
00134    if (!strlen(Scom)) SUMA_RETURN (SE_Empty);
00135    if (strcmp(Scom,"~") == 0) SUMA_RETURN (SE_Empty);
00136    
00137    /*fprintf(stdout,"Looking for %s\n", Scom);*/
00138    if (!strcmp(Scom,"SetLookAt")) SUMA_RETURN(SE_SetLookAt);   
00139    if (!strcmp(Scom,"SetLookFrom")) SUMA_RETURN(SE_SetLookFrom);
00140    if (!strcmp(Scom,"Redisplay")) SUMA_RETURN(SE_Redisplay);
00141    if (!strcmp(Scom,"RedisplayNow")) SUMA_RETURN(SE_RedisplayNow);
00142    if (!strcmp(Scom,"Redisplay_AllVisible")) SUMA_RETURN(SE_Redisplay_AllVisible);
00143    if (!strcmp(Scom,"SetNodeColor")) SUMA_RETURN (SE_SetNodeColor);
00144    if (!strcmp(Scom,"FlipLight0Pos"))   SUMA_RETURN(SE_FlipLight0Pos);
00145    if (!strcmp(Scom,"GetNearestNode"))   SUMA_RETURN (SE_GetNearestNode);
00146    if (!strcmp(Scom,"SetLookAtNode"))   SUMA_RETURN (SE_SetLookAtNode);
00147    if (!strcmp(Scom,"SetRotMatrix"))   SUMA_RETURN (SE_SetRotMatrix);
00148    if (!strcmp(Scom,"SetCrossHair"))   SUMA_RETURN (SE_SetCrossHair);
00149    if (!strcmp(Scom,"ToggleCrossHair"))   SUMA_RETURN (SE_ToggleCrossHair);
00150    if (!strcmp(Scom,"HighlightNodes"))   SUMA_RETURN (SE_HighlightNodes);
00151    if (!strcmp(Scom,"ToggleShowSelectedNode"))   SUMA_RETURN (SE_ToggleShowSelectedNode);
00152    if (!strcmp(Scom,"SetSelectedNode"))   SUMA_RETURN (SE_SetSelectedNode);
00153    if (!strcmp(Scom,"SetSelectedFaceSet"))   SUMA_RETURN (SE_SetSelectedFaceSet);
00154    if (!strcmp(Scom,"ToggleShowSelectedFaceSet"))   SUMA_RETURN (SE_ToggleShowSelectedFaceSet);
00155    if (!strcmp(Scom,"ToggleConnected")) SUMA_RETURN (SE_ToggleConnected);
00156    if (!strcmp(Scom,"SetAfniCrossHair")) SUMA_RETURN (SE_SetAfniCrossHair);
00157    if (!strcmp(Scom,"SetForceAfniSurf")) SUMA_RETURN (SE_SetForceAfniSurf);
00158    if (!strcmp(Scom,"CloseStream4All")) SUMA_RETURN (SE_CloseStream4All);
00159    if (!strcmp(Scom,"SetAfniSurf")) SUMA_RETURN (SE_SetAfniSurf);
00160    if (!strcmp(Scom,"BindCrossHair")) SUMA_RETURN(SE_BindCrossHair);
00161    if (!strcmp(Scom,"ToggleForeground")) SUMA_RETURN (SE_ToggleForeground);
00162    if (!strcmp(Scom,"ToggleBackground")) SUMA_RETURN (SE_ToggleBackground);
00163    if (!strcmp(Scom,"FOVreset")) SUMA_RETURN (SE_FOVreset);
00164    if (!strcmp(Scom,"ResetOpenGLState")) SUMA_RETURN (SE_ResetOpenGLState);
00165    if (!strcmp(Scom,"LockCrossHair")) SUMA_RETURN(SE_LockCrossHair);
00166    if (!strcmp(Scom,"Home")) SUMA_RETURN (SE_Home);
00167    if (!strcmp(Scom,"Home_AllVisible")) SUMA_RETURN (SE_Home_AllVisible);
00168    if (!strcmp(Scom,"ToggleLockAllCrossHair")) SUMA_RETURN(SE_ToggleLockAllCrossHair);
00169    if (!strcmp(Scom,"SetLockAllCrossHair")) SUMA_RETURN(SE_SetLockAllCrossHair);
00170    if (!strcmp(Scom,"ToggleLockView")) SUMA_RETURN(SE_ToggleLockView);
00171    if (!strcmp(Scom,"ToggleLockAllViews")) SUMA_RETURN(SE_ToggleLockAllViews);
00172    if (!strcmp(Scom,"Load_Group")) SUMA_RETURN(SE_Load_Group);
00173    if (!strcmp(Scom,"Help")) SUMA_RETURN(SE_Help);
00174    if (!strcmp(Scom,"UpdateLog")) SUMA_RETURN(SE_UpdateLog);
00175    if (!strcmp(Scom,"Log")) SUMA_RETURN(SE_Log);
00176    if (!strcmp(Scom,"SetRenderMode")) SUMA_RETURN(SE_SetRenderMode);
00177    if (!strcmp(Scom,"OpenDrawROI")) SUMA_RETURN(SE_OpenDrawROI);
00178    if (!strcmp(Scom,"RedisplayNow_AllVisible")) SUMA_RETURN(SE_RedisplayNow_AllVisible);
00179    if (!strcmp(Scom,"RedisplayNow_AllOtherVisible")) SUMA_RETURN(SE_RedisplayNow_AllOtherVisible);
00180    if (!strcmp(Scom,"SetLight0Pos")) SUMA_RETURN(SE_SetLight0Pos);
00181    if (!strcmp(Scom,"OpenColFileSelection")) SUMA_RETURN(SE_OpenColFileSelection);
00182    if (!strcmp(Scom,"SaveDrawnROIFileSelection")) SUMA_RETURN(SE_SaveDrawnROIFileSelection);
00183    if (!strcmp(Scom,"OpenDrawnROIFileSelection")) SUMA_RETURN(SE_OpenDrawnROIFileSelection);
00184    /*if (!strcmp(Scom,"")) SUMA_RETURN(SE_);*/
00185    
00186    /* Last one is Bad Code */
00187    SUMA_RETURN (SE_BadCode);
00188      
00189 }
00190 
00191 /*!
00192    \brief Transforms a command code into a string for human consumption
00193    const char *SUMA_CommandString (SUMA_ENGINE_CODE code);
00194 
00195 */ 
00196 const char *SUMA_CommandString (SUMA_ENGINE_CODE code)
00197 {
00198    static char FuncName[]={"SUMA_CommandString"};
00199    
00200    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00201    
00202    switch (code) {
00203       case SE_SetLookAt:
00204          SUMA_RETURN("SetLookAt");
00205       case SE_SetLookFrom:
00206          SUMA_RETURN("SetLookFrom");
00207       case SE_Redisplay:
00208          SUMA_RETURN("Redisplay");
00209       case SE_RedisplayNow:
00210          SUMA_RETURN("RedisplayNow");      
00211       case SE_Redisplay_AllVisible:
00212          SUMA_RETURN("Redisplay_AllVisible");      
00213       case SE_SetNodeColor:
00214          SUMA_RETURN("SetNodeColor");      
00215       case SE_FlipLight0Pos:
00216          SUMA_RETURN("FlipLight0Pos");      
00217       case SE_GetNearestNode: 
00218          SUMA_RETURN("GetNearestNode");      
00219       case SE_SetLookAtNode:
00220          SUMA_RETURN("SetLookAtNode");      
00221       case SE_SetRotMatrix:
00222          SUMA_RETURN("SetRotMatrix");      
00223       case SE_SetCrossHair:
00224          SUMA_RETURN("SetCrossHair");      
00225       case SE_ToggleCrossHair:
00226          SUMA_RETURN("ToggleCrossHair");      
00227       case SE_HighlightNodes:
00228          SUMA_RETURN("HighlightNodes");      
00229       case SE_ToggleShowSelectedNode:
00230          SUMA_RETURN("ToggleShowSelectedNode");      
00231       case SE_SetSelectedNode:
00232          SUMA_RETURN("SetSelectedNode");      
00233       case SE_SetSelectedFaceSet:
00234          SUMA_RETURN("SetSelectedFaceSet");      
00235       case SE_ToggleShowSelectedFaceSet:
00236          SUMA_RETURN("ToggleShowSelectedFaceSet");      
00237       case SE_ToggleConnected:
00238          SUMA_RETURN("ToggleConnected");      
00239       case SE_SetAfniCrossHair:
00240          SUMA_RETURN("SetAfniCrossHair");      
00241       case SE_SetForceAfniSurf:
00242          SUMA_RETURN("SetForceAfniSurf");      
00243       case SE_CloseStream4All:
00244          SUMA_RETURN("CloseStream4All");      
00245       case SE_SetAfniSurf: 
00246          SUMA_RETURN("SetAfniSurf");      
00247       case SE_BindCrossHair:
00248          SUMA_RETURN("BindCrossHair");      
00249       case SE_ToggleForeground:
00250          SUMA_RETURN("ToggleForeground");      
00251       case SE_ToggleBackground:
00252          SUMA_RETURN("ToggleBackground");      
00253       case SE_FOVreset:
00254          SUMA_RETURN("FOVreset");      
00255       case SE_ResetOpenGLState: 
00256          SUMA_RETURN("ResetOpenGLState");      
00257       case SE_LockCrossHair:
00258          SUMA_RETURN("LockCrossHair");      
00259       case SE_Home:
00260          SUMA_RETURN("Home"); 
00261       case SE_Home_AllVisible:
00262          SUMA_RETURN("Home_AllVisible");     
00263       case SE_Empty:
00264          SUMA_RETURN("Empty");
00265       case SE_ToggleLockAllCrossHair:
00266          SUMA_RETURN("ToggleLockAllCrossHair");      
00267       case SE_SetLockAllCrossHair:
00268          SUMA_RETURN("SetLockAllCrossHair"); 
00269       case SE_ToggleLockView:
00270          SUMA_RETURN("ToggleLockView");
00271       case SE_ToggleLockAllViews:
00272          SUMA_RETURN("ToggleLockAllViews");   
00273       case SE_Load_Group:
00274          SUMA_RETURN("Load_Group"); 
00275       case SE_Help:
00276          SUMA_RETURN("Help");
00277       case SE_UpdateLog:
00278          SUMA_RETURN("UpdateLog"); 
00279       case SE_Log:
00280          SUMA_RETURN("Log");
00281       case SE_SetRenderMode:
00282          SUMA_RETURN("SetRenderMode");
00283       case SE_OpenDrawROI:
00284          SUMA_RETURN("OpenDrawROI"); 
00285       case SE_RedisplayNow_AllVisible:
00286          SUMA_RETURN("RedisplayNow_AllVisible");
00287       case SE_RedisplayNow_AllOtherVisible:
00288          SUMA_RETURN("RedisplayNow_AllOtherVisible");
00289       case SE_SetLight0Pos:
00290          SUMA_RETURN("SetLight0Pos");      
00291       case SE_OpenColFileSelection:
00292          SUMA_RETURN("OpenColFileSelection");      
00293       case SE_SaveDrawnROIFileSelection:
00294          SUMA_RETURN("SaveDrawnROIFileSelection");      
00295       case SE_OpenDrawnROIFileSelection:
00296          SUMA_RETURN("OpenDrawnROIFileSelection");      
00297       /*case SE_:
00298          SUMA_RETURN("");      */
00299       default:        
00300          SUMA_RETURN ("BadCode");
00301    }
00302 }
00303 /*!**
00304    
00305 Purpose : 
00306    Append or prepend command Scom to S
00307    
00308    
00309 Usage : 
00310       Ret =  SUMA_RegisterCommand(char *S, char d, char term, char *Scom, SUMA_Boolean Prepend);
00311    
00312    
00313 Input paramters : 
00314 \param  S (char *) : String containing commands like "Initialize|ShowSurf~" MUST BE NULL TERMINATED
00315 \param  d (char)  : character delimiting multiple commands ('|' in this example)
00316 \param  term (char) : character terminating entire command ('~' in this example)
00317 \param  Scom (char *): Null terminated string that will contain latest command (LightsON) in this example
00318                      S will be returned "Initialize|ShowSurf/LightsON~" if Prepend is YUP
00319                      S will be returned "LightsON|Initialize|ShowSurf" is Prepend if NOPE
00320 \param Prepend (SUMA_Boolean): append or prepend command
00321 
00322 Returns : 
00323 \return   NOPE for failure, YUP success
00324    
00325 NOTE: OBSOLETE, use  SUMA_RegisterEngineListCommand  
00326       
00327    
00328 ***/
00329 SUMA_Boolean SUMA_RegisterCommand (char *S, char d, char term, char *Scom, SUMA_Boolean Prepend)
00330 {   int i, iStop, iorig, iStopNew, nCom;
00331    static char FuncName[]={"SUMA_RegisterCommand"};
00332    
00333    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00334    
00335    fprintf (SUMA_STDERR, "Error %s: This function is now obsolete. Must use SUMA_RegisterCommand instead.\n", FuncName);
00336    SUMA_RETURN (NOPE);
00337 
00338    iStop = strlen(S)-1;
00339       
00340    nCom = strlen(Scom);
00341    /*fprintf (stdout,"Scom->%s<-, length %d\n", Scom, nCom);*/
00342    if (strlen(Scom) + iStop + 2 > SUMA_MAX_COMMAND_LENGTH ) {
00343       fprintf (stderr, "%s Error: Resultant command longer than SUMA_MAX_COMMAND_LENGTH!\n\a", FuncName);
00344       SUMA_RETURN (NOPE);
00345    }
00346    if (S[iStop] != term) {
00347       fprintf (stderr, "%s Error: S improperly terminated!\n\a", FuncName);
00348       SUMA_RETURN (NOPE);
00349    }
00350    if (!Prepend) {
00351       /* add a delimiter */
00352       if (S[iStop-1] != d) { 
00353          S[iStop] = d;
00354          iStop += 1;
00355       }
00356       /*append the command */
00357       for (i=0; i <nCom; ++i) {
00358          S[iStop+i] = Scom[i];
00359       } 
00360       iStop += nCom;
00361       S[iStop] = term;
00362       S[iStop+1] = '\0';
00363       SUMA_RETURN (YUP);
00364    } else {
00365       /* move old string forward*/
00366       iStopNew = iStop+nCom+1;
00367       S[iStopNew+1] = '\0';
00368       iorig = 0;
00369       while (iorig <= iStop) {
00370          S[iStopNew-iorig] = S[iStop-iorig];
00371          ++iorig;
00372       }
00373       S[iStopNew-iorig] = d;
00374       
00375       /*add new one */
00376       for (i=0; i < nCom; ++i) {
00377          S[i] = Scom[i];
00378       }
00379       iStop = iStopNew;
00380       SUMA_RETURN (YUP);
00381    }
00382 }
00383 
00384 /*!
00385    \brief translates SUMA_ENGINE_FIELD_CODE to string
00386 */
00387 const char* SUMA_EngineFieldString (SUMA_ENGINE_FIELD_CODE i)
00388 {
00389    static char FuncName[]={"SUMA_EngineFieldString"};
00390    
00391    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00392 
00393    switch (i) {
00394       case (SEF_fm):
00395          SUMA_RETURN ("fm");
00396          break;
00397       case (SEF_im):
00398          SUMA_RETURN ("im");
00399          break;
00400       case (SEF_fv3):
00401          SUMA_RETURN ("fv3");
00402          break;
00403       case (SEF_iv3):
00404          SUMA_RETURN ("iv3");
00405          break;
00406       case (SEF_fv15):
00407          SUMA_RETURN ("fv15");
00408          break;
00409       case (SEF_iv15):
00410          SUMA_RETURN ("iv15");
00411          break;
00412       case (SEF_i):
00413          SUMA_RETURN ("i");
00414          break;
00415       case (SEF_f):
00416          SUMA_RETURN ("f");
00417          break;
00418       case (SEF_s):
00419          SUMA_RETURN ("s");
00420          break;
00421       case (SEF_vp):
00422          SUMA_RETURN ("vp");
00423          break;
00424       case (SEF_cp):
00425          SUMA_RETURN ("cp");
00426          break;
00427       case (SEF_fp):
00428          SUMA_RETURN ("fp");
00429          break;
00430       case (SEF_ip):
00431          SUMA_RETURN ("ip");
00432          break;
00433       default:
00434          SUMA_RETURN ("Unknown");
00435          break;
00436       
00437    }
00438    
00439 }
00440 
00441 SUMA_ENGINE_FIELD_CODE SUMA_EngineFieldCode(char *Scom)
00442 {   
00443    static char FuncName[]={"SUMA_EngineFieldCode"};
00444    
00445    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00446 
00447    if (!strlen(Scom)) SUMA_RETURN (SEF_Empty);
00448    
00449    /*fprintf(stdout,"Looking for %s\n", Scom);*/
00450    if (!strcmp(Scom,"fm")) SUMA_RETURN(SEF_fm);   
00451    if (!strcmp(Scom,"im")) SUMA_RETURN(SEF_im);   
00452    if (!strcmp(Scom,"fv3")) SUMA_RETURN(SEF_fv3);
00453    if (!strcmp(Scom,"iv3")) SUMA_RETURN(SEF_iv3);
00454    if (!strcmp(Scom,"fv15")) SUMA_RETURN(SEF_fv15);
00455    if (!strcmp(Scom,"iv15")) SUMA_RETURN(SEF_iv15);
00456    if (!strcmp(Scom,"i")) SUMA_RETURN(SEF_i);
00457    if (!strcmp(Scom,"f")) SUMA_RETURN (SEF_f);
00458    if (!strcmp(Scom,"s")) SUMA_RETURN (SEF_s);
00459    if (!strcmp(Scom,"vp")) SUMA_RETURN (SEF_vp); /* void pointer */
00460    if (!strcmp(Scom,"fp")) SUMA_RETURN(SEF_fp);
00461    if (!strcmp(Scom,"cp")) SUMA_RETURN(SEF_cp);
00462    if (!strcmp(Scom,"ip")) SUMA_RETURN(SEF_ip);
00463    /*if (!strcmp(Scom,"")) SUMA_RETURN(SEF_);*/
00464    
00465    /* Last one is Bad Code */
00466    SUMA_RETURN (SEF_BadCode);
00467      
00468 }
00469 
00470 int SUMA_EngineSourceCode (char *Scom)
00471 {
00472    static char FuncName[]={"SUMA_EngineSourceCode"};
00473    
00474    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00475 
00476    if (!strlen(Scom)) SUMA_RETURN (SES_Empty);
00477    if (!strcmp(Scom,"suma")) SUMA_RETURN(SES_Suma);
00478    if (!strcmp(Scom,"afni")) SUMA_RETURN(SES_Afni);
00479    if (!strcmp(Scom,"suma_widget")) SUMA_RETURN(SES_SumaWidget);
00480    if (!strcmp(Scom,"suma_from_afni")) SUMA_RETURN(SES_SumaFromAfni);
00481    if (!strcmp(Scom,"suma_from_any")) SUMA_RETURN(SES_SumaFromAny);
00482    if (!strcmp(Scom,"unknown")) SUMA_RETURN(SES_Unknown);
00483    
00484    /* got here? Unknown */
00485    SUMA_RETURN (SES_Unknown);
00486 }  
00487 
00488 void SUMA_EngineSourceString (char *Scom, int i)
00489 {
00490    static char FuncName[]={"SUMA_EngineSourceString"};
00491 
00492    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00493 
00494    switch (i) {
00495       case SES_Empty:
00496          Scom[0]='\0';
00497          break;
00498       case SES_Suma:
00499          sprintf(Scom,"suma");
00500          break;
00501       case SES_Afni:
00502          sprintf(Scom, "afni");
00503          break;
00504       case SES_SumaWidget:
00505          sprintf(Scom, "suma_widget");
00506          break;
00507       case SES_SumaFromAfni:
00508          sprintf(Scom, "suma_from_afni");
00509          break;
00510       case SES_SumaFromAny:
00511          sprintf(Scom, "suma_from_any");
00512          break;
00513       case SES_Unknown:
00514          sprintf(Scom, "unknown");
00515          break;
00516       default:
00517          sprintf(Scom, "Undetermined flag");
00518          break;
00519    }
00520    SUMA_RETURNe;
00521 }
00522 
00523 /*! 
00524 \brief Appends a new message to the list of SUMA messages, making sure
00525 the number of messages does not exceed SUMA_MAX_MESSAGES
00526 Ans = SUMA_RegisterMessage (  list, Message, Source, Type, Action );
00527 
00528 \param list (DList *) pointer to doubly linked list of messages
00529 \param Message (char *) null terminated message
00530 \param Source (char *) null terminated source of message
00531 \param Type (SUMA_MESSAGE_TYPES) Type of message to spit out
00532 \param Action (SUMA_MESSAGE_ACTION) Action to perform with message
00533 \return  YUP/NOPE, success/failure
00534 
00535 */
00536 SUMA_Boolean SUMA_RegisterMessage ( DList *list, char *Message, char *Source, SUMA_MESSAGE_TYPES Type, SUMA_MESSAGE_ACTION Action)
00537 {
00538    static char FuncName[]={"SUMA_RegisterMessage"};
00539    SUMA_MessageData *MD = NULL;
00540    SUMA_Boolean TryLogWindow = NOPE;
00541    int i=0, TrimTheFat=0;
00542    
00543    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00544    
00545    if (!list) {
00546       fprintf (SUMA_STDERR, "Warning %s: list has not been initialized.\n"
00547                             "Nothing done.\n", FuncName);
00548       SUMA_RETURN (YUP);
00549    }
00550    
00551    /* allocate and initialize element */
00552    MD = (SUMA_MessageData *) SUMA_malloc(sizeof(SUMA_MessageData));
00553    if (!MD) {
00554       fprintf (SUMA_STDERR, "Error %s: Failed to allocate.\n", FuncName);
00555       SUMA_RETURN (NOPE);
00556    }
00557    
00558    MD->Message = Message;
00559    MD->Source = Source;
00560    MD->Type = Type;
00561    MD->Action = Action;
00562    
00563    /* add element at end */
00564    if (dlist_ins_next (list, dlist_tail(list), (void *)MD) < 0) {
00565        fprintf (SUMA_STDERR, "Error %s: Failed to insert element in list.\n", FuncName);
00566        SUMA_RETURN(NOPE);
00567    }
00568    
00569    /* make sure size of list is < SUMA_MAX_MESSAGES */
00570    TrimTheFat = list->size - SUMA_MAX_MESSAGES;
00571    if ( TrimTheFat > 0) {
00572       for (i=0; i < TrimTheFat; ++i) {
00573          /* remove the head */
00574          if (!SUMA_ReleaseMessageListElement (list, dlist_head(list))) {
00575             fprintf (SUMA_STDERR, "Error %s: Failed in SUMA_ReleaseMessageListElement.\n", FuncName);
00576             SUMA_RETURN (NOPE);
00577          } 
00578       }
00579    }
00580    
00581    /* Decide on what to do with new element */
00582    switch (MD->Action) {
00583       case SMA_Nothing:
00584          break;
00585       case SMA_Log:
00586          TryLogWindow = YUP;
00587          break;
00588       case SMA_LogAndPopup:
00589          TryLogWindow = YUP;
00590          SUMA_PopUpMessage (MD);
00591          break;
00592       default:
00593          break;
00594    
00595    }
00596    
00597    if (TryLogWindow) {
00598       DList *Elist=NULL;
00599       SUMA_EngineData *ED=NULL;
00600 
00601       Elist = SUMA_CreateList();
00602       SUMA_REGISTER_HEAD_COMMAND_NO_DATA(Elist, SE_UpdateLog, SES_Suma, NULL);
00603 
00604       if (!SUMA_Engine (&Elist)) {
00605          fprintf(SUMA_STDERR, "Error %s: SUMA_Engine call failed.\n", FuncName);
00606          SUMA_RETURN (NOPE);
00607       }
00608    }
00609 
00610    
00611    SUMA_RETURN (YUP);
00612 }
00613 
00614 /*!
00615    \brief forms a string out of all the messages in the Message list
00616    
00617 */
00618 char *SUMA_BuildMessageLog (DList *ML)
00619 {
00620    static char FuncName[]={"SUMA_BuildMessageLog"};
00621    char *s=NULL;
00622    SUMA_STRING *SS = NULL;
00623    DListElmt *CurElmt=NULL;
00624    
00625    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00626    
00627   
00628    if (!ML->size) { /* Nothing */
00629       SUMA_RETURN (NULL);
00630    }
00631    
00632    SS = SUMA_StringAppend (NULL, NULL);
00633    
00634    if (!(CurElmt = dlist_head(ML))) {
00635       SUMA_RETURN (NULL);
00636    }
00637    do {
00638       SS = SUMA_StringAppend (SS, SUMA_FormatMessage ((SUMA_MessageData *)CurElmt->data)); 
00639       SS = SUMA_StringAppend (SS, "---------------------\n");
00640    } while ((CurElmt = dlist_next(CurElmt)));
00641    
00642    /* clean SS */
00643    SS = SUMA_StringAppend (SS, NULL);
00644    /* copy s pointer and free SS */
00645    s = SS->s;
00646    SUMA_free(SS); 
00647    
00648    SUMA_RETURN (s);
00649    
00650 }
00651 /*!
00652 \brief Adds a new element to the list of commands for SUMA_Engine.
00653 NewElement = SUMA_RegisterEngineListCommand (   list,  EngineData,  
00654                                                 FldCode, FldValp, 
00655                                                 SourceCode, SourcePointer, PassByPointer, 
00656                                                 InsertAt, Element);
00657                                                 
00658 \param list (DList *) pointer to doubly linked list of engine commands.
00659 \param EngineData (SUMA_EngineData *) a properly initialized pointer to EngineData structure.
00660 \param FldCode (SUMA_ENGINE_FIELD_CODE) code of field in EngineData structure to be filled.
00661 \param FldValp (void *) pointer to value that is to be placed in FldCode field of EngineData.
00662 \param SourceCode (SUMA_ENGINE_SOURCE) code of source issuing command.
00663 \param SourcePointer (void *) pointer to data structure of source issuing command. 
00664    I use this as a pointer to the calling surface viewer structure, but you can use it for anyting you please as long
00665    as SUMA_Engine knows what to do with it. Send NULL for none.
00666 \param PassByPointer (SUMA_Boolean) flag (YUP/NOPE), if YUP then assignment is done at the pointer level (EngineData->Fld = FldValp)
00667        if NOPE then space is allocated for Fld and values are copied from FldValp[i][j] to EngineData->Fld[i][j]
00668 \param InsertAt (SUMA_ENGINE_INSERT_LOCATION) Determines where to insert the next element in the list.
00669        SEI_Head : Insert at head of list (prepend)
00670        SEI_Tail : Insert at tail of list (append)
00671        SEI_Before : Insert before Element
00672        SEI_After : Insert after Element
00673        SEI_In : Inset in Element
00674 \param Element (DListElmt *) Element relative to which the insertion is made. NULL should be used with SEI_Head and SEI_Tail
00675 
00676 \return NewElement (DListElmt *) The new element inserted into the list. 
00677                                     NewElement = Element if SEI_In is used for InsertAt.
00678                                     NULL is returned if the function fails.
00679 
00680 
00681 \sa SUMA_InitializeEngineListData
00682 
00683 -PassByPointer option is only useful when dealing with fields that are/can be dynamically allocated like fm and fi. 
00684 For fields like fv3 or iv15 then assignments are done by value and not pointers.
00685 -You cannot set the value of a field unless the destination for the pre-existing data in that field has been reached                        
00686 -When passing by value for fields requiring allocation, like fm or fi, you must be sure that EngineData->N_cols and 
00687 EngineData->N_rows are set correctly before you call the function.
00688 
00689 -NOTE: If a Command requires that mutliple fields be filled, you can call this function repeatedly with the same 
00690 fields except FldCode, FldValp, SourcePointer and InsertAt should be SEI_In and Element should be the pointer 
00691 returned in the previous call for  SUMA_RegisterEngineListCommand.
00692 
00693 */
00694 DListElmt * SUMA_RegisterEngineListCommand (DList *list, SUMA_EngineData * EngineData,  
00695                                              SUMA_ENGINE_FIELD_CODE Fld, void *FldValp, 
00696                                              SUMA_ENGINE_SOURCE Src, void *Srcp, SUMA_Boolean PassByPointer, 
00697                                              SUMA_ENGINE_INSERT_LOCATION InsertAt, DListElmt *Element)
00698 { 
00699    SUMA_ENGINE_CODE Dest=SES_Empty;
00700    static char FuncName[]={"SUMA_RegisterEngineListCommand"};
00701    SUMA_Boolean LocalHead = NOPE, Refill = NOPE;
00702    DListElmt *tail=NULL, *head=NULL, *NewElement=NULL;
00703    SUMA_EngineData * Old_ED=NULL;
00704    
00705    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
00706    
00707    if (!list) {
00708       fprintf (SUMA_STDERR, "Error %s: list has not been initialized.\n", FuncName);
00709       SUMA_RETURN (NULL);
00710    }
00711    
00712    if (InsertAt == SEI_In) {
00713       /* adding fields to EngineData, check for errors */
00714       Refill = YUP;
00715       /* Src and Srcp should be the same as before */
00716       Old_ED = (SUMA_EngineData *)Element->data;
00717       if (Old_ED != EngineData) {
00718          fprintf (SUMA_STDERR, "Error %s: EngineData is different from initializing call for Element.\n", FuncName);
00719          SUMA_RETURN (NULL);
00720       }
00721       if (Old_ED->Src != Src) {
00722          fprintf (SUMA_STDERR, "Error %s: Src is different from initializing call for Element.\n", FuncName);
00723          SUMA_RETURN (NULL);
00724       }
00725       if (Old_ED->Srcp != Srcp) {
00726          fprintf (SUMA_STDERR, "Error %s: Srcp is different from initializing call for Element.\n", FuncName);
00727          SUMA_RETURN (NULL);
00728       }
00729       if (Old_ED->CommandCode != EngineData->CommandCode) {
00730          fprintf (SUMA_STDERR, "Error %s: CommandCode is different in EngineData from the one initializing call for Element.\n", FuncName);
00731          SUMA_RETURN (NULL);
00732       }
00733       
00734    } else Refill = NOPE;
00735    
00736    Dest = EngineData->CommandCode;
00737    
00738    if (!Refill) {
00739       /* make sure Destination is good and wholesome*/
00740       switch (Dest) {
00741          case SE_BadCode:
00742             fprintf (SUMA_STDERR, "Error in %s: Bad code string.\n", FuncName);
00743             SUMA_RETURN (NULL);
00744             break;
00745          case SE_Empty:
00746             fprintf (SUMA_STDERR, "Error in %s: Empty code string.\n", FuncName);
00747             SUMA_RETURN (NULL);
00748             break;
00749          default:
00750             break;
00751       }
00752 
00753       /* make sure that Srcp is empty or the same as in EngineData */
00754       if (EngineData->Srcp != NULL) {
00755          if (EngineData->Srcp != Srcp) {
00756             fprintf (SUMA_STDERR, "Error %s: Attempting to assign a Srcp to a structure that has a different Srcp.\n", FuncName);
00757             SUMA_RETURN (NULL); 
00758          }
00759       }
00760 
00761       EngineData->Srcp = Srcp;
00762       EngineData->Src = Src;
00763    }
00764    
00765    if (LocalHead) fprintf(SUMA_STDOUT, "%s: Registering %s for %s\n", FuncName, SUMA_EngineFieldString(Fld), SUMA_CommandString (Dest));
00766    
00767    switch (Fld) { /* switch Fld */
00768       case SEF_Empty:
00769          break;
00770       case SEF_fm:
00771          if (EngineData->fm_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
00772             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->fm_Dest);
00773             SUMA_RETURN (NULL);
00774          }
00775          /* space available*/
00776          if (PassByPointer) {
00777             /* pass the pointer */
00778             EngineData->fm = (float **)FldValp;
00779             EngineData->fm_LocalAlloc = NOPE; /* allocation not done by Engine functions */
00780          }
00781          else { /* pass by value */
00782             if (EngineData->fm != NULL) {
00783                fprintf(SUMA_STDERR, "Error %s: Passing by value and EngineData->fm is not NULL. Clean up your act.\n", FuncName);
00784                SUMA_RETURN(NULL);
00785             } 
00786             if (!EngineData->N_rows || !EngineData->N_cols) {
00787                fprintf(SUMA_STDERR, "Error %s: EngineData->N_rows or EngineData->N_cols is 0.\n", FuncName);
00788                SUMA_RETURN(NULL);
00789             }
00790             EngineData->fm = (float **)SUMA_allocate2D(EngineData->N_rows, EngineData->N_cols, sizeof(float));
00791             if (EngineData->fm == NULL) {
00792                fprintf(SUMA_STDERR, "Error %s: Failed to allocate fm.\n", FuncName);
00793                SUMA_RETURN(NULL);
00794             }
00795             EngineData->fm_LocalAlloc = YUP; /* allocation done by Engine functions, this can be freed*/
00796             {/* copy the data */
00797                float **fm; 
00798                int i, j;
00799                fm = (float **)FldValp;
00800                for (i=0; i < EngineData->N_rows; ++i) {
00801                   for (j=0; j < EngineData->N_cols; ++j) 
00802                      EngineData->fm[i][j] = fm[i][j];
00803                }
00804             }/* copy the data */
00805          }/* pass by value */
00806          /* set the new destination*/
00807          EngineData->fm_Dest = Dest;
00808          EngineData->fm_Source = Src;
00809          break;
00810       case SEF_im:
00811          if (EngineData->im_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
00812             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->im_Dest);
00813             SUMA_RETURN (NULL);
00814          }
00815          /* space available*/
00816          if (PassByPointer) {
00817             /* pass the pointer */
00818             EngineData->im = (int **)FldValp;
00819             EngineData->im_LocalAlloc = NOPE; /* allocation not done by Engine functions */
00820          }   else { /* pass by value */
00821             if (EngineData->im != NULL) {
00822                fprintf(SUMA_STDERR, "Error %s: Passing by value and EngineData->im is not NULL. Clean up your act.\n", FuncName);
00823                SUMA_RETURN(NULL);
00824             } 
00825             if (!EngineData->N_rows || !EngineData->N_cols) {
00826                fprintf(SUMA_STDERR, "Error %s: EngineData->N_rows or EngineData->N_cols is 0.\n", FuncName);
00827                SUMA_RETURN(NULL);
00828             }
00829             EngineData->im = (int **)SUMA_allocate2D(EngineData->N_rows, EngineData->N_cols, sizeof(int));
00830             if (EngineData->im == NULL) {
00831                fprintf(SUMA_STDERR, "Error %s: Failed to allocate im.\n", FuncName);
00832                SUMA_RETURN(NULL);
00833             }
00834             EngineData->im_LocalAlloc = YUP; /* allocation done by Engine functions, this can be freed*/
00835             {/* copy the data */
00836                int **im; 
00837                int i, j;
00838                im = (int **)FldValp;
00839                for (i=0; i < EngineData->N_rows; ++i) {
00840                   for (j=0; j < EngineData->N_cols; ++j) 
00841                      EngineData->im[i][j] = im[i][j];
00842                }
00843             }/* copy the data */
00844          }/* pass by value */
00845          /* set the new destination*/
00846          EngineData->im_Dest = Dest;
00847          EngineData->im_Source = Src;
00848          break;
00849 
00850       case SEF_i:
00851          if (EngineData->i_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
00852             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->i_Dest);
00853             SUMA_RETURN (NULL);
00854          }
00855          { /* assign by value */
00856             int *it;
00857             it = (int*)FldValp;
00858             EngineData->i = *it;
00859          }
00860          EngineData->i_Dest = Dest;
00861          EngineData->i_Source = Src;
00862          break;
00863          
00864       case SEF_f:
00865          if (EngineData->f_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
00866             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->f_Dest);
00867             SUMA_RETURN (NULL);
00868          }
00869          { /* assign by value */
00870             float *ft;
00871             ft = (float*)FldValp;
00872             EngineData->f = *ft;
00873          }
00874          EngineData->f_Dest = Dest;
00875          EngineData->f_Source = Src;
00876          break;
00877 
00878       case SEF_fv3:
00879          if (EngineData->fv3_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
00880             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->fv3_Dest);
00881             SUMA_RETURN (NULL);
00882          }
00883          { /* assign by value */
00884             float *fvt;
00885             int kt;
00886             fvt = (float*)FldValp;
00887             for (kt=0; kt < 3; ++kt) EngineData->fv3[kt] = fvt[kt];
00888          }
00889          EngineData->fv3_Dest = Dest;
00890          EngineData->fv3_Source = Src;
00891          break;
00892 
00893       case SEF_fv15:
00894          if (EngineData->fv15_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
00895             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->fv15_Dest);
00896             SUMA_RETURN (NULL);
00897          }
00898          { /* assign by value */
00899             float *fvt;
00900             int kt;
00901             fvt = (float*)FldValp;
00902             for (kt=0; kt < 15; ++kt) EngineData->fv15[kt] = fvt[kt];
00903          }
00904          EngineData->fv15_Dest = Dest;
00905          EngineData->fv15_Source = Src;
00906          break;
00907          
00908       case SEF_iv3:
00909          if (EngineData->iv3_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
00910             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->iv3_Dest);
00911             SUMA_RETURN (NULL);
00912          }
00913          { /* assign by value */
00914             int *ivt;
00915             int kt;
00916             ivt = (int*)FldValp;
00917             for (kt=0; kt < 3; ++kt) EngineData->iv3[kt] = ivt[kt];
00918          }
00919          EngineData->iv3_Dest = Dest;
00920          EngineData->iv3_Source = Src;
00921          break;
00922          
00923       case SEF_iv15:
00924          if (EngineData->iv15_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
00925             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->iv15_Dest);
00926             SUMA_RETURN (NULL);
00927          }
00928          { /* assign by value */
00929             int *ivt;
00930             int kt;
00931             ivt = (int*)FldValp;
00932             for (kt=0; kt < 15; ++kt) EngineData->iv15[kt] = ivt[kt];
00933          }
00934          EngineData->iv15_Dest = Dest;
00935          EngineData->iv15_Source = Src;
00936          break;
00937 
00938       case SEF_s:
00939          if (EngineData->s_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
00940             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->s_Dest);
00941             SUMA_RETURN (NULL);
00942          }
00943          { /* assign by value */
00944             char *st;
00945             st = (char*)FldValp;
00946             if (strlen(st) < SUMA_MAX_STRING_LENGTH) {
00947                sprintf(EngineData->s,"%s", st);
00948             } else {
00949                fprintf(SUMA_STDERR, "Error %s: string in FldValp is longer than SUMA_MAX_STRING_LENGTH.\n", FuncName);
00950                SUMA_RETURN (NULL);
00951             }
00952          }
00953          EngineData->s_Dest = Dest;
00954          EngineData->s_Source = Src;
00955          break;
00956       
00957       case SEF_vp:
00958          if (EngineData->vp_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
00959             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->vp_Dest);
00960             SUMA_RETURN (NULL);
00961          }
00962          EngineData->vp = (void *)FldValp;
00963          EngineData->vp_Dest = Dest;
00964          EngineData->vp_Source = Src;
00965          break;
00966             
00967       case SEF_ip:
00968          if (EngineData->ip_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
00969             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->ip_Dest);
00970             SUMA_RETURN (NULL);
00971          }
00972          EngineData->ip = (int *)FldValp;
00973          EngineData->ip_Dest = Dest;
00974          break;
00975             
00976       case SEF_fp:
00977          if (EngineData->fp_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
00978             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->fp_Dest);
00979             SUMA_RETURN (NULL);
00980          }
00981          EngineData->fp = (float *)FldValp;
00982          EngineData->fp_Dest = Dest;
00983          break;
00984              
00985       case SEF_cp:
00986          if (EngineData->cp_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
00987             fprintf(SUMA_STDERR, "Error %s: field %d has a preset destination (%d).\n", FuncName, Fld, EngineData->cp_Dest);
00988             SUMA_RETURN (NULL);
00989          }
00990          EngineData->cp = (char *)FldValp;
00991          EngineData->cp_Dest = Dest;
00992          break;
00993       
00994       default:
00995          fprintf(SUMA_STDERR, "Error %s: Not setup for field %d yet.\n", FuncName, Fld);
00996          SUMA_RETURN (NULL);
00997          break;
00998    }/* switch Fld */
00999     
01000    /* Now EngineData is filled up, add an element (if not present already) to the list with EngineData */
01001    switch (InsertAt) {
01002       case SEI_In:
01003          if (LocalHead) fprintf (SUMA_STDERR, "%s: Element already in list.\n", FuncName);
01004          NewElement = Element;
01005          break;
01006       case SEI_Tail:
01007          if (LocalHead) fprintf (SUMA_STDERR, "%s: Inserting new element at end of list \n", FuncName); 
01008          if (dlist_ins_next (list, dlist_tail(list), (void *)EngineData) < 0) {
01009             fprintf (SUMA_STDERR, "Error %s: Failed to insert element in list.\n", FuncName);
01010             SUMA_RETURN(NULL);
01011          }
01012          NewElement = dlist_tail(list);
01013          break;
01014       case SEI_Head:
01015          if (LocalHead) fprintf (SUMA_STDERR, "%s: Inserting new element at beginning of list \n", FuncName); 
01016          if (dlist_ins_prev (list, dlist_head(list), (void *)EngineData) < 0) {
01017             fprintf (SUMA_STDERR, "Error %s: Failed to insert element in list.\n", FuncName);
01018             SUMA_RETURN(NULL);
01019          }
01020          NewElement = dlist_head(list);
01021          break;
01022       case SEI_Before:
01023          if (LocalHead) fprintf (SUMA_STDERR, "%s: Inserting new element before specified element.\n", FuncName);
01024          if (!Element) fprintf (SUMA_STDERR, "Error %s: NULL Element!\n", FuncName);
01025          if (dlist_ins_prev (list, Element, (void *)EngineData) < 0) {
01026             fprintf (SUMA_STDERR, "Error %s: Failed to insert element in list.\n", FuncName);
01027             SUMA_RETURN(NULL);
01028          }
01029          NewElement = Element->prev;
01030          if (!NewElement) {
01031             fprintf (SUMA_STDERR, "Error %s: No previous element. List size %d", FuncName, dlist_size(list));
01032             SUMA_RETURN(NULL);
01033          }
01034          break;
01035       case SEI_After:
01036          if (LocalHead) fprintf (SUMA_STDERR, "%s: Inserting new element after specified element.\n", FuncName);
01037          if (!Element) fprintf (SUMA_STDERR, "Error %s: NULL Element!\n", FuncName);
01038          if (dlist_ins_next (list, Element, (void *)EngineData) < 0) {
01039             fprintf (SUMA_STDERR, "Error %s: Failed to insert element in list.\n", FuncName);
01040             SUMA_RETURN(NULL);
01041          }
01042          NewElement = Element->next;
01043          if (!NewElement) {
01044             fprintf (SUMA_STDERR, "Error %s: No next element. List size %d", FuncName, dlist_size(list));
01045             SUMA_RETURN(NULL);
01046          }
01047          break;
01048       case SEI_WTSDS:
01049       case SEI_BadLoc:
01050       default:
01051          fprintf (SUMA_STDERR, "Error %s: Bad insertion location!\n", FuncName);
01052          SUMA_RETURN(NULL);
01053          break;
01054          
01055    }
01056 
01057    SUMA_RETURN (NewElement);   
01058 }
01059 
01060 /*!
01061 SUMA_Boolean SUMA_RegisterEngineData (SUMA_EngineData *ED, char *Fldname, void *FldValp, char *DestName, char *SourceName, SUMA_Boolean PassByPointer)
01062 \param ED (SUMA_EngineData *) pointer to EngineData structure
01063 \param Fldname (char *) Field name
01064 \param FldValp (void *) Pointer to the value that is to be placed in Fldname
01065 \param DestName (char *) Name of EngineCommand that the data in Fldname is destined to
01066 \param PassByPointer (SUMA_Boolean) flag (YUP/NOPE), if YUP then assignment is done at the pointer level (ED->Fld = FldValp)
01067                         if NOPE then space is allocated for Fldname and values are copied from FldValp[i][j] to ED->Fld[i][j]
01068 
01069 \ret YUP/NOPE
01070 
01071 +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.
01072 +You cannot set the value of a field unless the destination for the pre-existing data in that field has been reached                        
01073 +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
01074 set correctly before you call the function.
01075 
01076 \sa SUMA_EngineDataFieldCode
01077 \sa SUMA_ReleaseEngineData
01078 \sa SUMA_InitializeEngineData
01079 \sa SUMA_FreeEngineData
01080 \sa EngineData
01081 \sa SUMA_define.h
01082 
01083 NOTE: OBSOLETE, use SUMA_RegisterEngineListCommand
01084 */
01085 
01086 SUMA_Boolean SUMA_RegisterEngineData (SUMA_EngineData *ED, char *Fldname, void *FldValp, char *DestName, char *SourceName, SUMA_Boolean PassByPointer)
01087 { /* SUMA_RegisterEngineData*/
01088    int Dest, Fld, Src;
01089    static char FuncName[]={"SUMA_RegisterEngineData"};
01090    
01091    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01092 
01093    fprintf (SUMA_STDERR, "Error %s: This function is now obsolete. Must use SUMA_RegisterEngineListCommand instead.\n", FuncName);
01094    SUMA_RETURN (NOPE);
01095    
01096    Dest = SUMA_CommandCode((char *)DestName);
01097    Fld = SUMA_EngineFieldCode((char *)Fldname);
01098    Src = SUMA_EngineSourceCode ((char *)SourceName);
01099    
01100    /* make sure Destination is good and wholesome*/
01101    switch (Dest) {
01102       case SE_BadCode:
01103          fprintf (SUMA_STDERR, "Error in %s: Bad code string.\n", FuncName);
01104          SUMA_RETURN (NOPE);
01105          break;
01106       case SE_Empty:
01107          fprintf (SUMA_STDERR, "Error in %s: Empty code string.\n", FuncName);
01108          SUMA_RETURN (NOPE);
01109          break;
01110       default:
01111          break;
01112    }
01113    
01114    /*fprintf(SUMA_STDOUT, "%s: Registering %s for %s\n", FuncName, Fldname, DestName);*/
01115    
01116    switch (Fld) { /* switch Fld */
01117       case SEF_fm:
01118          if (ED->fm_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
01119             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->fm_Dest);
01120             SUMA_RETURN (NOPE);
01121          }
01122          /* space available*/
01123          if (PassByPointer) {
01124             /* pass the pointer */
01125             ED->fm = (float **)FldValp;
01126             ED->fm_LocalAlloc = NOPE; /* allocation not done by Engine functions */
01127          }
01128          else { /* pass by value */
01129             if (ED->fm != NULL) {
01130                fprintf(SUMA_STDERR, "Error %s: Passing by value and ED->fm is not NULL. Clean up your act.\n", FuncName);
01131                SUMA_RETURN(NOPE);
01132             } 
01133             if (!ED->N_rows || !ED->N_cols) {
01134                fprintf(SUMA_STDERR, "Error %s: ED->N_rows or ED->N_cols is 0.\n", FuncName);
01135                SUMA_RETURN(NOPE);
01136             }
01137             ED->fm = (float **)SUMA_allocate2D(ED->N_rows, ED->N_cols, sizeof(float));
01138             if (ED->fm == NULL) {
01139                fprintf(SUMA_STDERR, "Error %s: Failed to allocate fm.\n", FuncName);
01140                SUMA_RETURN(NOPE);
01141             }
01142             ED->fm_LocalAlloc = YUP; /* allocation done by Engine functions, this can be freed*/
01143             {/* copy the data */
01144                float **fm; 
01145                int i, j;
01146                fm = (float **)FldValp;
01147                for (i=0; i < ED->N_rows; ++i) {
01148                   for (j=0; j < ED->N_cols; ++j) 
01149                      ED->fm[i][j] = fm[i][j];
01150                }
01151             }/* copy the data */
01152          }/* pass by value */
01153          /* set the new destination*/
01154          ED->fm_Dest = Dest;
01155          ED->fm_Source = Src;
01156          SUMA_RETURN (YUP);   
01157          break;
01158       case SEF_im:
01159          if (ED->im_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
01160             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->im_Dest);
01161             SUMA_RETURN (NOPE);
01162          }
01163          /* space available*/
01164          if (PassByPointer) {
01165             /* pass the pointer */
01166             ED->im = (int **)FldValp;
01167             ED->im_LocalAlloc = NOPE; /* allocation not done by Engine functions */
01168          }   else { /* pass by value */
01169             if (ED->im != NULL) {
01170                fprintf(SUMA_STDERR, "Error %s: Passing by value and ED->im is not NULL. Clean up your act.\n", FuncName);
01171                SUMA_RETURN(NOPE);
01172             } 
01173             if (!ED->N_rows || !ED->N_cols) {
01174                fprintf(SUMA_STDERR, "Error %s: ED->N_rows or ED->N_cols is 0.\n", FuncName);
01175                SUMA_RETURN(NOPE);
01176             }
01177             ED->im = (int **)SUMA_allocate2D(ED->N_rows, ED->N_cols, sizeof(int));
01178             if (ED->im == NULL) {
01179                fprintf(SUMA_STDERR, "Error %s: Failed to allocate im.\n", FuncName);
01180                SUMA_RETURN(NOPE);
01181             }
01182             ED->im_LocalAlloc = YUP; /* allocation done by Engine functions, this can be freed*/
01183             {/* copy the data */
01184                int **im; 
01185                int i, j;
01186                im = (int **)FldValp;
01187                for (i=0; i < ED->N_rows; ++i) {
01188                   for (j=0; j < ED->N_cols; ++j) 
01189                      ED->im[i][j] = im[i][j];
01190                }
01191             }/* copy the data */
01192          }/* pass by value */
01193          /* set the new destination*/
01194          ED->im_Dest = Dest;
01195          ED->im_Source = Src;
01196          SUMA_RETURN (YUP);   
01197          break;
01198 
01199       case SEF_i:
01200          if (ED->i_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
01201             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->i_Dest);
01202             SUMA_RETURN (NOPE);
01203          }
01204          { /* assign by value */
01205             int *it;
01206             it = (int*)FldValp;
01207             ED->i = *it;
01208          }
01209          ED->i_Dest = Dest;
01210          ED->i_Source = Src;
01211          SUMA_RETURN (YUP);   
01212          break;
01213          
01214       case SEF_f:
01215          if (ED->f_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
01216             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->f_Dest);
01217             SUMA_RETURN (NOPE);
01218          }
01219          { /* assign by value */
01220             float *ft;
01221             ft = (float*)FldValp;
01222             ED->f = *ft;
01223          }
01224          ED->f_Dest = Dest;
01225          ED->f_Source = Src;
01226          SUMA_RETURN (YUP);   
01227          break;
01228 
01229       case SEF_fv3:
01230          if (ED->fv3_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
01231             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->fv3_Dest);
01232             SUMA_RETURN (NOPE);
01233          }
01234          { /* assign by value */
01235             float *fvt;
01236             int kt;
01237             fvt = (float*)FldValp;
01238             for (kt=0; kt < 3; ++kt) ED->fv3[kt] = fvt[kt];
01239          }
01240          ED->fv3_Dest = Dest;
01241          ED->fv3_Source = Src;
01242          SUMA_RETURN (YUP);   
01243          break;
01244 
01245       case SEF_fv15:
01246          if (ED->fv15_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
01247             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->fv15_Dest);
01248             SUMA_RETURN (NOPE);
01249          }
01250          { /* assign by value */
01251             float *fvt;
01252             int kt;
01253             fvt = (float*)FldValp;
01254             for (kt=0; kt < 15; ++kt) ED->fv15[kt] = fvt[kt];
01255          }
01256          ED->fv15_Dest = Dest;
01257          ED->fv15_Source = Src;
01258          SUMA_RETURN (YUP);   
01259          break;
01260          
01261       case SEF_iv3:
01262          if (ED->iv3_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
01263             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->iv3_Dest);
01264             SUMA_RETURN (NOPE);
01265          }
01266          { /* assign by value */
01267             int *ivt;
01268             int kt;
01269             ivt = (int*)FldValp;
01270             for (kt=0; kt < 3; ++kt) ED->iv3[kt] = ivt[kt];
01271          }
01272          ED->iv3_Dest = Dest;
01273          ED->iv3_Source = Src;
01274          SUMA_RETURN (YUP);   
01275          break;
01276          
01277       case SEF_iv15:
01278          if (ED->iv15_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
01279             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->iv15_Dest);
01280             SUMA_RETURN (NOPE);
01281          }
01282          { /* assign by value */
01283             int *ivt;
01284             int kt;
01285             ivt = (int*)FldValp;
01286             for (kt=0; kt < 15; ++kt) ED->iv15[kt] = ivt[kt];
01287          }
01288          ED->iv15_Dest = Dest;
01289          ED->iv15_Source = Src;
01290          SUMA_RETURN (YUP);   
01291          break;
01292 
01293       case SEF_s:
01294          if (ED->s_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
01295             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->s_Dest);
01296             SUMA_RETURN (NOPE);
01297          }
01298          { /* assign by value */
01299             char *st;
01300             st = (char*)FldValp;
01301             if (strlen(st) < SUMA_MAX_STRING_LENGTH) {
01302                sprintf(ED->s,"%s", st);
01303             } else {
01304                fprintf(SUMA_STDERR, "Error %s: string in FldValp is longer than SUMA_MAX_STRING_LENGTH.\n", FuncName);
01305                SUMA_RETURN (NOPE);
01306             }
01307          }
01308          ED->s_Dest = Dest;
01309          ED->s_Source = Src;
01310          SUMA_RETURN (YUP);   
01311          break;
01312       
01313       case SEF_vp:
01314          if (ED->vp_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
01315             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->vp_Dest);
01316             SUMA_RETURN (NOPE);
01317          }
01318          ED->vp = (void *)FldValp;
01319          ED->vp_Dest = Dest;
01320          ED->vp_Source = Src;
01321          SUMA_RETURN (YUP);   
01322          break;
01323             
01324       case SEF_ip:
01325          if (ED->ip_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
01326             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->ip_Dest);
01327             SUMA_RETURN (NOPE);
01328          }
01329          ED->ip = (int *)FldValp;
01330          ED->ip_Dest = Dest;
01331          SUMA_RETURN (YUP);   
01332          break;
01333       
01334       case SEF_fp:
01335          if (ED->fp_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
01336             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->fp_Dest);
01337             SUMA_RETURN (NOPE);
01338          }
01339          ED->fp = (float *)FldValp;
01340          ED->fp_Dest = Dest;
01341          SUMA_RETURN (YUP);   
01342          break;
01343       
01344       case SEF_cp:
01345          if (ED->cp_Dest != SEF_Empty) { /* Make sure the data in this field in not predestined */
01346             fprintf(SUMA_STDERR, "Error %s: field %s has a preset destination (%d).\n", FuncName, Fldname, ED->cp_Dest);
01347             SUMA_RETURN (NOPE);
01348          }
01349          ED->cp = (char *)FldValp;
01350          ED->cp_Dest = Dest;
01351          SUMA_RETURN (YUP);   
01352          break;
01353       
01354       default:
01355          fprintf(SUMA_STDERR, "Error %s: Not setup for field %s yet.\n", FuncName, Fldname);
01356          SUMA_RETURN (NOPE);
01357          break;
01358    }/* switch Fld */
01359     
01360 
01361 }/* SUMA_RegisterEngineData*/
01362 
01363 /*!
01364    \brief allocate and initialize the data structure for EngineData
01365    SUMA_EngineData *SUMA_InitializeEngineListData (SUMA_ENGINE_CODE CommandCode);
01366    \param CommandCode (SUMA_ENGINE_CODE) command code to store in Engine data structure
01367    \return ED (SUMA_EngineData *) Pointer to empty engine data structure with the field ED->CommandCode set to CommandCode
01368       NULL if function failed.
01369      
01370 */
01371 SUMA_EngineData *SUMA_InitializeEngineListData (SUMA_ENGINE_CODE CommandCode)
01372 {
01373    static char FuncName[]={"SUMA_InitializeEngineListData"};
01374    SUMA_EngineData *ED=NULL;
01375    int i;
01376    
01377    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01378 
01379    if (CommandCode <= SE_Empty || CommandCode >= SE_BadCode) {
01380       fprintf(SUMA_STDERR,"Error %s: Bad command code.\n", FuncName);
01381       SUMA_RETURN (NULL); 
01382    }
01383    
01384    ED = SUMA_malloc(sizeof(SUMA_EngineData));
01385    if (!ED) {
01386       fprintf(SUMA_STDERR,"Error %s: Failed to allocate for ED.\n", FuncName);
01387       SUMA_RETURN (NULL);   
01388    }
01389    
01390    ED->CommandCode = CommandCode;
01391    ED->Srcp = NULL;
01392    ED->fm = NULL;
01393    ED->fm_LocalAlloc = NOPE;
01394    ED->im = NULL;
01395    ED->im_LocalAlloc = NOPE;
01396    ED->N_rows = 0;
01397    ED->N_cols = 0;
01398    ED->i = 0;
01399    ED->f = 0.0;
01400    ED->iv3[0] = ED->iv3[1] = ED->iv3[2] = 0;
01401    ED->fv3[0] = ED->fv3[1] = ED->fv3[2] = 0.0;
01402    for (i=0; i < 15; ++i) {
01403       ED->fv15[i] = 0.0;
01404       ED->iv15[i] = 0.0;
01405    }
01406    sprintf(ED->s,"NOTHING");
01407    
01408    ED->vp = NULL;
01409    
01410    ED->fm_Dest = ED->im_Dest = ED->i_Dest = ED->f_Dest = ED->iv3_Dest = ED->fv3_Dest = \
01411    ED->fv15_Dest = ED->iv15_Dest = ED->s_Dest = ED->vp_Dest = ED->ip_Dest = ED->fp_Dest = \
01412    ED->cp_Dest = SE_Empty;
01413    
01414    ED->fm_Source = ED->im_Source = ED->i_Source = ED->f_Source = ED->iv3_Source = ED->fv3_Source = \
01415    ED->fv15_Source = ED->iv15_Source = ED->s_Source = ED->vp_Source = SES_Empty;
01416    
01417    SUMA_RETURN (ED);
01418 
01419 }
01420 
01421 /*!
01422 SUMA_Boolean SUMA_InitializeEngineData (SUMA_EngineData *ED)
01423 \param ED (SUMA_EngineData *) pointer to allocated structure
01424    structure fields fm and im are set to NULL, s to "" 
01425    i, v, fv3, iv3, fv15 and iv15 are initialized to 0 or 0.0
01426    _Dest are all set to SE_Empty
01427    N_rows and N_cols = 0
01428 
01429 -- Discovered allocation bug here Jan 23 03.
01430 OBSOLETE, use SUMA_InitializeEngineListData 
01431 
01432 */
01433 SUMA_Boolean SUMA_InitializeEngineData (SUMA_EngineData *ED)
01434 {   int i;
01435    static char FuncName[]={"SUMA_InitializeEngineData"};
01436    
01437    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01438 
01439    fprintf (SUMA_STDERR, "Error %s: This function is now obsolete. Must use SUMA_InitializeEngineListData instead.\n", FuncName);
01440    SUMA_RETURN (NOPE);
01441 
01442    if (ED == NULL) {
01443       fprintf(SUMA_STDERR,"Error %s: Must pre-allocate for ED.\n", FuncName);
01444       SUMA_RETURN (NOPE);   
01445    }
01446    
01447    ED->fm = NULL;
01448    ED->im = NULL;
01449    ED->N_rows = 0;
01450    ED->N_cols = 0;
01451    ED->i = 0;
01452    ED->f = 0.0;
01453    ED->iv3[0] = ED->iv3[1] = ED->iv3[2] = 0;
01454    ED->fv3[0] = ED->fv3[1] = ED->fv3[2] = 0.0;
01455    for (i=0; i < 15; ++i) {
01456       ED->fv15[i] = 0.0;
01457       ED->iv15[i] = 0.0;
01458    }
01459    sprintf(ED->s,"NOTHING");
01460    
01461    ED->vp = NULL;
01462    
01463    ED->fm_Dest = ED->im_Dest = ED->i_Dest = ED->f_Dest = ED->iv3_Dest = ED->fv3_Dest = \
01464    ED->fv15_Dest = ED->iv15_Dest = ED->s_Dest = ED->vp_Dest = ED->ip_Dest = ED->fp_Dest = \
01465    ED->cp_Dest = SE_Empty;
01466    
01467    ED->fm_Source = ED->im_Source = ED->i_Source = ED->f_Source = ED->iv3_Source = ED->fv3_Source = \
01468    ED->fv15_Source = ED->iv15_Source = ED->s_Source = ED->vp_Source = SES_Empty;
01469 
01470    SUMA_RETURN (YUP);
01471 }
01472 
01473 /*!
01474    Free an action stack data structure 
01475    -frees AS_data->ActionData by calling destructor function 
01476    -frees AS_data
01477 */
01478 void SUMA_FreeActionStackData(void *asdata)
01479 {
01480    static char FuncName[]={"SUMA_FreeActionStackData"};
01481    SUMA_ACTION_STACK_DATA *AS_data=NULL;
01482    SUMA_Boolean LocalHead = NOPE;
01483    
01484    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01485 
01486    AS_data=(SUMA_ACTION_STACK_DATA *)asdata;
01487    if (AS_data) {
01488       if (LocalHead) fprintf (SUMA_STDERR, "%s: Destroying Action Stack Data \n", FuncName);
01489       /* first you want to free the Action Data */
01490       AS_data->ActionDataDestructor(AS_data->ActionData);
01491       
01492       /* Now you can free the Action Stucture Data */
01493       SUMA_free(AS_data);
01494    }
01495    
01496    SUMA_RETURNe;
01497 }
01498 
01499 /*!
01500    Releases an action stack data structure 
01501    -frees AS_data->ActionData WITHOUT calling destructor function 
01502    -frees AS_data
01503 */
01504 void SUMA_ReleaseActionStackData (void *asdata)
01505 {
01506    static char FuncName[]={"SUMA_ReleaseActionStackData"};
01507    SUMA_ACTION_STACK_DATA *AS_data=NULL;
01508    SUMA_Boolean LocalHead = NOPE;
01509    
01510    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01511 
01512    AS_data=(SUMA_ACTION_STACK_DATA *)asdata;
01513    if (AS_data) {
01514       if (LocalHead) fprintf (SUMA_STDERR, "%s: Releasing Action Stack Data structure\n", FuncName);
01515       /* first you want to free the Action Data */
01516       if (AS_data->ActionData) SUMA_free(AS_data->ActionData);
01517 
01518       /* Now you can free the Action Stucture Data */
01519       SUMA_free(AS_data);
01520    }
01521    
01522    SUMA_RETURNe;
01523 }
01524 /*!
01525    \brief free a message structure and any allocated space in its fields
01526    
01527    \param Hv (void *) pointer to Message structure. 
01528             It is type cast to void* to suit the standard list manipulation routines.
01529 */
01530 void SUMA_FreeMessageListData(void *Hv)
01531 {
01532    static char FuncName[]={"SUMA_FreeMessageListData"};
01533    SUMA_MessageData *H = NULL;
01534    
01535    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01536    
01537    H = (SUMA_MessageData *)Hv;
01538    
01539    if (!H) {
01540       fprintf(SUMA_STDERR,"Warning %s: H is null, nothing to do!\n", FuncName);
01541       SUMA_RETURNe;
01542    }
01543    
01544    if (H->Message) SUMA_free(H->Message);
01545    if (H->Source) SUMA_free(H->Source);
01546    if (H) SUMA_free(H);
01547    
01548    SUMA_RETURNe;
01549 }
01550 
01551 /*!
01552    \brief free an engine data structure and any allocated space in its fields
01553    SUMA_FreeEngineListData (EDv);
01554    
01555    \param EDv (void *) pointer to EngineData structure. 
01556             It is type cast to void* to suit the standard list manipulation routines.
01557 
01558 if space for im or fm has been dynamically allocated in SUMA_RegisterEngineListCommand()
01559 it is released. 
01560 
01561 */
01562 void SUMA_FreeEngineListData(void *EDv)
01563 {
01564    static char FuncName[]={"SUMA_FreeEngineListData"};
01565    SUMA_EngineData *ED = NULL;
01566    
01567    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01568 
01569    ED = (SUMA_EngineData *)EDv;
01570    
01571    if (ED == NULL) {
01572       fprintf(SUMA_STDERR,"Warning %s: ED is null, nothing to do!\n", FuncName);
01573       SUMA_RETURNe;
01574    }
01575    
01576    /* check on Dynamic Memory Allocations needs */
01577    if (ED->fm_LocalAlloc) {
01578       if (!ED->N_rows || !ED->N_cols) {
01579          fprintf(SUMA_STDERR,"Error %s: N_rows or N_cols are 0.\n\a", FuncName);
01580          SUMA_RETURNe;
01581       }
01582       if (ED->fm == NULL) {
01583          fprintf(SUMA_STDERR,"Error %s: ED->fm is NULL, not good here.\n\a", FuncName);
01584          SUMA_RETURNe;
01585       }
01586       /* OK, free ED->fm */
01587       SUMA_free2D((char **)ED->fm, ED->N_rows);
01588    } 
01589    
01590    if (ED->im_LocalAlloc) {
01591       if (!ED->N_rows || !ED->N_cols) {
01592          fprintf(SUMA_STDERR,"Error %s: N_rows or N_cols are 0.\n\a", FuncName);
01593          SUMA_RETURNe;
01594       }
01595       if (ED->im == NULL) {
01596          fprintf(SUMA_STDERR,"Error %s: ED->im is NULL, not good here.\n\a", FuncName);
01597          SUMA_RETURNe;
01598       }
01599       /* OK, free ED->im */
01600       SUMA_free2D((char **)ED->im, ED->N_rows);
01601    } 
01602    
01603    /* good deal, flush ED */
01604    SUMA_free(ED);
01605    SUMA_RETURNe;
01606 }
01607    
01608 /*!
01609 SUMA_Boolean SUMA_FreeEngineData (SUMA_EngineData *ED)
01610 
01611 free memory allocated for ED in SUMA_InitializeEngineData
01612 
01613 \param ED (SUMA_EngineData *) pointer to SUMA_EngineData
01614 
01615 \ret YUP/NOPE
01616 
01617 if space for im or fm has been dynamically allocated in SUMA_RegisterEngineData
01618 it is released. ED itself is not freed
01619 
01620 OBSOLETE: Use SUMA_FreeEngineListData
01621    
01622 */
01623 SUMA_Boolean SUMA_FreeEngineData (SUMA_EngineData *ED)
01624 {
01625    static char FuncName[]={"SUMA_FreeEngineData"};
01626    
01627    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01628 
01629    fprintf (SUMA_STDERR, "Error %s: This function is now obsolete. Must use SUMA_FreeEngineListData instead.\n", FuncName);
01630    SUMA_RETURN (NOPE);
01631 
01632    if (ED == NULL) {
01633       fprintf(SUMA_STDERR,"Error %s: ED is null, nothing to do!\n", FuncName);
01634       SUMA_RETURN (NOPE);
01635    }
01636    
01637    /* check on Dynamic Memory Allocations needs */
01638    if (ED->fm_LocalAlloc) {
01639       if (!ED->N_rows || !ED->N_cols) {
01640          fprintf(SUMA_STDERR,"Error %s: N_rows or N_cols are 0.\n", FuncName);
01641          SUMA_RETURN (NOPE);
01642       }
01643       if (ED->fm == NULL) {
01644          fprintf(SUMA_STDERR,"Error %s: ED->fm is NULL, not good here.\n", FuncName);
01645          SUMA_RETURN (NOPE);
01646       }
01647       /* OK, free ED->fm */
01648       SUMA_free2D((char **)ED->fm, ED->N_rows);
01649    } 
01650    
01651    if (ED->im_LocalAlloc) {
01652       if (!ED->N_rows || !ED->N_cols) {
01653          fprintf(SUMA_STDERR,"Error %s: N_rows or N_cols are 0.\n", FuncName);
01654          SUMA_RETURN (NOPE);
01655       }
01656       if (ED->im == NULL) {
01657          fprintf(SUMA_STDERR,"Error %s: ED->im is NULL, not good here.\n", FuncName);
01658          SUMA_RETURN (NOPE);
01659       }
01660       /* OK, free ED->im */
01661       SUMA_free2D((char **)ED->im, ED->N_rows);
01662    } 
01663    
01664    /* good deal, DO NOT flush ED in case it was not dynamically allocated*/
01665    SUMA_RETURN (YUP);
01666 }
01667 
01668 /*!
01669    \brief removes an element from the list, frees the data structure associated with the removed element
01670    ans = SUMA_ReleaseEngineListElement (list, element) 
01671    \param list (DList *)
01672    \param element (DListElmt *)
01673    \return (YUP/NOPE), success, failure
01674    
01675    - The list is not destroyed if no elements remain in it, 
01676    you should check for that after this function returns.
01677 */
01678 SUMA_Boolean SUMA_ReleaseEngineListElement (DList *list, DListElmt *element) 
01679 {
01680    static char FuncName[]={"SUMA_ReleaseEngineListElement"};
01681    void *ED=NULL;
01682    
01683    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01684    
01685    if (dlist_remove (list, element, &ED) < 0) {
01686       fprintf (SUMA_STDERR, "Error %s: Failed to remove element from list.\n", FuncName);
01687       SUMA_RETURN (NOPE);
01688    }
01689    if (ED) { /* had an if (!ED) here..... */
01690       SUMA_FreeEngineListData((SUMA_EngineData *)ED);
01691    }
01692    
01693    SUMA_RETURN (YUP);
01694 }
01695 
01696 /*!
01697    \brief removes an element from the list, frees the data structure associated with the removed element
01698    ans = SUMA_ReleaseMessageListElement (list, element) 
01699    \param list (DList *)
01700    \param element (DListElmt *)
01701    \return (YUP/NOPE), success, failure
01702    
01703    - The list is not destroyed if no elements remain in it, 
01704    you should check for that after this function returns.
01705 */
01706 SUMA_Boolean SUMA_ReleaseMessageListElement (DList *list, DListElmt *element) 
01707 {
01708    static char FuncName[]={"SUMA_ReleaseMessageListElement"};
01709    void *H=NULL;
01710    
01711    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01712    
01713    if (dlist_remove (list, element, &H) < 0) {
01714       fprintf (SUMA_STDERR, "Error %s: Failed to remove element from list.\n", FuncName);
01715       SUMA_RETURN (NOPE);
01716    }
01717    if (H) {/* had an if (!H) here..... */
01718       SUMA_FreeMessageListData((SUMA_MessageData *)H);
01719    }
01720    
01721    SUMA_RETURN (YUP);
01722 }
01723 
01724 
01725 /*!
01726    \brief destroys a list IF IT IS EMPTY !
01727    list = SUMA_DestroyList (list);
01728    
01729    \param list (DList *)
01730    \return ans (DList *) NULL if function succeeds, list if function fails
01731    
01732    \sa SUMA_EmptyDestroyList
01733 */
01734 DList * SUMA_DestroyList (DList *list) 
01735 {
01736    static char FuncName[]={"SUMA_DestroyList"};
01737    
01738    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01739    
01740    if (list->size) {
01741       fprintf (SUMA_STDERR, "Error %s: list still contains elements.\n", FuncName);
01742       SUMA_RETURN (list);
01743    }
01744    
01745    dlist_destroy(list);
01746    SUMA_RETURN (NULL);   
01747 } 
01748 
01749 /*!
01750    \brief destroys a list even if it is not empty
01751    list = SUMA_DestroyList (list);
01752    
01753    \param list (DList *)
01754    \return ans (DList *) NULL always
01755    \sa SUMA_DestroyList
01756 */
01757 DList * SUMA_EmptyDestroyList (DList *list) 
01758 {
01759    static char FuncName[]={"SUMA_EmptyDestroyList"};
01760    
01761    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01762    
01763    dlist_destroy(list);
01764    SUMA_RETURN (NULL);   
01765 } 
01766 
01767 /*!
01768    \brief creates a list for the Action Stack
01769    list = SUMA_CreateActionStack ();
01770    \return list (DList *) pointer to doubly linked list
01771             NULL if function fails
01772             
01773 */
01774 DList *SUMA_CreateActionStack (void)
01775 {
01776    static char FuncName[]={"SUMA_CreateActionStack"};
01777    DList *list=NULL;
01778    
01779    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01780 
01781    list = (DList *)malloc (sizeof(DList));
01782    if (!list) {
01783       fprintf (SUMA_STDERR, "Error %s: Failed to allocate for list.\n", FuncName);
01784       SUMA_RETURN(NULL);
01785    }
01786    
01787    /* 
01788       Do not use: dlist_init(list, SUMA_FreeActionStackData);
01789       You do not want to destroy data stored inside the ActionStack because
01790       the data is used elsewhere. Destruction of ActionStackData should
01791       only be done when a stack element is above the new Do element and will
01792       therefore never be used again. */
01793    
01794    dlist_init(list, SUMA_ReleaseActionStackData);
01795    
01796    SUMA_RETURN (list);
01797 }
01798 
01799 /*!
01800    \brief destroys the Action Stack
01801    ans = SUMA_DestroyActionStack (DList *AS);
01802    
01803    \returns NULL 
01804             
01805 */
01806 DList *SUMA_EmptyDestroyActionStack (DList *AS)
01807 {
01808    static char FuncName[]={"SUMA_DestroyActionStack"};
01809 
01810    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01811 
01812    dlist_destroy(AS);
01813    
01814    SUMA_RETURN (NULL);
01815 }
01816 
01817 /*!
01818    \brief creates a list for the message list
01819    list = SUMA_CreateMessageList ();
01820    \return list (DList *) pointer to doubly linked list
01821             NULL if function fails
01822             
01823             DO not use common field variables here.
01824 */
01825 DList *SUMA_CreateMessageList (void)
01826 {
01827    static char FuncName[]={"SUMA_CreateMessageList"};
01828    DList *list=NULL;
01829    
01830    
01831    list = (DList *)malloc (sizeof(DList));
01832    if (!list) {
01833       fprintf (SUMA_STDERR, "Error %s: Failed to allocate for list.\n", FuncName);
01834       return (NULL);
01835    }
01836    
01837    dlist_init(list, SUMA_FreeMessageListData);
01838    
01839    return (list);
01840 }
01841 
01842 /*!
01843    \brief creates a list for SUMA_Engine
01844    list = SUMA_CreateList ();
01845    \return list (DList *) pointer to doubly linked list
01846             NULL if function fails
01847 */
01848 DList *SUMA_CreateList (void)
01849 {
01850    static char FuncName[]={"SUMA_CreateList"};
01851    DList *list=NULL;
01852    
01853    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01854    
01855    list = (DList *)SUMA_malloc (sizeof(DList));
01856    if (!list) {
01857       fprintf (SUMA_STDERR, "Error %s: Failed to allocate for list.\n", FuncName);
01858       SUMA_RETURN (NULL);
01859    }
01860    
01861    dlist_init(list, SUMA_FreeEngineListData);
01862    
01863    SUMA_RETURN (list);
01864 }
01865 
01866 /*!
01867 SUMA_Boolean SUMA_ReleaseEngineData (SUMA_EngineData *ED, char *Location)
01868 
01869 This function releases data fields that were destined to Location
01870 
01871 \param ED (SUMA_EngineData *) pointer to Engine data structure
01872 \param Location (char *) location in SUMA_Engine, from which the function was called (one of the commands in SUMA_Engine)
01873 
01874 \ret YUP/NOPE
01875 
01876 Memory is freed for fm and im only if their assignment in SUMA_RegisterEngineData was done by value 
01877 
01878 \sa SUMA_EngineDataFieldCode
01879 \sa SUMA_ReleaseEngineData
01880 \sa SUMA_InitializeEngineData
01881 \sa SUMA_FreeEngineData
01882 \sa EngineData
01883 \sa SUMA_define.h
01884 \sa SUMA_RegisterEngineData
01885 
01886 OBSOLETE: Use SUMA_ReleaseEngineListElement
01887 */
01888 SUMA_Boolean SUMA_ReleaseEngineData (SUMA_EngineData *ED, char *Location)
01889 {/* SUMA_ReleaseEngineData*/
01890    static char FuncName[]={"SUMA_ReleaseEngineData"};
01891    int Loc;
01892 
01893    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
01894 
01895    fprintf (SUMA_STDERR, "Error %s: This function is now obsolete. Must use SUMA_ReleaseEngineListElement instead.\n", FuncName);
01896    SUMA_RETURN (NOPE);
01897 
01898    /* search through all fields and clear (or release) all those who should be */
01899    Loc = SUMA_CommandCode((char *)Location);
01900    
01901    /* make sure Destination is good and wholesome*/
01902    switch (Loc) {
01903       case SE_BadCode:
01904          fprintf (SUMA_STDERR, "Error in %s: Bad code string.\n", FuncName);
01905          SUMA_RETURN (NOPE);
01906          break;
01907       case SE_Empty:
01908          fprintf (SUMA_STDERR, "Error in %s: Empty code string.\n", FuncName);
01909          SUMA_RETURN (NOPE);
01910          break;
01911       default:
01912          break;
01913    }
01914 
01915    /*fprintf(SUMA_STDOUT,"%s : Releasing location %s\n", FuncName, Location);*/
01916    /* go through all the fields*/
01917    /* fm */
01918    if (ED->fm_Dest == Loc) {
01919       /* needs to be released */
01920       if (ED->fm_LocalAlloc) { /* locally allocated */
01921          /* must be freed */
01922          if (!ED->N_rows || !ED->N_cols) {
01923             fprintf (SUMA_STDERR, "Error in %s: ED->N_rows or ED->N_cols is 0 .\n", FuncName);
01924             SUMA_RETURN (NOPE);
01925          }
01926          if (ED->fm == NULL) {
01927             fprintf (SUMA_STDERR, "Error in %s: fm is null already. This should not be .\n", FuncName);
01928             SUMA_RETURN (NOPE);
01929          }
01930          SUMA_free2D((char **)ED->fm, ED->N_rows);
01931          ED->N_rows = ED->N_cols = 0; 
01932          ED->fm = NULL;
01933          ED->fm_Dest = SE_Empty;
01934          ED->fm_Source = SES_Empty;
01935       } /* locally allocated */ else { /* passed by pointer */
01936          ED->fm = NULL; 
01937          ED->N_rows = ED->N_cols = 0; 
01938          ED->fm_Dest = SE_Empty;
01939          ED->fm_Source = SES_Empty;
01940       }/* passed by pointer */
01941    }
01942    
01943    /*im*/
01944    if (ED->im_Dest == Loc) {
01945       /* needs to be released */
01946       if (ED->im_LocalAlloc) { /* locally allocated */
01947          /* must be freed */
01948          if (!ED->N_rows || !ED->N_cols) {
01949             fprintf (SUMA_STDERR, "Error in %s: ED->N_rows or ED->N_cols is 0 .\n", FuncName);
01950             SUMA_RETURN (NOPE);
01951          }
01952          if (ED->im == NULL) {
01953             fprintf (SUMA_STDERR, "Error in %s: im is null already. This should not be .\n", FuncName);
01954             SUMA_RETURN (NOPE);
01955          }
01956          SUMA_free2D((char **)ED->im, ED->N_rows);
01957          ED->N_rows = ED->N_cols = 0; 
01958          ED->im = NULL;
01959          ED->im_Dest = SE_Empty;
01960          ED->im_Source = SES_Empty;
01961       } /* locally allocated */ else { /* passed by pointer */
01962          ED->im = NULL; 
01963          ED->N_rows = ED->N_cols = 0; 
01964          ED->im_Dest = SE_Empty;
01965          ED->im_Source = SES_Empty;
01966       }/* passed by pointer */
01967    }
01968 
01969    /* i */
01970    if (ED->i_Dest == Loc) {
01971       ED->i_Dest = SE_Empty;
01972       ED->i_Source = SES_Empty;
01973    }
01974 
01975    /* iv3 */
01976    if (ED->iv3_Dest == Loc) {
01977       ED->iv3_Dest = SE_Empty;
01978       ED->iv3_Source = SES_Empty;
01979    }
01980    
01981    /* iv15 */
01982    if (ED->iv15_Dest == Loc) {
01983       ED->iv15_Dest = SE_Empty;
01984       ED->iv15_Source = SES_Empty;
01985    }
01986    
01987    /* f */
01988    if (ED->f_Dest == Loc) {
01989       ED->f_Dest = SE_Empty;
01990       ED->f_Source = SES_Empty;
01991    }
01992 
01993    /* fv3 */
01994    if (ED->fv3_Dest == Loc) {
01995       ED->fv3_Dest = SE_Empty;
01996       ED->fv3_Source = SES_Empty;
01997    }
01998    
01999    /* fv15 */
02000    if (ED->fv15_Dest == Loc) {
02001       ED->fv15_Dest = SE_Empty;
02002       ED->fv15_Source = SES_Empty;
02003    }
02004    
02005    /*s*/
02006    if (ED->s_Dest == Loc) {
02007       ED->s_Dest = SE_Empty;
02008       ED->s_Source = SES_Empty;
02009    }
02010 
02011    /* vp */
02012    if (ED->vp_Dest == Loc) {
02013       ED->vp_Dest = SE_Empty;
02014       ED->vp_Source = SES_Empty;
02015    }
02016    
02017    /* cp */
02018    if (ED->cp_Dest == Loc) {
02019       ED->cp_Dest = SE_Empty;
02020    }
02021    
02022    /* ip */
02023    if (ED->ip_Dest == Loc) {
02024       ED->ip_Dest = SE_Empty;
02025    }
02026    
02027    /* fp */
02028    if (ED->fp_Dest == Loc) {
02029       ED->fp_Dest = SE_Empty;
02030    }
02031    /* SUMA_RETURN, tout va bien */
02032    SUMA_RETURN (YUP);
02033 }
02034 
02035 /*!
02036    \brief Writes the commands to be executed in list 
02037           SUMA_ShowList (list, Out);
02038    \param list (DList *) Pointer to list
02039    \param Out (FILE *) pointer to output stream, if NULL then Out is stdout
02040    \return (void)
02041    
02042 */
02043 void SUMA_ShowList (DList *list, FILE *Out)
02044 {
02045    static char FuncName[]={"SUMA_ShowList"};
02046    DListElmt *NE;
02047    SUMA_EngineData *ED;
02048    
02049    if (SUMAg_CF->InOut_Notify) SUMA_DBG_IN_NOTIFY(FuncName);
02050 
02051    if (!Out) Out = stdout;
02052    
02053    if (!list) {
02054       fprintf (Out,"%s: NULL List.\n", FuncName);
02055       SUMA_RETURNe;
02056    }
02057    
02058    if (!list->size) {
02059       fprintf (Out,"%s: Empty List.\n", FuncName);
02060       SUMA_RETURNe;
02061    }
02062    
02063    fprintf (Out,"%s: List of %d elements.\n\t", FuncName, list->size);
02064    do{
02065       NE = dlist_head(list);
02066       ED = (SUMA_EngineData *) NE->data;
02067       if (!ED) {
02068          fprintf (Out, "NULL-This should not be | ");
02069       } else {
02070          fprintf (Out, "%s | ", SUMA_CommandString (ED->CommandCode));
02071       }
02072    } while (!dlist_is_tail(NE));
02073    
02074    fprintf (Out,"\n");
02075    
02076    SUMA_RETURNe;
02077 }
02078 
02079 #ifdef STAND_ALONE
02080 void usage ()
02081    
02082   {/*Usage*/
02083           printf ("\n\33[1mUsage: \33[0m SUMA_GetNextCommand ..... \n");
02084           printf ("\t ..... \n\n");
02085           printf ("\t To Compile:\ngcc -DSTAND_ALONE -Wall -o $1 $1.c -I/usr/X11R6/include -I./\n");
02086           printf ("\t\t Ziad S. Saad SSCC/NIMH/NIH ziad@nih.gov \tTue Feb 5 10:39:02 EST 2002 \n");
02087           exit (0);
02088   }/*Usage*/
02089    
02090 int main (int argc,char *argv[])
02091 {/* Main */
02092    char FuncName[100]; 
02093    char Scom[500], S[500], term, d;
02094 
02095    /* initialize Main function name for verbose output */
02096    sprintf (FuncName,"SUMA_GetNextCommand-Main-");
02097    
02098    term = '~';
02099    d = '|';
02100    
02101    if (argc < 2)
02102        {
02103           usage ();
02104           exit (1);
02105        }
02106    
02107    /* copy argc into string */
02108    sprintf (S,"%s", argv[1]);
02109    fprintf(stderr,"INITIAL: %s, \n", S);
02110 
02111    if(!SUMA_RegisterCommand (S,  d, term, "Newly Registered Append", NOPE)) {
02112       fprintf (stderr, "%s Error: Failed to register new command\n", FuncName);
02113    }
02114    if(!SUMA_RegisterCommand (S,  d, term, "Newly Registered Prepend", YUP)) {
02115       fprintf (stderr, "%s Error: Failed to register new command\n", FuncName);
02116    }
02117 
02118    /*repeat until nothing left */
02119    fprintf(stderr,"%s\n", S);
02120    while (SUMA_GetNextCommand (S, d, term, Scom) != SE_Empty)  {
02121        fprintf (stdout, "Command->%s<-\n", Scom);   
02122        fprintf(stderr,"%s\n", S);
02123    }
02124 return(0);
02125 }/* Main */
02126 #endif

Generated on Tue May 27 18:23:17 2003 for SUMA Source Code by doxygen1.2.12-20011209 written by Dimitri van Heesch, © 1997-2001