head	1.18;
access;
symbols
	core-8-5-9:1.11.2.3
	core-8-5-8:1.11.2.3
	macosx-cocoa-merge:1.17
	macosx-cocoa-premerge:1.17
	macosx-carbon-freeze:1.17
	core-8-5-7:1.11.2.3
	core-8-5-6:1.11.2.3
	core-8-6-b1:1.17
	core-8-6-a3:1.15
	core-8-5-5:1.11.2.3
	core-8-6-a2:1.14
	core-8-5-4:1.11.2.2
	core-8-5-3:1.11.2.2
	core-8-6-a1:1.14
	core-8-4-19:1.4
	core-8-5-branch:1.11.0.2
	core-8-5-2:1.11
	core-8-4-18:1.4
	core-8-5-1:1.11
	core-8-4-17:1.4
	core-8-5-0:1.11
	core-8-5-b3:1.10
	core-8-5-b2:1.9
	core-8-4-16:1.4
	core-8-5-b1:1.8
	core-stablilizer-merge:1.7
	core-stabilizer-branch:1.5.0.2
	core-stabilizer-merge:1.11.2.2
	core-8-4-15:1.4
	core-8-5-a6:1.5
	core-8-5-a5:1.5
	core-8-4-14:1.4
	core-8-5-a4:1.5
	core-8-4-13:1.4
	core-8-4-12:1.4
	core-8-4-11:1.4
	core-8-5-a3:1.4
	core-8-4-10:1.4
	core-8-4-9-branch:1.4.0.6
	core-8-5-a2:1.4
	core-8-4-9:1.4
	core-8-4-8:1.4
	core-8-4-7:1.4
	core-8-5-a1:1.4
	core-8-4-6:1.4
	core-8-4-5:1.4
	mistachkin-dev-branch:1.4.0.4
	core-8-4-4:1.4
	core-8-4-3:1.4
	core-8-4-branch:1.4.0.2
	core-8-4-2:1.4
	core-8-4-1:1.4
	core-8-3-5:1.3
	core-8-4-0:1.4
	macosx-8-4-merge-2002-08-31-trunk:1.4
	macosx-8-4-premerge-2002-08-31-branch:1.3.18.1
	macosx-8-4-premerge-2002-08-31-trunk:1.4
	macosx-8-4-merge-2002-08-30-branch:1.3.18.1
	macosx-8-4-merge-2002-08-30-trunk:1.4
	macosx-8-4-merge-2002-08-20-branch:1.3.18.1
	macosx-8-4-merge-2002-08-20-trunk:1.4
	core-8-4-b2:1.4
	core-8-4-b1:1.4
	macosx-premerge-6-9-02:1.3.18.1
	core-8-4-a4:1.4
	core-8-3-4:1.3
	macosx-8-4-branch:1.3.0.18
	macosx-8-4-branchpoint:1.3
	core-8-4-a3:1.3
	core-8-3-3:1.3
	dgp-privates-into-namespace:1.3.0.16
	tclpro-1-5-0:1.3
	core-8-4-win-speedup:1.3.0.14
	core-8-4-a2:1.3
	tclpro-1-4-1:1.3
	tclpro-1-4-0:1.3
	core-8-3-2:1.3
	ajuba-ajuba2-2-1-base:1.3
	ajuba-ajuba2-2-0:1.3
	core-8-4-a1:1.3
	core-8-3-1-branch:1.3.0.12
	core-8-3-1:1.3
	scriptics-sc-2-0-b5:1.3
	scriptics-sc-2-0-fixed:1.3
	scriptics-sc-2-0-b2:1.3
	scriptics-sc-2-0-b1:1.3
	core-8-3-0:1.3
	core-8-3-b2:1.3
	core-8-3-b1:1.3
	scriptics-sc-1-1:1.3
	scriptics-sc-1-1-b1:1.3
	core-8-2-3:1.3
	scriptics-sc-1-1-branch:1.3.0.10
	scriptics-sc-1-1-base:1.3
	scriptics-sc-1-0:1.3
	scriptics-sc-1-0-branch:1.3.0.8
	scriptics-sc-1-0-base:1.3
	core-8-2-2:1.3
	core-8-2-1:1.3
	scriptics-bc-1-0-b1:1.3
	core-8-2-1-branch:1.3.0.6
	scriptics-tclpro-1-3-0:1.3
	core-8-2-0:1.3
	core-8-2-b3-branch:1.3.0.4
	core-8-2-b3-base:1.3
	scriptics-tclpro-1-3-b4:1.3
	core-8-2-b2:1.3
	scriptics-tclpro-1-3-b3:1.3
	core-8-2-b1:1.3
	scriptics-tclpro-1-3-b2:1.3
	merge-to-mainline-5/21/99:1.3
	scriptics-tclpro-1-3-b2-branch:1.3.0.2
	core-8-1-1:1.3
	scriptics-tclpro-1-3-b1:1.3
	core-8-1-1-base:1.3
	core-8-1-0:1.3
	merge-to-mainline-4-29-99:1.3
	merge-to-mainline-4-23-99:1.3
	core-8-1-branch-old:1.1.0.4
	core-8-0-6-branch:1.2.0.6
	core-8-0-6-base:1.2
	core-8-0-5:1.2
	core-8-1-b3:1.1.4.2
	core-8-1-b2:1.1.4.2
	dev-8-1-stubs-branch:1.1.4.2.0.2
	dev-stubs-branch:1.2.0.4
	scriptics-tclpro-1-2:1.2
	scriptics-tclpro-1-2-b2:1.2
	core-8-1-merge-2/10/99:1.2
	core-8-0-5-branch:1.2.0.2
	core-8-0-5-base:1.2
	scriptics-tclpro-1-2-b1:1.2
	scriptics-tclpro-1-2-a1:1.2
	core-8-1-b1:1.1.4.2
	core-8-0-4:1.2
	core-8-1-a2:1.1.4.1
	core-8-0-2:1.1
	core-8-0-3:1.2;
