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.

160 lines
3.9 KiB

  1. //+----------------------------------------------------------------------------
  2. //
  3. // File: util.cpp
  4. //
  5. // Module: CMSAMPLE.DLL
  6. //
  7. // Synopsis: Utility functions for parsing command line arguments
  8. //
  9. // Copyright (c) 2000 Microsoft Corporation
  10. //
  11. //+----------------------------------------------------------------------------
  12. #include <windows.h>
  13. #define MAX_CMD_ARGS 15 // Maximum number of arguments expected
  14. //
  15. // Enumerations to keep pointer state for parsing command line arguments
  16. //
  17. typedef enum _CMDLN_STATE
  18. {
  19. CS_END_SPACE, // done handling a space
  20. CS_BEGIN_QUOTE, // we've encountered a begin quote
  21. CS_END_QUOTE, // we've encountered a end quote
  22. CS_CHAR, // we're scanning chars
  23. CS_DONE
  24. } CMDLN_STATE;
  25. //+----------------------------------------------------------------------------
  26. //
  27. // Function: GetArgV
  28. //
  29. // Synopsis: Simulates ArgV using GetCommandLine
  30. //
  31. // Arguments: LPSTR pszCmdLine - Ptr to a copy of the command line to be processed
  32. //
  33. // Returns: LPSTR * - Ptr to a ptr array containing the arguments. Caller is
  34. // responsible for releasing memory.
  35. //
  36. //
  37. //+----------------------------------------------------------------------------
  38. LPSTR *GetArgV(LPSTR pszCmdLine)
  39. {
  40. if (NULL == pszCmdLine || NULL == pszCmdLine[0])
  41. {
  42. return NULL;
  43. }
  44. //
  45. // Allocate Ptr array, up to MAX_CMD_ARGS ptrs
  46. //
  47. LPSTR *ppArgV = (LPSTR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(LPSTR) * MAX_CMD_ARGS);
  48. if (NULL == ppArgV)
  49. {
  50. return NULL;
  51. }
  52. //
  53. // Declare locals
  54. //
  55. LPSTR pszCurr;
  56. LPSTR pszNext;
  57. LPSTR pszToken;
  58. CMDLN_STATE state;
  59. state = CS_CHAR;
  60. int ndx = 0;
  61. //
  62. // Parse out pszCmdLine and store pointers in ppArgV
  63. //
  64. pszCurr = pszToken = pszCmdLine;
  65. do
  66. {
  67. switch (*pszCurr)
  68. {
  69. case TEXT(' '):
  70. if (state == CS_CHAR)
  71. {
  72. //
  73. // We found a token
  74. //
  75. pszNext = CharNext(pszCurr);
  76. *pszCurr = TEXT('\0');
  77. ppArgV[ndx] = pszToken;
  78. ndx++;
  79. pszCurr = pszToken = pszNext;
  80. state = CS_END_SPACE;
  81. continue;
  82. }
  83. else
  84. {
  85. if (state == CS_END_SPACE || state == CS_END_QUOTE)
  86. {
  87. pszToken = CharNext(pszToken);
  88. }
  89. }
  90. break;
  91. case TEXT('\"'):
  92. if (state == CS_BEGIN_QUOTE)
  93. {
  94. //
  95. // We found a token
  96. //
  97. pszNext = CharNext(pszCurr);
  98. *pszCurr = TEXT('\0');
  99. //
  100. // skip the opening quote
  101. //
  102. pszToken = CharNext(pszToken);
  103. ppArgV[ndx] = pszToken;
  104. ndx++;
  105. pszCurr = pszToken = pszNext;
  106. state = CS_END_QUOTE;
  107. continue;
  108. }
  109. else
  110. {
  111. state = CS_BEGIN_QUOTE;
  112. }
  113. break;
  114. case TEXT('\0'):
  115. if (state != CS_END_QUOTE)
  116. {
  117. //
  118. // End of the line, set last token
  119. //
  120. ppArgV[ndx] = pszToken;
  121. }
  122. state = CS_DONE;
  123. break;
  124. default:
  125. if (state == CS_END_SPACE || state == CS_END_QUOTE)
  126. {
  127. state = CS_CHAR;
  128. }
  129. break;
  130. }
  131. pszCurr = CharNext(pszCurr);
  132. } while (state != CS_DONE);
  133. return ppArgV;
  134. }