/[dtapublic]/projs/trunk/shared_source/c_tk_base_7_5_w_mods/tkargv.c
ViewVC logotype

Diff of /projs/trunk/shared_source/c_tk_base_7_5_w_mods/tkargv.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

to_be_filed/sf_code/esrgpcpj/shared/tk_base/tkargv.c revision 29 by dashley, Sat Oct 8 07:08:47 2016 UTC projs/trunk/shared_source/c_tk_base_7_5_w_mods/tkargv.c revision 71 by dashley, Sat Nov 5 11:07:06 2016 UTC
# Line 1  Line 1 
 /* $Header: /cvsroot/esrg/sfesrg/esrgpcpj/shared/tk_base/tkargv.c,v 1.1.1.1 2001/06/13 04:53:35 dtashley Exp $ */  
   
 /*  
  * tkArgv.c --  
  *  
  *      This file contains a procedure 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.1.1.1 2001/06/13 04:53:35 dtashley 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,   (char *) NULL,  (char *) NULL,  
         "Print summary of command-line options and abort"},  
     {NULL,      TK_ARGV_END,    (char *) NULL,  (char *) NULL,  
         (char *) NULL}  
 };  
   
 /*  
  * Forward declarations for procedures defined in this file:  
  */  
   
 static void     PrintUsage _ANSI_ARGS_((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 procedures 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. */  
     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. */  
     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,  
                              "\"", (char *) 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, "\"", (char *) 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], "\"", (char *) NULL);  
                         return TCL_ERROR;  
                     }  
                     srcIndex++;  
                     argc--;  
                 }  
                 break;  
             case TK_ARGV_STRING:  
                 if (argc == 0) {  
                     goto missingArg;  
                 } else {  
                     *((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 *, 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)_ANSI_ARGS_((char *, Tcl_Interp *,  
                         char *, int, 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",  
                             (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);  
                 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] = (char *) NULL;  
     *argcPtr = dstIndex;  
     return TCL_OK;  
   
     missingArg:  
     Tcl_AppendResult(interp, "\"", curArg,  
             "\" option requires an additional argument", (char *) 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(interp, argTable, flags)  
     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:", (char *) 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);  
                 continue;  
             }  
             Tcl_AppendResult(interp, "\n ", infoPtr->key, ":", (char *) 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;  
             }  
             Tcl_AppendResult(interp, infoPtr->help, (char *) 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;  
   
                     string = *((char **) infoPtr->dst);  
                     if (string != NULL) {  
                         Tcl_AppendResult(interp, "\n\t\tDefault value: \"",  
                                 string, "\"", (char *) NULL);  
                     }  
                     break;  
                 }  
                 default: {  
                     break;  
                 }  
             }  
         }  
   
         if ((flags & TK_ARGV_NO_DEFAULTS) || (i > 0)) {  
             break;  
         }  
         Tcl_AppendResult(interp, "\nGeneric options for all commands:",  
                 (char *) NULL);  
     }  
 }  
   
   
 /* $History: tkArgv.c $  
  *  
  * *****************  Version 1  *****************  
  * User: Dtashley     Date: 1/02/01    Time: 2:19a  
  * Created in $/IjuScripter, IjuConsole/Source/Tk Base  
  * Initial check-in.  
  */  
   
 /* End of TKARGV.C */  