locks; strict;
comment	@ * @;


1.18
date	2010.02.16.21.12.56;	author nijtmans;	state Exp;
branches;
next	1.17;

1.17
date	2008.11.08.18.44.39;	author dkf;	state Exp;
branches;
next	1.16;

1.16
date	2008.10.28.22.33.06;	author nijtmans;	state Exp;
branches;
next	1.15;

1.15
date	2008.10.03.13.13.31;	author dkf;	state Exp;
branches;
next	1.14;

1.14
date	2008.04.27.22.38.55;	author dkf;	state Exp;
branches;
next	1.13;

1.13
date	2008.04.07.22.27.41;	author hobbs;	state Exp;
branches;
next	1.12;

1.12
date	2008.04.07.18.39.36;	author hobbs;	state Exp;
branches;
next	1.11;

1.11
date	2007.12.13.15.24.13;	author dgp;	state Exp;
branches
	1.11.2.1;
next	1.10;

1.10
date	2007.11.17.23.07.45;	author patthoyts;	state Exp;
branches;
next	1.9;

1.9
date	2007.10.15.07.24.48;	author das;	state Exp;
branches;
next	1.8;

1.8
date	2007.09.07.00.34.51;	author dgp;	state Exp;
branches;
next	1.7;

1.7
date	2007.06.25.19.07.15;	author dgp;	state Exp;
branches;
next	1.6;

1.6
date	2007.06.24.16.07.34;	author dkf;	state Exp;
branches;
next	1.5;

1.5
date	2005.11.04.11.52.50;	author dkf;	state Exp;
branches
	1.5.2.1;
next	1.4;

1.4
date	2002.01.25.21.09.36;	author dgp;	state Exp;
branches;
next	1.3;

1.3
date	99.04.16.01.51.10;	author stanton;	state Exp;
branches
	1.3.14.1
	1.3.18.1;
next	1.2;

1.2
date	98.09.14.18.23.03;	author stanton;	state Exp;
branches;
next	1.1;

1.1
date	98.04.01.09.51.50;	author rjohnson;	state Exp;
branches
	1.1.4.1;
next	;

1.1.4.1
date	98.09.29.00.25.11;	author stanton;	state Exp;
branches;
next	1.1.4.2;

