mdtest/src/getopt/optlist.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;
}