diff options
Diffstat (limited to 'generic/tkArgv.c')
-rw-r--r-- | generic/tkArgv.c | 467 |
1 files changed, 221 insertions, 246 deletions
diff --git a/generic/tkArgv.c b/generic/tkArgv.c index 4ee3b78..a338e45 100644 --- a/generic/tkArgv.c +++ b/generic/tkArgv.c @@ -1,85 +1,81 @@ /* * tkArgv.c -- * - * This file contains a procedure that handles table-based - * argv-argc parsing. + * This file contains a function that handles table-based argv-argc + * parsing. * * Copyright (c) 1990-1994 The Regents of the University of California. * Copyright (c) 1994-1997 Sun Microsystems, Inc. * - * See the file "license.terms" for information on usage and redistribution - * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include "tkPort.h" -#include "tk.h" +#include "tkInt.h" /* - * Default table of argument descriptors. These are normally available - * in every application. + * Default table of argument descriptors. These are normally available in + * every application. */ static Tk_ArgvInfo defaultTable[] = { - {"-help", TK_ARGV_HELP, (char *) NULL, (char *) NULL, + {"-help", TK_ARGV_HELP, NULL, NULL, "Print summary of command-line options and abort"}, - {NULL, TK_ARGV_END, (char *) NULL, (char *) NULL, - (char *) NULL} + {NULL, TK_ARGV_END, NULL, NULL, NULL} }; /* - * Forward declarations for procedures defined in this file: + * Forward declarations for functions defined in this file: */ -static void PrintUsage _ANSI_ARGS_((Tcl_Interp *interp, - Tk_ArgvInfo *argTable, int flags)); +static void PrintUsage(Tcl_Interp *interp, Tk_ArgvInfo *argTable, + int flags); /* *---------------------------------------------------------------------- * * Tk_ParseArgv -- * - * Process an argv array according to a table of expected - * command-line options. See the manual page for more details. + * Process an argv array according to a table of expected command-line + * options. See the manual page for more details. * * Results: - * The return value is a standard Tcl return value. If an - * error occurs then an error message is left in the interp's result. - * Under normal conditions, both *argcPtr and *argv are modified - * to return the arguments that couldn't be processed here (they - * didn't match the option table, or followed an TK_ARGV_REST - * argument). + * The return value is a standard Tcl return value. If an error occurs + * then an error message is left in the interp's result. Under normal + * conditions, both *argcPtr and *argv are modified to return the + * arguments that couldn't be processed here (they didn't match the + * option table, or followed an TK_ARGV_REST argument). * * Side effects: - * Variables may be modified, resources may be entered for tkwin, - * or procedures may be called. It all depends on the arguments - * and their entries in argTable. See the user documentation - * for details. + * Variables may be modified, resources may be entered for tkwin, or + * functions may be called. It all depends on the arguments and their + * entries in argTable. See the user documentation for details. * *---------------------------------------------------------------------- */ int -Tk_ParseArgv(interp, tkwin, argcPtr, argv, argTable, flags) - Tcl_Interp *interp; /* Place to store error message. */ - Tk_Window tkwin; /* Window to use for setting Tk options. - * NULL means ignore Tk option specs. */ - int *argcPtr; /* Number of arguments in argv. Modified - * to hold # args left in argv at end. */ - CONST char **argv; /* Array of arguments. Modified to hold - * those that couldn't be processed here. */ - Tk_ArgvInfo *argTable; /* Array of option descriptions */ - int flags; /* Or'ed combination of various flag bits, +Tk_ParseArgv( + Tcl_Interp *interp, /* Place to store error message. */ + Tk_Window tkwin, /* Window to use for setting Tk options. NULL + * means ignore Tk option specs. */ + int *argcPtr, /* Number of arguments in argv. Modified to + * hold # args left in argv at end. */ + CONST char **argv, /* Array of arguments. Modified to hold those + * that couldn't be processed here. */ + Tk_ArgvInfo *argTable, /* Array of option descriptions */ + int flags) /* Or'ed combination of various flag bits, * such as TK_ARGV_NO_DEFAULTS. */ { register Tk_ArgvInfo *infoPtr; - /* Pointer to the current entry in the - * table of argument descriptions. */ + /* Pointer to the current entry in the table + * of argument descriptions. */ Tk_ArgvInfo *matchPtr; /* Descriptor that matches current argument. */ CONST char *curArg; /* Current argument */ register char c; /* Second character of current arg (used for - * quick check for matching; use 2nd char. - * because first char. will almost always - * be '-'). */ + * quick check for matching; use 2nd char. + * because first char. will almost always be + * '-'). */ int srcIndex; /* Location from which to read next argument * from argv. */ int dstIndex; /* Index into argv to which next unused @@ -109,9 +105,8 @@ Tk_ParseArgv(interp, tkwin, argcPtr, argv, argTable, flags) } /* - * Loop throught the argument descriptors searching for one with - * the matching key string. If found, leave a pointer to it in - * matchPtr. + * Loop throught the argument descriptors searching for one with the + * matching key string. If found, leave a pointer to it in matchPtr. */ matchPtr = NULL; @@ -123,44 +118,43 @@ Tk_ParseArgv(interp, tkwin, argcPtr, argv, argTable, flags) } for (; (infoPtr != NULL) && (infoPtr->type != TK_ARGV_END); infoPtr++) { - if (infoPtr->key == NULL) { - continue; - } - if ((infoPtr->key[1] != c) - || (strncmp(infoPtr->key, curArg, length) != 0)) { - continue; - } - if ((tkwin == NULL) - && ((infoPtr->type == TK_ARGV_CONST_OPTION) - || (infoPtr->type == TK_ARGV_OPTION_VALUE) - || (infoPtr->type == TK_ARGV_OPTION_NAME_VALUE))) { - continue; - } - if (infoPtr->key[length] == 0) { - matchPtr = infoPtr; - goto gotMatch; - } - if (flags & TK_ARGV_NO_ABBREV) { - continue; - } - if (matchPtr != NULL) { - Tcl_AppendResult(interp, "ambiguous option \"", curArg, - "\"", (char *) NULL); - return TCL_ERROR; - } - matchPtr = infoPtr; + if (infoPtr->key == NULL) { + continue; + } + if ((infoPtr->key[1] != c) + || (strncmp(infoPtr->key, curArg, length) != 0)) { + continue; + } + if ((tkwin == NULL) + && ((infoPtr->type == TK_ARGV_CONST_OPTION) + || (infoPtr->type == TK_ARGV_OPTION_VALUE) + || (infoPtr->type == TK_ARGV_OPTION_NAME_VALUE))) { + continue; + } + if (infoPtr->key[length] == 0) { + matchPtr = infoPtr; + goto gotMatch; + } + if (flags & TK_ARGV_NO_ABBREV) { + continue; + } + if (matchPtr != NULL) { + Tcl_AppendResult(interp, "ambiguous option \"", curArg, + "\"", NULL); + return TCL_ERROR; + } + matchPtr = infoPtr; } } if (matchPtr == NULL) { - /* - * Unrecognized argument. Just copy it down, unless the caller + * Unrecognized argument. Just copy it down, unless the caller * prefers an error to be registered. */ if (flags & TK_ARGV_NO_LEFTOVERS) { Tcl_AppendResult(interp, "unrecognized argument \"", - curArg, "\"", (char *) NULL); + curArg, "\"", NULL); return TCL_ERROR; } argv[dstIndex] = curArg; @@ -172,154 +166,143 @@ Tk_ParseArgv(interp, tkwin, argcPtr, argv, argTable, flags) * Take the appropriate action based on the option type */ - gotMatch: + gotMatch: infoPtr = matchPtr; switch (infoPtr->type) { - case TK_ARGV_CONSTANT: - *((int *) infoPtr->dst) = (int) infoPtr->src; - break; - case TK_ARGV_INT: - if (argc == 0) { - goto missingArg; - } else { - char *endPtr; - - *((int *) infoPtr->dst) = - strtol(argv[srcIndex], &endPtr, 0); - if ((endPtr == argv[srcIndex]) || (*endPtr != 0)) { - Tcl_AppendResult(interp, "expected integer argument ", - "for \"", infoPtr->key, "\" but got \"", - argv[srcIndex], "\"", (char *) NULL); - return TCL_ERROR; - } - srcIndex++; - argc--; - } - break; - case TK_ARGV_STRING: - if (argc == 0) { - goto missingArg; - } else { - *((CONST char **)infoPtr->dst) = argv[srcIndex]; - srcIndex++; - argc--; - } - break; - case TK_ARGV_UID: - if (argc == 0) { - goto missingArg; - } else { - *((Tk_Uid *)infoPtr->dst) = Tk_GetUid(argv[srcIndex]); - srcIndex++; - argc--; - } - break; - case TK_ARGV_REST: - *((int *) infoPtr->dst) = dstIndex; - goto argsDone; - case TK_ARGV_FLOAT: - if (argc == 0) { - goto missingArg; - } else { - char *endPtr; - - *((double *) infoPtr->dst) = - strtod(argv[srcIndex], &endPtr); - if ((endPtr == argv[srcIndex]) || (*endPtr != 0)) { - Tcl_AppendResult(interp, "expected floating-point ", - "argument for \"", infoPtr->key, - "\" but got \"", argv[srcIndex], "\"", - (char *) NULL); - return TCL_ERROR; - } - srcIndex++; - argc--; - } - break; - case TK_ARGV_FUNC: { - typedef int (ArgvFunc) _ANSI_ARGS_ ((char *, char *, - CONST char *)); - ArgvFunc *handlerProc; + case TK_ARGV_CONSTANT: + *((int *) infoPtr->dst) = PTR2INT(infoPtr->src); + break; + case TK_ARGV_INT: + if (argc == 0) { + goto missingArg; + } else { + char *endPtr; - handlerProc = (ArgvFunc *) infoPtr->src; - if ((*handlerProc)(infoPtr->dst, infoPtr->key, - argv[srcIndex])) { - srcIndex += 1; - argc -= 1; + *((int *) infoPtr->dst) = strtol(argv[srcIndex], &endPtr, 0); + if ((endPtr == argv[srcIndex]) || (*endPtr != 0)) { + Tcl_AppendResult(interp,"expected integer argument for \"", + infoPtr->key, "\" but got \"", argv[srcIndex], + "\"", NULL); + return TCL_ERROR; } - break; + srcIndex++; + argc--; + } + break; + case TK_ARGV_STRING: + if (argc == 0) { + goto missingArg; + } + *((CONST char **)infoPtr->dst) = argv[srcIndex]; + srcIndex++; + argc--; + break; + case TK_ARGV_UID: + if (argc == 0) { + goto missingArg; } - case TK_ARGV_GENFUNC: { - typedef int (ArgvGenFunc)_ANSI_ARGS_((char *, Tcl_Interp *, - char *, int, CONST char **)); - ArgvGenFunc *handlerProc; + *((Tk_Uid *)infoPtr->dst) = Tk_GetUid(argv[srcIndex]); + srcIndex++; + argc--; + break; + case TK_ARGV_REST: + *((int *) infoPtr->dst) = dstIndex; + goto argsDone; + case TK_ARGV_FLOAT: + if (argc == 0) { + goto missingArg; + } else { + char *endPtr; - handlerProc = (ArgvGenFunc *) infoPtr->src; - argc = (*handlerProc)(infoPtr->dst, interp, infoPtr->key, - argc, argv+srcIndex); - if (argc < 0) { + *((double *) infoPtr->dst) = strtod(argv[srcIndex], &endPtr); + if ((endPtr == argv[srcIndex]) || (*endPtr != 0)) { + Tcl_AppendResult(interp, "expected floating-point ", + "argument for \"", infoPtr->key, "\" but got \"", + argv[srcIndex], "\"", NULL); return TCL_ERROR; } - break; + srcIndex++; + argc--; } - case TK_ARGV_HELP: - PrintUsage (interp, argTable, flags); - return TCL_ERROR; - case TK_ARGV_CONST_OPTION: - Tk_AddOption(tkwin, infoPtr->dst, infoPtr->src, - TK_INTERACTIVE_PRIO); - break; - case TK_ARGV_OPTION_VALUE: - if (argc < 1) { - goto missingArg; - } - Tk_AddOption(tkwin, infoPtr->dst, argv[srcIndex], - TK_INTERACTIVE_PRIO); + break; + case TK_ARGV_FUNC: { + typedef int (ArgvFunc)(char *, char *, CONST char *); + ArgvFunc *handlerProc = (ArgvFunc *) infoPtr->src; + + if ((*handlerProc)(infoPtr->dst, infoPtr->key, argv[srcIndex])) { srcIndex++; argc--; - break; - case TK_ARGV_OPTION_NAME_VALUE: - if (argc < 2) { - Tcl_AppendResult(interp, "\"", curArg, - "\" option requires two following arguments", - (char *) NULL); - return TCL_ERROR; - } - Tk_AddOption(tkwin, argv[srcIndex], argv[srcIndex+1], - TK_INTERACTIVE_PRIO); - srcIndex += 2; - argc -= 2; - break; - default: { - char buf[64 + TCL_INTEGER_SPACE]; - - sprintf(buf, "bad argument type %d in Tk_ArgvInfo", - infoPtr->type); - Tcl_SetResult(interp, buf, TCL_VOLATILE); + } + break; + } + case TK_ARGV_GENFUNC: { + typedef int (ArgvGenFunc)(char *, Tcl_Interp *, char *, int, + CONST char **); + ArgvGenFunc *handlerProc = (ArgvGenFunc *) infoPtr->src; + + argc = (*handlerProc)(infoPtr->dst, interp, infoPtr->key, + argc, argv+srcIndex); + if (argc < 0) { + return TCL_ERROR; + } + break; + } + case TK_ARGV_HELP: + PrintUsage(interp, argTable, flags); + return TCL_ERROR; + case TK_ARGV_CONST_OPTION: + Tk_AddOption(tkwin, infoPtr->dst, infoPtr->src, + TK_INTERACTIVE_PRIO); + break; + case TK_ARGV_OPTION_VALUE: + if (argc < 1) { + goto missingArg; + } + Tk_AddOption(tkwin, infoPtr->dst, argv[srcIndex], + TK_INTERACTIVE_PRIO); + srcIndex++; + argc--; + break; + case TK_ARGV_OPTION_NAME_VALUE: + if (argc < 2) { + Tcl_AppendResult(interp, "\"", curArg, + "\" option requires two following arguments", NULL); return TCL_ERROR; } + Tk_AddOption(tkwin, argv[srcIndex], argv[srcIndex+1], + TK_INTERACTIVE_PRIO); + srcIndex += 2; + argc -= 2; + break; + default: { + char buf[64 + TCL_INTEGER_SPACE]; + + sprintf(buf, "bad argument type %d in Tk_ArgvInfo", infoPtr->type); + Tcl_SetResult(interp, buf, TCL_VOLATILE); + return TCL_ERROR; + } } } /* - * If we broke out of the loop because of an OPT_REST argument, - * copy the remaining arguments down. + * If we broke out of the loop because of an OPT_REST argument, copy the + * remaining arguments down. */ - argsDone: + argsDone: while (argc) { argv[dstIndex] = argv[srcIndex]; srcIndex++; dstIndex++; argc--; } - argv[dstIndex] = (char *) NULL; + argv[dstIndex] = NULL; *argcPtr = dstIndex; return TCL_OK; - missingArg: + missingArg: Tcl_AppendResult(interp, "\"", curArg, - "\" option requires an additional argument", (char *) NULL); + "\" option requires an additional argument", NULL); return TCL_ERROR; } @@ -331,10 +314,9 @@ Tk_ParseArgv(interp, tkwin, argcPtr, argv, argTable, flags) * Generate a help string describing command-line options. * * Results: - * The interp's result will be modified to hold a help string - * describing all the options in argTable, plus all those - * in the default table unless TK_ARGV_NO_DEFAULTS is - * specified in flags. + * The interp's result will be modified to hold a help string describing + * all the options in argTable, plus all those in the default table + * unless TK_ARGV_NO_DEFAULTS is specified in flags. * * Side effects: * None. @@ -343,31 +325,29 @@ Tk_ParseArgv(interp, tkwin, argcPtr, argv, argTable, flags) */ static void -PrintUsage(interp, argTable, flags) - Tcl_Interp *interp; /* Place information in this interp's - * result area. */ - Tk_ArgvInfo *argTable; /* Array of command-specific argument +PrintUsage( + Tcl_Interp *interp, /* Place information in this interp's result + * area. */ + Tk_ArgvInfo *argTable, /* Array of command-specific argument * descriptions. */ - int flags; /* If the TK_ARGV_NO_DEFAULTS bit is set - * in this word, then don't generate - * information for default options. */ + int flags) /* If the TK_ARGV_NO_DEFAULTS bit is set in + * this word, then don't generate information + * for default options. */ { register Tk_ArgvInfo *infoPtr; - int width, i, numSpaces; -#define NUM_SPACES 20 - static CONST char spaces[] = " "; + size_t width, i, numSpaces; char tmp[TCL_DOUBLE_SPACE]; /* - * First, compute the width of the widest option key, so that we - * can make everything line up. + * First, compute the width of the widest option key, so that we can make + * everything line up. */ width = 4; for (i = 0; i < 2; i++) { for (infoPtr = i ? defaultTable : argTable; infoPtr->type != TK_ARGV_END; infoPtr++) { - int length; + size_t length; if (infoPtr->key == NULL) { continue; } @@ -378,59 +358,54 @@ PrintUsage(interp, argTable, flags) } } - Tcl_AppendResult(interp, "Command-specific options:", (char *) NULL); + Tcl_AppendResult(interp, "Command-specific options:", NULL); for (i = 0; ; i++) { for (infoPtr = i ? defaultTable : argTable; infoPtr->type != TK_ARGV_END; infoPtr++) { if ((infoPtr->type == TK_ARGV_HELP) && (infoPtr->key == NULL)) { - Tcl_AppendResult(interp, "\n", infoPtr->help, (char *) NULL); + Tcl_AppendResult(interp, "\n", infoPtr->help, NULL); continue; } - Tcl_AppendResult(interp, "\n ", infoPtr->key, ":", (char *) NULL); + Tcl_AppendResult(interp, "\n ", infoPtr->key, ":", NULL); numSpaces = width + 1 - strlen(infoPtr->key); - while (numSpaces > 0) { - if (numSpaces >= NUM_SPACES) { - Tcl_AppendResult(interp, spaces, (char *) NULL); - } else { - Tcl_AppendResult(interp, spaces+NUM_SPACES-numSpaces, - (char *) NULL); - } - numSpaces -= NUM_SPACES; + while (numSpaces-- > 0) { + Tcl_AppendResult(interp, " ", NULL); } - Tcl_AppendResult(interp, infoPtr->help, (char *) NULL); + Tcl_AppendResult(interp, infoPtr->help, NULL); switch (infoPtr->type) { - case TK_ARGV_INT: { - sprintf(tmp, "%d", *((int *) infoPtr->dst)); - Tcl_AppendResult(interp, "\n\t\tDefault value: ", - tmp, (char *) NULL); - break; - } - case TK_ARGV_FLOAT: { - sprintf(tmp, "%g", *((double *) infoPtr->dst)); - Tcl_AppendResult(interp, "\n\t\tDefault value: ", - tmp, (char *) NULL); - break; - } - case TK_ARGV_STRING: { - char *string; + case TK_ARGV_INT: + sprintf(tmp, "%d", *((int *) infoPtr->dst)); + Tcl_AppendResult(interp, "\n\t\tDefault value: ", tmp, NULL); + break; + case TK_ARGV_FLOAT: + Tcl_PrintDouble(NULL, *((double *) infoPtr->dst), tmp); + Tcl_AppendResult(interp, "\n\t\tDefault value: ", tmp, NULL); + break; + case TK_ARGV_STRING: { + char *string = *((char **) infoPtr->dst); - string = *((char **) infoPtr->dst); - if (string != NULL) { - Tcl_AppendResult(interp, "\n\t\tDefault value: \"", - string, "\"", (char *) NULL); - } - break; - } - default: { - break; + if (string != NULL) { + Tcl_AppendResult(interp, "\n\t\tDefault value: \"", string, + "\"", NULL); } + break; + } + default: + break; } } if ((flags & TK_ARGV_NO_DEFAULTS) || (i > 0)) { break; } - Tcl_AppendResult(interp, "\nGeneric options for all commands:", - (char *) NULL); + Tcl_AppendResult(interp, "\nGeneric options for all commands:", NULL); } } + +/* + * Local Variables: + * mode: c + * c-basic-offset: 4 + * fill-column: 78 + * End: + */ |