summaryrefslogtreecommitdiff
path: root/board/MAI/bios_emulator/scitech/src/common/cmdline.c
diff options
context:
space:
mode:
Diffstat (limited to 'board/MAI/bios_emulator/scitech/src/common/cmdline.c')
-rwxr-xr-xboard/MAI/bios_emulator/scitech/src/common/cmdline.c428
1 files changed, 428 insertions, 0 deletions
diff --git a/board/MAI/bios_emulator/scitech/src/common/cmdline.c b/board/MAI/bios_emulator/scitech/src/common/cmdline.c
new file mode 100755
index 0000000..531e5e1
--- /dev/null
+++ b/board/MAI/bios_emulator/scitech/src/common/cmdline.c
@@ -0,0 +1,428 @@
+/****************************************************************************
+*
+* ========================================================================
+*
+* 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 options
+
+HEADER:
+cmdline.h
+
+PARAMETERS:
+argc - Value passed to program through argc variable
+argv - Pointer to the argv array passed to the program
+format - A string representing the expected format of the command line
+argument - Pointer to optional argument on command line
+
+RETURNS:
+Character code representing the next option parsed from the command line by
+getcmdopt. Returns ALLDONE (-1) when there are no more parameters to be parsed
+on the command line, PARAMETER (-2) when the argument being parsed is a
+parameter and not an option switch and lastly INVALID (-3) if an error
+occured 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 valid
+option that is parsed from the command line as specified by the Format
+string. The format string should be in the following form:
+
+ "abcd:e:f:"
+
+where a,b and c represent single switch style options and the character
+code returned by getcmdopt is the only value returned. Also d, e and f
+represent options that expect arguments immediately after them on the
+command line. The argument that follows the option on the command line is
+returned via a reference in the pointer argument. Thus a valid command line
+for this format string might be:
+
+ myprogram -adlines -b -f format infile outfile
+
+where 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 the
+argument format.
+
+When getcmdopt returns with PARAMETER (we attempted to parse a paramter, not
+an option), the global variable NextArgv will hold an index in the argv
+array to the argument on the command line AFTER the options, ie in the
+above example the string 'infile'. If the parameter is successfully used,
+NextArgv should be incremented and getcmdopt can be called again to parse any
+more options. Thus you can also have options interspersed throught the
+command line. eg:
+
+ myprogram -adlines infile -b outfile -f format
+
+can 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 parsing
+argument - String to parse
+
+RETURNS:
+INVALID on error, ALLDONE on success.
+
+REMARKS:
+Parses the argument string depending on the type of argument that is
+expected, filling in the argument for that option. Note that to parse a
+string, 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.h
+
+PARAMETERS:
+argc - Number of arguments on command line
+argv - Array of command line arguments
+num_opt - Number of options in option array
+optarr - Array to specify how to parse the command line
+do_param - Routine to handle a command line parameter
+
+RETURNS:
+ALLDONE, INVALID or HELP
+
+REMARKS:
+Function to parse the command line according to a table of options. This
+routine calls getcmdopt above to parse each individual option and attempts
+to parse each option into a variable of the specified type. The routine
+can parse integers and long integers in either decimal, octal, hexadecimal
+notation, unsigned integers and unsigned longs, strings and option switches.
+Option switches are simply boolean variables that get turned on if the
+switch was parsed.
+
+Parameters are extracted from the command line by calling a user supplied
+routine do_param() to handle each parameter as it is encountered. The
+routine do_param() should accept a pointer to the parameter on the command
+line 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 return
+ALLDONE 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.h
+
+PARAMETERS:
+num_opt - Number of options in the table
+optarr - Table of option descriptions
+
+REMARKS:
+Prints the description of each option in a standard format to the standard
+output device. The description for each option is obtained from the table
+of 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.h
+
+PARAMETERS:
+moduleName - Module name for program
+cmdLine - Command line to parse
+pargc - Pointer to 'argc' parameter
+pargv - Pointer to 'argv' parameter
+maxArgc - Maximum argv array index
+
+REMARKS:
+Parses a command line from a single string into the C style 'argc' and
+'argv' format. Most useful for Windows programs where the command line
+is 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);
+}