1    /* $Header$ */
2    
3    /*
4     * tkArgv.c --
5     *
6     *      This file contains a procedure that handles table-based
7     *      argv-argc parsing.
8     *
9     * Copyright (c) 1990-1994 The Regents of the University of California.
10     * Copyright (c) 1994-1997 Sun Microsystems, Inc.
11     *
12     * See the file "license.terms" for information on usage and redistribution
13     * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14     *
15     * RCS: @(#) $Id: tkargv.c,v 1.1.1.1 2001/06/13 04:53:35 dtashley Exp $
16     */
17    
18    #include "tkPort.h"
19    #include "tk.h"
20    
21    /*
22     * Default table of argument descriptors.  These are normally available
23     * in every application.
24     */
25    
26    static Tk_ArgvInfo defaultTable[] = {
27        {"-help",   TK_ARGV_HELP,   (char *) NULL,  (char *) NULL,
28            "Print summary of command-line options and abort"},
29        {NULL,      TK_ARGV_END,    (char *) NULL,  (char *) NULL,
30            (char *) NULL}
31    };
32    
33    /*
34     * Forward declarations for procedures defined in this file:
35     */
36    
37    static void     PrintUsage _ANSI_ARGS_((Tcl_Interp *interp,
38                        Tk_ArgvInfo *argTable, int flags));
39    
40    /*
41     *----------------------------------------------------------------------
42     *
43     * Tk_ParseArgv --
44     *
45     *      Process an argv array according to a table of expected
46     *      command-line options.  See the manual page for more details.
47     *
48     * Results:
49     *      The return value is a standard Tcl return value.  If an
50     *      error occurs then an error message is left in the interp's result.
51     *      Under normal conditions, both *argcPtr and *argv are modified
52     *      to return the arguments that couldn't be processed here (they
53     *      didn't match the option table, or followed an TK_ARGV_REST
54     *      argument).
55     *
56     * Side effects:
57     *      Variables may be modified, resources may be entered for tkwin,
58     *      or procedures may be called.  It all depends on the arguments
59     *      and their entries in argTable.  See the user documentation
60     *      for details.
61     *
62     *----------------------------------------------------------------------
63     */
64    
65    int
66    Tk_ParseArgv(interp, tkwin, argcPtr, argv, argTable, flags)
67        Tcl_Interp *interp;         /* Place to store error message. */
68        Tk_Window tkwin;            /* Window to use for setting Tk options.
69                                     * NULL means ignore Tk option specs. */
70        int *argcPtr;               /* Number of arguments in argv.  Modified
71                                     * to hold # args left in argv at end. */
72        char **argv;                /* Array of arguments.  Modified to hold
73                                     * those that couldn't be processed here. */
74        Tk_ArgvInfo *argTable;      /* Array of option descriptions */
75        int flags;                  /* Or'ed combination of various flag bits,
76                                     * such as TK_ARGV_NO_DEFAULTS. */
77    {
78        register Tk_ArgvInfo *infoPtr;
79                                    /* Pointer to the current entry in the
80                                     * table of argument descriptions. */
81        Tk_ArgvInfo *matchPtr;      /* Descriptor that matches current argument. */
82        char *curArg;               /* Current argument */
83        register char c;            /* Second character of current arg (used for
84                                     * quick check for matching;  use 2nd char.
85                                     * because first char. will almost always
86                                     * be '-'). */
87        int srcIndex;               /* Location from which to read next argument
88                                     * from argv. */
89        int dstIndex;               /* Index into argv to which next unused
90                                     * argument should be copied (never greater
91                                     * than srcIndex). */
92        int argc;                   /* # arguments in argv still to process. */
93        size_t length;              /* Number of characters in current argument. */
94        int i;
95    
96        if (flags & TK_ARGV_DONT_SKIP_FIRST_ARG) {
97            srcIndex = dstIndex = 0;
98            argc = *argcPtr;
99        } else {
100            srcIndex = dstIndex = 1;
101            argc = *argcPtr-1;
102        }
103    
104        while (argc > 0) {
105            curArg = argv[srcIndex];
106            srcIndex++;
107            argc--;
108            length = strlen(curArg);
109            if (length > 0) {
110                c = curArg[1];
111            } else {
112                c = 0;
113            }
114    
115            /*
116             * Loop throught the argument descriptors searching for one with
117             * the matching key string.  If found, leave a pointer to it in
118             * matchPtr.
119             */
120    
121            matchPtr = NULL;
122            for (i = 0; i < 2; i++) {
123                if (i == 0) {
124                    infoPtr = argTable;
125                } else {
126                    infoPtr = defaultTable;
127                }
128                for (; (infoPtr != NULL) && (infoPtr->type != TK_ARGV_END);
129                        infoPtr++) {
130                     if (infoPtr->key == NULL) {
131                         continue;
132                     }
133                     if ((infoPtr->key[1] != c)
134                             || (strncmp(infoPtr->key, curArg, length) != 0)) {
135                         continue;
136                     }
137                     if ((tkwin == NULL)
138                             && ((infoPtr->type == TK_ARGV_CONST_OPTION)
139                             || (infoPtr->type == TK_ARGV_OPTION_VALUE)
140                             || (infoPtr->type == TK_ARGV_OPTION_NAME_VALUE))) {
141                         continue;
142                     }
143                     if (infoPtr->key[length] == 0) {
144                         matchPtr = infoPtr;
145                         goto gotMatch;
146                     }
147                     if (flags & TK_ARGV_NO_ABBREV) {
148                         continue;
149                     }
150                     if (matchPtr != NULL) {
151                         Tcl_AppendResult(interp, "ambiguous option \"", curArg,
152                                 "\"", (char *) NULL);
153                         return TCL_ERROR;
154                     }
155                     matchPtr = infoPtr;
156                }
157            }
158            if (matchPtr == NULL) {
159    
160                /*
161                 * Unrecognized argument.  Just copy it down, unless the caller
162                 * prefers an error to be registered.
163                 */
164    
165                if (flags & TK_ARGV_NO_LEFTOVERS) {
166                    Tcl_AppendResult(interp, "unrecognized argument \"",
167                            curArg, "\"", (char *) NULL);
168                    return TCL_ERROR;
169                }
170                argv[dstIndex] = curArg;
171                dstIndex++;
172                continue;
173            }
174    
175            /*
176             * Take the appropriate action based on the option type
177             */
178    
179            gotMatch:
180            infoPtr = matchPtr;
181            switch (infoPtr->type) {
182                case TK_ARGV_CONSTANT:
183                    *((int *) infoPtr->dst) = (int) infoPtr->src;
184                    break;
185                case TK_ARGV_INT:
186                    if (argc == 0) {
187                        goto missingArg;
188                    } else {
189                        char *endPtr;
190    
191                        *((int *) infoPtr->dst) =
192                                strtol(argv[srcIndex], &endPtr, 0);
193                        if ((endPtr == argv[srcIndex]) || (*endPtr != 0)) {
194                            Tcl_AppendResult(interp, "expected integer argument ",
195                                    "for \"", infoPtr->key, "\" but got \"",
196                                    argv[srcIndex], "\"", (char *) NULL);
197                            return TCL_ERROR;
198                        }
199                        srcIndex++;
200                        argc--;
201                    }
202                    break;
203                case TK_ARGV_STRING:
204                    if (argc == 0) {
205                        goto missingArg;
206                    } else {
207                        *((char **)infoPtr->dst) = argv[srcIndex];
208                        srcIndex++;
209                        argc--;
210                    }
211                    break;
212                case TK_ARGV_UID:
213                    if (argc == 0) {
214                        goto missingArg;
215                    } else {
216                        *((Tk_Uid *)infoPtr->dst) = Tk_GetUid(argv[srcIndex]);
217                        srcIndex++;
218                        argc--;
219                    }
220                    break;
221                case TK_ARGV_REST:
222                    *((int *) infoPtr->dst) = dstIndex;
223                    goto argsDone;
224                case TK_ARGV_FLOAT:
225                    if (argc == 0) {
226                        goto missingArg;
227                    } else {
228                        char *endPtr;
229    
230                        *((double *) infoPtr->dst) =
231                                strtod(argv[srcIndex], &endPtr);
232                        if ((endPtr == argv[srcIndex]) || (*endPtr != 0)) {
233                            Tcl_AppendResult(interp, "expected floating-point ",
234                                    "argument for \"", infoPtr->key,
235                                    "\" but got \"", argv[srcIndex], "\"",
236                                    (char *) NULL);
237                            return TCL_ERROR;
238                        }
239                        srcIndex++;
240                        argc--;
241                    }
242                    break;
243                case TK_ARGV_FUNC: {
244                    typedef int (ArgvFunc)_ANSI_ARGS_((char *, char *, char *));
245                    ArgvFunc *handlerProc;
246    
247                    handlerProc = (ArgvFunc *) infoPtr->src;
248                    if ((*handlerProc)(infoPtr->dst, infoPtr->key,
249                            argv[srcIndex])) {
250                        srcIndex += 1;
251                        argc -= 1;
252                    }
253                    break;
254                }
255                case TK_ARGV_GENFUNC: {
256                    typedef int (ArgvGenFunc)_ANSI_ARGS_((char *, Tcl_Interp *,
257                            char *, int, char **));
258                    ArgvGenFunc *handlerProc;
259    
260                    handlerProc = (ArgvGenFunc *) infoPtr->src;
261                    argc = (*handlerProc)(infoPtr->dst, interp, infoPtr->key,
262                            argc, argv+srcIndex);
263                    if (argc < 0) {
264                        return TCL_ERROR;
265                    }
266                    break;
267                }
268                case TK_ARGV_HELP:
269                    PrintUsage (interp, argTable, flags);
270                    return TCL_ERROR;
271                case TK_ARGV_CONST_OPTION:
272                    Tk_AddOption(tkwin, infoPtr->dst, infoPtr->src,
273                            TK_INTERACTIVE_PRIO);
274                    break;
275                case TK_ARGV_OPTION_VALUE:
276                    if (argc < 1) {
277                        goto missingArg;
278                    }
279                    Tk_AddOption(tkwin, infoPtr->dst, argv[srcIndex],
280                            TK_INTERACTIVE_PRIO);
281                    srcIndex++;
282                    argc--;
283                    break;
284                case TK_ARGV_OPTION_NAME_VALUE:
285                    if (argc < 2) {
286                        Tcl_AppendResult(interp, "\"", curArg,
287                                "\" option requires two following arguments",
288                                (char *) NULL);
289                        return TCL_ERROR;
290                    }
291                    Tk_AddOption(tkwin, argv[srcIndex], argv[srcIndex+1],
292                            TK_INTERACTIVE_PRIO);
293                    srcIndex += 2;
294                    argc -= 2;
295                    break;
296                default: {
297                    char buf[64 + TCL_INTEGER_SPACE];
298                    
299                    sprintf(buf, "bad argument type %d in Tk_ArgvInfo",
300                            infoPtr->type);
301                    Tcl_SetResult(interp, buf, TCL_VOLATILE);
302                    return TCL_ERROR;
303                }
304            }
305        }
306    
307        /*
308         * If we broke out of the loop because of an OPT_REST argument,
309         * copy the remaining arguments down.
310         */
311    
312        argsDone:
313        while (argc) {
314            argv[dstIndex] = argv[srcIndex];
315            srcIndex++;
316            dstIndex++;
317            argc--;
318        }
319        argv[dstIndex] = (char *) NULL;
320        *argcPtr = dstIndex;
321        return TCL_OK;
322    
323        missingArg:
324        Tcl_AppendResult(interp, "\"", curArg,
325                "\" option requires an additional argument", (char *) NULL);
326        return TCL_ERROR;
327    }
328    
329    /*
330     *----------------------------------------------------------------------
331     *
332     * PrintUsage --
333     *
334     *      Generate a help string describing command-line options.
335     *
336     * Results:
337     *      The interp's result will be modified to hold a help string
338     *      describing all the options in argTable, plus all those
339     *      in the default table unless TK_ARGV_NO_DEFAULTS is
340     *      specified in flags.
341     *
342     * Side effects:
343     *      None.
344     *
345     *----------------------------------------------------------------------
346     */
347    
348    static void
349    PrintUsage(interp, argTable, flags)
350        Tcl_Interp *interp;         /* Place information in this interp's
351                                     * result area. */
352        Tk_ArgvInfo *argTable;      /* Array of command-specific argument
353                                     * descriptions. */
354        int flags;                  /* If the TK_ARGV_NO_DEFAULTS bit is set
355                                     * in this word, then don't generate
356                                     * information for default options. */
357    {
358        register Tk_ArgvInfo *infoPtr;
359        int width, i, numSpaces;
360    #define NUM_SPACES 20
361        static char spaces[] = "                    ";
362        char tmp[TCL_DOUBLE_SPACE];
363    
364        /*
365         * First, compute the width of the widest option key, so that we
366         * can make everything line up.
367         */
368    
369        width = 4;
370        for (i = 0; i < 2; i++) {
371            for (infoPtr = i ? defaultTable : argTable;
372                    infoPtr->type != TK_ARGV_END; infoPtr++) {
373                int length;
374                if (infoPtr->key == NULL) {
375                    continue;
376                }
377                length = strlen(infoPtr->key);
378                if (length > width) {
379                    width = length;
380                }
381            }
382        }
383    
384        Tcl_AppendResult(interp, "Command-specific options:", (char *) NULL);
385        for (i = 0; ; i++) {
386            for (infoPtr = i ? defaultTable : argTable;
387                    infoPtr->type != TK_ARGV_END; infoPtr++) {
388                if ((infoPtr->type == TK_ARGV_HELP) && (infoPtr->key == NULL)) {
389                    Tcl_AppendResult(interp, "\n", infoPtr->help, (char *) NULL);
390                    continue;
391                }
392                Tcl_AppendResult(interp, "\n ", infoPtr->key, ":", (char *) NULL);
393                numSpaces = width + 1 - strlen(infoPtr->key);
394                while (numSpaces > 0) {
395                    if (numSpaces >= NUM_SPACES) {
396                        Tcl_AppendResult(interp, spaces, (char *) NULL);
397                    } else {
398                        Tcl_AppendResult(interp, spaces+NUM_SPACES-numSpaces,
399                                (char *) NULL);
400                    }
401                    numSpaces -= NUM_SPACES;
402                }
403                Tcl_AppendResult(interp, infoPtr->help, (char *) NULL);
404                switch (infoPtr->type) {
405                    case TK_ARGV_INT: {
406                        sprintf(tmp, "%d", *((int *) infoPtr->dst));
407                        Tcl_AppendResult(interp, "\n\t\tDefault value: ",
408                                tmp, (char *) NULL);
409                        break;
410                    }
411                    case TK_ARGV_FLOAT: {
412                        sprintf(tmp, "%g", *((double *) infoPtr->dst));
413                        Tcl_AppendResult(interp, "\n\t\tDefault value: ",
414                                tmp, (char *) NULL);
415                        break;
416                    }
417                    case TK_ARGV_STRING: {
418                        char *string;
419    
420                        string = *((char **) infoPtr->dst);
421                        if (string != NULL) {
422                            Tcl_AppendResult(interp, "\n\t\tDefault value: \"",
423                                    string, "\"", (char *) NULL);
424                        }
425                        break;
426                    }
427                    default: {
428                        break;
429                    }
430                }
431            }
432    
433            if ((flags & TK_ARGV_NO_DEFAULTS) || (i > 0)) {
434                break;
435            }
436            Tcl_AppendResult(interp, "\nGeneric options for all commands:",
437                    (char *) NULL);
438        }
439    }
440    
441    /* End of tkargv.c */

Legend:
Removed from v.29  
changed lines
  Added in v.71

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25