📄 cmdline.c
字号:
/****************************************************************************** ========================================================================** The contents of this file are subject to the SciTech MGL Public* License Version 1.0 (the "License"); you may not use this file* except in compliance with the License. You may obtain a copy of* the License at http://www.scitechsoft.com/mgl-license.txt** Software distributed under the License is distributed on an* "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or* implied. See the License for the specific language governing* rights and limitations under the License.** The Original Code is Copyright (C) 1991-1998 SciTech Software, Inc.** The Initial Developer of the Original Code is SciTech Software, Inc.* All Rights Reserved.** ========================================================================** Language: ANSI C* Environment: any** Description: This module contains code to parse the command line,* extracting options and parameters in standard System V* style.*****************************************************************************/#include <stdio.h>#include <string.h>#include <ctype.h>#include "cmdline.h"/*------------------------- Global variables ------------------------------*/int nextargv = 1; /* Index into argv array */char *nextchar = NULL; /* Pointer to next character *//*-------------------------- Implementation -------------------------------*/#define IS_SWITCH_CHAR(c) ((c) == '-')#define IS_NOT_SWITCH_CHAR(c) ((c) != '-')/****************************************************************************DESCRIPTION:Parse the command line for specific optionsHEADER:cmdline.hPARAMETERS:argc - Value passed to program through argc variableargv - Pointer to the argv array passed to the programformat - A string representing the expected format of the command lineargument - Pointer to optional argument on command lineRETURNS:Character code representing the next option parsed from the command line bygetcmdopt. Returns ALLDONE (-1) when there are no more parameters to be parsedon the command line, PARAMETER (-2) when the argument being parsed is aparameter and not an option switch and lastly INVALID (-3) if an erroroccured while parsing the command line.REMARKS:Function to parse the command line option switches in UNIX System V style.When getcmdopt is called, it returns the character code of the next validoption that is parsed from the command line as specified by the Formatstring. The format string should be in the following form: "abcd:e:f:"where a,b and c represent single switch style options and the charactercode returned by getcmdopt is the only value returned. Also d, e and frepresent options that expect arguments immediately after them on thecommand line. The argument that follows the option on the command line isreturned via a reference in the pointer argument. Thus a valid command linefor this format string might be: myprogram -adlines -b -f format infile outfilewhere a and b will be returned as single character options with no argument,while d is returned with the argument lines and f is returned with theargument format.When getcmdopt returns with PARAMETER (we attempted to parse a paramter, notan option), the global variable NextArgv will hold an index in the argvarray to the argument on the command line AFTER the options, ie in theabove example the string 'infile'. If the parameter is successfully used,NextArgv should be incremented and getcmdopt can be called again to parse anymore options. Thus you can also have options interspersed throught thecommand line. eg: myprogram -adlines infile -b outfile -f formatcan be made to be a valid form of the above command line.****************************************************************************/int getcmdopt( int argc, char **argv, char *format, char **argument){ char ch; char *formatchar; if (argc > nextargv) { if (nextchar == NULL) { nextchar = argv[nextargv]; /* Index next argument */ if (nextchar == NULL) { nextargv++; return ALLDONE; /* No more options */ } if (IS_NOT_SWITCH_CHAR(*nextchar)) { nextchar = NULL; return PARAMETER; /* We have a parameter */ } nextchar++; /* Move past switch operator */ if (IS_SWITCH_CHAR(*nextchar)) { nextchar = NULL; return INVALID; /* Ignore rest of line */ } } if ((ch = *(nextchar++)) == 0) { nextchar = NULL; return INVALID; /* No options on line */ } if (ch == ':' || (formatchar = strchr(format, ch)) == NULL) return INVALID; if (*(++formatchar) == ':') { /* Expect an argument after option */ nextargv++; if (*nextchar == 0) { if (argc <= nextargv) return INVALID; nextchar = argv[nextargv++]; } *argument = nextchar; nextchar = NULL; } else { /* We have a switch style option */ if (*nextchar == 0) { nextargv++; nextchar = NULL; } *argument = NULL; } return ch; /* return the option specifier */ } nextchar = NULL; nextargv++; return ALLDONE; /* no arguments on command line */}/****************************************************************************PARAMETERS:optarr - Description for the option we are parsingargument - String to parseRETURNS:INVALID on error, ALLDONE on success.REMARKS:Parses the argument string depending on the type of argument that isexpected, filling in the argument for that option. Note that to parse astring, we simply return a pointer to argument.****************************************************************************/static int parse_option( Option *optarr, char *argument){ int num_read; switch ((int)(optarr->type)) { case OPT_INTEGER: num_read = sscanf(argument,"%d",(int*)optarr->arg); break; case OPT_HEX: num_read = sscanf(argument,"%x",(int*)optarr->arg); break; case OPT_OCTAL: num_read = sscanf(argument,"%o",(int*)optarr->arg); break; case OPT_UNSIGNED: num_read = sscanf(argument,"%u",(uint*)optarr->arg); break; case OPT_LINTEGER: num_read = sscanf(argument,"%ld",(long*)optarr->arg); break; case OPT_LHEX: num_read = sscanf(argument,"%lx",(long*)optarr->arg); break; case OPT_LOCTAL: num_read = sscanf(argument,"%lo",(long*)optarr->arg); break; case OPT_LUNSIGNED: num_read = sscanf(argument,"%lu",(ulong*)optarr->arg); break; case OPT_FLOAT: num_read = sscanf(argument,"%f",(float*)optarr->arg); break; case OPT_DOUBLE: num_read = sscanf(argument,"%lf",(double*)optarr->arg); break; case OPT_LDOUBLE: num_read = sscanf(argument,"%Lf",(long double*)optarr->arg); break; case OPT_STRING: num_read = 1; /* This always works */ *((char**)optarr->arg) = argument; break; default: return INVALID; } if (num_read == 0) return INVALID; else return ALLDONE;}/****************************************************************************HEADER:cmdline.hPARAMETERS:argc - Number of arguments on command lineargv - Array of command line argumentsnum_opt - Number of options in option arrayoptarr - Array to specify how to parse the command linedo_param - Routine to handle a command line parameterRETURNS:ALLDONE, INVALID or HELPREMARKS:Function to parse the command line according to a table of options. Thisroutine calls getcmdopt above to parse each individual option and attemptsto parse each option into a variable of the specified type. The routinecan parse integers and long integers in either decimal, octal, hexadecimalnotation, unsigned integers and unsigned longs, strings and option switches.Option switches are simply boolean variables that get turned on if theswitch was parsed.Parameters are extracted from the command line by calling a user suppliedroutine do_param() to handle each parameter as it is encountered. Theroutine do_param() should accept a pointer to the parameter on the commandline and an integer representing how many parameters have been encountered(ie: 1 if this is the first parameter, 10 if it is the 10th etc), and returnALLDONE upon successfully parsing it or INVALID if the parameter was invalid.We return either ALLDONE if all the options were successfully parsed,INVALID if an invalid option was encountered or HELP if any of -h, -H or-? were present on the command line.****************************************************************************/int getargs( int argc, char *argv[], int num_opt, Option optarr[], int (*do_param)( char *param, int num)){ int i,opt; char *argument; int param_num = 1; char cmdstr[MAXARG*2 + 4]; /* Build the command string from the array of options */ strcpy(cmdstr,"hH?"); for (i = 0,opt = 3; i < num_opt; i++,opt++) { cmdstr[opt] = optarr[i].opt; if (optarr[i].type != OPT_SWITCH) { cmdstr[++opt] = ':'; } } cmdstr[opt] = '\0'; for (;;) { opt = getcmdopt(argc,argv,cmdstr,&argument); switch (opt) { case 'H': case 'h': case '?': return HELP; case ALLDONE: return ALLDONE; case INVALID: return INVALID; case PARAMETER: if (do_param == NULL) return INVALID; if (do_param(argv[nextargv],param_num) == INVALID) return INVALID; nextargv++; param_num++; break; default: /* Search for the option in the option array. We are * guaranteed to find it. */ for (i = 0; i < num_opt; i++) { if (optarr[i].opt == opt) break; } if (optarr[i].type == OPT_SWITCH) *((ibool*)optarr[i].arg) = true; else { if (parse_option(&optarr[i],argument) == INVALID) return INVALID; } break; } }}/****************************************************************************HEADER:cmdline.hPARAMETERS:num_opt - Number of options in the tableoptarr - Table of option descriptionsREMARKS:Prints the description of each option in a standard format to the standardoutput device. The description for each option is obtained from the tableof options.****************************************************************************/void print_desc( int num_opt, Option optarr[]){ int i; for (i = 0; i < num_opt; i++) { if (optarr[i].type == OPT_SWITCH) printf(" -%c %s\n",optarr[i].opt,optarr[i].desc); else printf(" -%c<arg> %s\n",optarr[i].opt,optarr[i].desc); }}/****************************************************************************HEADER:cmdline.hPARAMETERS:moduleName - Module name for programcmdLine - Command line to parsepargc - Pointer to 'argc' parameterpargv - Pointer to 'argv' parametermaxArgc - Maximum argv array indexREMARKS:Parses a command line from a single string into the C style 'argc' and'argv' format. Most useful for Windows programs where the command lineis passed in verbatim.****************************************************************************/int parse_commandline( char *moduleName, char *cmdLine, int *pargc, char *argv[], int maxArgv){ static char str[512]; static char filename[260]; char *prevWord = NULL; ibool inQuote = FALSE; ibool noStrip = FALSE; int argc; argc = 0; strcpy(filename,moduleName); argv[argc++] = filename; cmdLine = strncpy(str, cmdLine, sizeof(str)-1); while (*cmdLine) { switch (*cmdLine) { case '"' : if (prevWord != NULL) { if (inQuote) { if (!noStrip) *cmdLine = '\0'; argv [argc++] = prevWord; prevWord = NULL; } else noStrip = TRUE; } inQuote = !inQuote; break; case ' ' : case '\t' : if (!inQuote) { if (prevWord != NULL) { *cmdLine = '\0'; argv [argc++] = prevWord; prevWord = NULL; noStrip = FALSE; } } break; default : if (prevWord == NULL) prevWord = cmdLine; break; } if (argc >= maxArgv - 1) break; cmdLine++; } if ((prevWord != NULL || (inQuote && prevWord != NULL)) && argc < maxArgv - 1) { *cmdLine = '\0'; argv [argc++] = prevWord; } argv[argc] = NULL; /* Return updated parameters */ return (*pargc = argc);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -