Annotation of gpl/axl/knife/exarg.c, revision 1.1.1.2

1.1.1.2 ! misho       1: /** 
1.1       misho       2:  *  LibExploreArguments: a library to parse command line options
                      3:  *  Copyright (C) 2005 Advanced Software Production Line, S.L.
                      4:  * 
                      5:  *  This program is free software; you can redistribute it and/or
                      6:  *  modify it under the terms of the GNU Lesser General Public License
                      7:  *  as published by the Free Software Foundation; either version 2.1 of
                      8:  *  the License, or (at your option) any later version.
                      9:  *
                     10:  *  This program is distributed in the hope that it will be useful,
                     11:  *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
                     12:  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  
                     13:  *  GNU Lesser General Public License for more details.
                     14:  *
                     15:  *  You should have received a copy of the GNU Lesser General Public
                     16:  *  License along with this program; if not, write to the Free
                     17:  *  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
                     18:  *  02111-1307 USA
                     19:  *  
                     20:  *  You may find a copy of the license under this software is released
                     21:  *  at COPYING file. This is LGPL software: you are wellcome to
                     22:  *  develop propietary applications using this library withtout any
                     23:  *  royalty or fee but returning back any change, improvement or
                     24:  *  addition in the form of source code, project image, documentation
                     25:  *  patches, etc. 
                     26:  *
                     27:  *  Contact us at:
                     28:  *          
                     29:  *      Postal address:
                     30:  *         Advanced Software Production Line, S.L.
                     31:  *         C/ Dr. Michavila NÂș 14
                     32:  *         Coslada 28820 Madrid
                     33:  *         Spain
                     34:  *
                     35:  *      Email address:
                     36:  *         info@aspl.es - http://fact.aspl.es
                     37:  *
                     38:  */
                     39: #include <exarg.h>
                     40: 
                     41: #if defined(__GNUC__)
                     42: #  ifndef _GNU_SOURCE
                     43: #  define _GNU_SOURCE
                     44: #  endif
                     45: #endif
                     46: 
                     47: /* local includes */
                     48: #include <stdio.h>
                     49: #include <string.h>
                     50: #include <stdarg.h>
                     51: #include <stdlib.h>
                     52: 
                     53: #define LOG_DOMAIN "exarg"
                     54: 
                     55: typedef struct _ExArgNodeOption ExArgNodeOption;
                     56: 
                     57: /** 
                     58:  * @internal Definition for the void *.
                     59:  */
                     60: typedef void * epointer;
                     61: 
                     62: /** 
                     63:  * @brief First argument option supported (this is the head of the
                     64:  * list of arguments supported).
                     65:  */
                     66: ExArgNodeOption * argument_options          = NULL;
                     67: ExArgument      * params                    = NULL;
                     68: const char      * exarg_exec_name           = NULL;
                     69: char            * __exarg_usage_header      = NULL;
                     70: char            * __exarg_help_header       = NULL;
                     71: char            * __exarg_post_usage_header = NULL;
                     72: char            * __exarg_post_help_header  = NULL;
                     73: int               __exarg_disable_free_args = 0;
                     74: 
                     75: typedef enum { 
                     76:        /** 
                     77:         * @internal Parse mode not defined.
                     78:         */
                     79:        PARSE_MODE_NOT_DEF,
                     80:        /** 
                     81:         * @internal Parse mode unix defined.
                     82:         */
                     83:        PARSE_MODE_UNIX,
                     84:        /** 
                     85:         * @internal Parse module windows defined.
                     86:         */
                     87:        PARSE_MODE_WINDOWS
                     88: } ExArgParseMode;
                     89: 
                     90: /** 
                     91:  * @internal This allows to know the parse mode used by exarg. Parse
                     92:  * mode allows to differenciate arguments that are file path under
                     93:  * unix by options under windows. This option is automatic, being the
                     94:  * first option parse to configure the parse mode. This means that the
                     95:  * user can't mix options provided using the windows and unix mode at
                     96:  * the same time.
                     97:  */
                     98: ExArgParseMode   parse_mode = PARSE_MODE_NOT_DEF;
                     99: 
                    100: /** 
                    101:  * @internal Function used by the exarg library to drop a message.
                    102:  * 
                    103:  * @param format The message to print using a printf format.
                    104:  */
                    105: void exarg_msg (char * format, ...)
                    106: {
                    107:        va_list args;
                    108: 
                    109:        /* print the message */
                    110:        va_start (args, format);
                    111:        vprintf (format, args);
                    112:        va_end (args);
                    113: 
                    114:        /* flush */
                    115:        fflush (stdout);
                    116: 
                    117:        /* exit from the library */
                    118:        exit (-1);
                    119: 
                    120:        return;
                    121: }
                    122: 
                    123: /** 
                    124:  * @brief Allows to check current parse mode, return ok if the parse
                    125:  * mode isn't defined or the current parse mode is the one provided.
                    126:  * 
                    127:  * @param mode The parse mode to check.
                    128:  * 
                    129:  * @return 1 if the parse mode is ok or 0 if current parse mode is
                    130:  * incompatible.
                    131:  */
                    132: #define CHECK_PARSE_MODE(mode) ((parse_mode == PARSE_MODE_NOT_DEF) || (parse_mode == mode))
                    133: 
                    134: /** 
                    135:  * @brief Allows to update current parse mode.
                    136:  * 
                    137:  * @param mode The parse mode to configure.
                    138:  * 
                    139:  */
                    140: #define UPDATE_PARSE_MODE(mode)\
                    141: if (parse_mode == PARSE_MODE_NOT_DEF)\
                    142:    parse_mode = mode;
                    143: 
                    144: /**
                    145:  * \mainpage LibExArg (Explore Arguments Library)  Manual
                    146:  * \section Introduction
                    147:  *
                    148:  *  LibExArg library is a small, easy to use with a consistent API
                    149:  *  which allows you to parse command line argument for your program.
                    150:  *
                    151:  *  It doesn't require any external dependency for its function, it
                    152:  *  really portable and at this point is running on <b>GNU/Linux</b>
                    153:  *  platforms and <b>Microsoft Windows</b> platforms.
                    154:  *
                    155:  *  For details on how to starting to use LibExarg, you can find the
                    156:  *  \ref exarg "module documentation for LibExArg here". You can find
                    157:  *  \ref exarg_example "here an example about using LibExArg".
                    158:  *
                    159:  * \section licence Library License
                    160:  *
                    161:  *  The library is released under the terms of the GNU LGPL (The GNU
                    162:  *  Lesser General Public License) licence. You can get a copy of the
                    163:  *  license http://www.gnu.org/licenses/licenses.html#LGPL.
                    164:  *
                    165:  *  This license allows you to write applications using LibExArg which
                    166:  *  are using some GPL compatible license or commercial applications.
                    167:  *
                    168:  */
                    169: 
                    170: /**
                    171:  * \page exarg_example A simple example on using LibExarg
                    172:  *
                    173:  * \section Introduction
                    174:  *
                    175:  *  You may find interesting the following example which makes use of
                    176:  *  LibExArg. This example install 3 arguments to be accepted as valid
                    177:  *  command line options and the write down to the terminal the result
                    178:  *  of those command used by the user.
                    179:  * 
                    180:  *  Once the arguments are installed, the user can execute 
                    181:  *
                    182:  *
                    183:  *  \include "test-exarg.c"
                    184:  * 
                    185:  */
                    186: 
                    187: /** \defgroup exarg ExArg module: functions to parse command line argument in your program
                    188:  *
                    189:  */
                    190: 
                    191: /** 
                    192:  * @brief Argument dependency (a list of nodes that each argument has
                    193:  * to define for its dependencies and its mutual exclusions).
                    194:  */
                    195: typedef struct _ExArgDependency ExArgDependency;
                    196: 
                    197: struct _ExArgDependency {
                    198:        ExArgNodeOption * node;
                    199:        ExArgDependency  * next;
                    200: };
                    201: 
                    202: 
                    203: /**
                    204:  * \addtogroup exarg
                    205:  * @{ 
                    206:  */
                    207: 
                    208: struct _ExArgNodeOption {
                    209:        /** 
                    210:         * @brief Holds the argument name (long value recognized by
                    211:         * --long-option and /long-option).
                    212:         */
                    213:        const char      * arg_name;
                    214:        /** 
                    215:         * @brief Holds the optional short argument option.
                    216:         */
                    217:        const char      * arg_short_name;
                    218:        /** 
                    219:         * @brief Argument type.
                    220:         */
                    221:        ExArgType         type;
                    222:        /** 
                    223:         * @brief Argument description.
                    224:         */
                    225:        const char      * description;
                    226:        /** 
                    227:         * @brief If the argument is \ref EXARG_STRING, this holds the
                    228:         * string value associated if defined.
                    229:         */
                    230:        char            * string_value;
                    231:        /** 
                    232:         * @brief If the argument is \ref EXARG_INT, this holds the
                    233:         * int value associated if defined.
                    234:         */
                    235:        int               int_value;
                    236:        /** 
                    237:         * @brief Boolean value that allows to know if the argument
                    238:         * option was defined
                    239:         */
                    240:        int               is_defined;
                    241: 
                    242:        /** 
                    243:         * @brief Allows to configure if the provided argument is
                    244:         * optional.
                    245:         */
                    246:        int               is_optional;
                    247: 
                    248:        /** 
                    249:         * @brief Pointer to the next argument option stored.
                    250:         */
                    251:        ExArgNodeOption * next;
                    252: 
                    253:        /* a reference to the first dependecy argument */
                    254:        ExArgDependency * depends;
                    255: 
                    256:        ExArgDependency * excludes;
                    257: };
                    258: 
                    259: struct _ExArgument {
                    260:        /** 
                    261:         * @brief The string value that is encapsulated by the
                    262:         * argument.
                    263:         */
                    264:        char       * string;
                    265: 
                    266:        /** 
                    267:         * @brief A reference to the next argument in the list.
                    268:         */
                    269:        ExArgument * next;
                    270: };
                    271: 
                    272: 
                    273: /** 
                    274:  * @internal Definition to allocate memory.
                    275:  * 
                    276:  * @param type The type to allocate
                    277:  * @param count The amount of memory to allocate.
                    278:  * 
                    279:  * @return Returns a newly allocated memory.
                    280:  */
                    281: #define exarg_new(type, count) (type *) calloc (count, sizeof (type))
                    282: 
                    283: /** 
                    284:  * @internal Definition to dealloc an object.
                    285:  * 
                    286:  * @param ref The reference to dealloc.
                    287:  */
                    288: void exarg_free (epointer ref)
                    289: {
                    290:        if (ref == NULL)
                    291:                return;
                    292:        free (ref);
                    293:        
                    294:        return;
                    295: }
                    296: 
                    297: /** 
                    298:  * @internal Allows to get the basename for the file path provided.
                    299:  * 
                    300:  * @param file_path The file path that is requested to return the
                    301:  * basename value.
                    302:  * 
                    303:  * @return A reference to the basename (the return must not be
                    304:  * dealloc).
                    305:  */
                    306: const char * exarg_basename (char * file_path) 
                    307: {
                    308:        int iterator = strlen (file_path);
                    309: 
                    310:        while ((iterator != 0) && 
                    311:               (file_path [iterator - 1]  != '/') && 
                    312:               (file_path [iterator - 1]  != '\\')) {
                    313:                /* decrease iterator */
                    314:                iterator--;
                    315:        }
                    316: 
                    317:        /* return the base name */
                    318:        return file_path + iterator;
                    319: }
                    320: 
                    321: /** 
                    322:  * @internal Allows to split the provided string using the provided
                    323:  * separators.
                    324:  * 
                    325:  * @param chunk The chunk to split.
                    326:  * @param separator_num The number of separators.
                    327:  * 
                    328:  * @return A newly allocated set of strings.
                    329:  */
                    330: char     ** exarg_split           (const char * chunk, int separator_num, ...)
                    331: {
                    332:        va_list      args;
                    333:        char      ** separators;
                    334:        char      ** result;
                    335:        int          iterator;
                    336:        int          index;
                    337:        int          previous_index;
                    338:        int          count      = 0;
                    339:        int          length     = 0;
                    340: 
                    341:        /* check received values */
                    342:        if (chunk == NULL)
                    343:                return NULL;
                    344:        if (separator_num < 1)
                    345:                return NULL;
                    346: 
                    347:        separators = exarg_new (char *, separator_num + 1);
                    348:        iterator   = 0;
                    349:        va_start (args, separator_num);
                    350: 
                    351:        /* get all separators to be used */
                    352:        while (iterator < separator_num) {
                    353:                separators[iterator] = va_arg (args, char *);
                    354:                iterator++;
                    355:        }
                    356:        
                    357:        va_end (args);
                    358: 
                    359:        /* now, count the number of strings that we will get by
                    360:         * separating the string into several pieces */
                    361:        index    = 0;
                    362:        while (*(chunk + index) != 0) {
                    363: 
                    364:                /* reset the iterator */
                    365:                iterator = 0;
                    366:                while (iterator < separator_num) { 
                    367: 
                    368:                        /* compare the current index with the current
                    369:                         * separator */
                    370:                        length = strlen (separators[iterator]);
                    371:                        if (! memcmp (chunk + index, separators[iterator], length)) {
                    372: 
                    373:                                /* update items found */
                    374:                                count++;
                    375: 
                    376:                                /* update index to skip the item found */
                    377:                                index += length - 1; /* make the last index to be captured the the -1 */
                    378: 
                    379:                                /* break the loop */
                    380:                                break;
                    381:                        }
                    382:                        iterator++;
                    383:                }
                    384: 
                    385:                /* update the index to the next item */
                    386:                index++;
                    387:        }
                    388:        
                    389:        /* create the result that will hold items separated */
                    390:        result = exarg_new (char *, count + 2);
                    391: 
                    392:        /* now copy items found */
                    393:        count          = 0;
                    394:        index          = 0;
                    395: 
                    396:        /* remember previous_index */
                    397:        previous_index = index;
                    398:        while (*(chunk + index) != 0) {
                    399: 
                    400:                /* reset the iterator */
                    401:                iterator = 0;
                    402:                while (iterator < separator_num) { 
                    403: 
                    404:                        /* compare the current index with the current
                    405:                         * separator */
                    406:                        length = strlen (separators[iterator]);
                    407:                        if (! memcmp (chunk + index, separators[iterator], length)) {
                    408: 
                    409:                                /* copy the chunk found */
                    410:                                result[count] = exarg_new (char, index - previous_index + 1);
                    411:                                memcpy (result[count], chunk + previous_index, index - previous_index);
                    412: 
                    413:                                /* update items found */
                    414:                                count++;
                    415: 
                    416:                                /* update index to skip the item found */
                    417:                                if (*(chunk + index + length) == 0) {
                    418:                                        /* in the case no more elements to read will be found */
                    419:                                        /* put an empty space at the end */
                    420:                                        result [count]    = exarg_new (char, 1);
                    421:                                        
                    422:                                        exarg_free (separators);
                    423:                                        return result;
                    424:                                }
                    425: 
                    426:                                /* remember previous_index */
                    427:                                index += length; 
                    428:                                previous_index = index;
                    429:                                index--; /* make the last index to be captured the the -1 */
                    430:                                break;
                    431:                        }
                    432:                        iterator++;
                    433:                }
                    434: 
                    435:                /* update the index to the next item */
                    436:                index++;
                    437:        }
                    438: 
                    439:        /* check for a last chunk */
                    440:        if (index != previous_index) {
                    441:                /* copy the chunk found */
                    442:                result[count] = exarg_new (char, index - previous_index + 1);
                    443:                memcpy (result[count], chunk + previous_index, index - previous_index);
                    444:        }
                    445: 
                    446:        
                    447:        /* release memory */
                    448:        exarg_free (separators);
                    449:        
                    450:        return result;
                    451: }
                    452: 
                    453: /** 
                    454:  * @internal Allows to calculate the amount of memory required to
                    455:  * store the string that will representing the construction provided
                    456:  * by the printf-like format received and its arguments.
                    457:  * 
                    458:  * @param format The printf-like format to be printed.
                    459:  *
                    460:  * @param args The set of arguments that the printf applies to.
                    461:  *
                    462:  * <i><b>NOTE:</b> not all printf specification is supported. Generally, the
                    463:  * following is supported: %s, %d, %f, %g, %ld, %lg and all
                    464:  * combinations that provides precision, number of items inside the
                    465:  * integer part, etc: %6.2f, %+2d, etc. An especial case not supported
                    466:  * is %lld, %llu and %llg.</i>
                    467:  *
                    468:  * @return Return the number of bytes that must be allocated to hold
                    469:  * the string (including the string terminator \0). If the format is
                    470:  * not correct or it is not properly formated according to the value
                    471:  * found at the argument set, the function will return -1.
                    472:  */
                    473: int exarg_vprintf_len (const char * format, va_list args)
                    474: {
                    475:        /** IMPLEMENTATION NOTE: in the case this code is update,
                    476:         * update axl_stream_vprintf_len **/
                    477: 
                    478: # if defined (OS_WIN32) && ! defined (__GNUC__)
                    479: #   if HAVE_VSCPRINTF
                    480:        if (format == NULL)
                    481:                return 0;
                    482:        return _vscprintf (format, args) + 1;
                    483: #   else
                    484:        char buffer[8192];
                    485:        if (format == NULL)
                    486:                return 0;
                    487:        return _vsnprintf (buffer, 8191, format, args) + 1;
                    488: #   endif
                    489: #else
                    490:        /* gnu gcc case */
                    491:        if (format == NULL)
                    492:                return 0;
                    493:        return vsnprintf (NULL, 0, format, args) + 1;
                    494: 
                    495: #endif
                    496: }
                    497: 
                    498: 
                    499: 
                    500: /** 
                    501:  * @internal Allows to produce an string representing the message hold by
                    502:  * chunk with the parameters provided.
                    503:  * 
                    504:  * @param chunk The message chunk to print.
                    505:  * @param args The arguments for the chunk.
                    506:  * 
                    507:  * @return A newly allocated string.
                    508:  */
                    509: char  * exarg_strdup_printfv    (char * chunk, va_list args)
                    510: {
1.1.1.2 ! misho     511:        /** IMPLEMENTATION NOTE: place update axl_stream_strdup_printfv
1.1       misho     512:         * code in the case this code is updated **/
                    513: 
                    514: #ifndef HAVE_VASPRINTF
                    515:        int       size;
                    516: #endif
                    517:        char    * result   = NULL;
                    518: 
                    519:        if (chunk == NULL)
                    520:                return NULL;
                    521: 
                    522: #ifdef HAVE_VASPRINTF
                    523:        /* do the operation using the GNU extension */
1.1.1.2 ! misho     524:        if (vasprintf (&result, chunk, args) == -1)
        !           525:                return NULL;
1.1       misho     526: #else
                    527:        /* get the amount of memory to be allocated */
                    528:        size = exarg_vprintf_len (chunk, args);
                    529: 
                    530:        /* check result */
                    531:        if (size == -1) {
                    532:                printf ("error: unable to calculate the amount of memory for the strdup_printf operation");
                    533:                return NULL;
                    534:        } /* end if */
                    535: 
                    536:        /* allocate memory */
                    537:        result   = exarg_new (char, size + 2);
                    538:        
                    539:        /* copy current size */
1.1.1.2 ! misho     540: #  if defined(OS_WIN32) && ! defined (__GNUC__)
        !           541:        _vsnprintf_s (result, size + 1, size, chunk, args);
        !           542: #  else
        !           543:        vsnprintf (result, size + 1, chunk, args);
        !           544: #  endif
1.1       misho     545: #endif
                    546:        /* return the result */
                    547:        return result;
                    548: }
                    549: 
                    550: /** 
                    551:  * @internal Implementation that allows to produce dinamically
                    552:  * allocated strings using printf-like format.
                    553:  * 
                    554:  * @param chunk The chunk representing the format.
                    555:  * 
                    556:  * @return An dynamically allocated string.
                    557:  */
                    558: char      * exarg_strdup_printf   (char * chunk, ...)
                    559: {
                    560:        char    * result   = NULL;
                    561:        va_list   args;
                    562: 
                    563:        /* return a null value if null chunk is received */
                    564:        if (chunk == NULL)
                    565:                return NULL;
                    566: 
                    567:        /* open std args */
                    568:        va_start (args, chunk);
                    569: 
                    570:        /* get the string */
                    571:        result = exarg_strdup_printfv (chunk, args);
                    572:        
                    573:        /* close std args */
                    574:        va_end (args);
                    575:        
                    576:        return result;
                    577: }
                    578: 
                    579: /** 
                    580:  * @internal Allows to copy the given chunk, supposing that is a
                    581:  * properly format C string that ends with a '\\0' value.
                    582:  *
                    583:  * This function allows to perform a copy for the given string. If a
                    584:  * copy limited by a size is required, use \ref axl_stream_strdup_n.
                    585:  * 
                    586:  * @param chunk The chunk to copy
                    587:  * 
                    588:  * @return A newly allocated string or NULL if fails.
                    589:  */
                    590: char      * exarg_strdup          (char * chunk)
                    591: {
                    592:        char * result;
                    593:        int    length;
                    594: 
                    595:        /* do not copy if null reference is received */
                    596:        if (chunk == NULL)
                    597:                return NULL;
                    598: 
                    599:        length = strlen (chunk);
                    600:        result = exarg_new (char, length + 1);
                    601:        
                    602:        memcpy (result, chunk, length);
                    603: 
                    604:        return result;
                    605: }
                    606: 
                    607: /** 
                    608:  * @internal Internal function that allows to dealloc the provided array of chunks.
                    609:  * 
                    610:  * @param chunks An array containing pointers to chunks.
                    611:  */
                    612: void        exarg_freev           (char ** chunks)
                    613: {
                    614:        int iterator = 0;
                    615: 
                    616:        /* return if the received reference is null */
                    617:        if (chunks == NULL)
                    618:                return;
                    619:         
                    620:        /* release memory used by all elements inside the chunk */
                    621:        while (chunks[iterator] != 0) {
                    622:                exarg_free (chunks[iterator]);
                    623:                iterator++;
                    624:        }
                    625:        
                    626:        /* now release the chunk inside */
                    627:        exarg_free (chunks);
                    628:        
                    629:        /* nothing more to do */
                    630:        return;
                    631: }
                    632: 
                    633: 
                    634: /** 
                    635:  * @internal Adds the argument to the current argument list.
                    636:  * 
                    637:  * @param argument The argument to add.
                    638:  */
                    639: void __exarg_add_argument (char * argument)
                    640: {
                    641:        ExArgument * arg;
                    642:        ExArgument * arg2;
                    643: 
                    644:        /* creates the node */
                    645:        arg         = exarg_new (ExArgument, 1);
                    646:        arg->string = argument;
                    647: 
                    648:        if (params == NULL) {
                    649:                /* basic case, only one argument */
                    650:                params = arg;
                    651:                
                    652:                return;
                    653:        } /* end if */
                    654: 
                    655:        /* complex case, lookup for the last node */
                    656:        arg2 = params;
                    657:        while (arg2->next != NULL)
                    658:                arg2 = arg2->next;
                    659: 
                    660:        /* set the argument on the last position */
                    661:        arg2->next = arg;
                    662: 
                    663:        return;
                    664: }
                    665: 
                    666: /**
                    667:  * @internal
                    668:  * @brief Perfom a look up inside the argument option installed.
                    669:  *
                    670:  * This function tries to return the ExArgNodeOption using the given
                    671:  * value as index key. 
                    672:  *
                    673:  * The given value can represent the long key option or the short
                    674:  * form.
                    675:  * 
                    676:  * @param arg_name the key to use on lookup process
                    677:  *
                    678:  * @return the function retuns the argument option if found or NULL if
                    679:  * not.
                    680:  */
                    681: ExArgNodeOption * exarg_lookup_node (const char * arg_name)
                    682: {
                    683:        ExArgNodeOption * result      = NULL;
                    684:        int               arg_name_len;
                    685: 
                    686:        /* check for null value */
                    687:        if (arg_name == NULL)
                    688:                return NULL;
                    689: 
                    690:        /* get length */
                    691:        arg_name_len = strlen (arg_name);
                    692: 
                    693:        /* look up the item on the current argument option */
                    694:        result = argument_options;
                    695:        while (result != NULL) {
                    696: 
                    697:                /* check value with long argument form */
                    698:                if (arg_name_len == strlen (result->arg_name) &&
                    699:                    !memcmp (arg_name, result->arg_name, strlen (arg_name))) {
                    700: 
                    701:                        /* return found node */
                    702:                        return result;
                    703:                }
                    704:                
                    705:                /* check value with short argument form */
                    706:                if ((result->arg_short_name != NULL) && 
                    707:                    (arg_name_len == strlen (result->arg_short_name)) &&
                    708:                    !memcmp (arg_name, result->arg_short_name, strlen (arg_name))) {
                    709: 
                    710:                        /* return node found */
                    711:                        return result;
                    712:                }
                    713:                
                    714:                /* update to the next item */
                    715:                result = result->next;
                    716: 
                    717:        } /* end while */
                    718: 
                    719:        /* return that we didn't found an item */
                    720:        return result;
                    721:        
                    722: } /* end exarg_lookup_node */
                    723: 
                    724: 
                    725: 
                    726: 
                    727: int exarg_is_argument (char * argument) 
                    728: {
                    729: 
                    730:        int iterator = 1;
                    731: 
                    732:        /* support standard unix format definition */
                    733:        if (CHECK_PARSE_MODE (PARSE_MODE_UNIX) && !memcmp (argument, "--", 2)) {
                    734: 
                    735:                /* update parse mode */
                    736:                UPDATE_PARSE_MODE (PARSE_MODE_UNIX);
                    737:                return 1;
                    738:        }
                    739: 
                    740:        /* support sort argument format definition */
                    741:        if (CHECK_PARSE_MODE (PARSE_MODE_UNIX) && (strlen (argument) == 2) && (argument[0] == '-')) {
                    742: 
                    743:                /* update parse mode */
                    744:                UPDATE_PARSE_MODE (PARSE_MODE_UNIX);
                    745: 
                    746:                return 1;
                    747:        }
                    748:        
                    749:        /* support windows argument format */
                    750:        if (CHECK_PARSE_MODE (PARSE_MODE_WINDOWS) && (strlen (argument) > 2) && (argument[0] == '/')) {
                    751: 
                    752:                /* now check if the argument doesn't have more bars */
                    753:                while (argument[iterator] != 0) {
                    754:                        /* check value */
                    755:                        if (argument[iterator] == '/')
                    756:                                return 0;
                    757: 
                    758:                        /* update iterator */
                    759:                        iterator++;
                    760:                        
                    761:                } /* end while */
                    762: 
                    763:                /* update parse mode */
                    764:                UPDATE_PARSE_MODE (PARSE_MODE_WINDOWS);
                    765:                
                    766:                return 1;
                    767:        }
                    768: 
                    769:        return 0;
                    770: }
                    771: 
                    772: char * exarg_get_argument (char * argument)
                    773: {
                    774:        /* support getting the argument value for unix standard
                    775:         * argument */
                    776:        if (!memcmp (argument, "--", 2))
                    777:                return &(argument[2]);
                    778:        
                    779:        /* support getting the argument value for short def */
                    780:        if ((strlen (argument) == 2) && (argument[0] == '-'))
                    781:                return &(argument[1]);
                    782: 
                    783:        /* support getting the argument value for windows def */
                    784:        if ((strlen (argument) > 2) && (argument[0] == '/'))
                    785:                return &(argument[1]);
                    786: 
                    787:        return NULL;
                    788: }
                    789: 
                    790: int exarg_check_help_argument (char * argument)
                    791: {
                    792:        if (!memcmp (argument, "help", 4) || !memcmp (argument, "?", 1))
                    793:                return 1;
                    794:        return 0;
                    795: }
                    796: 
                    797: void     exarg_wrap_and_print (const char * text, int size_to_wrap, const char * fill_text)
                    798: {
                    799:        char    ** stringv      = NULL;
                    800:        int        i            = 0;
                    801:        int        sum          = 0;
                    802:        char     * working_line = NULL;
                    803:        char     * aux_string   = NULL;
                    804:        int        first_line   = 1;
                    805: 
                    806:        /* do not print anything if a null value is received */
                    807:        if (text == NULL)
                    808:                return;
                    809: 
                    810:        if (strlen (text) <= size_to_wrap) {
                    811:                printf ("%s\n", text);
                    812:                return;
                    813:        }
                    814: 
                    815:        stringv = exarg_split (text, 1, " ");
                    816:        for (i = 0; stringv[i]; i++) {
                    817:                if (working_line) {
                    818:                        aux_string   = working_line;
                    819:                        working_line = exarg_strdup_printf ("%s %s", working_line, stringv[i]);
                    820:                        exarg_free (aux_string);
                    821:                }else
                    822:                        working_line = exarg_strdup (stringv[i]);
                    823:                sum = sum + strlen (stringv[i]) + 1;
                    824: 
                    825:                if (sum >= size_to_wrap) {
                    826:                        sum = 0;
                    827:                        if (first_line) {
                    828:                                first_line = 0;
                    829:                                printf ("%s\n", working_line);
                    830:                        }else
                    831:                                printf ("%s%s\n", fill_text, working_line);
                    832:                        exarg_free (working_line);
                    833:                        working_line = NULL;
                    834:                }
                    835: 
                    836:        }
                    837:        if (sum) {
                    838:                printf ("%s%s\n", fill_text, working_line);
                    839:                exarg_free (working_line);
                    840:        }
                    841:        exarg_freev (stringv);
                    842:        
                    843:        
                    844:        return;
                    845: }
                    846: 
                    847: void __exarg_show_usage_foreach (epointer key, epointer value, epointer user_data)
                    848: {
                    849:        char            ** string_aux = (char **) user_data;
                    850:        char             * str        = (* string_aux);
                    851:        char             * aux        = NULL;
                    852:        ExArgNodeOption  * node       = (ExArgNodeOption  *) value;
                    853: 
                    854:        switch (node->type) {
                    855:        case EXARG_NONE:
                    856:                if (node->arg_short_name)
                    857:                        (*string_aux) = exarg_strdup_printf (" [-%s|--%s]", node->arg_short_name, node->arg_name);
                    858:                else
                    859:                        (*string_aux) = exarg_strdup_printf (" [--%s]", node->arg_name);
                    860:                break;
                    861:        case EXARG_INT:
                    862:                if (node->arg_short_name)
                    863:                        (*string_aux) = exarg_strdup_printf (" [-%s <number>|--%s <number>]", node->arg_short_name, node->arg_name);
                    864:                else
                    865:                        (*string_aux) = exarg_strdup_printf (" [--%s <number>]", node->arg_name);
                    866:                break;
                    867:        case EXARG_STRING:
                    868:                if (node->arg_short_name)
                    869:                        (*string_aux) = exarg_strdup_printf (" [-%s <string>|--%s <string>]", node->arg_short_name, node->arg_name);
                    870:                else
                    871:                        (*string_aux) = exarg_strdup_printf (" [--%s <string>]", node->arg_name);
                    872:                break;
                    873:        } /* end switch */
                    874: 
                    875:        if (str != NULL) {
                    876:                /* get a reference to previous content */
                    877:                aux           = (* string_aux);
                    878:                (*string_aux) = exarg_strdup_printf ("%s%s", str, (*string_aux));
                    879:                
                    880:                /* dealloc both pieces that joined are the result */
                    881:                exarg_free (str);
                    882:                exarg_free (aux);
                    883:        }
                    884:        return;
                    885: }
                    886: 
                    887: void exarg_show_usage (int show_header)
                    888: {
                    889:        char            * string_aux = NULL;
                    890:        ExArgNodeOption * node;
                    891:        
                    892:        if (show_header && (__exarg_usage_header && (* __exarg_usage_header)))
1.1.1.2 ! misho     893:                printf ("%s", __exarg_usage_header);
1.1       misho     894: 
                    895:        printf ("Usage: %s ", exarg_exec_name);
                    896:        
                    897:        /* get the first node */
                    898:        node = argument_options;
                    899:        while (node != NULL) {
                    900:                /* call to the foreach function */
                    901:                __exarg_show_usage_foreach ((epointer) node->arg_name, node, &string_aux);
                    902:                
                    903:                /* update to the next */
                    904:                node = node->next;
                    905:                
                    906:        } /* end while */
                    907: 
                    908:        exarg_wrap_and_print (string_aux, 55, "               ");
                    909:        printf ("\n");
                    910: 
                    911:        /* free string created */
                    912:        exarg_free (string_aux);
                    913: 
                    914:        if (show_header && (__exarg_post_usage_header && (* __exarg_post_usage_header)))
1.1.1.2 ! misho     915:                printf ("%s", __exarg_post_usage_header);
1.1       misho     916:        
                    917:        return;
                    918: }
                    919: 
                    920: char * __exarg_build_dep_string (ExArgNodeOption * node, int exclude)
                    921: {
                    922:        char            * result;
                    923:        char            * aux;
                    924:        ExArgDependency * dep;
                    925: 
                    926:        /* check node dependency */
                    927:        if (!exclude && ! node->depends)
                    928:                return NULL;
                    929:        if (exclude && ! node->excludes)
                    930:                return NULL;
                    931: 
                    932:        if (exclude) 
                    933:                result = exarg_strdup ("[excludes: ");
                    934:        else
                    935:                result = exarg_strdup ("[depends on: ");
                    936:        
                    937:        /* foreach each dependency configured */
                    938:        if (exclude)
                    939:                dep    = node->excludes;
                    940:        else
                    941:                dep    = node->depends;
                    942:        while (dep != NULL) {
                    943: 
                    944:                aux    = result;
                    945:                if (dep->next != NULL)
                    946:                        result = exarg_strdup_printf ("%s --%s", result, dep->node->arg_name);
                    947:                else
                    948:                        result = exarg_strdup_printf ("%s --%s]", result, dep->node->arg_name);
                    949:                exarg_free (aux);
                    950:                
                    951:                /* get next dependency */
                    952:                dep = dep->next;
                    953: 
                    954:        } /* end while */
                    955: 
                    956:        /* return string created */
                    957:        return result;
                    958: }
                    959: 
                    960: void __exarg_show_help_foreach (epointer key, epointer value, epointer user_data)
                    961: {
                    962:        ExArgNodeOption * node = (ExArgNodeOption  *) value;
                    963:        char            * dep;
                    964:        int               chars = 35;
                    965:        int               iterator = 0;
                    966:        
                    967:        /* print argument help */
                    968:        if (node->arg_short_name) {
                    969:                printf ("  -%s, --%-18s       ", 
                    970:                        node->arg_short_name, node->arg_name);
                    971:                exarg_wrap_and_print (node->description, 40, "                                 ");
                    972: 
                    973:        }else {
                    974:                printf ("  --%-22s       ", node->arg_name);
                    975:                exarg_wrap_and_print (node->description, 40, "                                 ");
                    976:        }
                    977: 
                    978:        /* print argument dependency */
                    979:        dep = __exarg_build_dep_string (node, 0);
                    980:        if (dep != NULL) {
                    981:                /* write spaces */
                    982:                while (iterator < chars) {
                    983:                        printf (" ");
                    984:                        iterator++;
                    985:                }
                    986:                exarg_wrap_and_print (dep, 40, "                                 ");
                    987:        }
                    988:        exarg_free (dep);
                    989: 
                    990:        /* print argument exclusion */
                    991:        iterator = 0;
                    992:        dep      = __exarg_build_dep_string (node, 1);
                    993:        if (dep != NULL) {
                    994:                /* write spaces */
                    995:                while (iterator < chars) {
                    996:                        printf (" ");
                    997:                        iterator++;
                    998:                }
                    999:                exarg_wrap_and_print (dep, 40, "                                 ");
                   1000:        }
                   1001:        exarg_free (dep);
                   1002:        return;
                   1003: }
                   1004: 
