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.

396 lines
7.4 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. parsearg.c
  5. Abstract:
  6. Argument Handling
  7. Author:
  8. MikeTs
  9. Environment:
  10. Any
  11. Revision History:
  12. --*/
  13. #include "pch.h"
  14. //
  15. // Local function prototypes
  16. //
  17. ULONG
  18. LOCAL
  19. ParseArgSwitch(
  20. PUCHAR *Argument,
  21. PARGTYPE ArgumentArray,
  22. PPROGINFO ProgramInfo
  23. );
  24. VOID
  25. LOCAL
  26. PrintError(
  27. ULONG ErrorCode,
  28. PUCHAR Argument,
  29. PPROGINFO ProgramInfo
  30. );
  31. VOID
  32. EXPORT
  33. ParseProgramInfo(
  34. PUCHAR ProgramName,
  35. PPROGINFO ProgramInfo
  36. )
  37. /*++
  38. Routine Description:
  39. This routine parses program path and module name
  40. Arguments:
  41. ProgramName - The Argv[0] from main()
  42. ProgramInfo - Program Information structure
  43. Return Value:
  44. None
  45. --*/
  46. {
  47. PUCHAR ptr;
  48. ProgramInfo->ProgPath = _strlwr(ProgramName);
  49. ptr = strrchr( ProgramName, '\\' );
  50. if (ptr != NULL) {
  51. *ptr = '\0';
  52. ProgramInfo->ProgName = ptr + 1;
  53. } else {
  54. ProgramInfo->ProgName = ProgramName;
  55. }
  56. ptr = strchr(ProgramInfo->ProgName, '.');
  57. if (ptr != NULL) {
  58. *ptr = '\0';
  59. }
  60. }
  61. ULONG
  62. EXPORT
  63. ParseSwitches(
  64. PULONG ArgumentCount,
  65. PUCHAR **ArgumentList,
  66. PARGTYPE ArgumentArray,
  67. PPROGINFO ProgramInfo
  68. )
  69. /*++
  70. Routine Description:
  71. Parse command line switches
  72. Arguments:
  73. ArgumentCount - Pointer to the number of arguments
  74. ArgumentList - Pointer to the pointer to the list of arguments
  75. ArgumentArray - How to parse the arguments
  76. ProgramInfo - Program Specific structure
  77. Return Value:
  78. ULONG - Success = ARGERR_NONE
  79. --*/
  80. {
  81. PUCHAR argument;
  82. ULONG status = ARGERR_NONE;
  83. if (ProgramInfo->SwitchChars == NULL) {
  84. ProgramInfo->SwitchChars = DEF_SWITCHCHARS;
  85. }
  86. if (ProgramInfo->Separators == NULL) {
  87. ProgramInfo->Separators = DEF_SEPARATORS;
  88. }
  89. for (; *ArgumentCount; (*ArgumentCount)--, (*ArgumentList)++)
  90. {
  91. argument = **ArgumentList;
  92. if (strchr(ProgramInfo->SwitchChars, *argument)) {
  93. argument++;
  94. status = ParseArgSwitch(
  95. &argument,
  96. ArgumentArray,
  97. ProgramInfo
  98. );
  99. if (status != ARGERR_NONE) {
  100. PrintError( status, argument, ProgramInfo );
  101. break;
  102. }
  103. } else {
  104. break;
  105. }
  106. }
  107. return status;
  108. }
  109. ULONG
  110. LOCAL
  111. ParseArgSwitch(
  112. PUCHAR *Argument,
  113. PARGTYPE ArgumentArray,
  114. PPROGINFO ProgramInfo
  115. )
  116. /*++
  117. Routine Description:
  118. Parse a command line switch
  119. Arguments
  120. Argument - Pointer to argument
  121. ArgumentArray - How to handle the argument
  122. ProgramInfo - Program Information Structure
  123. Return Value:
  124. ULONG
  125. --*/
  126. {
  127. BOOL found = FALSE;
  128. PARGTYPE tableEntry;
  129. PUCHAR argumentEnd;
  130. ULONG length = 0;
  131. ULONG status = ARGERR_NONE;
  132. tableEntry = ArgumentArray;
  133. while (tableEntry->ArgID[0]) {
  134. length = strlen(tableEntry->ArgID);
  135. if (tableEntry->ParseFlags & PF_NOI) {
  136. found = (strncmp(tableEntry->ArgID, *Argument, length) == 0);
  137. } else {
  138. found = (_strnicmp(tableEntry->ArgID, *Argument, length) == 0);
  139. }
  140. if (found) {
  141. break;
  142. }
  143. tableEntry++;
  144. }
  145. if (found) {
  146. *Argument += length;
  147. switch (tableEntry->ArgType) {
  148. case AT_STRING:
  149. case AT_NUM:
  150. if (tableEntry->ParseFlags & PF_SEPARATOR)
  151. {
  152. if (**Argument &&
  153. strchr(ProgramInfo->Separators, **Argument)) {
  154. (*Argument)++;
  155. } else {
  156. status = ARGERR_NO_SEPARATOR;
  157. break;
  158. }
  159. }
  160. if (tableEntry->ArgType == AT_STRING) {
  161. *(UCHAR **)tableEntry->ArgData = *Argument;
  162. } else {
  163. *(ULONG *)tableEntry->ArgData = (ULONG)
  164. strtoul(*Argument, &argumentEnd, tableEntry->ArgParam);
  165. if (*Argument == argumentEnd) {
  166. status = ARGERR_INVALID_NUM;
  167. break;
  168. }
  169. *Argument = argumentEnd;
  170. }
  171. if (tableEntry->ArgVerify) {
  172. status = (*tableEntry->ArgVerify)(Argument, tableEntry);
  173. }
  174. break;
  175. case AT_ENABLE:
  176. case AT_DISABLE:
  177. if (tableEntry->ArgType == AT_ENABLE) {
  178. *(ULONG *)tableEntry->ArgData |= tableEntry->ArgParam;
  179. } else {
  180. *(ULONG *)tableEntry->ArgData &= ~tableEntry->ArgParam;
  181. }
  182. if ( tableEntry->ArgVerify) {
  183. status = (*tableEntry->ArgVerify)(Argument, tableEntry);
  184. if (status == ARGERR_NONE) {
  185. break;
  186. }
  187. }
  188. if (**Argument) {
  189. if (strchr(ProgramInfo->SwitchChars, **Argument)) {
  190. (*Argument)++;
  191. }
  192. status = ParseArgSwitch(
  193. Argument,
  194. ArgumentArray,
  195. ProgramInfo
  196. );
  197. }
  198. break;
  199. case AT_ACTION:
  200. if (tableEntry->ParseFlags & PF_SEPARATOR)
  201. {
  202. if (**Argument &&
  203. strchr(ProgramInfo->Separators, **Argument)) {
  204. (*Argument)++;
  205. } else {
  206. status = ARGERR_NO_SEPARATOR;
  207. break;
  208. }
  209. }
  210. #pragma warning(disable: 4055)
  211. status = (*(PFNARG)tableEntry->ArgData)(Argument, tableEntry);
  212. #pragma warning(default: 4055)
  213. break;
  214. }
  215. } else {
  216. status = ARGERR_UNKNOWN_SWITCH;
  217. }
  218. return status;
  219. }
  220. VOID
  221. LOCAL
  222. PrintError(
  223. ULONG ErrorCode,
  224. PUCHAR Argument,
  225. PPROGINFO ProgramInfo
  226. )
  227. /*++
  228. Routine Description:
  229. Print Appropriate Error Message according to error code
  230. Arguments:
  231. ErrorCode - The error which occured
  232. Argument - Argument in Error
  233. ProgramInfo - Program info structure
  234. Return Value:
  235. VOID
  236. --*/
  237. {
  238. switch (ErrorCode) {
  239. case ARGERR_UNKNOWN_SWITCH:
  240. fprintf(
  241. stderr,
  242. "%s: unknown switch \"%s\"\n",
  243. ProgramInfo->ProgName,
  244. Argument
  245. );
  246. break;
  247. case ARGERR_NO_SEPARATOR:
  248. fprintf(
  249. stderr,
  250. "%s: separator missing after the switch char '%c'\n",
  251. ProgramInfo->ProgName,
  252. *(Argument-1)
  253. );
  254. break;
  255. case ARGERR_INVALID_NUM:
  256. fprintf(
  257. stderr,
  258. "%s: invalid numeric switch \"%s\"\n",
  259. ProgramInfo->ProgName,
  260. Argument
  261. );
  262. break;
  263. case ARGERR_INVALID_TAIL:
  264. fprintf(
  265. stderr,
  266. "%s: invalid argument tail \"%s\"\n",
  267. ProgramInfo->ProgName,
  268. Argument
  269. );
  270. }
  271. }