Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

201 lines
5.9 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. getopt.c
  5. Abstract:
  6. Utility function to parse command line options.
  7. Inspired by UNIX getopt - but coded from scratch.
  8. Not thread-safe currently (don't call this from
  9. multiple threads simultaneously)
  10. Author:
  11. Ravisankar Pudipeddi (ravisp) 27 June 1997
  12. Environment:
  13. User
  14. Notes:
  15. Revision History:
  16. --*/
  17. #include "pch.h"
  18. #pragma hdrstop
  19. #include "getopt.h"
  20. WCHAR* optarg;
  21. ULONG optind=1;
  22. static ULONG optcharind;
  23. static ULONG hyphen=0;
  24. WCHAR
  25. getopt (ULONG Argc, WCHAR* Argv[], WCHAR* Opts)
  26. /*++
  27. Routine Description:
  28. Parses command line arguments.
  29. This function should be repeatedly called
  30. to parse all the supplied command line options.
  31. A command line argument prefixed with a hyphen/slash
  32. ('-' or '/') is treated as a command line option(s).
  33. The set of options the caller is interested in
  34. is passed via the Opts argument.
  35. The format of this desired options list is:
  36. "<option-letter1>[:]<option-letter2>[:]......."
  37. Examples: "ds:g", "x:o:r" etc.
  38. Each letter in this string is an option the
  39. caller is interested in.
  40. If there is a colon (':') after the option letter,
  41. then the caller expects an argument with this option
  42. letter.
  43. On each call, successive options are processed and
  44. the next matching option in the list of desired options
  45. is returned. If the option requires an argument, then
  46. the option argument is in the global 'optarg'.
  47. If all the options have been processed then the value
  48. EOF is returned at which point caller should desist
  49. calling this function again for the lifetime of the process.
  50. A single hyphen/slash ('-' or '/) unaccompanied by any option
  51. letter in the command line indicates getopt to stop processing
  52. command line options and treat the rest of the arguments
  53. as regular command line arguments.
  54. After all the options have been processed (i.e. getopt
  55. returned EOF), the global 'optind' contains the index
  56. to the start of the non-option arguments which may be
  57. processed by the caller.
  58. Note: This function *does not* return an error code if
  59. an non-desired option is encountered in the command line.
  60. Arguments:
  61. Argc - number of command line arguments
  62. Argv - pointer to array of command line arguments
  63. (Argv[0] is skipped in processing the options,
  64. treated as the base filename of the executable)
  65. Opts - String containing the desired options
  66. Return Value:
  67. EOF - No more options. Don't call this function again.
  68. The global 'optind' points to index of the first argument
  69. following the options on the command line
  70. 0 - Error in specifying command line options
  71. Any other character - Next option on the command line.
  72. The value 'optarg' points to the command line
  73. argument string following this option, if
  74. the option was indicated as requiring an argument
  75. (i.e. preceding a colon in the Opts string)
  76. --*/
  77. {
  78. WCHAR ch;
  79. WCHAR* indx;
  80. do {
  81. if (optind >= Argc) {
  82. return EOF;
  83. }
  84. ch = Argv[optind][optcharind++];
  85. if (ch == '\0') {
  86. optind++; optcharind=0;
  87. hyphen = 0;
  88. continue;
  89. }
  90. if ( hyphen || (ch == '-') || (ch == '/')) {
  91. if (!hyphen) {
  92. ch = Argv[optind][optcharind++];
  93. if (ch == '\0') {
  94. //
  95. // just a '-' (or '/') without any other
  96. // char after it indicates to stop
  97. // processing options, the rest are
  98. // regular command line arguments
  99. // optind points to the arguments after
  100. // this lone hyphen
  101. //
  102. optind++;
  103. return EOF;
  104. }
  105. } else if (ch == '\0') {
  106. //
  107. // End of options on this arg.
  108. // continue to next...
  109. optind++;
  110. optcharind = 0;
  111. continue;
  112. }
  113. //indx = strchr(Opts, ch);
  114. indx = wcschr(Opts, ch);
  115. if (indx == NULL) {
  116. //
  117. // Non-desired option encountered
  118. // We just ignore it
  119. //
  120. continue;
  121. }
  122. if (*(indx+1) == ':') {
  123. if (Argv[optind][optcharind] != '\0'){
  124. optarg = &Argv[optind][optcharind];
  125. } else {
  126. if ((optind + 1) >= Argc ||
  127. (Argv[optind+1][0] == '-' ||
  128. Argv[optind+1][0] == '/' )) {
  129. //
  130. // This is a case when one of the following error
  131. // condition exists:
  132. // 1. The user didn't supply an argument to an option
  133. // which requires one (ie, this option was the last
  134. // command line argument on the line)
  135. // 2. The supplied another option as an argument to this
  136. // option. Currently we treat this as an error
  137. //
  138. return 0;
  139. }
  140. optarg = Argv[++optind];
  141. }
  142. optind++;
  143. hyphen = optcharind = 0;
  144. return ch;
  145. }
  146. //
  147. // Argument not required for this option
  148. // So any other characters in the same
  149. // argument would be other valid options
  150. //
  151. hyphen = 1;
  152. return ch;
  153. } else {
  154. //
  155. // Non option encountered.
  156. // No more options present..
  157. //
  158. return EOF;
  159. }
  160. } while (1);
  161. }