291 lines
11 KiB
C
291 lines
11 KiB
C
/***************************************************************************
|
|
* Command Line Option Parser
|
|
*
|
|
* File : optlist.c
|
|
* Purpose : Provide getopt style command line option parsing
|
|
* Author : Michael Dipperstein
|
|
* Date : August 1, 2007
|
|
*
|
|
****************************************************************************
|
|
*
|
|
* OptList: A command line option parsing library
|
|
* Copyright (C) 2007, 2014 by
|
|
* Michael Dipperstein (mdipper@alumni.engr.ucsb.edu)
|
|
*
|
|
* This file is part of the OptList library.
|
|
*
|
|
* OptList is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or (at
|
|
* your option) any later version.
|
|
*
|
|
* OptList 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 Lesser
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* INCLUDED FILES
|
|
***************************************************************************/
|
|
#include "optlist.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
/***************************************************************************
|
|
* TYPE DEFINITIONS
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* CONSTANTS
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* GLOBAL VARIABLES
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* PROTOTYPES
|
|
***************************************************************************/
|
|
static option_t *MakeOpt(
|
|
const char option, char *const argument, const int index);
|
|
|
|
static size_t MatchOpt(
|
|
const char argument, char *const options);
|
|
|
|
/***************************************************************************
|
|
* FUNCTIONS
|
|
***************************************************************************/
|
|
|
|
/****************************************************************************
|
|
* Function : GetOptList
|
|
* Description: This function is similar to the POSIX function getopt. All
|
|
* options and their corresponding arguments are returned in a
|
|
* linked list. This function should only be called once per
|
|
* an option list and it does not modify argv or argc.
|
|
* Parameters : argc - the number of command line arguments (including the
|
|
* name of the executable)
|
|
* argv - pointer to the open binary file to write encoded
|
|
* output
|
|
* options - getopt style option list. A NULL terminated
|
|
* string of single character options. Follow an
|
|
* option with a colon to indicate that it requires
|
|
* an argument.
|
|
* Effects : Creates a link list of command line options and their
|
|
* arguments.
|
|
* Returned : option_t type value where the option and arguement fields
|
|
* contain the next option symbol and its argument (if any).
|
|
* The argument field will be set to NULL if the option is
|
|
* specified as having no arguments or no arguments are found.
|
|
* The option field will be set to PO_NO_OPT if no more
|
|
* options are found.
|
|
*
|
|
* NOTE: The caller is responsible for freeing up the option list when it
|
|
* is no longer needed.
|
|
****************************************************************************/
|
|
option_t *GetOptList(const int argc, char *const argv[], char *const options)
|
|
{
|
|
int nextArg;
|
|
option_t *head, *tail;
|
|
size_t optIndex;
|
|
size_t argIndex;
|
|
|
|
/* start with first argument and nothing found */
|
|
nextArg = 1;
|
|
head = NULL;
|
|
tail = NULL;
|
|
|
|
/* loop through all of the command line arguments */
|
|
while (nextArg < argc)
|
|
{
|
|
argIndex = 1;
|
|
|
|
while ((strlen(argv[nextArg]) > argIndex) && ('-' == argv[nextArg][0]))
|
|
{
|
|
/* attempt to find a matching option */
|
|
optIndex = MatchOpt(argv[nextArg][argIndex], options);
|
|
|
|
if (options[optIndex] == argv[nextArg][argIndex])
|
|
{
|
|
/* we found the matching option */
|
|
if (NULL == head)
|
|
{
|
|
head = MakeOpt(options[optIndex], NULL, OL_NOINDEX);
|
|
tail = head;
|
|
}
|
|
else
|
|
{
|
|
tail->next = MakeOpt(options[optIndex], NULL, OL_NOINDEX);
|
|
tail = tail->next;
|
|
}
|
|
|
|
if (':' == options[optIndex + 1])
|
|
{
|
|
/* the option found should have a text arguement */
|
|
argIndex++;
|
|
|
|
if (strlen(argv[nextArg]) > argIndex)
|
|
{
|
|
/* no space between argument and option */
|
|
tail->argument = &(argv[nextArg][argIndex]);
|
|
tail->argIndex = nextArg;
|
|
}
|
|
else if (nextArg < argc)
|
|
{
|
|
/* there must be space between the argument option */
|
|
nextArg++;
|
|
tail->argument = argv[nextArg];
|
|
tail->argIndex = nextArg;
|
|
}
|
|
|
|
break; /* done with argv[nextArg] */
|
|
}
|
|
}
|
|
|
|
argIndex++;
|
|
}
|
|
|
|
nextArg++;
|
|
}
|
|
|
|
return head;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Function : MakeOpt
|
|
* Description: This function uses malloc to allocate space for an option_t
|
|
* type structure and initailizes the structure with the
|
|
* values passed as a parameter.
|
|
* Parameters : option - this option character
|
|
* argument - pointer string containg the argument for option.
|
|
* Use NULL for no argument
|
|
* index - argv[index] contains argument use OL_NOINDEX for
|
|
* no argument
|
|
* Effects : A new option_t type variable is created on the heap.
|
|
* Returned : Pointer to newly created and initialized option_t type
|
|
* structure. NULL if space for structure can't be allocated.
|
|
****************************************************************************/
|
|
static option_t *MakeOpt(
|
|
const char option, char *const argument, const int index)
|
|
{
|
|
option_t *opt;
|
|
|
|
opt = malloc(sizeof(option_t));
|
|
|
|
if (opt != NULL)
|
|
{
|
|
opt->option = option;
|
|
opt->argument = argument;
|
|
opt->argIndex = index;
|
|
opt->next = NULL;
|
|
}
|
|
else
|
|
{
|
|
perror("Failed to Allocate option_t");
|
|
}
|
|
|
|
return opt;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Function : FreeOptList
|
|
* Description: This function will free all the elements in an option_t
|
|
* type linked list starting from the node passed as a
|
|
* parameter.
|
|
* Parameters : list - head of linked list to be freed
|
|
* Effects : All elements of the linked list pointed to by list will
|
|
* be freed and list will be set to NULL.
|
|
* Returned : None
|
|
****************************************************************************/
|
|
void FreeOptList(option_t *list)
|
|
{
|
|
option_t *head, *next;
|
|
|
|
head = list;
|
|
list = NULL;
|
|
|
|
while (head != NULL)
|
|
{
|
|
next = head->next;
|
|
free(head);
|
|
head = next;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Function : MatchOpt
|
|
* Description: This function searches for an arguement in an option list.
|
|
* It will return the index to the option matching the
|
|
* arguement or the index to the NULL if none is found.
|
|
* Parameters : arguement - character arguement to be matched to an
|
|
* option in the option list
|
|
* options - getopt style option list. A NULL terminated
|
|
* string of single character options. Follow an
|
|
* option with a colon to indicate that it requires
|
|
* an argument.
|
|
* Effects : None
|
|
* Returned : Index of argument in option list. Index of end of string
|
|
* if arguement does not appear in the option list.
|
|
****************************************************************************/
|
|
static size_t MatchOpt(
|
|
const char argument, char *const options)
|
|
{
|
|
size_t optIndex = 0;
|
|
|
|
/* attempt to find a matching option */
|
|
while ((options[optIndex] != '\0') &&
|
|
(options[optIndex] != argument))
|
|
{
|
|
do
|
|
{
|
|
optIndex++;
|
|
}
|
|
while ((options[optIndex] != '\0') &&
|
|
(':' == options[optIndex]));
|
|
}
|
|
|
|
return optIndex;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Function : FindFileName
|
|
* Description: This is function accepts a pointer to the name of a file
|
|
* along with path information and returns a pointer to the
|
|
* first character that is not part of the path.
|
|
* Parameters : fullPath - pointer to an array of characters containing
|
|
* a file name and possible path modifiers.
|
|
* Effects : None
|
|
* Returned : Returns a pointer to the first character after any path
|
|
* information.
|
|
****************************************************************************/
|
|
char *FindFileName(const char *const fullPath)
|
|
{
|
|
int i;
|
|
const char *start; /* start of file name */
|
|
const char *tmp;
|
|
const char delim[3] = {'\\', '/', ':'}; /* path deliminators */
|
|
|
|
start = fullPath;
|
|
|
|
/* find the first character after all file path delimiters */
|
|
for (i = 0; i < 3; i++)
|
|
{
|
|
tmp = strrchr(start, delim[i]);
|
|
|
|
if (tmp != NULL)
|
|
{
|
|
start = tmp + 1;
|
|
}
|
|
}
|
|
|
|
return (char *)start;
|
|
}
|
|
|