1.1.1.2 ! misho    1005: void   exarg_show_help (void) 
1.1       misho    1006: {
                   1007:        ExArgNodeOption * node;
                   1008: 
                   1009:        if (__exarg_help_header && (* __exarg_help_header))
1.1.1.2 ! misho    1010:                printf ("%s", __exarg_help_header);
1.1       misho    1011: 
                   1012:        exarg_show_usage (0);
                   1013: 
                   1014:        printf ("\nCommand options:\n");
                   1015: 
                   1016:        /* get first node */
                   1017:        node = argument_options;
                   1018:        while (node != NULL) {
                   1019:                /* call to show the node information */
                   1020:                __exarg_show_help_foreach ((epointer) node->arg_name, node, NULL);
                   1021: 
                   1022:                /* update to the next node */
                   1023:                node = node->next;
                   1024:        } /* end while */
                   1025: 
                   1026:        printf ("\nHelp options:\n");
                   1027:        printf ("  -?, --help                    Show this help message.\n");
                   1028:        printf ("  --usage                       Display brief usage message.\n");
                   1029: 
                   1030:        if (__exarg_post_help_header && (* __exarg_post_help_header))
1.1.1.2 ! misho    1031:                printf ("%s", __exarg_post_help_header);
1.1       misho    1032: 
                   1033:        return;
                   1034: }
                   1035: 
                   1036: void exarg_check_argument_value (char ** argv, int iterator) 
                   1037: {
                   1038: 
                   1039:        if (argv[iterator] == NULL) {
                   1040:                printf ("error: not defined value for argument: %s, exiting..",
                   1041:                        argv[iterator - 1]);
                   1042:                fflush (stdout);
                   1043:                exit (-1);
                   1044:        }
                   1045: 
                   1046:        if (exarg_is_argument (argv[iterator])) {
                   1047:                printf ("error: not defined value for argument: %s, instead found another argument: %s, exiting..",
                   1048:                        argv[iterator - 1],
                   1049:                        argv[iterator]);
                   1050:                fflush (stdout);
                   1051:                exit (-1);
                   1052:        }
                   1053: 
                   1054:        return;
                   1055: }
                   1056: 
                   1057: 
