Annotation of gpl/axl/knife/exarg.c, revision 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>