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

1.1       misho       1: /**
                      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 Proto-type declaration to avoid gcc complaining.
                    455:  */
                    456: int vsnprintf(char *str, size_t size, const char *format, va_list ap);
                    457: 
                    458: /** 
                    459:  * @internal Allows to calculate the amount of memory required to
                    460:  * store the string that will representing the construction provided
                    461:  * by the printf-like format received and its arguments.
                    462:  * 
                    463:  * @param format The printf-like format to be printed.
                    464:  *
                    465:  * @param args The set of arguments that the printf applies to.
                    466:  *
                    467:  * <i><b>NOTE:</b> not all printf specification is supported. Generally, the
                    468:  * following is supported: %s, %d, %f, %g, %ld, %lg and all
                    469:  * combinations that provides precision, number of items inside the
                    470:  * integer part, etc: %6.2f, %+2d, etc. An especial case not supported
                    471:  * is %lld, %llu and %llg.</i>
                    472:  *
                    473:  * @return Return the number of bytes that must be allocated to hold
                    474:  * the string (including the string terminator \0). If the format is
                    475:  * not correct or it is not properly formated according to the value
                    476:  * found at the argument set, the function will return -1.
                    477:  */
                    478: int exarg_vprintf_len (const char * format, va_list args)
                    479: {
                    480:        /** IMPLEMENTATION NOTE: in the case this code is update,
                    481:         * update axl_stream_vprintf_len **/
                    482: 
                    483: # if defined (OS_WIN32) && ! defined (__GNUC__)
                    484: #   if HAVE_VSCPRINTF
                    485:        if (format == NULL)
                    486:                return 0;
                    487:        return _vscprintf (format, args) + 1;
                    488: #   else
                    489:        char buffer[8192];
                    490:        if (format == NULL)
                    491:                return 0;
                    492:        return _vsnprintf (buffer, 8191, format, args) + 1;
                    493: #   endif
                    494: #else
                    495:        /* gnu gcc case */
                    496:        if (format == NULL)
                    497:                return 0;
                    498:        return vsnprintf (NULL, 0, format, args) + 1;
                    499: 
                    500: #endif
                    501: }
                    502: 
                    503: 
                    504: 
                    505: /** 
                    506:  * @internal Allows to produce an string representing the message hold by
                    507:  * chunk with the parameters provided.
                    508:  * 
                    509:  * @param chunk The message chunk to print.
                    510:  * @param args The arguments for the chunk.
                    511:  * 
                    512:  * @return A newly allocated string.
                    513:  */
                    514: char  * exarg_strdup_printfv    (char * chunk, va_list args)
                    515: {
                    516:        /** IMPLEMENTATION NOTE: place update axl_stream_printf_buffer
                    517:         * code in the case this code is updated **/
                    518: 
                    519: #ifndef HAVE_VASPRINTF
                    520:        int       size;
                    521: #endif
                    522:        char    * result   = NULL;
                    523:        int       new_size = -1;
                    524: 
                    525:        if (chunk == NULL)
                    526:                return NULL;
                    527: 
                    528: #ifdef HAVE_VASPRINTF
                    529:        /* do the operation using the GNU extension */
                    530:        new_size = vasprintf (&result, chunk, args);
                    531: #else
                    532:        /* get the amount of memory to be allocated */
                    533:        size = exarg_vprintf_len (chunk, args);
                    534: 
                    535:        /* check result */
                    536:        if (size == -1) {
                    537:                printf ("error: unable to calculate the amount of memory for the strdup_printf operation");
                    538:                return NULL;
                    539:        } /* end if */
                    540: 
                    541:        /* allocate memory */
                    542:        result   = exarg_new (char, size + 2);
                    543:        
                    544:        /* copy current size */
                    545: #if defined(OS_WIN32) && ! defined (__GNUC__)
                    546:        new_size = _vsnprintf_s (result, size + 1, size, chunk, args);
                    547: #else
                    548:        new_size = vsnprintf (result, size + 1, chunk, args);
                    549: #endif
                    550: #endif
                    551:        /* return the result */
                    552:        return result;
                    553: }
                    554: 
                    555: /** 
                    556:  * @internal Implementation that allows to produce dinamically
                    557:  * allocated strings using printf-like format.
                    558:  * 
                    559:  * @param chunk The chunk representing the format.
                    560:  * 
                    561:  * @return An dynamically allocated string.
                    562:  */
                    563: char      * exarg_strdup_printf   (char * chunk, ...)
                    564: {
                    565:        char    * result   = NULL;
                    566:        va_list   args;
                    567: 
                    568:        /* return a null value if null chunk is received */
                    569:        if (chunk == NULL)
                    570:                return NULL;
                    571: 
                    572:        /* open std args */
                    573:        va_start (args, chunk);
                    574: 
                    575:        /* get the string */
                    576:        result = exarg_strdup_printfv (chunk, args);
                    577:        
                    578:        /* close std args */
                    579:        va_end (args);
                    580:        
                    581:        return result;
                    582: }
                    583: 
                    584: /** 
                    585:  * @internal Allows to copy the given chunk, supposing that is a
                    586:  * properly format C string that ends with a '\\0' value.
                    587:  *
                    588:  * This function allows to perform a copy for the given string. If a
                    589:  * copy limited by a size is required, use \ref axl_stream_strdup_n.
                    590:  * 
                    591:  * @param chunk The chunk to copy
                    592:  * 
                    593:  * @return A newly allocated string or NULL if fails.
                    594:  */
                    595: char      * exarg_strdup          (char * chunk)
                    596: {
                    597:        char * result;
                    598:        int    length;
                    599: 
                    600:        /* do not copy if null reference is received */
                    601:        if (chunk == NULL)
                    602:                return NULL;
                    603: 
                    604:        length = strlen (chunk);
                    605:        result = exarg_new (char, length + 1);
                    606:        
                    607:        memcpy (result, chunk, length);
                    608: 
                    609:        return result;
                    610: }
                    611: 
                    612: /** 
                    613:  * @internal Internal function that allows to dealloc the provided array of chunks.
                    614:  * 
                    615:  * @param chunks An array containing pointers to chunks.
                    616:  */
                    617: void        exarg_freev           (char ** chunks)
                    618: {
                    619:        int iterator = 0;
                    620: 
                    621:        /* return if the received reference is null */
                    622:        if (chunks == NULL)
                    623:                return;
                    624:         
                    625:        /* release memory used by all elements inside the chunk */
                    626:        while (chunks[iterator] != 0) {
                    627:                exarg_free (chunks[iterator]);
                    628:                iterator++;
                    629:        }
                    630:        
                    631:        /* now release the chunk inside */
                    632:        exarg_free (chunks);
                    633:        
                    634:        /* nothing more to do */
                    635:        return;
                    636: }
                    637: 
                    638: 
                    639: /** 
                    640:  * @internal Adds the argument to the current argument list.
                    641:  * 
                    642:  * @param argument The argument to add.
                    643:  */
                    644: void __exarg_add_argument (char * argument)
                    645: {
                    646:        ExArgument * arg;
                    647:        ExArgument * arg2;
                    648: 
                    649:        /* creates the node */
                    650:        arg         = exarg_new (ExArgument, 1);
                    651:        arg->string = argument;
                    652: 
                    653:        if (params == NULL) {
                    654:                /* basic case, only one argument */
                    655:                params = arg;
                    656:                
                    657:                return;
                    658:        } /* end if */
                    659: 
                    660:        /* complex case, lookup for the last node */
                    661:        arg2 = params;
                    662:        while (arg2->next != NULL)
                    663:                arg2 = arg2->next;
                    664: 
                    665:        /* set the argument on the last position */
                    666:        arg2->next = arg;
                    667: 
                    668:        return;
                    669: }
                    670: 
                    671: /**
                    672:  * @internal
                    673:  * @brief Perfom a look up inside the argument option installed.
                    674:  *
                    675:  * This function tries to return the ExArgNodeOption using the given
                    676:  * value as index key. 
                    677:  *
                    678:  * The given value can represent the long key option or the short
                    679:  * form.
                    680:  * 
                    681:  * @param arg_name the key to use on lookup process
                    682:  *
                    683:  * @return the function retuns the argument option if found or NULL if
                    684:  * not.
                    685:  */
                    686: ExArgNodeOption * exarg_lookup_node (const char * arg_name)
                    687: {
                    688:        ExArgNodeOption * result      = NULL;
                    689:        int               arg_name_len;
                    690: 
                    691:        /* check for null value */
                    692:        if (arg_name == NULL)
                    693:                return NULL;
                    694: 
                    695:        /* get length */
                    696:        arg_name_len = strlen (arg_name);
                    697: 
                    698:        /* look up the item on the current argument option */
                    699:        result = argument_options;
                    700:        while (result != NULL) {
                    701: 
                    702:                /* check value with long argument form */
                    703:                if (arg_name_len == strlen (result->arg_name) &&
                    704:                    !memcmp (arg_name, result->arg_name, strlen (arg_name))) {
                    705: 
                    706:                        /* return found node */
                    707:                        return result;
                    708:                }
                    709:                
                    710:                /* check value with short argument form */
                    711:                if ((result->arg_short_name != NULL) && 
                    712:                    (arg_name_len == strlen (result->arg_short_name)) &&
                    713:                    !memcmp (arg_name, result->arg_short_name, strlen (arg_name))) {
                    714: 
                    715:                        /* return node found */
                    716:                        return result;
                    717:                }
                    718:                
                    719:                /* update to the next item */
                    720:                result = result->next;
                    721: 
                    722:        } /* end while */
                    723: 
                    724:        /* return that we didn't found an item */
                    725:        return result;
                    726:        
                    727: } /* end exarg_lookup_node */
                    728: 
                    729: 
                    730: 
                    731: 
                    732: int exarg_is_argument (char * argument) 
                    733: {
                    734: 
                    735:        int iterator = 1;
                    736: 
                    737:        /* support standard unix format definition */
                    738:        if (CHECK_PARSE_MODE (PARSE_MODE_UNIX) && !memcmp (argument, "--", 2)) {
                    739: 
                    740:                /* update parse mode */
                    741:                UPDATE_PARSE_MODE (PARSE_MODE_UNIX);
                    742:                return 1;
                    743:        }
                    744: 
                    745:        /* support sort argument format definition */
                    746:        if (CHECK_PARSE_MODE (PARSE_MODE_UNIX) && (strlen (argument) == 2) && (argument[0] == '-')) {
                    747: 
                    748:                /* update parse mode */
                    749:                UPDATE_PARSE_MODE (PARSE_MODE_UNIX);
                    750: 
                    751:                return 1;
                    752:        }
                    753:        
                    754:        /* support windows argument format */
                    755:        if (CHECK_PARSE_MODE (PARSE_MODE_WINDOWS) && (strlen (argument) > 2) && (argument[0] == '/')) {
                    756: 
                    757:                /* now check if the argument doesn't have more bars */
                    758:                while (argument[iterator] != 0) {
                    759:                        /* check value */
                    760:                        if (argument[iterator] == '/')
                    761:                                return 0;
                    762: 
                    763:                        /* update iterator */
                    764:                        iterator++;
                    765:                        
                    766:                } /* end while */
                    767: 
                    768:                /* update parse mode */
                    769:                UPDATE_PARSE_MODE (PARSE_MODE_WINDOWS);
                    770:                
                    771:                return 1;
                    772:        }
                    773: 
                    774:        return 0;
                    775: }
                    776: 
                    777: char * exarg_get_argument (char * argument)
                    778: {
                    779:        /* support getting the argument value for unix standard
                    780:         * argument */
                    781:        if (!memcmp (argument, "--", 2))
                    782:                return &(argument[2]);
                    783:        
                    784:        /* support getting the argument value for short def */
                    785:        if ((strlen (argument) == 2) && (argument[0] == '-'))
                    786:                return &(argument[1]);
                    787: 
                    788:        /* support getting the argument value for windows def */
                    789:        if ((strlen (argument) > 2) && (argument[0] == '/'))
                    790:                return &(argument[1]);
                    791: 
                    792:        return NULL;
                    793: }
                    794: 
                    795: int exarg_check_help_argument (char * argument)
                    796: {
                    797:        if (!memcmp (argument, "help", 4) || !memcmp (argument, "?", 1))
                    798:                return 1;
                    799:        return 0;
                    800: }
                    801: 
                    802: void     exarg_wrap_and_print (const char * text, int size_to_wrap, const char * fill_text)
                    803: {
                    804:        char    ** stringv      = NULL;
                    805:        int        i            = 0;
                    806:        int        sum          = 0;
                    807:        char     * working_line = NULL;
                    808:        char     * aux_string   = NULL;
                    809:        int        first_line   = 1;
                    810: 
                    811:        /* do not print anything if a null value is received */
                    812:        if (text == NULL)
                    813:                return;
                    814: 
                    815:        if (strlen (text) <= size_to_wrap) {
                    816:                printf ("%s\n", text);
                    817:                return;
                    818:        }
                    819: 
                    820:        stringv = exarg_split (text, 1, " ");
                    821:        for (i = 0; stringv[i]; i++) {
                    822:                if (working_line) {
                    823:                        aux_string   = working_line;
                    824:                        working_line = exarg_strdup_printf ("%s %s", working_line, stringv[i]);
                    825:                        exarg_free (aux_string);
                    826:                }else
                    827:                        working_line = exarg_strdup (stringv[i]);
                    828:                sum = sum + strlen (stringv[i]) + 1;
                    829: 
                    830:                if (sum >= size_to_wrap) {
                    831:                        sum = 0;
                    832:                        if (first_line) {
                    833:                                first_line = 0;
                    834:                                printf ("%s\n", working_line);
                    835:                        }else
                    836:                                printf ("%s%s\n", fill_text, working_line);
                    837:                        exarg_free (working_line);
                    838:                        working_line = NULL;
                    839:                }
                    840: 
                    841:        }
                    842:        if (sum) {
                    843:                printf ("%s%s\n", fill_text, working_line);
                    844:                exarg_free (working_line);
                    845:        }
                    846:        exarg_freev (stringv);
                    847:        
                    848:        
                    849:        return;
                    850: }
                    851: 
                    852: void __exarg_show_usage_foreach (epointer key, epointer value, epointer user_data)
                    853: {
                    854:        char            ** string_aux = (char **) user_data;
                    855:        char             * str        = (* string_aux);
                    856:        char             * aux        = NULL;
                    857:        ExArgNodeOption  * node       = (ExArgNodeOption  *) value;
                    858: 
                    859:        switch (node->type) {
                    860:        case EXARG_NONE:
                    861:                if (node->arg_short_name)
                    862:                        (*string_aux) = exarg_strdup_printf (" [-%s|--%s]", node->arg_short_name, node->arg_name);
                    863:                else
                    864:                        (*string_aux) = exarg_strdup_printf (" [--%s]", node->arg_name);
                    865:                break;
                    866:        case EXARG_INT:
                    867:                if (node->arg_short_name)
                    868:                        (*string_aux) = exarg_strdup_printf (" [-%s <number>|--%s <number>]", node->arg_short_name, node->arg_name);
                    869:                else
                    870:                        (*string_aux) = exarg_strdup_printf (" [--%s <number>]", node->arg_name);
                    871:                break;
                    872:        case EXARG_STRING:
                    873:                if (node->arg_short_name)
                    874:                        (*string_aux) = exarg_strdup_printf (" [-%s <string>|--%s <string>]", node->arg_short_name, node->arg_name);
                    875:                else
                    876:                        (*string_aux) = exarg_strdup_printf (" [--%s <string>]", node->arg_name);
                    877:                break;
                    878:        } /* end switch */
                    879: 
                    880:        if (str != NULL) {
                    881:                /* get a reference to previous content */
                    882:                aux           = (* string_aux);
                    883:                (*string_aux) = exarg_strdup_printf ("%s%s", str, (*string_aux));
                    884:                
                    885:                /* dealloc both pieces that joined are the result */
                    886:                exarg_free (str);
                    887:                exarg_free (aux);
                    888:        }
                    889:        return;
                    890: }
                    891: 
                    892: void exarg_show_usage (int show_header)
                    893: {
                    894:        char            * string_aux = NULL;
                    895:        ExArgNodeOption * node;
                    896:        
                    897:        if (show_header && (__exarg_usage_header && (* __exarg_usage_header)))
                    898:                printf (__exarg_usage_header);
                    899: 
                    900:        printf ("Usage: %s ", exarg_exec_name);
                    901:        
                    902:        /* get the first node */
                    903:        node = argument_options;
                    904:        while (node != NULL) {
                    905:                /* call to the foreach function */
                    906:                __exarg_show_usage_foreach ((epointer) node->arg_name, node, &string_aux);
                    907:                
                    908:                /* update to the next */
                    909:                node = node->next;
                    910:                
                    911:        } /* end while */
                    912: 
                    913:        exarg_wrap_and_print (string_aux, 55, "               ");
                    914:        printf ("\n");
                    915: 
                    916:        /* free string created */
                    917:        exarg_free (string_aux);
                    918: 
                    919:        if (show_header && (__exarg_post_usage_header && (* __exarg_post_usage_header)))
                    920:                printf (__exarg_post_usage_header);
                    921:        
                    922:        return;
                    923: }
                    924: 
                    925: char * __exarg_build_dep_string (ExArgNodeOption * node, int exclude)
                    926: {
                    927:        char            * result;
                    928:        char            * aux;
                    929:        ExArgDependency * dep;
                    930: 
                    931:        /* check node dependency */
                    932:        if (!exclude && ! node->depends)
                    933:                return NULL;
                    934:        if (exclude && ! node->excludes)
                    935:                return NULL;
                    936: 
                    937:        if (exclude) 
                    938:                result = exarg_strdup ("[excludes: ");
                    939:        else
                    940:                result = exarg_strdup ("[depends on: ");
                    941:        
                    942:        /* foreach each dependency configured */
                    943:        if (exclude)
                    944:                dep    = node->excludes;
                    945:        else
                    946:                dep    = node->depends;
                    947:        while (dep != NULL) {
                    948: 
                    949:                aux    = result;
                    950:                if (dep->next != NULL)
                    951:                        result = exarg_strdup_printf ("%s --%s", result, dep->node->arg_name);
                    952:                else
                    953:                        result = exarg_strdup_printf ("%s --%s]", result, dep->node->arg_name);
                    954:                exarg_free (aux);
                    955:                
                    956:                /* get next dependency */
                    957:                dep = dep->next;
                    958: 
                    959:        } /* end while */
                    960: 
                    961:        /* return string created */
                    962:        return result;
                    963: }
                    964: 
                    965: void __exarg_show_help_foreach (epointer key, epointer value, epointer user_data)
                    966: {
                    967:        ExArgNodeOption * node = (ExArgNodeOption  *) value;
                    968:        char            * dep;
                    969:        int               chars = 35;
                    970:        int               iterator = 0;
                    971:        
                    972:        /* print argument help */
                    973:        if (node->arg_short_name) {
                    974:                printf ("  -%s, --%-18s       ", 
                    975:                        node->arg_short_name, node->arg_name);
                    976:                exarg_wrap_and_print (node->description, 40, "                                 ");
                    977: 
                    978:        }else {
                    979:                printf ("  --%-22s       ", node->arg_name);
                    980:                exarg_wrap_and_print (node->description, 40, "                                 ");
                    981:        }
                    982: 
                    983:        /* print argument dependency */
                    984:        dep = __exarg_build_dep_string (node, 0);
                    985:        if (dep != NULL) {
                    986:                /* write spaces */
                    987:                while (iterator < chars) {
                    988:                        printf (" ");
                    989:                        iterator++;
                    990:                }
                    991:                exarg_wrap_and_print (dep, 40, "                                 ");
                    992:        }
                    993:        exarg_free (dep);
                    994: 
                    995:        /* print argument exclusion */
                    996:        iterator = 0;
                    997:        dep      = __exarg_build_dep_string (node, 1);
                    998:        if (dep != NULL) {
                    999:                /* write spaces */
                   1000:                while (iterator < chars) {
                   1001:                        printf (" ");
                   1002:                        iterator++;
                   1003:                }
                   1004:                exarg_wrap_and_print (dep, 40, "                                 ");
                   1005:        }
                   1006:        exarg_free (dep);
                   1007:        return;
                   1008: }
                   1009: 
                   1010: void   exarg_show_help () 
                   1011: {
                   1012:        ExArgNodeOption * node;
                   1013: 
                   1014:        if (__exarg_help_header && (* __exarg_help_header))
                   1015:                printf (__exarg_help_header);
                   1016: 
                   1017:        exarg_show_usage (0);
                   1018: 
                   1019:        printf ("\nCommand options:\n");
                   1020: 
                   1021:        /* get first node */
                   1022:        node = argument_options;
                   1023:        while (node != NULL) {
                   1024:                /* call to show the node information */
                   1025:                __exarg_show_help_foreach ((epointer) node->arg_name, node, NULL);
                   1026: 
                   1027:                /* update to the next node */
                   1028:                node = node->next;
                   1029:        } /* end while */
                   1030: 
                   1031:        printf ("\nHelp options:\n");
                   1032:        printf ("  -?, --help                    Show this help message.\n");
                   1033:        printf ("  --usage                       Display brief usage message.\n");
                   1034: 
                   1035:        if (__exarg_post_help_header && (* __exarg_post_help_header))
                   1036:                printf (__exarg_post_help_header);
                   1037: 
                   1038:        return;
                   1039: }
                   1040: 
                   1041: void exarg_check_argument_value (char ** argv, int iterator) 
                   1042: {
                   1043: 
                   1044:        if (argv[iterator] == NULL) {
                   1045:                printf ("error: not defined value for argument: %s, exiting..",
                   1046:                        argv[iterator - 1]);
                   1047:                fflush (stdout);
                   1048:                exit (-1);
                   1049:        }
                   1050: 
                   1051:        if (exarg_is_argument (argv[iterator])) {
                   1052:                printf ("error: not defined value for argument: %s, instead found another argument: %s, exiting..",
                   1053:                        argv[iterator - 1],
                   1054:                        argv[iterator]);
                   1055:                fflush (stdout);
                   1056:                exit (-1);
                   1057:        }
                   1058: 
                   1059:        return;
                   1060: }
                   1061: 
                   1062: 
                   1063: void __exarg_parse_check_non_optional ()
                   1064: {
                   1065:        ExArgNodeOption * node = argument_options;
                   1066: 
                   1067:        /* for each node */
                   1068:        while (node != NULL) {
                   1069:                /* check the node */
                   1070:                if (! node->is_optional && ! node->is_defined) {
                   1071:                        exarg_msg ("error: argument '%s' is not defined, but it is required for a proper function..\n",
                   1072:                                   node->arg_name);
                   1073:                } /* end if */
                   1074: 
                   1075:                /* get the next */
                   1076:                node = node->next;
                   1077: 
                   1078:        } /* end while */
                   1079: 
                   1080:        return;
                   1081: }
                   1082: 
                   1083: void __exarg_parse_check_depends ()
                   1084: {
                   1085:        /* first argument */
                   1086:        ExArgNodeOption * node = argument_options;
                   1087:        ExArgDependency * dep;
                   1088: 
                   1089:        /* for each argument defined */
                   1090:        while (node != NULL) {
                   1091: 
                   1092:                /* check if the argument was defined, and hence
                   1093:                 * activates its dependencies */
                   1094:                if (! node->is_defined) {
                   1095:                        node = node->next;
                   1096:                        continue;
                   1097:                }
                   1098: 
                   1099:                /* check depends */
                   1100:                dep = node->depends;
                   1101:                while (dep != NULL) {
                   1102: 
                   1103:                        /* check that the dependency is defined */
                   1104:                        if (! dep->node->is_defined) {
                   1105:                                exarg_msg ("You must define argument (--%s) if used (--%s). Try %s --help.", 
                   1106:                                           dep->node->arg_name, node->arg_name, exarg_exec_name);
                   1107:                                return;
                   1108:                        } /* end if */
                   1109: 
                   1110:                        /* get next dependency */
                   1111:                        dep = dep->next;
                   1112:                        
                   1113:                } /* end while */
                   1114: 
                   1115:                /* check depends */
                   1116:                dep = node->excludes;
                   1117:                while (dep != NULL) {
                   1118:                        
                   1119:                        /* check that the dependency is defined */
                   1120:                        if (dep->node->is_defined) {
                   1121:                                printf ("You can't define argument (--%s) if used (--%s). Try %s --help.\n", 
                   1122:                                        node->arg_name, dep->node->arg_name, exarg_exec_name);
                   1123:                                fflush (stdout);
                   1124:                                return;
                   1125:                        } /* end if */
                   1126: 
                   1127:                        /* get next dependency */
                   1128:                        dep = dep->next;
                   1129:                        
                   1130:                } /* end while */
                   1131: 
                   1132:                /* get next node */
                   1133:                node = node->next;
                   1134:  
                   1135:        } /* end whle */
                   1136: 
                   1137:        /* nothing more to check */
                   1138:        return;
                   1139: }
                   1140: 
                   1141: 
                   1142: /** 
                   1143:  * \brief Makes exarg to start parsing argument options.
                   1144:  *
                   1145:  * Makes LibExArg to start command line parsing by using arguments
                   1146:  * installed. 
                   1147:  * 
                   1148:  * Once this functions is called it is posible to call the set of
                   1149:  * function which returns data obtained: \ref exarg_is_defined,
                   1150:  * \ref exarg_get_int, \ref exarg_get_string and \ref exarg_get_params.
                   1151:  *
                   1152:  * The advantage is that LibExArg allows you to get access to command
                   1153:  * line data from any point of your program.
                   1154:  * 
                   1155:  * @param argc the argc value the current application have received.
                   1156:  * @param argv the argv value the current application have received.
                   1157:  */
                   1158: void       exarg_parse         (int         argc,
                   1159:                                char     ** argv)
                   1160: {
                   1161:        int              iterator = 1;
                   1162:        ExArgNodeOption * node;
                   1163:        char           * argument;
                   1164: 
                   1165:        /* check how many argument have been defined */
                   1166:        if (iterator == argc) {
                   1167:                /* once terminated, check if the non optional options
                   1168:                 * were defined */
                   1169:                
                   1170:                __exarg_parse_check_non_optional ();
                   1171:                return;
                   1172:        }
                   1173: 
                   1174:        exarg_exec_name = exarg_basename (argv[0]);
                   1175:        
                   1176:        /* iterate over all arguments */
                   1177:        while (iterator < argc) {
                   1178: 
                   1179:                if (!exarg_is_argument (argv[iterator])) {
                   1180:                        /* check free argument configuration */
                   1181:                        if (__exarg_disable_free_args) {
                   1182:                                exarg_msg ("error: provided a free argument='%s', not listed in the accept command line option", argv[iterator]);
                   1183: 
                   1184:                        } /* end if */
                   1185: 
                   1186:                        /* save and increase iterator */
                   1187:                        __exarg_add_argument (argv[iterator]);
                   1188:                        iterator++;
                   1189:                        continue;
                   1190:                }
                   1191:                
                   1192:                /* get clean argument */
                   1193:                argument = exarg_get_argument (argv[iterator]);
                   1194: 
                   1195:                /* check for help argument */
                   1196:                if (exarg_check_help_argument (argument)){
                   1197:                        exarg_show_help ();
                   1198:                        exarg_end ();
                   1199:                        exit (0);
                   1200:                }
                   1201:                
                   1202:                /* check for usage argument */
                   1203:                if (!memcmp (argument, "usage", 5)) {
                   1204:                        exarg_show_usage (1);
                   1205:                        exarg_end ();
                   1206:                        exit (0);
                   1207:                }
                   1208: 
                   1209:                /* get node argument */
                   1210:                node = exarg_lookup_node (argument);
                   1211:                if (node == NULL) {
                   1212:                        exarg_msg ("%s error: argument not found: %s, try: %s --help\n",
                   1213:                                   exarg_exec_name, argv[iterator], exarg_exec_name);
                   1214:                }
                   1215:                
                   1216:                /* check if node is defined */
                   1217:                if (node->is_defined) {
                   1218:                        exarg_msg ("%s error: argument %s already defined, exiting..\n",
                   1219:                                   exarg_exec_name, argv[iterator]);
                   1220:                }
                   1221: 
                   1222:                
                   1223:                /* set this argument to be defined */
                   1224:                node->is_defined = 1;
                   1225:                switch (node->type) {
                   1226:                case EXARG_NONE:
                   1227:                        /* nothing to do */ 
                   1228:                                break;
                   1229:                case EXARG_INT:
                   1230:                        /* save int value */
                   1231:                        iterator++;
                   1232: 
                   1233:                        exarg_check_argument_value (argv, iterator);
                   1234: 
                   1235:                        node->int_value    = atoi (argv[iterator]);
                   1236:                        break;
                   1237:                case EXARG_STRING:
                   1238:                        iterator++;
                   1239:                        
                   1240:                        exarg_check_argument_value (argv, iterator);
                   1241: 
                   1242:                        node->string_value = argv[iterator];
                   1243: 
                   1244:                        break;
                   1245:                }
                   1246:                
                   1247:                /* update iterator */
                   1248:                iterator++;
                   1249:        }
                   1250: 
                   1251:        /* once terminated, check if the non optional options were
                   1252:         * defined */
                   1253:        __exarg_parse_check_non_optional ();
                   1254: 
                   1255:        /* check argument dependency and argument mutual exclusion. */
                   1256:        __exarg_parse_check_depends ();
                   1257: 
                   1258:        return;
                   1259: }
                   1260: 
                   1261: void __exarg_end_free_dep (ExArgDependency * dep)
                   1262: {
                   1263:        ExArgDependency * next;
                   1264: 
                   1265:        /* foreach dependency established */
                   1266:        while (dep != NULL) {
                   1267: 
                   1268:                /* free the dep node */
                   1269:                next = dep->next;
                   1270:                exarg_free (dep);
                   1271:                dep  = next;
                   1272:        } /* end while */
                   1273: 
                   1274:        return;
                   1275: }
                   1276: 
                   1277: /**
                   1278:  * \brief Ends exarg library execution.
                   1279:  * 
                   1280:  * Terminates the exarg function. This function will free all
                   1281:  * resources allocated so the library cannot be used any more for the
                   1282:  * current execution.
                   1283:  *
                   1284:  * This function is reatrant. Several threads can actually call this
                   1285:  * function. It will take care about making only one thread to
                   1286:  * actually free resources.
                   1287:  **/
                   1288: void       exarg_end           ()
                   1289: {
                   1290:        ExArgNodeOption * node;
                   1291:        ExArgNodeOption * node2;
                   1292:        
                   1293:        ExArgument      * params2;
                   1294:        
                   1295: 
                   1296:        if (argument_options != NULL) {
                   1297:                /* get a reference to the table, and dealloc it */
                   1298:                node             = argument_options;
                   1299:                argument_options = NULL;
                   1300:                
                   1301:                while (node != NULL) {
                   1302:                        /* get a reference to the next */
                   1303:                        node2 = node->next;
                   1304: 
                   1305:                        /* free node arguments dependencies and mutual
                   1306:                         * exclusions */
                   1307:                        __exarg_end_free_dep (node->depends);
                   1308:                        __exarg_end_free_dep (node->excludes);
                   1309: 
                   1310:                        /* free current node */
                   1311:                        exarg_free (node);
                   1312:                        
                   1313:                        /* update the node ref */
                   1314:                        node = node2;
                   1315:                } /* end while */
                   1316: 
                   1317:        } /* end if */
                   1318: 
                   1319:        if (params != NULL) {
                   1320:                while (params != NULL) {
                   1321:                        /* get a reference to the next node */
                   1322:                        params2 = params->next;
                   1323: 
                   1324:                        /* free params node */
                   1325:                        exarg_free (params);
                   1326: 
                   1327:                        /* configure the next argument to dealloc */
                   1328:                        params = params2;
                   1329:                } /* end while */
                   1330:        } /* end if */
                   1331: 
                   1332:        return;
                   1333: }
                   1334: 
                   1335: /**
                   1336:  * \brief Disable autohelp.
                   1337:  * 
                   1338:  * Allows to disable auto help and --help and -? option
                   1339:  * recognition. This is useful if you don't want your program to
                   1340:  * accept --help and --usage options.
                   1341:  **/
                   1342: void       exarg_disable_help ()
                   1343: {
                   1344:        return;
                   1345: }
                   1346: 
                   1347: /**
                   1348:  * \brief Adds user defined header to automatic usage command generated.
                   1349:  * 
                   1350:  * Once a program is linked to libexarg is able to produce a usage
                   1351:  * help by accepting the --usage command line option. But that usage
                   1352:  * help is showed as is. This function allows you to define a header
                   1353:  * to be showed preceding the usage info. You can use this, for
                   1354:  * example, to introduce your copyright.
                   1355:  *
                   1356:  * This function doesn't make a copy of the given string so you
                   1357:  * must not free the header provided or use an static string.
                   1358:  **/
                   1359: void       exarg_add_usage_header (char * header)
                   1360: {
                   1361:        __exarg_usage_header = header;
                   1362: }
                   1363: 
                   1364: /**
                   1365:  * \brief Adds user defined header to automatic help command generated.
                   1366:  * 
                   1367:  * Once a program is linked to libexarg is able to produce a help by
                   1368:  * accepting the --help or -? command line option. But that help is
                   1369:  * showed as is. This function allows you to define a header to be
                   1370:  * showed preceding the help info. You can use this, for example, to
                   1371:  * introduce your copyright.
                   1372:  *
                   1373:  * This function doesn't make a copy of the given string so you
                   1374:  * must not free the header provided or use an static string.
                   1375:  **/
                   1376: void       exarg_add_help_header  (char * header)
                   1377: {
                   1378:        __exarg_help_header = header;
                   1379: }
                   1380: 
                   1381: /**
                   1382:  * \brief Adds user defined post header for usage command.
                   1383:  * 
                   1384:  * This function works pretty much like \ref exarg_add_usage_header but
                   1385:  * adding the header provided to be appended at the end of the usage
                   1386:  * automatically generated.
                   1387:  **/
                   1388: void       exarg_post_usage_header (char * post_header)
                   1389: {
                   1390:        __exarg_post_usage_header = post_header;
                   1391: }
                   1392: 
                   1393: /**
                   1394:  * \brief Adds user defined post header for help command.
                   1395:  * 
                   1396:  * This function works pretty much like \ref exarg_add_help_header but
                   1397:  * adding the header provided to be appended at the end of the help
                   1398:  * automatically generated.
                   1399:  **/
                   1400: void       exarg_post_help_header (char * post_header)
                   1401: {
                   1402:        __exarg_post_help_header = post_header;
                   1403: }
                   1404: 
                   1405: /**
                   1406:  * \internal
                   1407:  * Internal ExArg function. This function allows \ref exarg_install_arg to
                   1408:  * check if there are already installed an short argument as the one
                   1409:  * been installed.
                   1410:  **/
                   1411: void __exarg_check_short_arg (epointer key, epointer value, epointer user_data)
                   1412: {
                   1413:        ExArgNodeOption * node         = (ExArgNodeOption  *) value;
                   1414:        char           * arg_to_check = (char *) user_data;
                   1415: 
                   1416:        if (node->arg_short_name != NULL) {
                   1417:                if (!memcmp (node->arg_short_name, arg_to_check, strlen (arg_to_check))) {
                   1418:                        exarg_msg ("error: found that short arg installed is already found: %s\n", arg_to_check);
                   1419:                } /* end if */
                   1420:        } /* end if */
                   1421: 
                   1422:        return;
                   1423: }
                   1424: 
                   1425: /**
                   1426:  * \brief Installs a new command line to be accepted.
                   1427:  * 
                   1428:  * This functions allows you to install new arguments to be
                   1429:  * accepted. Every argument passed in to the program which is not
                   1430:  * installed throught this function will no be accepted and will
                   1431:  * generate a non recognized command line error.
                   1432:  *
                   1433:  * Let's see an example on how to use exarg to install the --version
                   1434:  * argument. You should call exarg as follows:
                   1435:  * 
                   1436:  * \code
                   1437:  *       exarg_install_arg ("version", "v", EXARG_NONE, 
                   1438:  *                          "show program version");
                   1439:  *
                   1440:  * \endcode
                   1441:  * 
                   1442:  * Previous line have installed a argument called "version" which will
                   1443:  * be invoked by the user as --version. The short alias
                   1444:  * in this case is "v" which as we have see will allow user to invoke
                   1445:  * your program as -v.
                   1446:  *
                   1447:  * Because you could install arguments which may conflict, this
                   1448:  * function will abort the program execution on that case. This will
                   1449:  * ensure you, as programer, to have a binary compiled with no
                   1450:  * problems due to exarg.
                   1451:  *
                   1452:  * Later on, you can use \ref exarg_is_defined to check the status of
                   1453:  * installed arguments. Once you install an argument the user may
                   1454:  * invoke it and you could check that status using previous
                   1455:  * function. Because the "version" argument type is \ref EXARG_NONE you can
                   1456:  * only use \ref exarg_is_defined. But, for other argument types as
                   1457:  * \ref EXARG_STRING, you can also use \ref exarg_get_string function to get the
                   1458:  * value defined by user. Let's see an example.
                   1459:  *
                   1460:  * \code
                   1461:  *       exarg_install_arg ("load-library", "l", EXARG_STRING,
                   1462:  *                          "loads the library defined as argument");
                   1463:  * \endcode
                   1464:  * 
                   1465:  * This previous line will allow user to invoke your program as 
                   1466:  * --load-library path/to/lib. Then you can use \ref exarg_get_string to get
                   1467:  * the path/to/lib value by using:
                   1468:  * 
                   1469:  * \code
                   1470:  *       // check user have defined this argument
                   1471:  *       if (exarg_is_defined ("load-library")) {
                   1472:  *
                   1473:  *             arg_value = exarg_get_string ("load-library");
                   1474:  *
                   1475:  *             printf ("The library defined by user was: %s\n", 
                   1476:  *                      arg_value);
                   1477:  *       }
                   1478:  * 
                   1479:  * \endcode
                   1480:  *
                   1481:  * You must install all argument before calling \ref exarg_parse. That function
                   1482:  * will parse argument options by using installed arguments. Check the info
                   1483:  * about that function.
                   1484:  * 
                   1485:  * ExArg is not thread-safe which doesn't means anything wrong but you
                   1486:  * must call all exarg function from the same thread to get the right
                   1487:  * results. 
                   1488:  *
                   1489:  * This function will not do a copy from arg_name, arg_short_name or
                   1490:  * description. This means you should not free that values while
                   1491:  * using exarg. To end exarg using check \ref exarg_end. It is recomended to use
                   1492:  * static values and shows on previous examples.
                   1493:  **/
                   1494: void       exarg_install_arg  (const char     * arg_name, 
                   1495:                               const char     * arg_short_name, 
                   1496:                               ExArgType   type,
                   1497:                               const char     * description)
                   1498: {
                   1499:        ExArgNodeOption * node;
                   1500:        ExArgNodeOption * node2;
                   1501: 
                   1502:        /* init hash table */
                   1503:        if (argument_options != NULL) {
                   1504:                /* check if there are an argument with the same name */
                   1505:                if (exarg_lookup_node (arg_name)) {
                   1506:                        exarg_end ();
                   1507:                        exarg_msg ("error: argument being installed is already defined: %s..",
                   1508:                                   arg_name);
                   1509:                }
                   1510:                
                   1511:                /* check if there are an shor argument with the same
                   1512:                 * name */
                   1513:                if (arg_short_name != NULL) {
                   1514:                        node = argument_options;
                   1515:                        
                   1516:                        /* while there are options to process */
                   1517:                        while (node != NULL) {
                   1518:                                /* call to check */
                   1519:                                __exarg_check_short_arg ((epointer) node->arg_name, node, (epointer) arg_short_name);
                   1520: 
                   1521:                                /* update to the next */
                   1522:                                node = node->next;
                   1523:                        } /* end while */
                   1524:                } /* end if */
                   1525:        } /* end if */
                   1526:                
                   1527:        /* create node option */
                   1528:        node                 = exarg_new (ExArgNodeOption, 1);
                   1529:        node->arg_name       = arg_name;
                   1530:        node->arg_short_name = arg_short_name;
                   1531:        node->type           = type;
                   1532:        node->description    = description;
                   1533:        node->is_optional    = 1;
                   1534: 
                   1535:        /* lookup for the last position */
                   1536:        if (argument_options == NULL)
                   1537:                argument_options = node;
                   1538:        else {
                   1539:                /* lookup for the last */
                   1540:                node2 = argument_options;
                   1541:                while (node2->next != NULL)
                   1542:                        node2 = node2->next;
                   1543: 
                   1544:                /* set it */
                   1545:                node2->next = node;
                   1546:        } /* end if */
                   1547: 
                   1548:        return;
                   1549: }
                   1550: 
                   1551: /**
                   1552:  * \brief Installs several command lines to be accepted.
                   1553:  * 
                   1554:  * This function does the same that \ref exarg_install_arg but making 
                   1555:  * group of argument to be installed in one step.
                   1556:  *
                   1557:  * Think about installing two argument. To install them we have to do
                   1558:  * the following:
                   1559:  *
                   1560:  * \code
                   1561:  *    exarg_install_arg ("version", "v", 
                   1562:  *                       EXARG_NONE, "show argument version");
                   1563:  *    exarg_install_arg ("load-library", "l", 
                   1564:  *                       EXARG_STRING, "load my library");
                   1565:  * \endcode
                   1566:  *
                   1567:  * Because some people doesn't like to perform several calls to the
                   1568:  * same funcion the previous code can be done by using one step as:
                   1569:  *
                   1570:  * \code
                   1571:  *    exarg_install_argv (2, "version", "v", EXARG_NONE, 
                   1572:  *                        "show argument version", 
                   1573:  *                        "load-library", "l",
                   1574:  *                        EXARG_STRING, "load my library");
                   1575:  * \endcode
                   1576:  *
                   1577:  * When you install argument this way you have to specify how many
                   1578:  * argument is going to be installed. In this case that number is
                   1579:  * 2. This allows exarg to know how many arguments needs to search
                   1580:  * inside the argv. If something is wrong while specifying the number
                   1581:  * or argument or the argument information itself you'll get a
                   1582:  * segmentation fault or something similar.
                   1583:  *
                   1584:  * While calling to \ref exarg_install_arg the short_name argument can be
                   1585:  * optional. This is *NOT* applied to this function. If you don't want
                   1586:  * to define a short argument name you must use NULL as value.
                   1587:  * 
                   1588:  * @param num_arg Must be at least 1 or error will happen and library will abort
                   1589:  * application execution.
                   1590:  **/
                   1591: void       exarg_install_argv (int num_arg, ...)
                   1592: {
                   1593:        va_list      args;
                   1594:        int         iterator;
                   1595:        char      * arg_name;
                   1596:        char      * arg_short_name;
                   1597:        ExArgType    type;
                   1598:        char      * description;
                   1599: 
                   1600:        if (num_arg <= 0) {
                   1601:                exarg_end ();
                   1602:                exarg_msg ("error: calling to exarg_install_argv with num_arg equal or less to 0..");
                   1603:        }
                   1604: 
                   1605:        va_start (args, num_arg);
                   1606: 
                   1607:        for (iterator = 0; iterator < num_arg; iterator++) {
                   1608: 
                   1609:                /* get the argument info */
                   1610:                arg_name       = va_arg (args, char *);
                   1611:                arg_short_name = va_arg (args, char *);
                   1612:                type           = va_arg (args, ExArgType);
                   1613:                description    = va_arg (args, char *);
                   1614:                
                   1615:                exarg_install_arg (arg_name, arg_short_name, type, description);
                   1616:        }
                   1617:        va_end (args);
                   1618:        return;
                   1619: }
                   1620: 
                   1621: /** 
                   1622:  * @brief Allows to define a parameter dependency between the to
                   1623:  * arguments defined. The kind of dependency has direction. This means
                   1624:  * that the first argument will depend on the second argument, forcing
                   1625:  * the user to define the second argument if the first one is defined.
                   1626:  *
                   1627:  * You can call to this function several times making the first
                   1628:  * argument to depend on any number of argument defined. You must not
                   1629:  * call to establish a dependency to the argument itself.
                   1630:  * 
                   1631:  * @param arg_name The argument that will be configured with an
                   1632:  * argument dependency.
                   1633:  *
                   1634:  * @param arg_dependency The argument that will receive the
                   1635:  * dependency.
                   1636:  *
                   1637:  *
                   1638:  */
                   1639: void         exarg_add_dependency   (const char * arg_name, 
                   1640:                                     const char * arg_dependency)
                   1641: {
                   1642:        ExArgNodeOption * node;
                   1643:        ExArgNodeOption * node2;
                   1644:        ExArgDependency * dep;
                   1645:        /* check arguments received */
                   1646:        if (arg_name == NULL)
                   1647:                return;
                   1648:        if (arg_dependency == NULL)
                   1649:                return;
                   1650: 
                   1651:        /* check that both arguments aren't equal */
                   1652:        if (strlen (arg_name) == strlen (arg_dependency) &&
                   1653:            !memcmp (arg_name, arg_dependency, strlen (arg_name))) {
                   1654:                exarg_msg ("error: defined argument dependency with an argument itself.");
                   1655:                return;
                   1656:        }
                   1657:        
                   1658:        /* locates the argument node */
                   1659:        node = exarg_lookup_node (arg_name);
                   1660:        if (node == NULL) {
                   1661:                exarg_msg ("error: you did especify an argument that doesn't exists (%s)", arg_name);
                   1662:                return;
                   1663:        }
                   1664: 
                   1665:        /* locates dependecy argument node */
                   1666:        node2 = exarg_lookup_node (arg_dependency);
                   1667:        if (node2 == NULL) {
                   1668:                exarg_msg ("error: you did especify an argument that doesn't exists (%s)", arg_dependency);
                   1669:                return;
                   1670:        }
                   1671: 
                   1672:        /* make the first argument to depend on the second */
                   1673:        dep = node->depends;
                   1674:        
                   1675:        /* create the new dependency node */
                   1676:        node->depends       = exarg_new (ExArgDependency, 1);
                   1677:        node->depends->node = node2;
                   1678:        node->depends->next = dep;
                   1679: 
                   1680:        return;
                   1681: }
                   1682: 
                   1683: /** 
                   1684:  * @brief Allows to configure arguments that are mutually
                   1685:  * excluyents. This function will take the first arguments to be
                   1686:  * muatually excluyen with the second one without direction as it
                   1687:  * happens with \ref exarg_add_dependency function.
                   1688:  *
                   1689:  * Once defined both arguments provided can't be defined at the same
                   1690:  * time at the command line options.
                   1691:  * 
                   1692:  * @param arg_name The first argument to make mutual exclusion with
                   1693:  * the second argument.
                   1694:  *
                   1695:  * @param arg_excluded Second argument to make mutual exclusion with
                   1696:  * the first argument.
                   1697:  */
                   1698: void         exarg_add_exclusion     (const char * arg_name, 
                   1699:                                      const char * arg_excluded)
                   1700: {
                   1701:        ExArgNodeOption * node;
                   1702:        ExArgNodeOption * node2;
                   1703:        ExArgDependency * dep;
                   1704: 
                   1705:        /* check arguments received */
                   1706:        if (arg_name == NULL)
                   1707:                return;
                   1708:        
                   1709:        if (arg_excluded == NULL)
                   1710:                return;
                   1711: 
                   1712:        /* check that both arguments aren't equal */
                   1713:        if (strlen (arg_name) == strlen (arg_excluded) &&
                   1714:            !memcmp (arg_name, arg_excluded, strlen (arg_name))) {
                   1715:                exarg_msg ("error: defined argument dependency with an argument itself.");
                   1716:                return;
                   1717:        }
                   1718:        
                   1719:        /* locates the argument node */
                   1720:        node = exarg_lookup_node (arg_name);
                   1721:        if (node == NULL) {
                   1722:                exarg_msg ("error: you did especify an argument that doesn't exists (%s)", arg_name);
                   1723:                return;
                   1724:        }
                   1725: 
                   1726:        /* locates dependecy argument node */
                   1727:        node2 = exarg_lookup_node (arg_excluded);
                   1728:        if (node2 == NULL) {
                   1729:                exarg_msg ("error: you did especify an argument that doesn't exists (%s)", arg_excluded);
                   1730:                return;
                   1731:        }
                   1732: 
                   1733:        /* make the first argument to depend on the second */
                   1734:        dep = node->excludes;
                   1735:        
                   1736:        /* create the new dependency node */
                   1737:        node->excludes       = exarg_new (ExArgDependency, 1);
                   1738:        node->excludes->node = node2;
                   1739:        node->excludes->next = dep;
                   1740: 
                   1741:        return;
                   1742: }
                   1743: 
                   1744: 
                   1745: /** 
                   1746:  * @brief Makes an argument installed to be obligatory (not optional
                   1747:  * at the user command line input).
                   1748:  *
                   1749:  * Once called \ref exarg_install_arg, you can use this function to
                   1750:  * make the program to make the option obligatory.
                   1751:  * 
                   1752:  * @param arg_name The argument to make it obligatory.
                   1753:  */
                   1754: void       exarg_set_obligatory   (char * arg_name)
                   1755: {
                   1756:        ExArgNodeOption * node;
                   1757: 
                   1758:        /* perform some environment checks */
                   1759:        if (arg_name == NULL)
                   1760:                return;
                   1761: 
                   1762:        node = exarg_lookup_node (arg_name);
                   1763:        if (node == NULL) {
                   1764:                return;
                   1765:        }
                   1766: 
                   1767:        /* make it to be defined */
                   1768:        node->is_optional = 0;
                   1769: 
                   1770:        return;
                   1771: }
                   1772: 
                   1773: 
                   1774: /** 
                   1775:  * @brief Allows to configure exarg library to accept or not free
                   1776:  * arguments. 
                   1777:  * 
                   1778:  * Free arguments are optional parameters provided to the application,
                   1779:  * such files, which aren't associated to a particular option.
                   1780:  *
                   1781:  * If your command line application do not uses free arguments, you
                   1782:  * can use this function to enable exarg library to show an error
                   1783:  * message to the user:
                   1784:  *
                   1785:  * \code
                   1786:  * // disable free arguments
                   1787:  * exarg_accept_free_args (0);
                   1788:  * \endcode
                   1789:  * 
                   1790:  * @param accept 1 to accept free arguments. It is the default value,
                   1791:  * so it is not required to enable it. 0 to disable free arguments.
                   1792:  */
                   1793: void         exarg_accept_free_args (int accept)
                   1794: {
                   1795:        /* configure free arguments */
                   1796:        __exarg_disable_free_args = (accept == 0);
                   1797: 
                   1798:        return;
                   1799: }
                   1800: 
                   1801: /** 
                   1802:  * @brief Allows to simulate user defined command line options alread
                   1803:  * installed by \ref exarg_install_arg, without requiring the user to
                   1804:  * set those values.
                   1805:  *
                   1806:  * This function allows to install values received or to just define
                   1807:  * the argument to be supported by the program, without requiring the
                   1808:  * user to provide such option. This is a convenient to make some
                   1809:  * options to be default, writting your application relying on
                   1810:  * arguments defined by command line.
                   1811:  *
                   1812:  * The function won't define the argument if not installed
                   1813:  * previously. If the argument isn't found, the function takes no
                   1814:  * action.
                   1815:  *
                   1816:  * @param arg_name The argument o define as provided by the user.
                   1817:  * @param value The value to be associated to the argument. Some
                   1818:  * arguments doesn't require this paremeters (\ref EXARG_NONE), so,
                   1819:  * you can provide NULL to this parameter.
                   1820:  */
                   1821: void       exarg_define           (char * arg_name,
                   1822:                                   char * value)
                   1823: {
                   1824:        ExArgNodeOption * node;
                   1825: 
                   1826:        /* perform some environment checks */
                   1827:        if (arg_name == NULL)
                   1828:                return;
                   1829: 
                   1830:        node = exarg_lookup_node (arg_name);
                   1831:        if (node == NULL) {
                   1832:                return;
                   1833:        }
                   1834:        /* make it to be defined */
                   1835:        node->is_defined = 1;
                   1836: 
                   1837:        /* check argument value */
                   1838:        if (value != NULL) {
                   1839:                switch (node->type) {
                   1840:                case EXARG_NONE:
                   1841:                        /* nothing to set */
                   1842:                        break;
                   1843:                case EXARG_INT:
                   1844:                        /* integer value */
                   1845:                        node->int_value = strtol (value, NULL, 10);
                   1846:                        break;
                   1847:                case EXARG_STRING:
                   1848:                        /* string value */
                   1849:                        node->string_value = value;
                   1850:                        break;
                   1851:                }
                   1852:        } /* end if */
                   1853: 
                   1854:        /* nothing to do over here */
                   1855:        return;
                   1856: }
                   1857: 
                   1858: /**
                   1859:  * \brief Allows to check if a user have defined a command.
                   1860:  * 
                   1861:  * Once an argument is installed the user may or may not define it. To
                   1862:  * define it simply means to use this argument as command line
                   1863:  * option. This function allows to check if an argument was used for
                   1864:  * the current command line option.
                   1865:  *
                   1866:  * This function is expecting to receive the argument name to lookup
                   1867:  * not the short name. User may be using the short name to invoke the
                   1868:  * argument but the lookup is allways done by using the argument name.
                   1869:  * 
                   1870:  * \return TRUE if argument was defined or FALSE if not.
                   1871:  **/
                   1872: int   exarg_is_defined   (char     * arg_name)
                   1873: {
                   1874:        ExArgNodeOption * node;
                   1875: 
                   1876:        /* perform some environment checks */
                   1877:        if (arg_name == NULL)
                   1878:                return 0;
                   1879:        
                   1880:        if (argument_options == NULL)
                   1881:                return 0;
                   1882: 
                   1883:        node = exarg_lookup_node (arg_name);
                   1884:        if (node == NULL) {
                   1885:                return 0;
                   1886:        }
                   1887:        return node->is_defined;
                   1888: }
                   1889: 
                   1890: /** 
                   1891:  * @brief Allows to check several values to be defined at the same time.
                   1892:  *
                   1893:  * This allows to check if several command line options have been
                   1894:  * defined at the same time. 
                   1895:  * Example:
                   1896:  * \code
                   1897:  *   if (exarg_is_definedv ("param1", "param2", NULL)) {
                   1898:  *         //param1 and param2 have been defined by the user
                   1899:  *   }
                   1900:  * \endcode
                   1901:  *
                   1902:  * This is a short way for actually doing:
                   1903:  * \code
                   1904:  *  if (exarg_is_defined ("param1") && exarg_is_defined ("param2")) {
                   1905:  *      // param1 and para2 have been defined by the user
                   1906:  *  }
                   1907:  * \endcode
                   1908:  * 
                   1909:  * Do not forget to pass a NULL value for the last item.
                   1910:  * 
                   1911:  * @return TRUE if all values are defined, otherwise FALSE.
                   1912:  */
                   1913: int   exarg_is_definedv      (char * first_value, ...)
                   1914: {
                   1915:        int       result = 1;
                   1916:        char    * string_value;
                   1917:        va_list    args;
                   1918: 
                   1919:        if (first_value == NULL)
                   1920:                return 0;
                   1921: 
                   1922:        /* check first value */
                   1923:        if (!exarg_is_defined (first_value))
                   1924:                return 0;
                   1925: 
                   1926:        /* open stdargs */
                   1927:        va_start        (args, first_value);
                   1928:        string_value = va_arg (args, char *);
                   1929: 
                   1930:        /* check for last NULL value */
                   1931:        while ((string_value != NULL) && (* string_value)) {
                   1932:                /* check next value */
                   1933:                result       = result && exarg_is_defined (string_value);
                   1934: 
                   1935:                /* get next value */
                   1936:                string_value = va_arg (args, char *);
                   1937:        }
                   1938: 
                   1939:        /* return current value */
                   1940:        va_end (args);
                   1941:        return result;
                   1942: }
                   1943: 
                   1944: /**
                   1945:  * \brief Allows to get defined string for a given command line.
                   1946:  * 
                   1947:  * Returns the value associated with the argument name. The returned
                   1948:  * value must not be deallocated. If it is needed a string copy use
                   1949:  * \ref exarg_get_string_alloc.
                   1950:  * 
                   1951:  * \return The value associated with the param or NULL if fail.
                   1952:  **/
                   1953: char    * exarg_get_string   (char     * arg_name)
                   1954: {
                   1955:        ExArgNodeOption * node;
                   1956: 
                   1957:        if (arg_name == NULL)
                   1958:                return NULL;
                   1959:        
                   1960:        if (argument_options == NULL)
                   1961:                return NULL;
                   1962: 
                   1963:        node = exarg_lookup_node (arg_name);
                   1964:        if (node == NULL) {
                   1965:                exarg_msg ("error: calling to get string value for: %s, but this argument isn't defined..",
                   1966:                           arg_name);
                   1967:        }
                   1968:        if (node->type != EXARG_STRING) {
                   1969:                exarg_msg ("error: calling to get string value for: %s, but the argument wasn't defined as EXARG_STRING..",
                   1970:                           arg_name);
                   1971:        }
                   1972:        
                   1973:        return node->string_value;
                   1974: }
                   1975: 
                   1976: /**
                   1977:  * \brief Allows to get defined string for a given command line allocating the result.
                   1978:  * 
                   1979:  * Returns the value associated with the argument name. The returned
                   1980:  * value must be <b>deallocated</b> using g_free. You can also use
                   1981:  * \ref exarg_get_string to get a value that doesn't need to be
                   1982:  * unrefered.
                   1983:  * 
                   1984:  * \return The value associated with the param or NULL if fail.
                   1985:  **/
                   1986: char    * exarg_get_string_alloc (char * arg_name)
                   1987: {
                   1988:        char * string_value;
                   1989: 
                   1990:        string_value = exarg_get_string (arg_name);
                   1991:        if (string_value == NULL)
                   1992:                return NULL;
                   1993:        return exarg_strdup (string_value);
                   1994: }
                   1995: 
                   1996: /**
                   1997:  * \brief Allows to get int value for a given command line argument.
                   1998:  * 
                   1999:  * Returns the value associated with the argument name. The returned
                   2000:  * may be 0 which means the user may not defined that argument or may
                   2001:  * defined it by using the 0 as value. To avoid confusing cases you
                   2002:  * should use \ref exarg_is_defined to know if the user have used that
                   2003:  * argument and then call this function.
                   2004:  * 
                   2005:  * \return the value defined for this argument. If the argument
                   2006:  * is null or the exarg is not initialized the function will return -1.
                   2007:  **/
                   2008: int       exarg_get_int      (char     * arg_name)
                   2009: {
                   2010:        ExArgNodeOption * node;
                   2011: 
                   2012:        if (arg_name == NULL)
                   2013:                return -1;
                   2014:        if (argument_options == NULL)
                   2015:                return -1;
                   2016: 
                   2017:        node = exarg_lookup_node (arg_name);
                   2018:        if (node == NULL) {
                   2019:                exarg_msg ("error: calling to get int value for: %s, but this argument isn't defined..",
                   2020:                           arg_name);
                   2021:        }
                   2022: 
                   2023:        if (node->type != EXARG_INT) {
                   2024:                exarg_msg ("error: calling to get int value for: %s, but the argument wasn't defined as EXARG_INT..",
                   2025:                           arg_name);
                   2026:        }
                   2027:        
                   2028:        return node->int_value;
                   2029: }
                   2030: 
                   2031: /**
                   2032:  * \brief Returns free params defined at command line.
                   2033:  * 
                   2034:  * Every value which is not an argument is considered to be a
                   2035:  * parameter. All of them are stored and retrieved by using this
                   2036:  * function and the following functions:
                   2037:  *
                   2038:  *  - \ref exarg_param_get 
                   2039:  *  - \ref exarg_param_next
                   2040:  *
                   2041:  * An example about using this function could be the next. A program
                   2042:  * have defined several arguments using the function \ref
                   2043:  * exarg_install_arg but that program also needs to receive several
                   2044:  * file path. 
                   2045:  * 
                   2046:  * Once the \ref exarg_parse have detected all argument, all
                   2047:  * parameters are stored, and this function provides access to the
                   2048:  * first argument *found. Then a call to \ref exarg_param_get is
                   2049:  * required to get the *argument value and a call to \ref
                   2050:  * exarg_param_next to get a *reference to the next argument.
                   2051:  * 
                   2052:  *
                   2053:  * A program which may receive the argument --save-all but also several
                   2054:  * files:
                   2055:  *
                   2056:  * \code
                   2057:  *    a_program --save-all file1 file2 file3
                   2058:  * \endcode
                   2059:  *
                   2060:  * Will need to call this function to get the list: file1 file2 and
                   2061:  * file3. 
                   2062:  * 
                   2063:  * \return The first param provided to the program. The returned value
                   2064:  * must not be deallocated.
                   2065:  */
                   2066: ExArgument   * exarg_get_params   ()
                   2067: {
                   2068:        return params;
                   2069: }
                   2070: 
                   2071: /** 
                   2072:  * @brief Allows to get the string value that is represeting the argument received.
                   2073:  * 
                   2074:  * @param arg The argument that was received by the program.
                   2075:  * 
                   2076:  * @return An string reference that must not be deallocated.
                   2077:  */
                   2078: const char * exarg_param_get        (ExArgument * arg)
                   2079: {
                   2080:        /* check for null value received */
                   2081:        if (arg == NULL)
                   2082:                return NULL;
                   2083:        
                   2084:        /* return the string value inside */
                   2085:        return arg->string;
                   2086: }
                   2087: 
                   2088: /** 
                   2089:  * @brief Allows to get the next parameters defined at the command
                   2090:  * line option that is following the argument provided.
                   2091:  * 
                   2092:  * @param arg The argument which is previous to the argument to be
                   2093:  * returned.
                   2094:  * 
                   2095:  * @return An argument reference to the next or NULL if there are no
                   2096:  * more arguments.
                   2097:  */
                   2098: ExArgument * exarg_param_next       (ExArgument * arg)
                   2099: {
                   2100:        /* check for null value received */
                   2101:        if (arg == NULL)
                   2102:                return NULL;
                   2103:        
                   2104:        /* return the next argument */
                   2105:        return arg->next;
                   2106: }
                   2107: 
                   2108: 
                   2109: /** 
                   2110:  * @brief Allows to get the number of parameters that were defined by
                   2111:  * the user. 
                   2112:  *
                   2113:  * Check also the following function \ref exarg_get_params_num.
                   2114:  * 
                   2115:  * @return The number of parameters starting from 0.
                   2116:  */
                   2117: int       exarg_get_params_num   ()
                   2118: {
                   2119:        ExArgument * arg    = NULL;
                   2120:        int          result = 0;
                   2121: 
                   2122:        if (params == NULL)
                   2123:                return 0;
                   2124: 
                   2125:        /* count the number of params */
                   2126:        arg = params;
                   2127:        while (arg != NULL) {
                   2128:                /* update the count */
                   2129:                result++;
                   2130: 
                   2131:                /* update to the next */
                   2132:                arg = arg->next;
                   2133: 
                   2134:        } /* end while */
                   2135: 
                   2136:        /* return current count */
                   2137:        return result;
                   2138: }
                   2139: 
                   2140: /* @} */
                   2141: 

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