/* argparser.c  --  Simple argument parser - inspired by getopt, but simpler
 *
 *  GPLv2 only - Copyright (C) 2008 - 2012
 *               David Sommerseth <dazo@users.sourceforge.net>
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; version 2
 *  of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 */

/**
 * @file   argparser.c
 * @author David Sommerseth <dazo@users.sourceforge.net>
 * @date   2008-12-04
 *
 * @brief  A simple argument parser, inspired by getopt.
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define ARGPARSER_C
#include "argparser.h"

char *optargs[MAX_ARGUMENTS];   /**< If an argument takes parameters, they will be put into this array */


/**
 * Internal argument parser.  Normally called via the eurephia_getopt(...) macro.  Parses an
 * argument and prepares the char **optargs array with parameters to the arguments.
 *
 * @param module    string (const char *) containing a descriptive module name, used in error situations.
 * @param curarg    pointer to the argument index counter which gets updated during parsing.
 * @param argc      Input argument counter
 * @param argv      Input argument array (char **)
 * @param argopts   e_options struct array containing valid argument
 *
 * @return returns the short arg value on success, or -1 on failure.
 */
int _eurephia_getopt(const char *module, int *curarg, int argc, char **argv, e_options *argopts) {
        int i = 0;
        char *arg = argv[*curarg];

        if( arg == NULL ) {
                return -1;
        }

        for( i = 0; argopts[i].longarg != NULL; i++ ) {
                if( (strcmp(argopts[i].longarg, arg) == 0)
                    || (strcmp(argopts[i].shortarg, arg) == 0) )
                        {
                                if( (argopts[i].param > 0) && (argc > (*curarg)+argopts[i].param) ) {
                                        int j = 0;
                                        for( j = 0; j < argopts[i].param; j++ ) {
                                                optargs[j] = argv[(*curarg)+1];
                                                (*curarg)++;
                                        }
                                } else if( (argopts[i].param > 0) ) {
                                        fprintf(stderr, "%s: ERROR :: Missing argument(s) to '%s'\n", module, arg);
                                        return -1;
                                }
                                return (int) *(&(*argopts[i].shortarg)+1);
                        }
        }
        fprintf(stderr, "%s: ERROR :: Unknown argument '%s'\n", module, arg);
        return -1;
}


/**
 * This function will take (argc,argv) and copy pointers over to (**outargv), starting from
 * the index given in stidx (start index).  The outargv array must have been allocated first
 * by calloc(sizeof(char *), elmnts).  The outsize must not exceed the number of elements you
 * have allocated space for.  The function returns number of elements copied (the new argc, kind of)
 *
 * @param stidx    start index of where to start the copy
 * @param inargc   input argument counter (size of the input array)
 * @param inargv   input argument array (char **)
 * @param outargv  pointer to an array of where to put the values being copied.
 * @param outsize  Size of the output array.
 *
 * @return Returns number of argument copied over to the output array.
 */
size_t eurephia_arraycp(int stidx, int inargc, char **inargv, char **outargv, size_t outsize) {
        int i, outargc;

        outargc = 0;
        for( i = stidx; ((i < inargc) && (outargc < outsize)); i++ ) {
                outargv[outargc++] = inargv[i];
        }

        return outargc;
}