1.1.4.2
date	98.09.30.02.16.37;	author stanton;	state Exp;
branches;
next	;

1.3.14.1
date	2002.04.02.21.00.46;	author hobbs;	state Exp;
branches;
next	;

1.3.18.1
date	2002.02.05.02.25.14;	author wolfsuit;	state Exp;
branches;
next	;

1.5.2.1
date	2007.06.25.19.12.12;	author dgp;	state Exp;
branches;
next	1.5.2.2;

1.5.2.2
date	2007.09.07.01.25.33;	author dgp;	state Exp;
branches;
next	1.5.2.3;

1.5.2.3
date	2007.10.15.18.38.32;	author dgp;	state Exp;
branches;
next	1.5.2.4;

1.5.2.4
date	2007.11.21.16.46.26;	author dgp;	state Exp;
branches;
next	1.5.2.5;

1.5.2.5
date	2008.06.25.16.46.03;	author dgp;	state Exp;
branches;
next	;

1.11.2.1
date	2008.04.07.18.38.01;	author hobbs;	state Exp;
branches;
next	1.11.2.2;

1.11.2.2
date	2008.04.07.22.27.21;	author hobbs;	state Exp;
branches;
next	1.11.2.3;

1.11.2.3
date	2008.10.05.11.34.46;	author dkf;	state Exp;
branches;
next	;


desc
@@


1.18
log
@tkWindow.c/tkStubInit.c adapted from stub changes in Tcl
tkArgv.c      make defaultTable const
tkScrollbar.c Store default for "-with" in static non-const memory
tkWinInt.h        make tkWinProcs const, and 5
tkWinX.c          procs MODULE_SCOPE
tkWinColor.c      make sysColors const
tkWinKey.c        make keymap const
tkWinScrlbr.c     Simplify copying of "-with" default value.
tkUnixWm.c       make TkSetTransientFor static
tests/textImage.test  textImage-1.13 depends on hash-order
@
text
@/*
 * 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.17 2008/11/08 18:44:39 dkf Exp $
 */

#include "tkInt.h"

/*
 * Default table of argument descriptors. These are normally available in
 * every application.
 */

