Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

phArgTable.cpp

Go to the documentation of this file.
00001 /* ---------------------------------------------------------------------------
00002     Phission : 
00003         Realtime Vision Processing System
00004     
00005     Copyright (C) 2003-2006 Philip D.S. Thoren (pthoren@cs.uml.edu)
00006     University of Massachusetts at Lowell,
00007     Laboratory for Artificial Intelligence and Robotics
00008     
00009     This file is part of Phission.
00010 
00011     Phission is free software; you can redistribute it and/or modify
00012     it under the terms of the GNU Lesser General Public License as published by
00013     the Free Software Foundation; either version 2 of the License, or
00014     (at your option) any later version.
00015 
00016     Phission is distributed in the hope that it will be useful,
00017     but WITHOUT ANY WARRANTY; without even the implied warranty of
00018     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019     GNU Lesser General Public License for more details.
00020 
00021     You should have received a copy of the GNU Lesser General Public License
00022     along with Phission; if not, write to the Free Software
00023     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00024 
00025  ---------------------------------------------------------------------------*/
00026 /* ----------------------------------------------------------------------- */
00027 /* argtable.c - this code is used for easily constructing a command line   *
00028  * interface for command line driven programs.                             *
00029  *                                                                         */
00030 /* ----------------------------------------------------------------------- */
00031 /* Coded by Philip D.S. Thoren (pthoren@cs.uml.edu)                        */
00032 /* ----------------------------------------------------------------------- */
00033 #ifdef HAVE_CONFIG_H
00034     #include <phissionconfig.h>
00035 #endif
00036 
00037 #include <phStandard.h>
00038 #include <phObject.h>
00039 #include <phArgTable.h>
00040 
00041 #ifdef HAVE_LIMITS_H
00042     #include <limits.h>
00043 #endif
00044 
00045 #include <phError.h>
00046 #include <phMemory.h>
00047 #include <phPrint.h>
00048 
00049 /*--------------------------------------------------------------------------*/
00056 typedef struct arg_node_t 
00057 {
00058     char               *flag;   
00060     uint32_t            length; 
00061     void               *pointer;
00064     int                 type;
00065     struct arg_node_t  *next;
00066 } arg_node_struct;
00067 
00068 /*--------------------------------------------------------------------------*/
00073 struct argument_table_t{
00074     arg_node_struct    *list;
00075     int                 total_arguments;
00076 };
00077 
00078 /*---------------------------------------------------------------------------*/
00079 static int ph_copy_string( char *orig, char **copy);
00080 
00081 static int ph_parse_arguments( int                      argc, 
00082                                char                    **argv, 
00083                                struct argument_table_t  *table);
00084 
00085 static int ph_add_argument( const char              *flag, 
00086                             void                    *pointer, 
00087                             int                     type, 
00088                             struct argument_table_t *table );
00089 
00090 static int ph_free_argument_table( struct argument_table_t **table );
00091 
00092 static int ph_new_argument_table( struct argument_table_t **table );
00093 
00094 
00095 /*---------------------------------------------------------------------------*/
00100 int ph_copy_string( char *orig, char **copy) 
00101 {
00102     phFUNCTION("ph_copy_string")
00103     int length = 0;
00104     
00105     /* Make sure the parameters are valid */
00106     phCHECK_NULLPTR(orig,NULL,"Invalid function parameter: char *orig");
00107     phCHECK_NULLPTR(copy,NULL,"Invalid function parameter: char **copy");
00108     
00109     length = strlen(orig);
00110 
00111     /* Allocate memory for the copied string */
00112     (*copy) = (char *)phCalloc(length + 1, sizeof(char));
00113             
00114     /* Check the allocation */
00115     phCHECK_NULLPTR((*copy),"phCalloc","allocation of address string failed");
00116 
00117     /* Copy the string */
00118     phMemcpy((*copy),orig,length);
00119     
00120     (*copy)[length] = '\0';
00121 
00122     return phSUCCESS;
00123 
00124 error:
00125     return phFAIL;
00126 }
00127 /*---------------------------------------------------------------------------*/
00144 int ph_parse_arguments( int                     argc, 
00145                         char                    **argv, 
00146                         struct argument_table_t *table) 
00147 {
00148     phFUNCTION("ph_parse_arguments")
00149     
00150     int             i       =   1;
00151     arg_node_struct *node   =   NULL;
00152 
00153     phCHECK_NULLPTR(table,NULL,"Invalid function parameter: table");
00154 
00155     /* Go through all the arguments passed to the program*/
00156     while ( i < argc ) 
00157     {
00158         /* Initialize the node pointer to the start of the list */
00159         node = table->list;
00160 
00161         /* Go through all the arguments available */
00162         while (node != NULL) 
00163         {
00164             /* Check for a match */
00165             //if (strncmp(argv[i],node->flag,strlen(node->flag)) == 0) {
00166             DEBUG_PRINT("Checking - %s against %s\n",argv[i],node->flag);
00167             
00168             if (strncmp(argv[i],node->flag,node->length) == 0) 
00169             {
00170                 /* Since the existance of the flag/switch... */
00171                 if (node->type == phARG_BOOL) {
00172                     DEBUG_PRINT( "Parsed phARG_BOOL - %s\n",argv[i]);
00173 
00174                     /* ... tells that the user wants something on */
00175                     /* then turn it on, and leave the next arg alone */
00176                     /* The fact the switch is around means it's on */
00177                     /* it's a BOOL: no flag == 0. flag == 1 */
00178                     (*((int*)(node->pointer))) = 1;
00179                     node = NULL;
00180                     continue;
00181                 }
00182                 else if (node->type == phARG_FUNC) 
00183                 {
00184                     /* convert the argument to a long number and set it */
00185                     ph_argtable_funcptr func = (ph_argtable_funcptr)(node->pointer);
00186                     (func)();
00187                 }
00188                 
00189                 /* Check to make sure there are enough arguments */
00190                 if (argc <= (i+1)) 
00191                 {
00192                     printf("\n%s - needs more arguments.\n",node->flag);
00193                     printf("Not enough arguments passed to program.\n");
00194                     return phFAIL;
00195                 }
00196                 
00197                 /* Check the type of the argument for what to do with it */
00198                 switch (node->type)
00199                 {
00200                     /* ----------------------------------------------------- */
00201                     case phARG_CHAR:
00202                     {
00203                     DEBUG_PRINT( "Parsed phARG_CHAR - %s\n",argv[i]);
00204 
00205                     /* Copy the string */
00206                     if (ph_copy_string(argv[++i],(char **)node->pointer) == phFAIL)
00207                         return phFAIL;
00208                     }
00209                     break;
00210                     
00211                     /* ----------------------------------------------------- */
00212                     case phARG_INT:
00213                     {
00214                     DEBUG_PRINT( "Parsed phARG_INT - %s\n",argv[i]);
00215 
00216                     /* convert the argument to a number and set it */
00217                     (*((int*)(node->pointer))) = atoi(argv[++i]);
00218                     }
00219                     break;
00220                     
00221                     /* ----------------------------------------------------- */
00222                     case phARG_UINT:
00223                     { 
00224                     DEBUG_PRINT( "Parsed phARG_UINT - %s\n",argv[i]);
00225 
00226                     long long tempnum = atoll(argv[++i]);
00227                     if ((tempnum < 0) || (tempnum > UINT_MAX))
00228                     {
00229                         phCHECK_RC(-1,NULL,
00230                                 "Argument out of bounds: %lld != [%d..%d]\n",
00231                                 tempnum,0,UINT_MAX);
00232                     }
00233                     /* convert the argument to an unsigned integer and set it */
00234                     (*((unsigned int*)(node->pointer))) = (unsigned int)tempnum;
00235                     }
00236                     break;
00237 
00238                     /* ----------------------------------------------------- */
00239                     case phARG_LONG:
00240                     {
00241                     DEBUG_PRINT( "Parsed phARG_LONG - %s\n",argv[i]);
00242 
00243                     /* convert the argument to a long number and set it */
00244                     (*((long*)(node->pointer))) = atol(argv[++i]);
00245                     }
00246                     break;
00247                     
00248                     /* ----------------------------------------------------- */
00249                     case phARG_ULONG:
00250                     {
00251                     DEBUG_PRINT( "Parsed phARG_ULONG - %s\n",argv[i] );
00252 
00253                     /* convert the argument to a long number and set it */
00254                     (*((unsigned long*)(node->pointer))) = (unsigned long)atol(argv[++i]);
00255                     }
00256                     break;
00257     
00258                     /* ----------------------------------------------------- */
00259                     case phARG_INT32:
00260                     {
00261                     DEBUG_PRINT( "Parsed phARG_INT32 - %s\n",argv[i]);
00262 
00263                     long long tempnum = atoll(argv[++i]);
00264                     if ((tempnum < INT_MIN) || (tempnum > INT_MAX))
00265                     {
00266                         phCHECK_RC(-1,NULL,
00267                                 "Argument out of bounds: %lld != [%d..%d]\n",
00268                                  tempnum,INT_MIN,INT_MAX);
00269                     }
00270                     /* convert the argument to a number and set it */
00271                     (*((int32_t*)(node->pointer))) = (int32_t)tempnum;
00272                     }
00273                     break;
00274                     
00275                     /* ----------------------------------------------------- */
00276                     case phARG_UINT32:
00277                     { 
00278                     DEBUG_PRINT( "Parsed phARG_UINT32 - %s\n",argv[i]);
00279 
00280                     long long tempnum = atoll(argv[++i]);
00281                     if ((tempnum < 0) || (tempnum > UINT_MAX))
00282                     {
00283                         phCHECK_RC(-1,NULL,
00284                                 "Argument out of bounds: %lld != [%d..%d]\n",
00285                                  tempnum, 0,UINT_MAX );
00286                     }
00287                     
00288                     /* convert the argument to an unsigned integer and set it */
00289                     (*((uint32_t*)(node->pointer))) = (uint32_t)tempnum;
00290                     }
00291                     break;
00292 
00293                     /* ----------------------------------------------------- */
00294                     case phARG_INT16:
00295                     {
00296                     DEBUG_PRINT( "Parsed phARG_INT16 - %s\n",argv[i]);
00297 
00298                     long long tempnum = atoll(argv[++i]);
00299                     if ((tempnum < 0) || (tempnum > UINT_MAX))
00300                     {
00301                         phCHECK_RC(-1,NULL,
00302                                 "Argument out of bounds: %lld != [%d..%d]\n",
00303                                  tempnum, 0,UINT_MAX);
00304                     }
00305                     /* convert the argument to a number and set it */
00306                     (*((int16_t*)(node->pointer))) = (int16_t)tempnum;
00307                     }
00308                     break;
00309                     
00310                     /* ----------------------------------------------------- */
00311                     case phARG_UINT16:
00312                     { 
00313                     DEBUG_PRINT( "Parsed phARG_UINT16 - %s\n",argv[i]);
00314 
00315                     long long tempnum = atoll(argv[++i]);
00316                     if ((tempnum < 0) || (tempnum > USHRT_MAX))
00317                     {
00318                         phCHECK_RC(-1,NULL,
00319                                 "Argument out of bounds: %lld != [%d..%d]\n",
00320                                  tempnum,0,USHRT_MAX);
00321                     }
00322                     
00323                     /* convert the argument to an unsigned integer and set it */
00324                     (*((uint16_t*)(node->pointer))) = (uint16_t)tempnum;
00325                     }
00326                     break;
00327 
00328                     /* ----------------------------------------------------- */
00329                     case phARG_INT8:
00330                     {
00331                     DEBUG_PRINT( "Parsed phARG_INT8 - %s\n",argv[i]);
00332                     long long tempnum = atol(argv[++i]);
00333 
00334                     if ((tempnum < SCHAR_MIN) || (tempnum > SCHAR_MAX))
00335                     {
00336                         phCHECK_RC(-1,NULL,
00337                                 "Argument out of bounds: %lld != [%d..%d].\n",
00338                                 tempnum,SCHAR_MIN,SCHAR_MAX);
00339                     }
00340                     /* convert the argument to a number and set it */
00341                     (*((int8_t*)(node->pointer))) = (int8_t)tempnum;
00342                     }
00343                     break;
00344                     
00345                     /* ----------------------------------------------------- */
00346                     case phARG_UINT8:
00347                     { 
00348                     DEBUG_PRINT( "Parsed phARG_UINT8 - %s\n",argv[i]);
00349 
00350                     long long tempnum = atoll(argv[++i]);
00351                     if ((tempnum < 0) || (tempnum > CHAR_MAX))
00352                     {
00353                         phCHECK_RC(-1,NULL,
00354                                 "Argument out of bounds: %lld != [%d..%d].\n",
00355                                  tempnum,0,CHAR_MAX);
00356                     }
00357                     
00358                     /* convert the argument to an unsigned integer and set it */
00359                     (*((uint8_t*)(node->pointer))) = (uint8_t)tempnum;
00360                     }
00361                     break;
00362 
00363                     /* ----------------------------------------------------- */
00364                     case phARG_FLOAT:
00365                     { 
00366                     DEBUG_PRINT( "Parsed phARG_FLOAT - %s\n",argv[i]);
00367 
00368                     float tempnum = (float)atof(argv[++i]);
00369                     /* convert the argument to an unsigned integer and set it */
00370                     (*((float*)(node->pointer))) = (float)tempnum;
00371                     }
00372                     break;
00373 
00374                     /* ----------------------------------------------------- */
00375                     case phARG_DOUBLE:
00376                     { 
00377                     DEBUG_PRINT( "Parsed phARG_DOUBLE - %s\n",argv[i]);
00378 
00379                     double tempnum = atof(argv[++i]);
00380                     /* convert the argument to an unsigned integer and set it */
00381                     (*((double*)(node->pointer))) = (double)tempnum;
00382                     }
00383                     break;
00384 
00385                     /* ----------------------------------------------------- */
00386                     default:
00387                         /* Don't fail here
00388                         phCHECK_RC(-1,NULL,
00389                            "default in switch reached. Invalid argument");                    
00390                         */
00391                     break;
00392                 }
00393                 
00394                 node = NULL;
00395             }
00396             else {
00397                 /* Get the next node */
00398                 node = node->next;
00399             }
00400         }
00401         i++;
00402     }
00403 
00404     return phSUCCESS;
00405 
00406 error:
00407     return phFAIL;
00408 }
00409 
00410 /*---------------------------------------------------------------------------*/
00415 int ph_add_argument( const char                *flag, 
00416                      void                      *pointer, 
00417                      int                        type, 
00418                      struct argument_table_t   *table ) 
00419 {
00420     phFUNCTION("ph_add_argument")
00421     
00422     arg_node_struct *newNode = NULL;
00423    
00424     /* Check the arguments for validity */
00425     phCHECK_NULLPTR(flag,NULL,"Invalid function parameter: flag");
00426     phCHECK_NULLPTR(pointer,NULL,"Invalid function parameter: pointer");
00427 
00428     /* This is the list of valid argument types supported */
00429     if ((type < phARG_MIN) || (type > phARG_MAX))
00430     {
00431         phCHECK_RC(-1,NULL, "Invalid type: %d",type );
00432     }
00433     phCHECK_NULLPTR(table,NULL,"table == NULL" );
00434    
00435     /* Allocate space and copy over the argument switch string */
00436     newNode = (arg_node_struct *)phCalloc(1,sizeof(arg_node_struct));
00437  
00438     /* Get the length of the flag string */
00439     newNode->length = strlen(flag);
00440     /* allocate space for the flag string */
00441     newNode->flag = (char *)phCalloc(newNode->length + 1, sizeof(char));
00442     /* Check the allocation */
00443     phCHECK_NULLPTR(newNode->flag,"phCalloc",
00444             "Couldn't allocate memory for arg node flag." );
00445     
00446     /* copy the flag into the struct field */
00447     sprintf(newNode->flag,"%s",flag);
00448 
00449     /* set pointer to argument that string/int will be copied to */
00450     newNode->pointer = pointer;
00451     newNode->type = type;
00452     
00453     /* keep track of the rest of the list...*/
00454     newNode->next = table->list;
00455 
00456     /* ...Update the table */
00457     table->list = newNode;
00458     table->total_arguments++;
00459     
00460     return phSUCCESS;
00461 
00462 error:
00463         
00464     phFree(newNode);
00465 
00466     return phFAIL;
00467 }
00468 /*---------------------------------------------------------------------------*/
00472 int ph_free_argument_table( struct argument_table_t **table ) 
00473 {
00474     phFUNCTION("ph_free_argument_table")
00475     
00476     arg_node_struct *node = NULL;
00477     arg_node_struct *temp = NULL;
00478 
00479     /* Check the table parameter passed to the function */
00480     phCHECK_NULLPTR(table,NULL,"Invalid function parameter: table");
00481     phCHECK_NULLPTR((*table),NULL,"Invalid function parameter: *table");
00482 
00483     /* Initialize the node pointer */
00484     node = (*table)->list;
00485     
00486     /* While there are nodes in the list, free them */
00487     while( node != NULL ) 
00488     {
00489         /* Hold a place for the current node */
00490         temp = node;
00491         
00492         /* get the next node for the next loop around */
00493         node = node->next;
00494         
00495         /* free the flag, which was allocated in 
00496          * the ph_add_argument function */
00497         phFree(temp->flag);
00498         phFree(temp);
00499     }
00500 
00501     /* Re-initialize the table */
00502     (*table)->list = NULL;
00503     (*table)->total_arguments = 0;
00504 
00505     phFree(*table);
00506     
00507     return phSUCCESS;
00508 
00509 error:
00510     return phFAIL;
00511 }
00512 
00513 /*---------------------------------------------------------------------------*/
00514 int ph_new_argument_table( struct argument_table_t **table ) 
00515 {
00516     phFUNCTION("ph_new_argument_table")
00517 
00518     phCHECK_NULLPTR(table,NULL,"Invalid function parameter: table");
00519 
00520     /* Allocate the table */
00521     (*table) = (struct argument_table_t *)
00522             phCalloc(1,sizeof(struct argument_table_t));
00523     phCHECK_NULLPTR((*table),"phCalloc","Couldn't allocate arg_table.");
00524     
00525     /* initialize the table's parameter fields */
00526     (*table)->list = NULL;
00527     (*table)->total_arguments = 0;
00528     
00529     return phSUCCESS;
00530 
00531 error:
00532     return phFAIL;
00533 }
00534 
00535 /*---------------------------------------------------------------------------*/
00536 phArgTable::phArgTable()
00537 {
00538     phFUNCTION("phArgTable::phArgTable")
00539 
00540     this->m_table = NULL;
00541 
00542     this->setName("phArgTable");
00543 
00544     /*static int ph_new_argument_table( struct argument_table_t **table );*/
00545     rc = ph_new_argument_table(&this->m_table);
00546     phPRINT_RC(rc,NULL,"ph_new_argument_table");
00547 }
00548 
00549 /*---------------------------------------------------------------------------*/
00550 phArgTable::~phArgTable()
00551 {
00552     phFUNCTION("phArgTable::~phArgTable")
00553 
00554     /* static int ph_free_argument_table( struct argument_table_t **table );*/
00555 
00556     rc = ph_free_argument_table(&this->m_table);
00557     phPRINT_RC(rc,NULL,"ph_free_argument_table");
00558 }
00559 
00560 /*---------------------------------------------------------------------------*/
00561 int phArgTable::parse( int argc, char *argv[] )
00562 {
00563     phFUNCTION("phArgTable::parse")
00564     
00565     /* static int ph_parse_arguments( int argc, 
00566      *                                char **argv, 
00567      *                                struct argument_table_t *table); 
00568      */
00569     rc = ph_parse_arguments( argc, argv, this->m_table);
00570     phCHECK_RC(rc,NULL,"ph_parse_arguments");
00571 
00572     return phSUCCESS;
00573 
00574 error:
00575     return phFAIL;
00576 }
00577 
00578 /*---------------------------------------------------------------------------*/
00579 int phArgTable::add( const char *flag,
00580                      void *pointer,
00581                      int type )
00582 {
00583     phFUNCTION("phArgTable::add")
00584 
00585     /* static int ph_add_argument(  const char *flag, 
00586      *                              void *pointer, 
00587      *                              int type, 
00588      *                              struct argument_table_t *table );
00589      */
00590     rc = ph_add_argument( flag, pointer, type, this->m_table);
00591     phCHECK_RC(rc,NULL,"ph_add_argument");
00592     
00593     return phSUCCESS;
00594 
00595 error:
00596     return phFAIL;
00597 }
00598 
00599 
00600 
00601 
00602 




Copyright (C) 2002 - 2007 Philip D.S. Thoren ( pthoren@users.sourceforge.net )
University Of Massachusetts at Lowell
Robotics Lab
SourceForge.net Logo

Generated on Sat Jun 16 02:44:02 2007 for phission by  doxygen 1.4.4