File:  [ELWIX - Embedded LightWeight unIX -] / gpl / axl / knife / exarg.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Fri Feb 17 12:50:02 2012 UTC (12 years, 4 months ago) by misho
Branches: axl, MAIN
CVS tags: HEAD, AXL0_6_7
version 0.6.7

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

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