home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume16 / parse / part01 next >
Internet Message Format  |  1991-01-19  |  6KB

  1. From: hermit@ucscf.ucsc.edu (William R. Ward)
  2. Newsgroups: comp.sources.misc
  3. Subject: v16i076:  parse - parse command-line arguments, Part01/01
  4. Message-ID: <1991Jan14.223656.28555@sparky.IMD.Sterling.COM>
  5. Date: 14 Jan 91 22:36:56 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Checksum-Snefru: 473abec9 35263f30 8a956dee 4c78b900
  8.  
  9. Submitted-by: hermit@ucscf.ucsc.edu (William R. Ward)
  10. Posting-number: Volume 16, Issue 76
  11. Archive-name: parse/part01
  12.  
  13. The following utility, to be linked into c programs which use
  14. command-line arguments.
  15.  
  16. example program that uses this utility:
  17.  
  18. #include "parse.h"
  19.  
  20. int    main( argc, argv )
  21. int    argc;
  22. char    **argv;
  23. {
  24.     char        c;
  25.     struct arg    *args;
  26.  
  27.     args = parse_args( argc, argv );
  28.     for ( c='a' ; c!='z'; c++ )
  29.         if ( args[ chindex( c )].ch )
  30.             if ( args[ chindex( c )].str )
  31.                 printf( "Argument for %c is %s.\n", c,
  32.                   args[ chindex( c )].str );
  33.             else
  34.                 printf( "Flag %c set.\n", c );
  35. }
  36.  
  37. Note that parse_args() returns a pointer to a series of struct
  38. args.  (an array, but the returned value is a pointer, which is
  39. almost the same thing.)  The index of the array is from 0 to
  40. MAXARGS-1 (52), with 0 being any arguments specified without a -x
  41. option (ie, if you gave the command "foo bar" the "bar" would be
  42. in args[0]).  1-26 is for lower case characters ("foo -m bar" goes
  43. in args[13]) and 27-52 are for uppercase characters.  The macros
  44. chindex() and indexch() in parse.h perform the conversion between
  45. character <-> index.
  46.  
  47. If the flag exists, args[n].ch contains the character corresponding
  48. to 'n' and args[n].str contains any argument(s) associated with
  49. it.  Also, note that if more than one argument is given for any
  50. flag (or without any flags) they are concatenated with one space
  51. between arguments.  This means that any flagless arg must precede
  52. any flags or it will *not* end up in args[0].  I decided this was
  53. better than only allowing one argument.  If you want to fix it, go
  54. ahead, but please send me a patch so I can have both versions--both
  55. are useful.  (Examples: The command "foo -n14 bar" puts "14 bar"
  56. in args[12]; "foo -n hello -xn world" places "hello world" in
  57. args[12].str and NULL in args[24].str.)
  58.  
  59. checksums using BSD4.3 'sum' program:
  60.  
  61. 36727     2 parse.c
  62. 18452     1 parse.h
  63.  
  64. to unbundle, "sh" this file -- DO NOT use csh
  65. SHAR archive format.  Archive created Fri Jan 4 12:45:26 PST 1991
  66.  
  67. -- cut here --
  68. #!/bin/sh
  69. echo x - parse.c
  70. sed 's/^X//' > parse.c <<'+FUNKY+STUFF+'
  71. X/*
  72. X *    parse.c        William R. Ward <hermit@ucscb.UCSC.EDU>
  73. X *
  74. X *    Given parameters (argc,argv) representing command-line
  75. X *    arguments, function parse_args() returns an array of argument
  76. X *    values.  The array is of type struct arg, which is described in
  77. X *    the file parse.h.
  78. X *
  79. X *    The routine defines a argument as follows: all uppercase or
  80. X *    lowercase letters in a word starting with '-' up to the first
  81. X *    non-letter in the word, with any words not beginning with '-'
  82. X *    or parts of a word after and including the last argument letter
  83. X *    given as that argument's parameter.
  84. X *
  85. X *    For example, given the following strings in (argc, argv),
  86. X *    parse_args recognizes the following as arguments:
  87. X *
  88. X *        input:        argument(s):    parameter:
  89. X *        -r        r        (none)
  90. X *        -abc        a        (none)
  91. X *                b        (none)
  92. X *                c        (none)
  93. X *        -xy74        x        (none)
  94. X *                y        74
  95. X *        -z45h        z        45h
  96. X *        -f filename    f        filename
  97. X */
  98. X
  99. X#include "parse.h"
  100. X#include <stdio.h>
  101. X#include <strings.h>
  102. X
  103. Xstruct arg    *parse_args( argc, argv )
  104. Xint    argc;
  105. Xchar    *argv[];
  106. X{
  107. X    int    i, set_ch();
  108. X    static struct arg    args[ MAXARGS ];
  109. X    char    *p, last = 0;
  110. X    void    set_str();
  111. X
  112. X    for( i=1; i<argc; i++ )
  113. X        if ( *argv[i] == '-' && *(argv[i]+1) ) {
  114. X            for( p=argv[i]+1; chindex(*p); p++ )
  115. X                if ( set_ch( args, *p ))
  116. X                    last = *p;
  117. X            if ( *p )
  118. X                if ( p==argv[i]+1 )
  119. X                    set_str( args, p-1, last );
  120. X                else
  121. X                    set_str( args, p, last );
  122. X        } else
  123. X            set_str( args, argv[i], last );
  124. X    return args;
  125. X}
  126. X
  127. Xint    set_ch( args, x )
  128. Xstruct arg    args[];
  129. Xchar    x;
  130. X{
  131. X    int    index;
  132. X
  133. X    index = chindex(x);
  134. X    if ( index ) {
  135. X        args[ index ].ch = 1;
  136. X        return 1;
  137. X    } else
  138. X        return 0;
  139. X}
  140. X
  141. Xvoid    set_str( args, x, last )
  142. Xstruct arg    args[];
  143. Xchar    *x,
  144. X    last;
  145. X{
  146. X    char    *t;
  147. X    int    index;
  148. X
  149. X    index = chindex( last );
  150. X    if ( args[ index ].str == NULL ) {
  151. X        t = ( char * )calloc( strlen( x ), sizeof( char ));
  152. X        strcpy( t, x );
  153. X    } else {
  154. X        t = ( char * )calloc( strlen( args[ index ].str ) +
  155. X            strlen( x ) + 1, sizeof( char ));
  156. X        strcpy( t, args[ index ].str );
  157. X        strcat( t, " " );
  158. X        strcat( t, x );
  159. X    }
  160. X    free( args[ index ].str );
  161. X    args[ index ].str = t;
  162. X}
  163. +FUNKY+STUFF+
  164. echo '-rw-------  1 hermit       2037 Feb  9  1990 parse.c    (as sent)'
  165. chmod u=rw,g=,o= parse.c
  166. ls -l parse.c
  167. echo x - parse.h
  168. sed 's/^X//' > parse.h <<'+FUNKY+STUFF+'
  169. X#include <ctype.h>
  170. X
  171. X#define MAXARGS    53
  172. X    /* 26 lowercase + 26 uppercase + zero for non-letter */
  173. X#define chindex(x) ( isalpha(x) ? ( islower(x) ? (x)-'a'+1 : (x)-'A'+27 ) : 0 )
  174. X    /* macro, given a char x, returns the index into args[] */
  175. X#define indexch(x) ( (x) ? ( (x)<=26 ? (x)+'a'-1 : (x)+'A'-27 ) : 0 )
  176. X    /* macro, given an index into args[] 0 <= x <= MAXARGS, returns char */
  177. X
  178. Xstruct arg {
  179. X    char    ch;    /* true/false: is there an arg for this letter? */
  180. X    char    *str;    /* holds pointer to string containing parameter
  181. X                or NULL if no parameter */
  182. X};
  183. +FUNKY+STUFF+
  184. echo '-rw-------  1 hermit        551 Feb  9  1990 parse.h    (as sent)'
  185. chmod u=rw,g=,o= parse.h
  186. ls -l parse.h
  187. exit 0
  188. -- cut here --
  189. -- 
  190. ------------------------------------------------------------------------
  191. William R. Ward      | UC Santa Cruz, CIS    | [backbone]!ucbvax!
  192. (408) 426-7267       | hermit@ucscf.UCSC.EDU |        ucscc!ucscf!hermit
  193. UCSC-Cowell-787      +--------------------------------------------------
  194. Santa Cruz, CA 95064 | Disclaimer: Nobody reads this anyway.
  195. ------------------------------------------------------------------------
  196. exit 0 # Just in case...
  197. -- 
  198. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  199. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  200. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  201. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  202.