static const 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, const 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. */
    const Tk_ArgvInfo *argTable,	/* Array of option descriptions */
    int flags)			/* Or'ed combination of various flag bits,
				 * such as TK_ARGV_NO_DEFAULTS. */
{
    register const Tk_ArgvInfo *infoPtr;
				/* Pointer to the current entry in the table
				 * of argument descriptions. */
    const 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) = PTR2INT(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 *, const 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 *, const 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. */
    const 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 const Tk_ArgvInfo *infoPtr;
    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.
     */

    width = 4;
    for (i = 0; i < 2; i++) {
	for (infoPtr = i ? defaultTable : argTable;
		infoPtr->type != TK_ARGV_END; infoPtr++) {
	    size_t 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) {
		Tcl_AppendResult(interp, " ", 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, 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);

		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:
 */
@


1.17
log
@Lots of small changes to make code more pretty and C89-like.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkArgv.c,v 1.16 2008/10/28 22:33:06 nijtmans Exp $
d23 1
a23 1
static Tk_ArgvInfo defaultTable[] = {
@


1.16
log
@CONSTify TkPrintPadAmount, TkCreateFrame, TkCreateMainWindow
and Tk_ParseArgv. move TkSelGetSelection to internal stub table
(needed in tkWinTest.c)
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkArgv.c,v 1.15 2008/10/03 13:13:31 dkf Exp $
d234 1
a234 1
	    if ((*handlerProc)(infoPtr->dst, infoPtr->key, argv[srcIndex])) {
d245 2
a246 2
	    argc = (*handlerProc)(infoPtr->dst, interp, infoPtr->key,
		    argc, argv+srcIndex);
@


1.15
log
@Convert %g to Tcl_PrintDouble to avoid locale trouble. [Bug 2112563]
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkArgv.c,v 1.14 2008/04/27 22:38:55 dkf Exp $
d33 1
a33 1
static void	PrintUsage(Tcl_Interp *interp, Tk_ArgvInfo *argTable,
d68 1
a68 1
    Tk_ArgvInfo *argTable,	/* Array of option descriptions */
d72 1
a72 1
    register Tk_ArgvInfo *infoPtr;
d75 1
a75 1
    Tk_ArgvInfo *matchPtr;	/* Descriptor that matches current argument. */
d231 1
a231 1
	    typedef int (ArgvFunc)(char *, char *, const char *);
d241 1
a241 1
	    typedef int (ArgvGenFunc)(char *, Tcl_Interp *, char *, int,
d333 1
a333 1
    Tk_ArgvInfo *argTable,	/* Array of command-specific argument
d339 1
a339 1
    register Tk_ArgvInfo *infoPtr;
@


1.14
log
@Get rid of pre-C89-isms (esp. CONST vs const).
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkArgv.c,v 1.13 2008/04/07 22:27:41 hobbs Exp $
d383 1
a383 1
		sprintf(tmp, "%g", *((double *) infoPtr->dst));
@


1.13
log
@use kenny variant for 1936238 fix
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkArgv.c,v 1.12 2008/04/07 18:39:36 hobbs Exp $
d66 1
a66 1
    CONST char **argv,		/* Array of arguments. Modified to hold those
d76 1
a76 1
    CONST char *curArg;		/* Current argument */
d198 1
a198 1
	    *((CONST char **)infoPtr->dst) = argv[srcIndex];
d231 1
a231 1
	    typedef int (ArgvFunc)(char *, char *, CONST char *);
d242 1
a242 1
		    CONST char **);
@


1.12
log
@	* generic/tkArgv.c: fix -help mem explosion. [Bug 1936238] (bachmann)
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkArgv.c,v 1.11 2007/12/13 15:24:13 dgp Exp $
d340 1
a340 4
    size_t width, i;
    int numSpaces; /* must be int to allow for negative values */
#define NUM_SPACES 20
    static char spaces[] = "                    ";
d373 2
a374 7
	    while (numSpaces > 0) {
		if (numSpaces >= NUM_SPACES) {
		    Tcl_AppendResult(interp, spaces, NULL);
		} else {
		    Tcl_AppendResult(interp, spaces+NUM_SPACES-numSpaces,NULL);
		}
		numSpaces -= NUM_SPACES;
@


1.11
log
@merge stable branch onto HEAD
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkArgv.c,v 1.5.2.4 2007/11/21 16:46:26 dgp Exp $
d340 2
a341 1
    size_t width, i, numSpaces;
@


1.11.2.1
log
@	* generic/tkArgv.c: fix -help mem explosion. [Bug 1936238] (bachmann)
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkArgv.c,v 1.11 2007/12/13 15:24:13 dgp Exp $
d340 1
a340 2
    size_t width, i;
    int numSpaces; /* must be int to allow for negative values */
@


1.11.2.2
log
@use kenny variant for 1936238 fix
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkArgv.c,v 1.11.2.1 2008/04/07 18:38:01 hobbs Exp $
d340 4
a343 1
    size_t width, i, numSpaces;
d376 7
a382 2
	    while (numSpaces-- > 0) {
		Tcl_AppendResult(interp, " ", NULL);
@


1.11.2.3
log
@Backport of fix for [Bug 2112563]
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkArgv.c,v 1.11.2.2 2008/04/07 22:27:21 hobbs Exp $
d383 1
a383 1
		Tcl_PrintDouble(NULL, *((double *) infoPtr->dst), tmp);
@


1.10
log
@Tidy up some variable types.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkArgv.c,v 1.9 2007/10/15 07:24:48 das Exp $
@


1.9
log
@	* generic/tkArgv.c:		Fix gcc warnings about 'cast to/from
	* generic/tkCanvUtil.c:		pointer from/to integer of different
	* generic/tkCanvas.c:		size' on 64-bit platforms by casting
	* generic/tkCursor.c:		to intermediate types
	* generic/tkInt.h:		intptr_t/uintptr_t via new PTR2INT(),
	* generic/tkListbox.c:		INT2PTR(), PTR2UINT() and UINT2PTR()
	* generic/tkObj.c:		macros.
	* generic/tkStyle.c:
	* generic/tkTextIndex.c:
	* generic/tkUtil.c:
	* generic/ttk/ttkTheme.h:
	* generic/ttk/ttkTreeview.c:
	* unix/tkUnixMenu.c:
	* unix/configure.in:

	* unix/configure:		autoconf-2.59
	* unix/tkConfig.h.in:		autoheader-2.59
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkArgv.c,v 1.8 2007/09/07 00:34:51 dgp Exp $
d340 1
a340 1
    int width, i, numSpaces;
d354 1
a354 1
	    int length;
@


1.8
log
@header cleanup
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkArgv.c,v 1.7 2007/06/25 19:07:15 dgp Exp $
d16 1
a16 1
#include "tkPort.h"
d175 1
a175 1
	    *((int *) infoPtr->dst) = (int) infoPtr->src;
@


1.7
log
@restore unix line endings
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkArgv.c,v 1.6 2007/06/24 16:07:34 dkf Exp $
a16 1
#include "tk.h"
@


1.6
log
@Cleaning up whitespace, comments, declarations. No functional changes.
@
text
@d1 421
a421 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;
	    }
	    *((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:
 */
@


1.5
log
@ANSIfy
@
text
@d1 421
a421 426
/*
 * 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.4 2002/01/25 21:09:36 dgp 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:
 */
@


1.5.2.1
log
@merge updates from HEAD
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkArgv.c,v 1.5 2005/11/04 11:52:50 dkf Exp $
d124 26
a149 26
		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;
d153 1
d188 2
a189 2
			    infoPtr->key, "\" but got \"", argv[srcIndex],
			    "\"", NULL);
d199 4
a203 3
	    *((CONST char **)infoPtr->dst) = argv[srcIndex];
	    srcIndex++;
	    argc--;
d208 4
a212 3
	    *((Tk_Uid *)infoPtr->dst) = Tk_GetUid(argv[srcIndex]);
	    srcIndex++;
	    argc--;
d236 1
a236 1
	    ArgvFunc *handlerProc = (ArgvFunc *) infoPtr->src;
d238 1
d240 2
a241 2
		srcIndex++;
		argc--;
d248 1
a248 1
	    ArgvGenFunc *handlerProc = (ArgvGenFunc *) infoPtr->src;
d250 1
@


1.5.2.2
log
@merge updates from HEAD
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkArgv.c,v 1.5.2.1 2007/06/25 19:12:12 dgp Exp $
d17 1
@


1.5.2.3
log
@merge updates from HEAD
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkArgv.c,v 1.5.2.2 2007/09/07 01:25:33 dgp Exp $
d16 1
a16 1
#include "tkInt.h"
d175 1
a175 1
	    *((int *) infoPtr->dst) = PTR2INT(infoPtr->src);
@


1.5.2.4
log
@merge updates from 8.5b3
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkArgv.c,v 1.5.2.3 2007/10/15 18:38:32 dgp Exp $
d340 1
a340 1
    size_t width, i, numSpaces;
d354 1
a354 1
	    size_t length;
@


1.5.2.5
log
@merge updates from 8.5 branch
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkArgv.c,v 1.5.2.4 2007/11/21 16:46:26 dgp Exp $
d341 2
d375 7
a381 2
	    while (numSpaces-- > 0) {
		Tcl_AppendResult(interp, " ", NULL);
@


1.4
log
@	* Updated callers of Tcl_SplitList and Tcl_Merge.
	* Updated callers of Tcl_GetStringResult.
	  Rewrote PrintScrollFractions to ScrollFractions to stop scribbling
	  directly on interp->result.
	* Updated callers of Tcl_GetVar, Tcl_GetVar2
	* Updated callers of Tcl_SplitPath, Tcl_JoinPath, and
	  Tcl_TranslateFileName.
@
text
@d4 2
a5 2
 *	This file contains a procedure that handles table-based
 *	argv-argc parsing.
d10 2
a11 2
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
d13 1
a13 1
 * RCS: @@(#) $Id: tkArgv.c,v 1.3 1999/04/16 01:51:10 stanton Exp $
d20 2
a21 2
 * Default table of argument descriptors.  These are normally available
 * in every application.
d25 1
a25 1
    {"-help",	TK_ARGV_HELP,	(char *) NULL,	(char *) NULL,
d27 1
a27 2
    {NULL,	TK_ARGV_END,	(char *) NULL,	(char *) NULL,
	(char *) NULL}
d31 1
a31 1
 * Forward declarations for procedures defined in this file:
d34 2
a35 2
static void	PrintUsage _ANSI_ARGS_((Tcl_Interp *interp,
		    Tk_ArgvInfo *argTable, int flags));
d42 2
a43 2
 *	Process an argv array according to a table of expected
 *	command-line options.  See the manual page for more details.
d46 5
a50 6
 *	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).
d53 3
a55 4
 *	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.
d61 10
a70 10
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,
d74 2
a75 2
				/* Pointer to the current entry in the
				 * table of argument descriptions. */
d79 3
a81 3
				 * quick check for matching;  use 2nd char.
				 * because first char. will almost always
				 * be '-'). */
d111 2
a112 3
	 * Loop throught the argument descriptors searching for one with
	 * the matching key string.  If found, leave a pointer to it in
	 * matchPtr.
d146 1
a146 1
			     "\"", (char *) NULL);
d155 1
a155 1
	     * Unrecognized argument.  Just copy it down, unless the caller
d161 1
a161 1
			curArg, "\"", (char *) NULL);
d173 1
a173 1
	gotMatch:
d176 8
a183 8
	    case TK_ARGV_CONSTANT:
		*((int *) infoPtr->dst) = (int) infoPtr->src;
		break;
	    case TK_ARGV_INT:
		if (argc == 0) {
		    goto missingArg;
		} else {
		    char *endPtr;
d185 6
a190 10
		    *((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--;
d192 2
a193 53
		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;

		handlerProc = (ArgvFunc *) infoPtr->src;
		if ((*handlerProc)(infoPtr->dst, infoPtr->key,
			argv[srcIndex])) {
		    srcIndex += 1;
		    argc -= 1;
		}
		break;
d195 8
a202 12
	    case TK_ARGV_GENFUNC: {
		typedef int (ArgvGenFunc)_ANSI_ARGS_((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;
d204 6
a209 13
	    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);
d212 16
a227 6
		break;
	    case TK_ARGV_OPTION_NAME_VALUE:
		if (argc < 2) {
		    Tcl_AppendResult(interp, "\"", curArg,
			    "\" option requires two following arguments",
			    (char *) NULL);
d230 48
a277 11
		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);
d280 12
d296 2
a297 2
     * If we broke out of the loop because of an OPT_REST argument,
     * copy the remaining arguments down.
d300 1
a300 1
    argsDone:
d307 1
a307 1
    argv[dstIndex] = (char *) NULL;
d311 1
a311 1
    missingArg:
d313 1
a313 1
	    "\" option requires an additional argument", (char *) NULL);
d325 3
a327 4
 *	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.
d336 4
a339 4
PrintUsage(interp, argTable, flags)
    Tcl_Interp *interp;		/* Place information in this interp's
				 * result area. */
    Tk_ArgvInfo *argTable;	/* Array of command-specific argument
d341 3
a343 3
    int flags;			/* If the TK_ARGV_NO_DEFAULTS bit is set
				 * in this word, then don't generate
				 * information for default options. */
d352 2
a353 2
     * First, compute the width of the widest option key, so that we
     * can make everything line up.
d371 1
a371 1
    Tcl_AppendResult(interp, "Command-specific options:", (char *) NULL);
d376 1
a376 1
		Tcl_AppendResult(interp, "\n", infoPtr->help, (char *) NULL);
d379 1
a379 1
	    Tcl_AppendResult(interp, "\n ", infoPtr->key, ":", (char *) NULL);
d383 1
a383 1
		    Tcl_AppendResult(interp, spaces, (char *) NULL);
d385 1
a385 2
		    Tcl_AppendResult(interp, spaces+NUM_SPACES-numSpaces,
			    (char *) NULL);
d389 1
a389 1
	    Tcl_AppendResult(interp, infoPtr->help, (char *) NULL);
d391 10
a400 14
		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;
d402 3
a404 9
		    string = *((char **) infoPtr->dst);
		    if (string != NULL) {
			Tcl_AppendResult(interp, "\n\t\tDefault value: \"",
				string, "\"", (char *) NULL);
		    }
		    break;
		}
		default: {
		    break;
d406 4
d416 1
a416 2
	Tcl_AppendResult(interp, "\nGeneric options for all commands:",
		(char *) NULL);
d419 8
@


1.3
log
@* Merged 8.1 branch into the main trunk
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id$
d70 1
a70 1
    char **argv;		/* Array of arguments.  Modified to hold
d80 1
a80 1
    char *curArg;		/* Current argument */
d205 1
a205 1
		    *((char **)infoPtr->dst) = argv[srcIndex];
d242 2
a243 1
		typedef int (ArgvFunc)_ANSI_ARGS_((char *, char *, char *));
d256 1
a256 1
			char *, int, char **));
@


1.3.14.1
log
@sync with head
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkArgv.c,v 1.4 2002/01/25 21:09:36 dgp Exp $
d70 1
a70 1
    CONST char **argv;		/* Array of arguments.  Modified to hold
d80 1
a80 1
    CONST char *curArg;		/* Current argument */
d205 1
a205 1
		    *((CONST char **)infoPtr->dst) = argv[srcIndex];
d242 1
a242 2
		typedef int (ArgvFunc) _ANSI_ARGS_ ((char *, char *,
			CONST char *));
d255 1
a255 1
			char *, int, CONST char **));
@


1.3.18.1
log
@Merge with current TOT
Added support for the wm stackorder command
Fixed crash when selecting Menu items in the Application menu that we didn't
put there.
Added first bits of the use of CG for low-level drawing.  The line-drawing works,
the rest doesn't yet.  You have to set the file static useCGDrawing to 1 and
rebuild to activate this code.
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkArgv.c,v 1.3 1999/04/16 01:51:10 stanton Exp $
d70 1
a70 1
    CONST char **argv;		/* Array of arguments.  Modified to hold
d80 1
a80 1
    CONST char *curArg;		/* Current argument */
d205 1
a205 1
		    *((CONST char **)infoPtr->dst) = argv[srcIndex];
d242 1
a242 2
		typedef int (ArgvFunc) _ANSI_ARGS_ ((char *, char *,
			CONST char *));
d255 1
a255 1
			char *, int, CONST char **));
@


1.2
log
@Replaced SCCS strings, fixed binary files
@
text
@d8 1
a8 1
 * Copyright (c) 1994 Sun Microsystems, Inc.
d48 1
a48 1
 *	error occurs then an error message is left in interp->result.
d294 4
a297 2
	    default:
		sprintf(interp->result, "bad argument type %d in Tk_ArgvInfo",
d299 1
d301 1
d335 1
a335 1
 *	Interp->result will be modified to hold a help string
d360 1
a360 1
    char tmp[30];
@


1.1
log
@Initial revision
@
text
@d13 1
a13 1
 * SCCS: @@(#) tkArgv.c 1.21 97/04/25 16:50:27
@


1.1.4.1
log
@initial tk8.1a2 version
@
text
@d8 1
a8 1
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
d13 1
a13 1
 * SCCS: @@(#) tkArgv.c 1.22 97/11/07 21:13:03
d48 1
a48 1
 *	error occurs then an error message is left in the interp's result.
d294 2
a295 4
	    default: {
		char buf[64 + TCL_INTEGER_SPACE];
		
		sprintf(buf, "bad argument type %d in Tk_ArgvInfo",
a296 1
		Tcl_SetResult(interp, buf, TCL_VOLATILE);
a297 1
	    }
d331 1
a331 1
 *	The interp's result will be modified to hold a help string
d356 1
a356 1
    char tmp[TCL_DOUBLE_SPACE];
@


1.1.4.2
log
@Merged 8.0.3 changes into 8.1
@
text
@d13 1
a13 1
 * RCS: @@(#) $Id: tkArgv.c,v 1.2 1998/09/14 18:23:03 stanton Exp $
@


