00001 /*************************************************************************** 00002 * Command Line Option Parser 00003 * 00004 * File : optlist.c 00005 * Purpose : Provide getopt style command line option parsing 00006 * Author : Michael Dipperstein 00007 * Date : August 1, 2007 00008 * 00009 **************************************************************************** 00010 * HISTORY 00011 * 00012 * $Id: optlist.c,v 1.1.1.2 2007/09/04 04:45:42 michael Exp $ 00013 * $Log: optlist.c,v $ 00014 * Revision 1.1.1.2 2007/09/04 04:45:42 michael 00015 * Added FreeOptList. 00016 * 00017 * Revision 1.1.1.1 2007/08/07 05:01:48 michael 00018 * Initial Release 00019 * 00020 **************************************************************************** 00021 * 00022 * OptList: A command line option parsing library 00023 * Copyright (C) 2007 by Michael Dipperstein (mdipper@alumni.engr.ucsb.edu) 00024 * 00025 * This file is part of the OptList library. 00026 * 00027 * OptList is free software; you can redistribute it and/or modify it 00028 * under the terms of the GNU Lesser General Public License as published by 00029 * the Free Software Foundation; either version 3 of the License, or (at 00030 * your option) any later version. 00031 * 00032 * OptList is distributed in the hope that it will be useful, but 00033 * WITHOUT ANY WARRANTY; without even the implied warranty of 00034 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 00035 * General Public License for more details. 00036 * 00037 * You should have received a copy of the GNU Lesser General Public License 00038 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00039 * 00040 ***************************************************************************/ 00041 00042 /*************************************************************************** 00043 * INCLUDED FILES 00044 ***************************************************************************/ 00045 #include "mimotera++/optlist.h" 00046 #include <stdio.h> 00047 #include <stdlib.h> 00048 #include <string.h> 00049 00050 /*************************************************************************** 00051 * TYPE DEFINITIONS 00052 ***************************************************************************/ 00053 00054 /*************************************************************************** 00055 * CONSTANTS 00056 ***************************************************************************/ 00057 00058 /*************************************************************************** 00059 * GLOBAL VARIABLES 00060 ***************************************************************************/ 00061 00062 /*************************************************************************** 00063 * PROTOTYPES 00064 ***************************************************************************/ 00065 option_t *MakeOpt(const char option, char *const argument, const int index); 00066 00067 /*************************************************************************** 00068 * FUNCTIONS 00069 ***************************************************************************/ 00070 00071 /**************************************************************************** 00072 * Function : GetOptList 00073 * Description: This function is similar to the POSIX function getopt. All 00074 * options and their corresponding arguments are returned in a 00075 * linked list. This function should only be called once per 00076 * an option list and it does not modify argv or argc. 00077 * Parameters : argc - the number of command line arguments (including the 00078 * name of the executable) 00079 * argv - pointer to the open binary file to write encoded 00080 * output 00081 * options - getopt style option list. A NULL terminated 00082 * string of single character options. Follow an 00083 * option with a colon to indicate that it requires 00084 * an argument. 00085 * Effects : Creates a link list of command line options and their 00086 * arguments. 00087 * Returned : option_t type value where the option and arguement fields 00088 * contain the next option symbol and its argument (if any). 00089 * The argument field will be set to NULL if the option is 00090 * specified as having no arguments or no arguments are found. 00091 * The option field will be set to PO_NO_OPT if no more 00092 * options are found. 00093 * 00094 * NOTE: The caller is responsible for freeing up the option list when it 00095 * is no longer needed. 00096 ****************************************************************************/ 00097 option_t *GetOptList(const int argc, char *const argv[], char *const options) 00098 { 00099 int nextArg; 00100 option_t *head, *tail; 00101 int optIndex; 00102 00103 /* start with first argument and nothing found */ 00104 nextArg = 1; 00105 head = NULL; 00106 tail = NULL; 00107 00108 /* loop through all of the command line arguments */ 00109 while (nextArg < argc) 00110 { 00111 if ((strlen(argv[nextArg]) > 1) && ('-' == argv[nextArg][0])) 00112 { 00113 /* possible option */ 00114 optIndex = 0; 00115 00116 /* attempt to find a matching option */ 00117 while ((options[optIndex] != '\0') && 00118 (options[optIndex] != argv[nextArg][1])) 00119 { 00120 do 00121 { 00122 optIndex++; 00123 } 00124 while ((options[optIndex] != '\0') && 00125 (':' == options[optIndex])); 00126 } 00127 00128 if (options[optIndex] == argv[nextArg][1]) 00129 { 00130 /* we found the matching option */ 00131 if (NULL == head) 00132 { 00133 head = MakeOpt(options[optIndex], NULL, OL_NOINDEX); 00134 tail = head; 00135 } 00136 else 00137 { 00138 tail->next = MakeOpt(options[optIndex], NULL, OL_NOINDEX); 00139 tail = tail->next; 00140 } 00141 00142 if (':' == options[optIndex + 1]) 00143 { 00144 /* the option found should have a text arguement */ 00145 if (strlen(argv[nextArg]) > 2) 00146 { 00147 /* no space between argument and option */ 00148 tail->argument = &(argv[nextArg][2]); 00149 tail->argIndex = nextArg; 00150 } 00151 else if (nextArg < argc) 00152 { 00153 /* there must be space between the argument option */ 00154 nextArg++; 00155 tail->argument = argv[nextArg]; 00156 tail->argIndex = nextArg; 00157 } 00158 } 00159 } 00160 } 00161 00162 nextArg++; 00163 } 00164 00165 return head; 00166 } 00167 00168 /**************************************************************************** 00169 * Function : MakeOpt 00170 * Description: This function uses malloc to allocate space for an option_t 00171 * type structure and initailizes the structure with the 00172 * values passed as a parameter. 00173 * Parameters : option - this option character 00174 * argument - pointer string containg the argument for option. 00175 * Use NULL for no argument 00176 * index - argv[index] contains argument us OL_NOINDEX for 00177 * no argument 00178 * Effects : A new option_t type variable is created on the heap. 00179 * Returned : Pointer to newly created and initialized option_t type 00180 * structure. NULL if space for structure can't be allocated. 00181 ****************************************************************************/ 00182 option_t *MakeOpt(const char option, char *const argument, const int index) 00183 { 00184 option_t *opt; 00185 00186 opt = malloc(sizeof(option_t)); 00187 00188 if (opt != NULL) 00189 { 00190 opt->option = option; 00191 opt->argument = argument; 00192 opt->argIndex = index; 00193 opt->next = NULL; 00194 } 00195 else 00196 { 00197 perror("Failed to Allocate option_t"); 00198 } 00199 00200 return opt; 00201 } 00202 00203 /**************************************************************************** 00204 * Function : FreeOptList 00205 * Description: This function will free all the elements in an option_t 00206 * type linked list starting from the node passed as a 00207 * parameter. 00208 * Parameters : list - head of linked list to be freed 00209 * Effects : All elements of the linked list pointed to by list will 00210 * be freed and list will be set to NULL. 00211 * Returned : None 00212 ****************************************************************************/ 00213 void FreeOptList(option_t *list) 00214 { 00215 option_t *head, *next; 00216 00217 head = list; 00218 list = NULL; 00219 00220 while (head != NULL) 00221 { 00222 next = head->next; 00223 free(head); 00224 head = next; 00225 } 00226 00227 return; 00228 }