home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / std_unix / mod.std.unix.v1 / text0008.txt < prev    next >
Encoding:
Internet Message Format  |  1987-06-30  |  9.5 KB

  1. From: John Quarterman (moderator) <ut-sally!std-unix>
  2.  
  3. Topic: yet more on getopt (command line arguments)
  4.  
  5. Two more messages, the first a followup to a previous posting, and
  6. the second public domain sources and man pages for getopt(3) and getopt(1).
  7.     -mod
  8.  
  9. ----------------------------------------------------------------------
  10.  
  11. From: ihnp4!utzoo!henry
  12. Date: 3 Jul 85 18:34:41 CDT (Wed)
  13. To: ihnp4!ut-sally!std-unix
  14. Subject: Re: command line arguments
  15.  
  16. > > A group of bundled options may end with an option that has an argument.
  17. > This creates confusion in using C-Kermit when you want to send an image
  18. > file.  For example:
  19. >     send -is filename     < ---  works fine
  20. >         send -si filename     < ---  bombs the program
  21.  
  22. The AT&T syntax standard (which getopt does not completely enforce)
  23. actually forbids both of these usages.  Options with arguments are not
  24. allowed to be bundled, and they must be separated from their arguments
  25. by a space.
  26.  
  27. > I would *much* prefer to bundle the flags, then
  28. > have those with arguments pick them up in the same order as the flags are
  29. > listed.
  30.  
  31. The few existing commands that use such a convention, notably tar(1), are
  32. (in my experience) the worse for it.  It's seriously error-prone.  I think
  33. the AT&T people did the right thing.
  34.  
  35. ------------------------------
  36.  
  37. Date: Tue, 2 Jul 85 13:07:09 edt
  38. From: ihnp4!utcs!ian (Ian F. Darwin)
  39. To: ihnp4!ut-sally!jsq@tzec.UTEXAS.ARPA
  40. Subject: here is getopt
  41.  
  42. Here is the source for getopt(3), the function that should be in
  43. everybody's C program, and getopt(1), a program that uses it to
  44. make shell programs comprehensible and consistent. There are man
  45. pages for both. Please send these on to the mod. group. Thanks.
  46.  
  47. [ I have hacked the following shell script slightly so that
  48. it doesn't extract directly into system source directories,
  49. rather into the current directory.  It should be assumed that
  50. this code comes with no warranty from me, Ian Darwin, or anyone
  51. else as to whether it accurately represents getopt as distributed
  52. with System V, or any command line standard, or that it works
  53. at all, or that it will cause no damage when extracted or used. -mod]
  54.  
  55. #! /bin/sh
  56. #! To unbundle, sh this file
  57. echo x - "(/usr/man/man3/getopt.3)" >&2
  58. echo x - mkdir lib >&2
  59. mkdir lib >&2
  60. echo x - lib/getopt.3 >&2
  61. cat >lib/getopt.3 <<"//SYSIN DD SYSOUT=BD"
  62. .TH GETOPT 3 local
  63. .DA 25 March 1982
  64. .SH NAME
  65. getopt \- get option letter from argv
  66. .SH SYNOPSIS
  67. .ft B
  68. int getopt(argc, argv, optstring)
  69. .br
  70. int argc;
  71. .br
  72. char **argv;
  73. .br
  74. char *optstring;
  75. .sp
  76. extern char *optarg;
  77. .br
  78. extern int optind;
  79. .ft
  80. .SH DESCRIPTION
  81. .I Getopt
  82. returns the next option letter in
  83. .I argv
  84. that matches a letter in
  85. .IR optstring .
  86. .I Optstring
  87. is a string of recognized option letters;
  88. if a letter is followed by a colon, the option is expected to have
  89. an argument that may or may not be separated from it by white space.
  90. .I Optarg
  91. is set to point to the start of the option argument on return from
  92. .IR getopt .
  93. .PP
  94. .I Getopt
  95. places in
  96. .I optind
  97. the
  98. .I argv
  99. index of the next argument to be processed.
  100. Because
  101. .I optind
  102. is external, it is normally initialized to zero automatically
  103. before the first call to 
  104. .IR getopt .
  105. .PP
  106. When all options have been processed (i.e., up to the first
  107. non-option argument),
  108. .I getopt
  109. returns
  110. .BR EOF .
  111. The special option
  112. .B \-\-
  113. may be used to delimit the end of the options;
  114. .B EOF
  115. will be returned, and
  116. .B \-\-
  117. will be skipped.
  118. .SH SEE ALSO
  119. getopt(1)
  120. .SH DIAGNOSTICS
  121. .I Getopt
  122. prints an error message on
  123. .I stderr
  124. and returns a question mark
  125. .RB ( ? )
  126. when it encounters an option letter not included in
  127. .IR optstring .
  128. .SH EXAMPLE
  129. The following code fragment shows how one might process the arguments
  130. for a command that can take the mutually exclusive options
  131. .B a
  132. and
  133. .BR b ,
  134. and the options
  135. .B f
  136. and
  137. .BR o ,
  138. both of which require arguments:
  139. .PP
  140. .RS
  141. .nf
  142. main(argc, argv)
  143. int argc;
  144. char **argv;
  145. {
  146.     int c;
  147.     extern int optind;
  148.     extern char *optarg;
  149.     \&.
  150.     \&.
  151.     \&.
  152.     while ((c = getopt(argc, argv, "abf:o:")) != EOF)
  153.         switch (c) {
  154.         case 'a':
  155.             if (bflg)
  156.                 errflg++;
  157.             else
  158.                 aflg++;
  159.             break;
  160.         case 'b':
  161.             if (aflg)
  162.                 errflg++;
  163.             else
  164.                 bproc();
  165.             break;
  166.         case 'f':
  167.             ifile = optarg;
  168.             break;
  169.         case 'o':
  170.             ofile = optarg;
  171.             break;
  172.         case '?':
  173.         default:
  174.             errflg++;
  175.             break;
  176.         }
  177.     if (errflg) {
  178.         fprintf(stderr, "Usage: ...");
  179.         exit(2);
  180.     }
  181.     for (; optind < argc; optind++) {
  182.         \&.
  183.         \&.
  184.         \&.
  185.     }
  186.     \&.
  187.     \&.
  188.     \&.
  189. }
  190. .RE
  191. .PP
  192. A template similar to this can be found in
  193. .IR /usr/pub/template.c .
  194. .SH HISTORY
  195. Written by Henry Spencer, working from a Bell Labs manual page.
  196. Behavior believed identical to the Bell version.
  197. .SH BUGS
  198. It is not obvious how
  199. `\-'
  200. standing alone should be treated;  this version treats it as
  201. a non-option argument, which is not always right.
  202. .PP
  203. Option arguments are allowed to begin with `\-';
  204. this is reasonable but reduces the amount of error checking possible.
  205. .PP
  206. .I Getopt
  207. is quite flexible but the obvious price must be paid:  there is much
  208. it could do that it doesn't, like
  209. checking mutually exclusive options, checking type of
  210. option arguments, etc.
  211. //SYSIN DD SYSOUT=BD
  212. echo x - "(/usr/man/man1/getopt.1)" >&2
  213. echo x - mkdir bin >&2
  214. mkdir bin >&2
  215. echo x - bin/getopt.1 >&2
  216. cat >bin/getopt.1 <<"//SYSIN DD SYSOUT=BD"
  217. .TH GETOPT 1 local
  218. .DA 12 April 1984
  219. .SH NAME
  220. getopt \- parse command options
  221. .SH SYNOPSIS
  222. .B set \-\- \`getopt
  223. optstring
  224. .B $*\`
  225. .SH DESCRIPTION
  226. .I Getopt
  227. is used to break up options in command lines for easy parsing by
  228. shell procedures, and to check for legal options.
  229. .I Optstring
  230. is a string of recognized option letters (see
  231. .IR getopt (3));
  232. if a letter is followed by a colon, the option
  233. is expected to have an argument which may or may not be
  234. separated from it by white space.
  235. The special option
  236. .B \-\-
  237. is used to delimit the end of the options.
  238. .I Getopt
  239. will place
  240. .B \-\-
  241. in the arguments at the end of the options,
  242. or recognize it if used explicitly.
  243. The shell arguments
  244. (\fB$1 $2\fR ...) are reset so that each option is
  245. preceded by a
  246. .B \-
  247. and in its own shell argument;
  248. each option argument is also in its own shell argument.
  249. .SH EXAMPLE
  250. The following code fragment shows how one might process the arguments
  251. for a command that can take the options
  252. .B a
  253. and
  254. .BR b ,
  255. and the option
  256. .BR o ,
  257. which requires an argument.
  258. .PP
  259. .RS
  260. .nf
  261. set \-\- \`getopt abo: $*\`
  262. if test $? != 0
  263. then
  264.     echo 'Usage: ...'
  265.     exit 2
  266. fi
  267. for i
  268. do
  269.     case "$i"
  270.     in
  271.         \-a|\-b)
  272.             flag=$i; shift;;
  273.         \-o)
  274.             oarg=$2; shift; shift;;
  275.         \-\-)
  276.             shift; break;;
  277.     esac
  278. done
  279. .fi
  280. .RE
  281. .PP
  282. This code will accept any of the following as equivalent:
  283. .PP
  284. .RS
  285. .nf
  286. cmd \-aoarg file file
  287. cmd \-a \-o arg file file
  288. cmd \-oarg -a file file
  289. cmd \-a \-oarg \-\- file file
  290. .RE
  291. .PP
  292. A program template similar to this example can be found in
  293. .IR /usr/pub/template.sh .
  294. .SH SEE ALSO
  295. sh(1), getopt(3)
  296. .SH DIAGNOSTICS
  297. .I Getopt
  298. prints an error message on the standard error output when it
  299. encounters an option letter not included in
  300. .IR optstring .
  301. .SH HISTORY
  302. Written by Henry Spencer, working from a Bell Labs manual page.
  303. Behavior believed identical to the Bell version.
  304. .SH BUGS
  305. Whatever
  306. .IR getopt (3)
  307. has.
  308. .PP
  309. Arguments containing white space or imbedded shell metacharacters
  310. generally will not survive intact;  this looks easy to fix but isn't.
  311. .PP
  312. The error message for an invalid option is identified as coming
  313. from
  314. .I getopt
  315. rather than from the shell procedure containing the invocation
  316. of
  317. .IR getopt ;
  318. this again is hard to fix.
  319. .PP
  320. The precise best way to use the
  321. .I set
  322. command to set the arguments without disrupting the value(s) of
  323. shell options varies from one shell version to another.
  324. //SYSIN DD SYSOUT=BD
  325. echo x - "(/usr/src/lib/libc/gen/getopt.c)" >&2
  326. echo x - lib/getopt.c >&2
  327. cat >lib/getopt.c <<"//SYSIN DD SYSOUT=BD"
  328. /*
  329.  * getopt - get option letter from argv
  330.  */
  331.  
  332. #include <stdio.h>
  333.  
  334. char    *optarg;    /* Global argument pointer. */
  335. int    optind = 0;    /* Global argv index. */
  336.  
  337. static char    *scan = NULL;    /* Private scan pointer. */
  338.  
  339. extern char    *index();
  340.  
  341. int
  342. getopt(argc, argv, optstring)
  343. int argc;
  344. char *argv[];
  345. char *optstring;
  346. {
  347.     register char c;
  348.     register char *place;
  349.  
  350.     optarg = NULL;
  351.  
  352.     if (scan == NULL || *scan == '\0') {
  353.         if (optind == 0)
  354.             optind++;
  355.     
  356.         if (optind >= argc || argv[optind][0] != '-' || argv[optind][1] == '\0')
  357.             return(EOF);
  358.         if (strcmp(argv[optind], "--")==0) {
  359.             optind++;
  360.             return(EOF);
  361.         }
  362.     
  363.         scan = argv[optind]+1;
  364.         optind++;
  365.     }
  366.  
  367.     c = *scan++;
  368.     place = index(optstring, c);
  369.  
  370.     if (place == NULL || c == ':') {
  371.         fprintf(stderr, "%s: unknown option -%c\n", argv[0], c);
  372.         return('?');
  373.     }
  374.  
  375.     place++;
  376.     if (*place == ':') {
  377.         if (*scan != '\0') {
  378.             optarg = scan;
  379.             scan = NULL;
  380.         } else if (optind < argc) {
  381.             optarg = argv[optind];
  382.             optind++;
  383.         } else {
  384.             fprintf(stderr, "%s: -%c argument missing\n", argv[0], c);
  385.             return('?');
  386.         }
  387.     }
  388.  
  389.     return(c);
  390. }
  391. //SYSIN DD SYSOUT=BD
  392. echo x - "(/usr/src/bin/getopt.c)" >&2
  393. echo x - bin/getopt.c >&2
  394. cat >bin/getopt.c <<"//SYSIN DD SYSOUT=BD"
  395. #include <stdio.h>
  396.  
  397. main(argc, argv)
  398. int argc;
  399. char *argv[];
  400. {
  401.     extern int optind;
  402.     extern char *optarg;
  403.     int c;
  404.     int status = 0;
  405.  
  406.     optind = 2;    /* Past the program name and the option letters. */
  407.     while ((c = getopt(argc, argv, argv[1])) != EOF)
  408.         switch (c) {
  409.         case '?':
  410.             status = 1;    /* getopt routine gave message */
  411.             break;
  412.         default:
  413.             if (optarg != NULL)
  414.                 printf(" -%c %s", c, optarg);
  415.             else
  416.                 printf(" -%c", c);
  417.             break;
  418.         }
  419.     printf(" --");
  420.     for (; optind < argc; optind++)
  421.         printf(" %s", argv[optind]);
  422.     printf("\n");
  423.     exit(status);
  424. }
  425. //SYSIN DD SYSOUT=BD
  426. exit 0
  427.  
  428. ----------------------------------------------------------------------
  429. -- 
  430.  
  431. John Quarterman, jsq@ut-sally.ARPA, {ihnp4,seismo,ctvax}!ut-sally!jsq
  432.  
  433. Volume-Number: Volume 1, Number 09
  434.  
  435.