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.

216 lines
5.6 KiB

  1. /*** cmdarg.c - Command argument parsing functions
  2. *
  3. * This module contains all the debug functions.
  4. *
  5. * Copyright (c) 1996,1997 Microsoft Corporation
  6. * Author: Michael Tsang (MikeTs)
  7. * Created 09/18/96
  8. *
  9. * MODIFICATION HISTORY
  10. */
  11. #include "pch.h"
  12. #ifdef DEBUGGER
  13. /*** Local function prototypes
  14. */
  15. LONG LOCAL DbgParseOneArg(PCMDARG ArgTable, PSZ psz, ULONG dwArgNum,
  16. PULONG pdwNonSWArgs);
  17. PCMDARG LOCAL DbgMatchArg(PCMDARG ArgTable, PSZ *ppsz, PULONG pdwNonSWArgs);
  18. /*** Local data
  19. */
  20. PSZ pszSwitchChars = "-/";
  21. PSZ pszOptionSeps = "=:";
  22. /***EP DbgParseArgs - parse command arguments
  23. *
  24. * ENTRY
  25. * pArgs -> command argument table
  26. * pdwNumArgs -> to hold the number of arguments parsed
  27. * pdwNonSWArgs -> to hold the number of non-switch arguments parsed
  28. * pszTokenSeps -> token separator characters string
  29. *
  30. * EXIT-SUCCESS
  31. * returns ARGERR_NONE
  32. * EXIT-FAILURE
  33. * returns negative error code
  34. */
  35. LONG LOCAL DbgParseArgs(PCMDARG ArgTable, PULONG pdwNumArgs,
  36. PULONG pdwNonSWArgs, PSZ pszTokenSeps)
  37. {
  38. LONG rc = ARGERR_NONE;
  39. PSZ psz;
  40. *pdwNumArgs = 0;
  41. *pdwNonSWArgs = 0;
  42. while ((psz = STRTOK(NULL, pszTokenSeps)) != NULL)
  43. {
  44. (*pdwNumArgs)++;
  45. if ((rc = DbgParseOneArg(ArgTable, psz, *pdwNumArgs, pdwNonSWArgs)) !=
  46. ARGERR_NONE)
  47. {
  48. break;
  49. }
  50. }
  51. return rc;
  52. } //DbgParseArgs
  53. /***LP DbgParseOneArg - parse one command argument
  54. *
  55. * ENTRY
  56. * pArgs -> command argument table
  57. * psz -> argument string
  58. * dwArgNum - argument number
  59. * pdwNonSWArgs -> to hold the number of non-switch arguments parsed
  60. *
  61. * EXIT-SUCCESS
  62. * returns ARGERR_NONE
  63. * EXIT-FAILURE
  64. * returns negative error code
  65. */
  66. LONG LOCAL DbgParseOneArg(PCMDARG ArgTable, PSZ psz, ULONG dwArgNum,
  67. PULONG pdwNonSWArgs)
  68. {
  69. LONG rc = ARGERR_NONE;
  70. PCMDARG pArg;
  71. PSZ pszEnd;
  72. if ((pArg = DbgMatchArg(ArgTable, &psz, pdwNonSWArgs)) != NULL)
  73. {
  74. switch (pArg->dwArgType)
  75. {
  76. case AT_STRING:
  77. case AT_NUM:
  78. if (pArg->dwfArg & AF_SEP)
  79. {
  80. if ((*psz != '\0') &&
  81. (STRCHR(pszOptionSeps, *psz) != NULL))
  82. {
  83. psz++;
  84. }
  85. else
  86. {
  87. ARG_ERROR(("argument missing option separator - %s",
  88. psz));
  89. rc = ARGERR_SEP_NOT_FOUND;
  90. break;
  91. }
  92. }
  93. if (pArg->dwArgType == AT_STRING)
  94. {
  95. *((PSZ *)pArg->pvArgData) = psz;
  96. }
  97. else
  98. {
  99. *((PLONG)pArg->pvArgData) =
  100. STRTOL(psz, &pszEnd, pArg->dwArgParam);
  101. if (psz == pszEnd)
  102. {
  103. ARG_ERROR(("invalid numeric argument - %s", psz));
  104. rc = ARGERR_INVALID_NUMBER;
  105. break;
  106. }
  107. }
  108. if (pArg->pfnArg != NULL)
  109. {
  110. rc = pArg->pfnArg(pArg, psz, dwArgNum, *pdwNonSWArgs);
  111. }
  112. break;
  113. case AT_ENABLE:
  114. case AT_DISABLE:
  115. if (pArg->dwArgType == AT_ENABLE)
  116. *((PULONG)pArg->pvArgData) |= pArg->dwArgParam;
  117. else
  118. *((PULONG)pArg->pvArgData) &= ~pArg->dwArgParam;
  119. if ((pArg->pfnArg != NULL) &&
  120. (pArg->pfnArg(pArg, psz, dwArgNum, *pdwNonSWArgs) !=
  121. ARGERR_NONE))
  122. {
  123. break;
  124. }
  125. if (*psz != '\0')
  126. {
  127. rc = DbgParseOneArg(ArgTable, psz, dwArgNum, pdwNonSWArgs);
  128. }
  129. break;
  130. case AT_ACTION:
  131. ASSERT(pArg->pfnArg != NULL);
  132. rc = pArg->pfnArg(pArg, psz, dwArgNum, *pdwNonSWArgs);
  133. break;
  134. default:
  135. ARG_ERROR(("invalid argument table"));
  136. rc = ARGERR_ASSERT_FAILED;
  137. }
  138. }
  139. else
  140. {
  141. ARG_ERROR(("invalid command argument - %s", psz));
  142. rc = ARGERR_INVALID_ARG;
  143. }
  144. return rc;
  145. } //DbgParseOneArg
  146. /***LP DbgMatchArg - match argument type from argument table
  147. *
  148. * ENTRY
  149. * ArgTable -> argument table
  150. * ppsz -> argument string pointer
  151. * pdwNonSWArgs -> to hold the number of non-switch arguments parsed
  152. *
  153. * EXIT-SUCCESS
  154. * returns pointer to argument entry matched
  155. * EXIT-FAILURE
  156. * returns NULL
  157. */
  158. PCMDARG LOCAL DbgMatchArg(PCMDARG ArgTable, PSZ *ppsz, PULONG pdwNonSWArgs)
  159. {
  160. PCMDARG pArg;
  161. for (pArg = ArgTable; pArg->dwArgType != AT_END; pArg++)
  162. {
  163. if (pArg->pszArgID == NULL) //NULL means match anything.
  164. {
  165. (*pdwNonSWArgs)++;
  166. break;
  167. }
  168. else
  169. {
  170. ULONG dwLen;
  171. if (STRCHR(pszSwitchChars, **ppsz) != NULL)
  172. (*ppsz)++;
  173. dwLen = STRLEN(pArg->pszArgID);
  174. if (StrCmp(pArg->pszArgID, *ppsz, dwLen,
  175. (BOOLEAN)((pArg->dwfArg & AF_NOI) != 0)) == 0)
  176. {
  177. (*ppsz) += dwLen;
  178. break;
  179. }
  180. }
  181. }
  182. if (pArg->dwArgType == AT_END)
  183. pArg = NULL;
  184. return pArg;
  185. } //DbgMatchArg
  186. #endif //ifdef DEBUGGER