Leaked source code of windows server 2003
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.

134 lines
3.2 KiB

  1. /*++
  2. UNPARSE.C
  3. utility function to convert a flat command back into an argc/argv pair.
  4. Scavenged from the Keytab subdirectory because it makes more sense here,
  5. on 8/19/1997 by DavidCHR
  6. --*/
  7. #include "private.h"
  8. /* UnparseOptions:
  9. cmd --> argc/argv. Free argv with free(). */
  10. BOOL
  11. UnparseOptions( PCHAR cmd,
  12. int *pargc,
  13. PCHAR *pargv[] ) {
  14. int argc=0;
  15. PCHAR *argv=NULL;
  16. char prevChar='\0';
  17. int szBuffer;
  18. int i=0;
  19. PCHAR heapBuffer=NULL;
  20. szBuffer = lstrlenA(cmd);
  21. for (i = 0; cmd[i] != '\0' ; i++ ) {
  22. /* count the characters while we count the words.
  23. could use strlen, but then we'd parse it twice,
  24. which is kind of unnecessary if the string can
  25. get fairly long */
  26. OPTIONS_DEBUG("[%d]'%c' ", i, cmd[i]);
  27. if (isspace(prevChar) && !isspace(cmd[i]) ) {
  28. /* ignore multiple spaces */
  29. OPTIONS_DEBUG("[New word boundary]");
  30. argc++;
  31. }
  32. prevChar = cmd[i];
  33. }
  34. if (!isspace(prevChar)) {
  35. argc++; /* trailing null is also a word boundary if the last
  36. character was non-whitespace */
  37. OPTIONS_DEBUG("Last character is not a space. Argc = %d.\n", argc);
  38. }
  39. OPTIONS_DEBUG("done parsing. i = %d. buffer-->%hs\n",
  40. i, cmd);
  41. OPTIONS_DEBUG("saving argc...");
  42. *pargc = argc; // save argc.
  43. /* ok, argc is our wordcount, so we must allocate argc+1
  44. (null terminate) pointers and i+1 (null terminate) characters */
  45. argv = (PCHAR *) malloc( ((argc+1) * sizeof( PCHAR )) +
  46. ((i+1) * sizeof(CHAR)) );
  47. if ( !argv ) {
  48. return FALSE;
  49. }
  50. OPTIONS_DEBUG("ok.\nsaving argv (0x%x)...", argv);
  51. *pargv = argv; // save the argv.
  52. OPTIONS_DEBUG( "ok.\n"
  53. "Assigning heapBuffer as argv[argc+1 = %d] = 0x%x...",
  54. argc+1, argv+argc+1);
  55. /* now we've got this glob of memory, separate the pointers from
  56. the characters. The pointers end at argv[argc], so &(argv[argc+1])
  57. should start the rest */
  58. heapBuffer = (PCHAR) &(argv[argc+1]);
  59. /* now, copy the string, translating spaces to null characters and
  60. filling in pointers at the same time */
  61. OPTIONS_DEBUG("ok\ncopying the string manually...");
  62. argc = 0; // reuse argc, since it's saved.
  63. prevChar = ' ';
  64. for (i = 0 ; cmd[i] != '\0' ; i++ ) {
  65. if (isspace(cmd[i])) {
  66. OPTIONS_DEBUG("[%d]'%c' --> NULL\n", i, cmd[i]);
  67. heapBuffer[i] = '\0';
  68. } else { // current char is not a space.
  69. heapBuffer[i] = cmd[i];
  70. OPTIONS_DEBUG("[%d]'%c' ", i, cmd[i]);
  71. if (isspace(prevChar)) {
  72. /* beginning of a word. Set the current word pointer
  73. (argv[argc]) in addition to the regular stuff */
  74. OPTIONS_DEBUG("[word boundary %d]", argc);
  75. argv[argc] = &(heapBuffer[i]);
  76. argc++;
  77. }
  78. }
  79. prevChar = cmd[i];
  80. }
  81. heapBuffer[i] = '\0'; // copy the null character too.
  82. OPTIONS_DEBUG("[%d] NULL\n", i );
  83. OPTIONS_DEBUG("returning:\n");
  84. for (i = 0 ; i < argc ; i++ ) {
  85. OPTIONS_DEBUG("[%d]%hs\n", i, argv[i]);
  86. }
  87. return TRUE;
  88. }