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.

331 lines
9.2 KiB

  1. // Copyright (c) 1998-1999 Microsoft Corporation
  2. /*****************************************************************************
  3. *
  4. * PARSE_A.C
  5. *
  6. * ANSI stubs / replacements for the UNICODE command line parsing
  7. * routines (parse.c)
  8. *
  9. * External Entry Points: (defined in utilsub.h)
  10. *
  11. * ParseCommandLineA()
  12. * IsTokenPresentA()
  13. * SetTokenPresentA()
  14. * SetTokenNotPresentA()
  15. *
  16. *
  17. ****************************************************************************/
  18. /* Get the standard C includes */
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22. #include <windows.h>
  23. #include <winstaw.h>
  24. #include <utilsub.h>
  25. /*=============================================================================
  26. == Local Functions Defined
  27. ============================================================================*/
  28. /*=============================================================================
  29. == External Functions Used
  30. ============================================================================*/
  31. /*=============================================================================
  32. == Local Variables Used
  33. ============================================================================*/
  34. /*=============================================================================
  35. == Global Variables Used
  36. ============================================================================*/
  37. /*****************************************************************************
  38. *
  39. * ParseCommandLineA (ANSI stub for ParseCommandLineW)
  40. *
  41. * Thunks over argv_a (ANSI) to argv_w (UNICODE) and TOKMAPA to TOKMAPW,
  42. * calls ParseCommandLineW(), then thunks back TOKMAPW to TOKMAPA and
  43. * returns
  44. *
  45. * ENTRY:
  46. * (refer to ParseCommandLineW)
  47. * EXIT:
  48. * (refer to ParseCommandLineW), plus
  49. * PARSE_FLAG_NOT_ENOUGH_MEMORY
  50. *
  51. ****************************************************************************/
  52. #define tmFormIsString(x) ((x == TMFORM_S_STRING) || (x == TMFORM_DATE) || (x == TMFORM_PHONE) || (x == TMFORM_STRING) || (x == TMFORM_X_STRING))
  53. USHORT WINAPI
  54. ParseCommandLineA( INT argc,
  55. CHAR **argv_a,
  56. PTOKMAPA ptm_a,
  57. USHORT flag )
  58. {
  59. int i, len1, len2;
  60. USHORT rc = PARSE_FLAG_NOT_ENOUGH_MEMORY; // default to memory error
  61. WCHAR **argv_w = NULL;
  62. PTOKMAPA ptmtmp_a;
  63. PTOKMAPW ptmtmp_w, ptm_w = NULL;
  64. /*
  65. * If no parameters, we skip a lot of work.
  66. */
  67. if ( argc == 0 ) {
  68. rc = PARSE_FLAG_NO_PARMS;
  69. return(rc);
  70. }
  71. /*
  72. * Alloc and form WCHAR argvw array.
  73. */
  74. if ( !(argv_w = (WCHAR **)malloc( (len1 = argc * sizeof(WCHAR *)) )) )
  75. goto done; // memory error
  76. memset(argv_w, 0, len1); // zero all to init pointers to NULL
  77. for ( i = 0; i < argc; i++ ) {
  78. if ( argv_w[i] = malloc((len1 = ((len2 = strlen(argv_a[i])+1) * 2))) ) {
  79. memset(argv_w[i], 0, len1);
  80. mbstowcs(argv_w[i], argv_a[i], len2);
  81. } else {
  82. goto done; // memory error
  83. }
  84. }
  85. /*
  86. * Alloc and form TOKMAPW array.
  87. */
  88. for ( ptmtmp_a=ptm_a, i=0;
  89. ptmtmp_a->tmToken != NULL;
  90. ptmtmp_a++, i++ );
  91. if ( !(ptm_w = (PTOKMAPW)malloc( (len1 = ++i * sizeof(TOKMAPW)) )) )
  92. goto done; // memory error
  93. memset(ptm_w, 0, len1); // zero all to init pointers to NULL
  94. for ( ptmtmp_w=ptm_w, ptmtmp_a=ptm_a;
  95. ptmtmp_a->tmToken != NULL;
  96. ptmtmp_w++, ptmtmp_a++ ) {
  97. /*
  98. * Allocate and convert token.
  99. */
  100. if ( ptmtmp_w->tmToken =
  101. malloc((len1 = ((len2 = strlen(ptmtmp_a->tmToken)+1) * 2))) ) {
  102. memset(ptmtmp_w->tmToken, 0, len1);
  103. mbstowcs(ptmtmp_w->tmToken, ptmtmp_a->tmToken, len2);
  104. } else {
  105. goto done; // memory error
  106. }
  107. /*
  108. * Copy flag, form, and length (no conversion needed).
  109. */
  110. ptmtmp_w->tmFlag = ptmtmp_a->tmFlag;
  111. ptmtmp_w->tmForm = ptmtmp_a->tmForm;
  112. ptmtmp_w->tmDLen = ptmtmp_a->tmDLen;
  113. /*
  114. * Allocate or copy address if a data length was specified.
  115. */
  116. if ( ptmtmp_w->tmDLen ) {
  117. /*
  118. * Allocate new WCHAR address if we're a string type.
  119. * Otherwise, point to original address (no conversion needed).
  120. */
  121. if ( tmFormIsString(ptmtmp_w->tmForm) ) {
  122. if ( ptmtmp_w->tmAddr =
  123. malloc(len1 = ptmtmp_w->tmDLen*sizeof(WCHAR)) )
  124. memset(ptmtmp_w->tmAddr, 0, len1);
  125. else
  126. goto done; // memory error
  127. } else {
  128. ptmtmp_w->tmAddr = ptmtmp_a->tmAddr;
  129. }
  130. /*
  131. * For proper default behavior, zero ANSI address contents if
  132. * the "don't clear memory" flag is not set.
  133. */
  134. if ( !(flag & PCL_FLAG_NO_CLEAR_MEMORY) )
  135. memset(ptmtmp_a->tmAddr, 0, ptmtmp_a->tmDLen);
  136. }
  137. }
  138. /*
  139. * Call ParseCommandLineW
  140. */
  141. rc = ParseCommandLineW(argc, argv_w, ptm_w, flag);
  142. /*
  143. * Copy flags for each TOPMAPW element. Also, convert to ANSI strings
  144. * that were present on the command line into caller's TOKMAPA array, if
  145. * data length was specified.
  146. */
  147. for ( ptmtmp_w=ptm_w, ptmtmp_a=ptm_a;
  148. ptmtmp_w->tmToken != NULL;
  149. ptmtmp_w++, ptmtmp_a++ ) {
  150. ptmtmp_a->tmFlag = ptmtmp_w->tmFlag;
  151. if ( ptmtmp_w->tmDLen &&
  152. (ptmtmp_w->tmFlag & TMFLAG_PRESENT) &&
  153. tmFormIsString(ptmtmp_w->tmForm) )
  154. wcstombs(ptmtmp_a->tmAddr, ptmtmp_w->tmAddr, ptmtmp_w->tmDLen);
  155. }
  156. done:
  157. /*
  158. * Free the argvw array.
  159. */
  160. if ( argv_w ) {
  161. for ( i = 0; i < argc; i++ ) {
  162. if ( argv_w[i] )
  163. free(argv_w[i]);
  164. }
  165. free(argv_w);
  166. }
  167. /*
  168. * Free the TOKMAPW tokens, string addresses, and TOKMAK array itself.
  169. */
  170. if ( ptm_w ) {
  171. for ( ptmtmp_w=ptm_w; ptmtmp_w->tmToken != NULL; ptmtmp_w++ ) {
  172. /*
  173. * Free token.
  174. */
  175. free(ptmtmp_w->tmToken);
  176. /*
  177. * Free address if a data length was specified and we're a
  178. * string type.
  179. */
  180. if ( ptmtmp_w->tmDLen && tmFormIsString(ptmtmp_w->tmForm) )
  181. free(ptmtmp_w->tmAddr);
  182. }
  183. free(ptm_w);
  184. }
  185. /*
  186. * Return ParseCommandLineW status.
  187. */
  188. return(rc);
  189. } // end ParseCommandLineA
  190. /*****************************************************************************
  191. *
  192. * IsTokenPresentA (ANSI version)
  193. *
  194. * Determines if a specified command line token (in given TOKMAPA array)
  195. * was present on the command line.
  196. *
  197. * ENTRY:
  198. * ptm (input)
  199. * Points to 0-terminated TOKMAPA array to scan.
  200. * pToken (input)
  201. * The token to scan for.
  202. *
  203. * EXIT:
  204. * TRUE if the specified token was present on the command line;
  205. * FALSE otherwise.
  206. *
  207. ****************************************************************************/
  208. BOOLEAN WINAPI
  209. IsTokenPresentA( PTOKMAPA ptm,
  210. PCHAR pToken )
  211. {
  212. int i;
  213. for ( i = 0; ptm[i].tmToken; i++ ) {
  214. if ( !strcmp( ptm[i].tmToken, pToken ) )
  215. return( (ptm[i].tmFlag & TMFLAG_PRESENT) ? TRUE : FALSE );
  216. }
  217. return(FALSE);
  218. } // end IsTokenPresentA
  219. /*****************************************************************************
  220. *
  221. * SetTokenPresentA (ANSI version)
  222. *
  223. * Forces a specified command line token (in given TOKMAPA array)
  224. * to be flagged as 'present' on the command line.
  225. *
  226. * ENTRY:
  227. * ptm (input)
  228. * Points to 0-terminated TOKMAPA array to scan.
  229. * pToken (input)
  230. * The token to scan for and set flags.
  231. *
  232. * EXIT:
  233. * TRUE if the specified token was found in the TOKMAPA array
  234. * (TMFLAG_PRESENT flag is set). FALSE otherwise.
  235. *
  236. ****************************************************************************/
  237. BOOLEAN WINAPI
  238. SetTokenPresentA( PTOKMAPA ptm,
  239. PCHAR pToken )
  240. {
  241. int i;
  242. for ( i = 0; ptm[i].tmToken; i++ ) {
  243. if ( !strcmp( ptm[i].tmToken, pToken ) ) {
  244. ptm[i].tmFlag |= TMFLAG_PRESENT;
  245. return(TRUE);
  246. }
  247. }
  248. return(FALSE);
  249. } // end SetTokenPresentA
  250. /*****************************************************************************
  251. *
  252. * SetTokenNotPresentA (ANSI Versio)
  253. *
  254. * Forces a specified command line token (in given TOKMAPA array)
  255. * to be flagged as 'not present' on the command line.
  256. *
  257. * ENTRY:
  258. * ptm (input)
  259. * Points to 0-terminated TOKMAPA array to scan.
  260. * pToken (input)
  261. * The token to scan for and set flags.
  262. *
  263. * EXIT:
  264. * TRUE if the specified token was found in the TOKMAPA array
  265. * (TMFLAG_PRESENT flag is reset). FALSE otherwise.
  266. *
  267. ****************************************************************************/
  268. BOOLEAN WINAPI
  269. SetTokenNotPresentA( PTOKMAPA ptm,
  270. PCHAR pToken )
  271. {
  272. int i;
  273. for ( i = 0; ptm[i].tmToken; i++ ) {
  274. if ( !strcmp( ptm[i].tmToken, pToken ) ) {
  275. ptm[i].tmFlag &= ~TMFLAG_PRESENT;
  276. return(TRUE);
  277. }
  278. }
  279. return(FALSE);
  280. } // end SetTokenNotPresentA