diff options
author | dkf <donal.k.fellows@manchester.ac.uk> | 2007-06-24 16:07:34 (GMT) |
---|---|---|
committer | dkf <donal.k.fellows@manchester.ac.uk> | 2007-06-24 16:07:34 (GMT) |
commit | b699b7f784bb3d3a71abd9a58580388514f4566e (patch) | |
tree | d6a57b5bb125238dcf67ca7c92fe84e4400d2916 /generic/tkArgv.c | |
parent | fa02a33e1916c8b6d2ba0318fc8b74f42e069808 (diff) | |
download | tk-b699b7f784bb3d3a71abd9a58580388514f4566e.zip tk-b699b7f784bb3d3a71abd9a58580388514f4566e.tar.gz tk-b699b7f784bb3d3a71abd9a58580388514f4566e.tar.bz2 |
Cleaning up whitespace, comments, declarations. No functional changes.
Diffstat (limited to 'generic/tkArgv.c')
-rw-r--r-- | generic/tkArgv.c | 847 |
1 files changed, 421 insertions, 426 deletions
diff --git a/generic/tkArgv.c b/generic/tkArgv.c index c1eb479..d0bfd77 100644 --- a/generic/tkArgv.c +++ b/generic/tkArgv.c @@ -1,426 +1,421 @@ -/* - * tkArgv.c -- - * - * 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. - * - * RCS: @(#) $Id: tkArgv.c,v 1.5 2005/11/04 11:52:50 dkf Exp $ - */ - -#include "tkPort.h" -#include "tk.h" - -/* - * Default table of argument descriptors. These are normally available in - * every application. - */ - -static Tk_ArgvInfo defaultTable[] = { - {"-help", TK_ARGV_HELP, NULL, NULL, - "Print summary of command-line options and abort"}, - {NULL, TK_ARGV_END, NULL, NULL, NULL} -}; - -/* - * Forward declarations for functions defined in this file: - */ - -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. - * - * 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). - * - * Side effects: - * 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( - 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. */ - 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 - * '-'). */ - int srcIndex; /* Location from which to read next argument - * from argv. */ - int dstIndex; /* Index into argv to which next unused - * argument should be copied (never greater - * than srcIndex). */ - int argc; /* # arguments in argv still to process. */ - size_t length; /* Number of characters in current argument. */ - int i; - - if (flags & TK_ARGV_DONT_SKIP_FIRST_ARG) { - srcIndex = dstIndex = 0; - argc = *argcPtr; - } else { - srcIndex = dstIndex = 1; - argc = *argcPtr-1; - } - - while (argc > 0) { - curArg = argv[srcIndex]; - srcIndex++; - argc--; - length = strlen(curArg); - if (length > 0) { - c = curArg[1]; - } else { - c = 0; - } - - /* - * Loop throught the argument descriptors searching for one with the - * matching key string. If found, leave a pointer to it in matchPtr. - */ - - matchPtr = NULL; - for (i = 0; i < 2; i++) { - if (i == 0) { - infoPtr = argTable; - } else { - infoPtr = defaultTable; - } - 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, - "\"", NULL); - return TCL_ERROR; - } - matchPtr = infoPtr; - } - } - if (matchPtr == NULL) { - - /* - * 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, "\"", NULL); - return TCL_ERROR; - } - argv[dstIndex] = curArg; - dstIndex++; - continue; - } - - /* - * Take the appropriate action based on the option type - */ - - 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],"\"", - 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], "\"", NULL); - return TCL_ERROR; - } - srcIndex++; - argc--; - } - break; - case TK_ARGV_FUNC: { - typedef int (ArgvFunc)(char *, char *, CONST char *); - ArgvFunc *handlerProc; - - handlerProc = (ArgvFunc *) infoPtr->src; - if ((*handlerProc)(infoPtr->dst, infoPtr->key, argv[srcIndex])) { - srcIndex += 1; - argc -= 1; - } - break; - } - case TK_ARGV_GENFUNC: { - typedef int (ArgvGenFunc)(char *, Tcl_Interp *, char *, int, - CONST char **); - ArgvGenFunc *handlerProc; - - 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. - */ - - argsDone: - while (argc) { - argv[dstIndex] = argv[srcIndex]; - srcIndex++; - dstIndex++; - argc--; - } - argv[dstIndex] = NULL; - *argcPtr = dstIndex; - return TCL_OK; - - missingArg: - Tcl_AppendResult(interp, "\"", curArg, - "\" option requires an additional argument", NULL); - return TCL_ERROR; -} - -/* - *---------------------------------------------------------------------- - * - * PrintUsage -- - * - * 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. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -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. */ -{ - register Tk_ArgvInfo *infoPtr; - int width, i, numSpaces; -#define NUM_SPACES 20 - static char spaces[] = " "; - char tmp[TCL_DOUBLE_SPACE]; - - /* - * 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; - if (infoPtr->key == NULL) { - continue; - } - length = strlen(infoPtr->key); - if (length > width) { - width = length; - } - } - } - - 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, NULL); - continue; - } - Tcl_AppendResult(interp, "\n ", infoPtr->key, ":", NULL); - numSpaces = width + 1 - strlen(infoPtr->key); - while (numSpaces > 0) { - if (numSpaces >= NUM_SPACES) { - Tcl_AppendResult(interp, spaces, NULL); - } else { - Tcl_AppendResult(interp, spaces+NUM_SPACES-numSpaces,NULL); - } - numSpaces -= NUM_SPACES; - } - 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, NULL); - break; - case TK_ARGV_FLOAT: - sprintf(tmp, "%g", *((double *) infoPtr->dst)); - Tcl_AppendResult(interp, "\n\t\tDefault value: ", tmp, NULL); - break; - case TK_ARGV_STRING: { - char *string = *((char **) infoPtr->dst); - - 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:", NULL); - } -} - -/* - * Local Variables: - * mode: c - * c-basic-offset: 4 - * fill-column: 78 - * End: - */ +/*
+ * tkArgv.c --
+ *
+ * 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.
+ *
+ * RCS: @(#) $Id: tkArgv.c,v 1.6 2007/06/24 16:07:34 dkf Exp $
+ */
+
+#include "tkPort.h"
+#include "tk.h"
+
+/*
+ * Default table of argument descriptors. These are normally available in
+ * every application.
+ */
+
+static Tk_ArgvInfo defaultTable[] = {
+ {"-help", TK_ARGV_HELP, NULL, NULL,
+ "Print summary of command-line options and abort"},
+ {NULL, TK_ARGV_END, NULL, NULL, NULL}
+};
+
+/*
+ * Forward declarations for functions defined in this file:
+ */
+
+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.
+ *
+ * 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).
+ *
+ * Side effects:
+ * 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(
+ 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. */
+ 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
+ * '-'). */
+ int srcIndex; /* Location from which to read next argument
+ * from argv. */
+ int dstIndex; /* Index into argv to which next unused
+ * argument should be copied (never greater
+ * than srcIndex). */
+ int argc; /* # arguments in argv still to process. */
+ size_t length; /* Number of characters in current argument. */
+ int i;
+
+ if (flags & TK_ARGV_DONT_SKIP_FIRST_ARG) {
+ srcIndex = dstIndex = 0;
+ argc = *argcPtr;
+ } else {
+ srcIndex = dstIndex = 1;
+ argc = *argcPtr-1;
+ }
+
+ while (argc > 0) {
+ curArg = argv[srcIndex];
+ srcIndex++;
+ argc--;
+ length = strlen(curArg);
+ if (length > 0) {
+ c = curArg[1];
+ } else {
+ c = 0;
+ }
+
+ /*
+ * Loop throught the argument descriptors searching for one with the
+ * matching key string. If found, leave a pointer to it in matchPtr.
+ */
+
+ matchPtr = NULL;
+ for (i = 0; i < 2; i++) {
+ if (i == 0) {
+ infoPtr = argTable;
+ } else {
+ infoPtr = defaultTable;
+ }
+ 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,
+ "\"", NULL);
+ return TCL_ERROR;
+ }
+ matchPtr = infoPtr;
+ }
+ }
+ if (matchPtr == NULL) {
+ /*
+ * 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, "\"", NULL);
+ return TCL_ERROR;
+ }
+ argv[dstIndex] = curArg;
+ dstIndex++;
+ continue;
+ }
+
+ /*
+ * Take the appropriate action based on the option type
+ */
+
+ 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],
+ "\"", NULL);
+ return TCL_ERROR;
+ }
+ 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;
+ }
+ *((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], "\"", NULL);
+ return TCL_ERROR;
+ }
+ srcIndex++;
+ argc--;
+ }
+ 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_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.
+ */
+
+ argsDone:
+ while (argc) {
+ argv[dstIndex] = argv[srcIndex];
+ srcIndex++;
+ dstIndex++;
+ argc--;
+ }
+ argv[dstIndex] = NULL;
+ *argcPtr = dstIndex;
+ return TCL_OK;
+
+ missingArg:
+ Tcl_AppendResult(interp, "\"", curArg,
+ "\" option requires an additional argument", NULL);
+ return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * PrintUsage --
+ *
+ * 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.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+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. */
+{
+ register Tk_ArgvInfo *infoPtr;
+ int width, i, numSpaces;
+#define NUM_SPACES 20
+ static char spaces[] = " ";
+ char tmp[TCL_DOUBLE_SPACE];
+
+ /*
+ * 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;
+ if (infoPtr->key == NULL) {
+ continue;
+ }
+ length = strlen(infoPtr->key);
+ if (length > width) {
+ width = length;
+ }
+ }
+ }
+
+ 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, NULL);
+ continue;
+ }
+ Tcl_AppendResult(interp, "\n ", infoPtr->key, ":", NULL);
+ numSpaces = width + 1 - strlen(infoPtr->key);
+ while (numSpaces > 0) {
+ if (numSpaces >= NUM_SPACES) {
+ Tcl_AppendResult(interp, spaces, NULL);
+ } else {
+ Tcl_AppendResult(interp, spaces+NUM_SPACES-numSpaces,NULL);
+ }
+ numSpaces -= NUM_SPACES;
+ }
+ 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, NULL);
+ break;
+ case TK_ARGV_FLOAT:
+ sprintf(tmp, "%g", *((double *) infoPtr->dst));
+ Tcl_AppendResult(interp, "\n\t\tDefault value: ", tmp, NULL);
+ break;
+ case TK_ARGV_STRING: {
+ char *string = *((char **) infoPtr->dst);
+
+ 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:", NULL);
+ }
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
|