1.1.1.2 ! misho    1058: void __exarg_parse_check_non_optional (void)
1.1       misho    1059: {
                   1060:        ExArgNodeOption * node = argument_options;
                   1061: 
                   1062:        /* for each node */
                   1063:        while (node != NULL) {
                   1064:                /* check the node */
                   1065:                if (! node->is_optional && ! node->is_defined) {
                   1066:                        exarg_msg ("error: argument '%s' is not defined, but it is required for a proper function..\n",
                   1067:                                   node->arg_name);
                   1068:                } /* end if */
                   1069: 
                   1070:                /* get the next */
                   1071:                node = node->next;
                   1072: 
                   1073:        } /* end while */
                   1074: 
                   1075:        return;
                   1076: }
                   1077: 
1.1.1.2 ! misho    1078: void __exarg_parse_check_depends (void)
1.1       misho    1079: {
                   1080:        /* first argument */
                   1081:        ExArgNodeOption * node = argument_options;
                   1082:        ExArgDependency * dep;
                   1083: 
                   1084:        /* for each argument defined */
                   1085:        while (node != NULL) {
                   1086: 
                   1087:                /* check if the argument was defined, and hence
                   1088:                 * activates its dependencies */
                   1089:                if (! node->is_defined) {
                   1090:                        node = node->next;
                   1091:                        continue;
                   1092:                }
                   1093: 
                   1094:                /* check depends */
                   1095:                dep = node->depends;
                   1096:                while (dep != NULL) {
                   1097: 
                   1098:                        /* check that the dependency is defined */
                   1099:                        if (! dep->node->is_defined) {
                   1100:                                exarg_msg ("You must define argument (--%s) if used (--%s). Try %s --help.", 
                   1101:                                           dep->node->arg_name, node->arg_name, exarg_exec_name);
                   1102:                                return;
                   1103:                        } /* end if */
                   1104: 
                   1105:                        /* get next dependency */
                   1106:                        dep = dep->next;
                   1107:                        
                   1108:                } /* end while */
                   1109: 
                   1110:                /* check depends */
                   1111:                dep = node->excludes;
                   1112:                while (dep != NULL) {
                   1113:                        
                   1114:                        /* check that the dependency is defined */
                   1115:                        if (dep->node->is_defined) {
                   1116:                                printf ("You can't define argument (--%s) if used (--%s). Try %s --help.\n", 
                   1117:                                        node->arg_name, dep->node->arg_name, exarg_exec_name);
                   1118:                                fflush (stdout);
                   1119:                                return;
                   1120:                        } /* end if */
                   1121: 
                   1122:                        /* get next dependency */
                   1123:                        dep = dep->next;
                   1124:                        
                   1125:                } /* end while */
                   1126: 
                   1127:                /* get next node */
                   1128:                node = node->next;
                   1129:  
                   1130:        } /* end whle */
                   1131: 
                   1132:        /* nothing more to check */
                   1133:        return;
                   1134: }
                   1135: 
                   1136: 
                   1137: /** 
                   1138:  * \brief Makes exarg to start parsing argument options.
                   1139:  *
                   1140:  * Makes LibExArg to start command line parsing by using arguments
                   1141:  * installed. 
                   1142:  * 
                   1143:  * Once this functions is called it is posible to call the set of
                   1144:  * function which returns data obtained: \ref exarg_is_defined,
                   1145:  * \ref exarg_get_int, \ref exarg_get_string and \ref exarg_get_params.
                   1146:  *
                   1147:  * The advantage is that LibExArg allows you to get access to command
                   1148:  * line data from any point of your program.
                   1149:  * 
                   1150:  * @param argc the argc value the current application have received.
                   1151:  * @param argv the argv value the current application have received.
                   1152:  */
                   1153: void       exarg_parse         (int         argc,
                   1154:                                char     ** argv)
                   1155: {
                   1156:        int              iterator = 1;
                   1157:        ExArgNodeOption * node;
                   1158:        char           * argument;
                   1159: 
                   1160:        /* check how many argument have been defined */
                   1161:        if (iterator == argc) {
                   1162:                /* once terminated, check if the non optional options
                   1163:                 * were defined */
                   1164:                
                   1165:                __exarg_parse_check_non_optional ();
                   1166:                return;
                   1167:        }
                   1168: 
                   1169:        exarg_exec_name = exarg_basename (argv[0]);
                   1170:        
                   1171:        /* iterate over all arguments */
                   1172:        while (iterator < argc) {
                   1173: 
                   1174:                if (!exarg_is_argument (argv[iterator])) {
                   1175:                        /* check free argument configuration */
                   1176:                        if (__exarg_disable_free_args) {
                   1177:                                exarg_msg ("error: provided a free argument='%s', not listed in the accept command line option", argv[iterator]);
                   1178: 
                   1179:                        } /* end if */
                   1180: 
                   1181:                        /* save and increase iterator */
                   1182:                        __exarg_add_argument (argv[iterator]);
                   1183:                        iterator++;
                   1184:                        continue;
                   1185:                }
                   1186:                
                   1187:                /* get clean argument */
                   1188:                argument = exarg_get_argument (argv[iterator]);
                   1189: 
                   1190:                /* check for help argument */
                   1191:                if (exarg_check_help_argument (argument)){
                   1192:                        exarg_show_help ();
                   1193:                        exarg_end ();
                   1194:                        exit (0);
                   1195:                }
                   1196:                
                   1197:                /* check for usage argument */
                   1198:                if (!memcmp (argument, "usage", 5)) {
                   1199:                        exarg_show_usage (1);
                   1200:                        exarg_end ();
                   1201:                        exit (0);
                   1202:                }
                   1203: 
                   1204:                /* get node argument */
                   1205:                node = exarg_lookup_node (argument);
                   1206:                if (node == NULL) {
                   1207:                        exarg_msg ("%s error: argument not found: %s, try: %s --help\n",
                   1208:                                   exarg_exec_name, argv[iterator], exarg_exec_name);
                   1209:                }
                   1210:                
                   1211:                /* check if node is defined */
                   1212:                if (node->is_defined) {
                   1213:                        exarg_msg ("%s error: argument %s already defined, exiting..\n",
                   1214:                                   exarg_exec_name, argv[iterator]);
                   1215:                }
                   1216: 
                   1217:                
                   1218:                /* set this argument to be defined */
                   1219:                node->is_defined = 1;
                   1220:                switch (node->type) {
                   1221:                case EXARG_NONE:
                   1222:                        /* nothing to do */ 
                   1223:                                break;
                   1224:                case EXARG_INT:
                   1225:                        /* save int value */
                   1226:                        iterator++;
                   1227: 
                   1228:                        exarg_check_argument_value (argv, iterator);
                   1229: 
                   1230:                        node->int_value    = atoi (argv[iterator]);
                   1231:                        break;
                   1232:                case EXARG_STRING:
                   1233:                        iterator++;
                   1234:                        
                   1235:                        exarg_check_argument_value (argv, iterator);
                   1236: 
                   1237:                        node->string_value = argv[iterator];
                   1238: 
                   1239:                        break;
                   1240:                }
                   1241:                
                   1242:                /* update iterator */
                   1243:                iterator++;
                   1244:        }
                   1245: 
                   1246:        /* once terminated, check if the non optional options were
                   1247:         * defined */
                   1248:        __exarg_parse_check_non_optional ();
                   1249: 
                   1250:        /* check argument dependency and argument mutual exclusion. */
                   1251:        __exarg_parse_check_depends ();
                   1252: 
                   1253:        return;
                   1254: }
                   1255: 
                   1256: void __exarg_end_free_dep (ExArgDependency * dep)
                   1257: {
                   1258:        ExArgDependency * next;
                   1259: 
                   1260:        /* foreach dependency established */
                   1261:        while (dep != NULL) {
                   1262: 
                   1263:                /* free the dep node */
                   1264:                next = dep->next;
                   1265:                exarg_free (dep);
                   1266:                dep  = next;
                   1267:        } /* end while */
                   1268: 
                   1269:        return;
                   1270: }
                   1271: 
                   1272: /**
                   1273:  * \brief Ends exarg library execution.
                   1274:  * 
                   1275:  * Terminates the exarg function. This function will free all
                   1276:  * resources allocated so the library cannot be used any more for the
                   1277:  * current execution.
                   1278:  *
                   1279:  * This function is reatrant. Several threads can actually call this
                   1280:  * function. It will take care about making only one thread to
                   1281:  * actually free resources.
                   1282:  **/
                   1283: void       exarg_end           ()
                   1284: {
                   1285:        ExArgNodeOption * node;
                   1286:        ExArgNodeOption * node2;
                   1287:        
                   1288:        ExArgument      * params2;
                   1289:        
                   1290: 
                   1291:        if (argument_options != NULL) {
                   1292:                /* get a reference to the table, and dealloc it */
                   1293:                node             = argument_options;
                   1294:                argument_options = NULL;
                   1295:                
                   1296:                while (node != NULL) {
                   1297:                        /* get a reference to the next */
                   1298:                        node2 = node->next;
                   1299: 
                   1300:                        /* free node arguments dependencies and mutual
                   1301:                         * exclusions */
                   1302:                        __exarg_end_free_dep (node->depends);
                   1303:                        __exarg_end_free_dep (node->excludes);
                   1304: 
                   1305:                        /* free current node */
                   1306:                        exarg_free (node);
                   1307:                        
                   1308:                        /* update the node ref */
                   1309:                        node = node2;
                   1310:                } /* end while */
                   1311: 
                   1312:        } /* end if */
                   1313: 
                   1314:        if (params != NULL) {
                   1315:                while (params != NULL) {
                   1316:                        /* get a reference to the next node */
                   1317:                        params2 = params->next;
                   1318: 
                   1319:                        /* free params node */
                   1320:                        exarg_free (params);
                   1321: 
                   1322:                        /* configure the next argument to dealloc */
                   1323:                        params = params2;
                   1324:                } /* end while */
                   1325:        } /* end if */
                   1326: 
                   1327:        return;
                   1328: }
                   1329: 
                   1330: /**
                   1331:  * \brief Disable autohelp.
                   1332:  * 
                   1333:  * Allows to disable auto help and --help and -? option
                   1334:  * recognition. This is useful if you don't want your program to
                   1335:  * accept --help and --usage options.
                   1336:  **/
                   1337: void       exarg_disable_help ()
                   1338: {
                   1339:        return;
                   1340: }
                   1341: 
                   1342: /**
                   1343:  * \brief Adds user defined header to automatic usage command generated.
                   1344:  * 
                   1345:  * Once a program is linked to libexarg is able to produce a usage
                   1346:  * help by accepting the --usage command line option. But that usage
                   1347:  * help is showed as is. This function allows you to define a header
                   1348:  * to be showed preceding the usage info. You can use this, for
                   1349:  * example, to introduce your copyright.
                   1350:  *
                   1351:  * This function doesn't make a copy of the given string so you
                   1352:  * must not free the header provided or use an static string.
                   1353:  **/
                   1354: void       exarg_add_usage_header (char * header)
                   1355: {
                   1356:        __exarg_usage_header = header;
                   1357: }
                   1358: 
                   1359: /**
                   1360:  * \brief Adds user defined header to automatic help command generated.
                   1361:  * 
                   1362:  * Once a program is linked to libexarg is able to produce a help by
                   1363:  * accepting the --help or -? command line option. But that help is
                   1364:  * showed as is. This function allows you to define a header to be
                   1365:  * showed preceding the help info. You can use this, for example, to
                   1366:  * introduce your copyright.
                   1367:  *
                   1368:  * This function doesn't make a copy of the given string so you
                   1369:  * must not free the header provided or use an static string.
                   1370:  **/
                   1371: void       exarg_add_help_header  (char * header)
                   1372: {
                   1373:        __exarg_help_header = header;
                   1374: }
                   1375: 
                   1376: /**
                   1377:  * \brief Adds user defined post header for usage command.
                   1378:  * 
                   1379:  * This function works pretty much like \ref exarg_add_usage_header but
                   1380:  * adding the header provided to be appended at the end of the usage
                   1381:  * automatically generated.
                   1382:  **/
                   1383: void       exarg_post_usage_header (char * post_header)
                   1384: {
                   1385:        __exarg_post_usage_header = post_header;
                   1386: }
                   1387: 
                   1388: /**
                   1389:  * \brief Adds user defined post header for help command.
                   1390:  * 
                   1391:  * This function works pretty much like \ref exarg_add_help_header but
                   1392:  * adding the header provided to be appended at the end of the help
                   1393:  * automatically generated.
                   1394:  **/
                   1395: void       exarg_post_help_header (char * post_header)
                   1396: {
                   1397:        __exarg_post_help_header = post_header;
                   1398: }
                   1399: 
                   1400: /**
                   1401:  * \internal
                   1402:  * Internal ExArg function. This function allows \ref exarg_install_arg to
                   1403:  * check if there are already installed an short argument as the one
                   1404:  * been installed.
                   1405:  **/
                   1406: void __exarg_check_short_arg (epointer key, epointer value, epointer user_data)
                   1407: {
                   1408:        ExArgNodeOption * node         = (ExArgNodeOption  *) value;
                   1409:        char           * arg_to_check = (char *) user_data;
                   1410: 
                   1411:        if (node->arg_short_name != NULL) {
                   1412:                if (!memcmp (node->arg_short_name, arg_to_check, strlen (arg_to_check))) {
                   1413:                        exarg_msg ("error: found that short arg installed is already found: %s\n", arg_to_check);
                   1414:                } /* end if */
                   1415:        } /* end if */
                   1416: 
                   1417:        return;
                   1418: }
                   1419: 
                   1420: /**
                   1421:  * \brief Installs a new command line to be accepted.
                   1422:  * 
                   1423:  * This functions allows you to install new arguments to be
                   1424:  * accepted. Every argument passed in to the program which is not
                   1425:  * installed throught this function will no be accepted and will
                   1426:  * generate a non recognized command line error.
                   1427:  *
                   1428:  * Let's see an example on how to use exarg to install the --version
                   1429:  * argument. You should call exarg as follows:
                   1430:  * 
                   1431:  * \code
                   1432:  *       exarg_install_arg ("version", "v", EXARG_NONE, 
                   1433:  *                          "show program version");
                   1434:  *
                   1435:  * \endcode
                   1436:  * 
                   1437:  * Previous line have installed a argument called "version" which will
                   1438:  * be invoked by the user as --version. The short alias
                   1439:  * in this case is "v" which as we have see will allow user to invoke
                   1440:  * your program as -v.
                   1441:  *
                   1442:  * Because you could install arguments which may conflict, this
                   1443:  * function will abort the program execution on that case. This will
                   1444:  * ensure you, as programer, to have a binary compiled with no
                   1445:  * problems due to exarg.
                   1446:  *
                   1447:  * Later on, you can use \ref exarg_is_defined to check the status of
                   1448:  * installed arguments. Once you install an argument the user may
                   1449:  * invoke it and you could check that status using previous
                   1450:  * function. Because the "version" argument type is \ref EXARG_NONE you can
                   1451:  * only use \ref exarg_is_defined. But, for other argument types as
                   1452:  * \ref EXARG_STRING, you can also use \ref exarg_get_string function to get the
                   1453:  * value defined by user. Let's see an example.
                   1454:  *
                   1455:  * \code
                   1456:  *       exarg_install_arg ("load-library", "l", EXARG_STRING,
                   1457:  *                          "loads the library defined as argument");
                   1458:  * \endcode
                   1459:  * 
                   1460:  * This previous line will allow user to invoke your program as 
                   1461:  * --load-library path/to/lib. Then you can use \ref exarg_get_string to get
                   1462:  * the path/to/lib value by using:
                   1463:  * 
                   1464:  * \code
                   1465:  *       // check user have defined this argument
                   1466:  *       if (exarg_is_defined ("load-library")) {
                   1467:  *
                   1468:  *             arg_value = exarg_get_string ("load-library");
                   1469:  *
                   1470:  *             printf ("The library defined by user was: %s\n", 
                   1471:  *                      arg_value);
                   1472:  *       }
                   1473:  * 
                   1474:  * \endcode
                   1475:  *
                   1476:  * You must install all argument before calling \ref exarg_parse. That function
                   1477:  * will parse argument options by using installed arguments. Check the info
                   1478:  * about that function.
                   1479:  * 
                   1480:  * ExArg is not thread-safe which doesn't means anything wrong but you
                   1481:  * must call all exarg function from the same thread to get the right
                   1482:  * results. 
                   1483:  *
                   1484:  * This function will not do a copy from arg_name, arg_short_name or
                   1485:  * description. This means you should not free that values while
                   1486:  * using exarg. To end exarg using check \ref exarg_end. It is recomended to use
                   1487:  * static values and shows on previous examples.
                   1488:  **/
                   1489: void       exarg_install_arg  (const char     * arg_name, 
                   1490:                               const char     * arg_short_name, 
                   1491:                               ExArgType   type,
                   1492:                               const char     * description)
                   1493: {
                   1494:        ExArgNodeOption * node;
                   1495:        ExArgNodeOption * node2;
                   1496: 
                   1497:        /* init hash table */
                   1498:        if (argument_options != NULL) {
                   1499:                /* check if there are an argument with the same name */
                   1500:                if (exarg_lookup_node (arg_name)) {
                   1501:                        exarg_end ();
                   1502:                        exarg_msg ("error: argument being installed is already defined: %s..",
                   1503:                                   arg_name);
                   1504:                }
                   1505:                
                   1506:                /* check if there are an shor argument with the same
                   1507:                 * name */
                   1508:                if (arg_short_name != NULL) {
                   1509:                        node = argument_options;
                   1510:                        
                   1511:                        /* while there are options to process */
                   1512:                        while (node != NULL) {
                   1513:                                /* call to check */
                   1514:                                __exarg_check_short_arg ((epointer) node->arg_name, node, (epointer) arg_short_name);
                   1515: 
                   1516:                                /* update to the next */
                   1517:                                node = node->next;
                   1518:                        } /* end while */
                   1519:                } /* end if */
                   1520:        } /* end if */
                   1521:                
                   1522:        /* create node option */
                   1523:        node                 = exarg_new (ExArgNodeOption, 1);
                   1524:        node->arg_name       = arg_name;
                   1525:        node->arg_short_name = arg_short_name;
                   1526:        node->type           = type;
                   1527:        node->description    = description;
                   1528:        node->is_optional    = 1;
                   1529: 
                   1530:        /* lookup for the last position */
                   1531:        if (argument_options == NULL)
                   1532:                argument_options = node;
                   1533:        else {
                   1534:                /* lookup for the last */
                   1535:                node2 = argument_options;
                   1536:                while (node2->next != NULL)
                   1537:                        node2 = node2->next;
                   1538: 
                   1539:                /* set it */
                   1540:                node2->next = node;
                   1541:        } /* end if */
                   1542: 
                   1543:        return;
                   1544: }
                   1545: 
                   1546: /**
                   1547:  * \brief Installs several command lines to be accepted.
                   1548:  * 
                   1549:  * This function does the same that \ref exarg_install_arg but making 
                   1550:  * group of argument to be installed in one step.
                   1551:  *
                   1552:  * Think about installing two argument. To install them we have to do
                   1553:  * the following:
                   1554:  *
                   1555:  * \code
                   1556:  *    exarg_install_arg ("version", "v", 
                   1557:  *                       EXARG_NONE, "show argument version");
                   1558:  *    exarg_install_arg ("load-library", "l", 
                   1559:  *                       EXARG_STRING, "load my library");
                   1560:  * \endcode
                   1561:  *
                   1562:  * Because some people doesn't like to perform several calls to the
                   1563:  * same funcion the previous code can be done by using one step as:
                   1564:  *
                   1565:  * \code
                   1566:  *    exarg_install_argv (2, "version", "v", EXARG_NONE, 
                   1567:  *                        "show argument version", 
                   1568:  *                        "load-library", "l",
                   1569:  *                        EXARG_STRING, "load my library");
                   1570:  * \endcode
                   1571:  *
                   1572:  * When you install argument this way you have to specify how many
                   1573:  * argument is going to be installed. In this case that number is
                   1574:  * 2. This allows exarg to know how many arguments needs to search
                   1575:  * inside the argv. If something is wrong while specifying the number
                   1576:  * or argument or the argument information itself you'll get a
                   1577:  * segmentation fault or something similar.
                   1578:  *
                   1579:  * While calling to \ref exarg_install_arg the short_name argument can be
                   1580:  * optional. This is *NOT* applied to this function. If you don't want
                   1581:  * to define a short argument name you must use NULL as value.
                   1582:  * 
                   1583:  * @param num_arg Must be at least 1 or error will happen and library will abort
                   1584:  * application execution.
                   1585:  **/
                   1586: void       exarg_install_argv (int num_arg, ...)
                   1587: {
                   1588:        va_list      args;
                   1589:        int         iterator;
                   1590:        char      * arg_name;
                   1591:        char      * arg_short_name;
                   1592:        ExArgType    type;
                   1593:        char      * description;
                   1594: 
                   1595:        if (num_arg <= 0) {
                   1596:                exarg_end ();
                   1597:                exarg_msg ("error: calling to exarg_install_argv with num_arg equal or less to 0..");
                   1598:        }
                   1599: 
                   1600:        va_start (args, num_arg);
                   1601: 
                   1602:        for (iterator = 0; iterator < num_arg; iterator++) {
                   1603: 
                   1604:                /* get the argument info */
                   1605:                arg_name       = va_arg (args, char *);
                   1606:                arg_short_name = va_arg (args, char *);
                   1607:                type           = va_arg (args, ExArgType);
                   1608:                description    = va_arg (args, char *);
                   1609:                
                   1610:                exarg_install_arg (arg_name, arg_short_name, type, description);
                   1611:        }
                   1612:        va_end (args);
                   1613:        return;
                   1614: }
                   1615: 
                   1616: /** 
                   1617:  * @brief Allows to define a parameter dependency between the to
                   1618:  * arguments defined. The kind of dependency has direction. This means
                   1619:  * that the first argument will depend on the second argument, forcing
                   1620:  * the user to define the second argument if the first one is defined.
                   1621:  *
                   1622:  * You can call to this function several times making the first
                   1623:  * argument to depend on any number of argument defined. You must not
                   1624:  * call to establish a dependency to the argument itself.
                   1625:  * 
                   1626:  * @param arg_name The argument that will be configured with an
                   1627:  * argument dependency.
                   1628:  *
                   1629:  * @param arg_dependency The argument that will receive the
                   1630:  * dependency.
                   1631:  *
                   1632:  *
                   1633:  */
                   1634: void         exarg_add_dependency   (const char * arg_name, 
                   1635:                                     const char * arg_dependency)
                   1636: {
                   1637:        ExArgNodeOption * node;
                   1638:        ExArgNodeOption * node2;
                   1639:        ExArgDependency * dep;
                   1640:        /* check arguments received */
                   1641:        if (arg_name == NULL)
                   1642:                return;
                   1643:        if (arg_dependency == NULL)
                   1644:                return;
                   1645: 
                   1646:        /* check that both arguments aren't equal */
                   1647:        if (strlen (arg_name) == strlen (arg_dependency) &&
                   1648:            !memcmp (arg_name, arg_dependency, strlen (arg_name))) {
                   1649:                exarg_msg ("error: defined argument dependency with an argument itself.");
                   1650:                return;
                   1651:        }
                   1652:        
                   1653:        /* locates the argument node */
                   1654:        node = exarg_lookup_node (arg_name);
                   1655:        if (node == NULL) {
                   1656:                exarg_msg ("error: you did especify an argument that doesn't exists (%s)", arg_name);
                   1657:                return;
                   1658:        }
                   1659: 
                   1660:        /* locates dependecy argument node */
                   1661:        node2 = exarg_lookup_node (arg_dependency);
                   1662:        if (node2 == NULL) {
                   1663:                exarg_msg ("error: you did especify an argument that doesn't exists (%s)", arg_dependency);
                   1664:                return;
                   1665:        }
                   1666: 
                   1667:        /* make the first argument to depend on the second */
                   1668:        dep = node->depends;
                   1669:        
                   1670:        /* create the new dependency node */
                   1671:        node->depends       = exarg_new (ExArgDependency, 1);
                   1672:        node->depends->node = node2;
                   1673:        node->depends->next = dep;
                   1674: 
                   1675:        return;
                   1676: }
                   1677: 
                   1678: /** 
                   1679:  * @brief Allows to configure arguments that are mutually
                   1680:  * excluyents. This function will take the first arguments to be
                   1681:  * muatually excluyen with the second one without direction as it
                   1682:  * happens with \ref exarg_add_dependency function.
                   1683:  *
                   1684:  * Once defined both arguments provided can't be defined at the same
                   1685:  * time at the command line options.
                   1686:  * 
                   1687:  * @param arg_name The first argument to make mutual exclusion with
                   1688:  * the second argument.
                   1689:  *
                   1690:  * @param arg_excluded Second argument to make mutual exclusion with
                   1691:  * the first argument.
                   1692:  */
                   1693: void         exarg_add_exclusion     (const char * arg_name, 
                   1694:                                      const char * arg_excluded)
                   1695: {
                   1696:        ExArgNodeOption * node;
                   1697:        ExArgNodeOption * node2;
                   1698:        ExArgDependency * dep;
                   1699: 
                   1700:        /* check arguments received */
                   1701:        if (arg_name == NULL)
                   1702:                return;
                   1703:        
                   1704:        if (arg_excluded == NULL)
                   1705:                return;
                   1706: 
                   1707:        /* check that both arguments aren't equal */
                   1708:        if (strlen (arg_name) == strlen (arg_excluded) &&
                   1709:            !memcmp (arg_name, arg_excluded, strlen (arg_name))) {
                   1710:                exarg_msg ("error: defined argument dependency with an argument itself.");
                   1711:                return;
                   1712:        }
                   1713:        
                   1714:        /* locates the argument node */
                   1715:        node = exarg_lookup_node (arg_name);
                   1716:        if (node == NULL) {
                   1717:                exarg_msg ("error: you did especify an argument that doesn't exists (%s)", arg_name);
                   1718:                return;
                   1719:        }
                   1720: 
                   1721:        /* locates dependecy argument node */
                   1722:        node2 = exarg_lookup_node (arg_excluded);
                   1723:        if (node2 == NULL) {
                   1724:                exarg_msg ("error: you did especify an argument that doesn't exists (%s)", arg_excluded);
                   1725:                return;
                   1726:        }
                   1727: 
                   1728:        /* make the first argument to depend on the second */
                   1729:        dep = node->excludes;
                   1730:        
                   1731:        /* create the new dependency node */
                   1732:        node->excludes       = exarg_new (ExArgDependency, 1);
                   1733:        node->excludes->node = node2;
                   1734:        node->excludes->next = dep;
                   1735: 
                   1736:        return;
                   1737: }
                   1738: 
                   1739: 
                   1740: /** 
                   1741:  * @brief Makes an argument installed to be obligatory (not optional
                   1742:  * at the user command line input).
                   1743:  *
                   1744:  * Once called \ref exarg_install_arg, you can use this function to
                   1745:  * make the program to make the option obligatory.
                   1746:  * 
                   1747:  * @param arg_name The argument to make it obligatory.
                   1748:  */
                   1749: void       exarg_set_obligatory   (char * arg_name)
                   1750: {
                   1751:        ExArgNodeOption * node;
                   1752: 
                   1753:        /* perform some environment checks */
                   1754:        if (arg_name == NULL)
                   1755:                return;
                   1756: 
                   1757:        node = exarg_lookup_node (arg_name);
                   1758:        if (node == NULL) {
                   1759:                return;
                   1760:        }
                   1761: 
                   1762:        /* make it to be defined */
                   1763:        node->is_optional = 0;
                   1764: 
                   1765:        return;
                   1766: }
                   1767: 
                   1768: 
                   1769: /** 
                   1770:  * @brief Allows to configure exarg library to accept or not free
                   1771:  * arguments. 
                   1772:  * 
                   1773:  * Free arguments are optional parameters provided to the application,
                   1774:  * such files, which aren't associated to a particular option.
                   1775:  *
                   1776:  * If your command line application do not uses free arguments, you
                   1777:  * can use this function to enable exarg library to show an error
                   1778:  * message to the user:
                   1779:  *
                   1780:  * \code
                   1781:  * // disable free arguments
                   1782:  * exarg_accept_free_args (0);
                   1783:  * \endcode
                   1784:  * 
                   1785:  * @param accept 1 to accept free arguments. It is the default value,
                   1786:  * so it is not required to enable it. 0 to disable free arguments.
                   1787:  */
                   1788: void         exarg_accept_free_args (int accept)
                   1789: {
                   1790:        /* configure free arguments */
                   1791:        __exarg_disable_free_args = (accept == 0);
                   1792: 
                   1793:        return;
                   1794: }
                   1795: 
                   1796: /** 
                   1797:  * @brief Allows to simulate user defined command line options alread
                   1798:  * installed by \ref exarg_install_arg, without requiring the user to
                   1799:  * set those values.
                   1800:  *
                   1801:  * This function allows to install values received or to just define
                   1802:  * the argument to be supported by the program, without requiring the
                   1803:  * user to provide such option. This is a convenient to make some
                   1804:  * options to be default, writting your application relying on
                   1805:  * arguments defined by command line.
                   1806:  *
                   1807:  * The function won't define the argument if not installed
                   1808:  * previously. If the argument isn't found, the function takes no
                   1809:  * action.
                   1810:  *
                   1811:  * @param arg_name The argument o define as provided by the user.
                   1812:  * @param value The value to be associated to the argument. Some
                   1813:  * arguments doesn't require this paremeters (\ref EXARG_NONE), so,
                   1814:  * you can provide NULL to this parameter.
                   1815:  */
                   1816: void       exarg_define           (char * arg_name,
                   1817:                                   char * value)
                   1818: {
                   1819:        ExArgNodeOption * node;
                   1820: 
                   1821:        /* perform some environment checks */
                   1822:        if (arg_name == NULL)
                   1823:                return;
                   1824: 
                   1825:        node = exarg_lookup_node (arg_name);
                   1826:        if (node == NULL) {
                   1827:                return;
                   1828:        }
                   1829:        /* make it to be defined */
                   1830:        node->is_defined = 1;
                   1831: 
                   1832:        /* check argument value */
                   1833:        if (value != NULL) {
                   1834:                switch (node->type) {
                   1835:                case EXARG_NONE:
                   1836:                        /* nothing to set */
                   1837:                        break;
                   1838:                case EXARG_INT:
                   1839:                        /* integer value */
                   1840:                        node->int_value = strtol (value, NULL, 10);
                   1841:                        break;
                   1842:                case EXARG_STRING:
                   1843:                        /* string value */
                   1844:                        node->string_value = value;
                   1845:                        break;
1.1.1.2 ! misho    1846:                } /* end switch */
1.1       misho    1847:        } /* end if */
                   1848: 
                   1849:        /* nothing to do over here */
                   1850:        return;
                   1851: }
                   1852: 
                   1853: /**
1.1.1.2 ! misho    1854:  * @brief Allows to undef the value associated and the definition
        !          1855:  * itself of the option provided (arg_name).
        !          1856:  *
        !          1857:  * @param arg_name The argument to undef.
        !          1858:  */
        !          1859: void         exarg_undef            (char * arg_name)
        !          1860: {
        !          1861:        ExArgNodeOption * node;
        !          1862: 
        !          1863:        /* perform some environment checks */
        !          1864:        if (arg_name == NULL)
        !          1865:                return;
        !          1866: 
        !          1867:        node = exarg_lookup_node (arg_name);
        !          1868:        if (node == NULL) 
        !          1869:                return;
        !          1870: 
        !          1871:        /* undef the value */
        !          1872:        node->is_defined = 0;
        !          1873: 
        !          1874:        /* check argument value */
        !          1875:        switch (node->type) {
        !          1876:        case EXARG_NONE:
        !          1877:                /* nothing to set */
        !          1878:                break;
        !          1879:        case EXARG_INT:
        !          1880:                /* integer value */
        !          1881:                node->int_value = 0;
        !          1882:                break;
        !          1883:        case EXARG_STRING:
        !          1884:                        /* string value */
        !          1885:                node->string_value = NULL;
        !          1886:                break;
        !          1887:        } /* end switch */
        !          1888: 
        !          1889:        /* nothing to do over here */
        !          1890:        return;
        !          1891: }
        !          1892: 
        !          1893: /**
1.1       misho    1894:  * \brief Allows to check if a user have defined a command.
                   1895:  * 
                   1896:  * Once an argument is installed the user may or may not define it. To
                   1897:  * define it simply means to use this argument as command line
                   1898:  * option. This function allows to check if an argument was used for
                   1899:  * the current command line option.
                   1900:  *
                   1901:  * This function is expecting to receive the argument name to lookup
                   1902:  * not the short name. User may be using the short name to invoke the
                   1903:  * argument but the lookup is allways done by using the argument name.
                   1904:  * 
                   1905:  * \return TRUE if argument was defined or FALSE if not.
                   1906:  **/
                   1907: int   exarg_is_defined   (char     * arg_name)
                   1908: {
                   1909:        ExArgNodeOption * node;
                   1910: 
                   1911:        /* perform some environment checks */
                   1912:        if (arg_name == NULL)
                   1913:                return 0;
                   1914:        
                   1915:        if (argument_options == NULL)
                   1916:                return 0;
                   1917: 
                   1918:        node = exarg_lookup_node (arg_name);
                   1919:        if (node == NULL) {
                   1920:                return 0;
                   1921:        }
                   1922:        return node->is_defined;
                   1923: }
                   1924: 
                   1925: /** 
                   1926:  * @brief Allows to check several values to be defined at the same time.
                   1927:  *
                   1928:  * This allows to check if several command line options have been
                   1929:  * defined at the same time. 
                   1930:  * Example:
                   1931:  * \code
                   1932:  *   if (exarg_is_definedv ("param1", "param2", NULL)) {
                   1933:  *         //param1 and param2 have been defined by the user
                   1934:  *   }
                   1935:  * \endcode
                   1936:  *
                   1937:  * This is a short way for actually doing:
                   1938:  * \code
                   1939:  *  if (exarg_is_defined ("param1") && exarg_is_defined ("param2")) {
                   1940:  *      // param1 and para2 have been defined by the user
                   1941:  *  }
                   1942:  * \endcode
                   1943:  * 
                   1944:  * Do not forget to pass a NULL value for the last item.
                   1945:  * 
                   1946:  * @return TRUE if all values are defined, otherwise FALSE.
                   1947:  */
                   1948: int   exarg_is_definedv      (char * first_value, ...)
                   1949: {
                   1950:        int       result = 1;
                   1951:        char    * string_value;
                   1952:        va_list    args;
                   1953: 
                   1954:        if (first_value == NULL)
                   1955:                return 0;
                   1956: 
                   1957:        /* check first value */
                   1958:        if (!exarg_is_defined (first_value))
                   1959:                return 0;
                   1960: 
                   1961:        /* open stdargs */
                   1962:        va_start        (args, first_value);
                   1963:        string_value = va_arg (args, char *);
                   1964: 
                   1965:        /* check for last NULL value */
                   1966:        while ((string_value != NULL) && (* string_value)) {
                   1967:                /* check next value */
                   1968:                result       = result && exarg_is_defined (string_value);
                   1969: 
                   1970:                /* get next value */
                   1971:                string_value = va_arg (args, char *);
                   1972:        }
                   1973: 
                   1974:        /* return current value */
                   1975:        va_end (args);
                   1976:        return result;
                   1977: }
                   1978: 
                   1979: /**
                   1980:  * \brief Allows to get defined string for a given command line.
                   1981:  * 
                   1982:  * Returns the value associated with the argument name. The returned
                   1983:  * value must not be deallocated. If it is needed a string copy use
                   1984:  * \ref exarg_get_string_alloc.
                   1985:  * 
                   1986:  * \return The value associated with the param or NULL if fail.
                   1987:  **/
                   1988: char    * exarg_get_string   (char     * arg_name)
                   1989: {
                   1990:        ExArgNodeOption * node;
                   1991: 
                   1992:        if (arg_name == NULL)
                   1993:                return NULL;
                   1994:        
                   1995:        if (argument_options == NULL)
                   1996:                return NULL;
                   1997: 
                   1998:        node = exarg_lookup_node (arg_name);
                   1999:        if (node == NULL) {
                   2000:                exarg_msg ("error: calling to get string value for: %s, but this argument isn't defined..",
                   2001:                           arg_name);
                   2002:        }
                   2003:        if (node->type != EXARG_STRING) {
                   2004:                exarg_msg ("error: calling to get string value for: %s, but the argument wasn't defined as EXARG_STRING..",
                   2005:                           arg_name);
                   2006:        }
                   2007:        
                   2008:        return node->string_value;
                   2009: }
                   2010: 
                   2011: /**
                   2012:  * \brief Allows to get defined string for a given command line allocating the result.
                   2013:  * 
                   2014:  * Returns the value associated with the argument name. The returned
                   2015:  * value must be <b>deallocated</b> using g_free. You can also use
                   2016:  * \ref exarg_get_string to get a value that doesn't need to be
                   2017:  * unrefered.
                   2018:  * 
                   2019:  * \return The value associated with the param or NULL if fail.
                   2020:  **/
                   2021: char    * exarg_get_string_alloc (char * arg_name)
                   2022: {
                   2023:        char * string_value;
                   2024: 
                   2025:        string_value = exarg_get_string (arg_name);
                   2026:        if (string_value == NULL)
                   2027:                return NULL;
                   2028:        return exarg_strdup (string_value);
                   2029: }
                   2030: 
                   2031: /**
                   2032:  * \brief Allows to get int value for a given command line argument.
                   2033:  * 
                   2034:  * Returns the value associated with the argument name. The returned
                   2035:  * may be 0 which means the user may not defined that argument or may
                   2036:  * defined it by using the 0 as value. To avoid confusing cases you
                   2037:  * should use \ref exarg_is_defined to know if the user have used that
                   2038:  * argument and then call this function.
                   2039:  * 
                   2040:  * \return the value defined for this argument. If the argument
                   2041:  * is null or the exarg is not initialized the function will return -1.
                   2042:  **/
                   2043: int       exarg_get_int      (char     * arg_name)
                   2044: {
                   2045:        ExArgNodeOption * node;
                   2046: 
                   2047:        if (arg_name == NULL)
                   2048:                return -1;
                   2049:        if (argument_options == NULL)
                   2050:                return -1;
                   2051: 
                   2052:        node = exarg_lookup_node (arg_name);
                   2053:        if (node == NULL) {
                   2054:                exarg_msg ("error: calling to get int value for: %s, but this argument isn't defined..",
                   2055:                           arg_name);
                   2056:        }
                   2057: 
                   2058:        if (node->type != EXARG_INT) {
                   2059:                exarg_msg ("error: calling to get int value for: %s, but the argument wasn't defined as EXARG_INT..",
                   2060:                           arg_name);
                   2061:        }
                   2062:        
                   2063:        return node->int_value;
                   2064: }
                   2065: 
                   2066: /**
                   2067:  * \brief Returns free params defined at command line.
                   2068:  * 
                   2069:  * Every value which is not an argument is considered to be a
                   2070:  * parameter. All of them are stored and retrieved by using this
                   2071:  * function and the following functions:
                   2072:  *
                   2073:  *  - \ref exarg_param_get 
                   2074:  *  - \ref exarg_param_next
                   2075:  *
                   2076:  * An example about using this function could be the next. A program
                   2077:  * have defined several arguments using the function \ref
                   2078:  * exarg_install_arg but that program also needs to receive several
                   2079:  * file path. 
                   2080:  * 
                   2081:  * Once the \ref exarg_parse have detected all argument, all
                   2082:  * parameters are stored, and this function provides access to the
                   2083:  * first argument *found. Then a call to \ref exarg_param_get is
                   2084:  * required to get the *argument value and a call to \ref
                   2085:  * exarg_param_next to get a *reference to the next argument.
                   2086:  * 
                   2087:  *
                   2088:  * A program which may receive the argument --save-all but also several
                   2089:  * files:
                   2090:  *
                   2091:  * \code
                   2092:  *    a_program --save-all file1 file2 file3
                   2093:  * \endcode
                   2094:  *
                   2095:  * Will need to call this function to get the list: file1 file2 and
                   2096:  * file3. 
                   2097:  * 
                   2098:  * \return The first param provided to the program. The returned value
                   2099:  * must not be deallocated.
                   2100:  */
                   2101: ExArgument   * exarg_get_params   ()
                   2102: {
                   2103:        return params;
                   2104: }
                   2105: 
                   2106: /** 
                   2107:  * @brief Allows to get the string value that is represeting the argument received.
                   2108:  * 
                   2109:  * @param arg The argument that was received by the program.
                   2110:  * 
                   2111:  * @return An string reference that must not be deallocated.
                   2112:  */
                   2113: const char * exarg_param_get        (ExArgument * arg)
                   2114: {
                   2115:        /* check for null value received */
                   2116:        if (arg == NULL)
                   2117:                return NULL;
                   2118:        
                   2119:        /* return the string value inside */
                   2120:        return arg->string;
                   2121: }
                   2122: 
                   2123: /** 
                   2124:  * @brief Allows to get the next parameters defined at the command
                   2125:  * line option that is following the argument provided.
                   2126:  * 
                   2127:  * @param arg The argument which is previous to the argument to be
                   2128:  * returned.
                   2129:  * 
                   2130:  * @return An argument reference to the next or NULL if there are no
                   2131:  * more arguments.
                   2132:  */
                   2133: ExArgument * exarg_param_next       (ExArgument * arg)
                   2134: {
                   2135:        /* check for null value received */
                   2136:        if (arg == NULL)
                   2137:                return NULL;
                   2138:        
                   2139:        /* return the next argument */
                   2140:        return arg->next;
                   2141: }
                   2142: 
                   2143: 
                   2144: /** 
                   2145:  * @brief Allows to get the number of parameters that were defined by
                   2146:  * the user. 
                   2147:  *
                   2148:  * Check also the following function \ref exarg_get_params_num.
                   2149:  * 
                   2150:  * @return The number of parameters starting from 0.
                   2151:  */
                   2152: int       exarg_get_params_num   ()
                   2153: {
                   2154:        ExArgument * arg    = NULL;
                   2155:        int          result = 0;
                   2156: 
                   2157:        if (params == NULL)
                   2158:                return 0;
                   2159: 
                   2160:        /* count the number of params */
                   2161:        arg = params;
                   2162:        while (arg != NULL) {
                   2163:                /* update the count */
                   2164:                result++;
                   2165: 
                   2166:                /* update to the next */
                   2167:                arg = arg->next;
                   2168: 
                   2169:        } /* end while */
                   2170: 
                   2171:        /* return current count */
                   2172:        return result;
                   2173: }
                   2174: 
                   2175: /* @} */
                   2176: 

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>