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.

475 lines
10 KiB

  1. /*** ntalias.cpp - Alias command processor for NT debugger
  2. *
  3. * Copyright <C> 1999-2001, Microsoft Corporation
  4. *
  5. * Purpose:
  6. * To establish, maintain, and translate alias command tokens
  7. *
  8. *
  9. * Revision History:
  10. *
  11. * [-] 08-Aug-1999 Richg Created.
  12. *
  13. *************************************************************************/
  14. #include "ntsdp.hpp"
  15. PALIAS g_AliasListHead; // List of alias elements
  16. ULONG g_NumAliases;
  17. HRESULT
  18. SetAlias(PCSTR SrcText, PCSTR DstText)
  19. {
  20. PALIAS pPrevAlias;
  21. PALIAS pCurAlias;
  22. PALIAS pNewAlias;
  23. pNewAlias = (PALIAS)malloc( sizeof(ALIAS) + strlen(SrcText) +
  24. strlen(DstText) + 2 );
  25. if (!pNewAlias)
  26. {
  27. return E_OUTOFMEMORY;
  28. }
  29. //
  30. // Locate Alias, or insertion point
  31. //
  32. // This insertion scheme maintains a sorted list of
  33. // alias elements by name.
  34. //
  35. pPrevAlias = NULL;
  36. pCurAlias = g_AliasListHead;
  37. while (( pCurAlias != NULL ) &&
  38. ( strcmp( SrcText, pCurAlias->Name ) > 0 ))
  39. {
  40. pPrevAlias = pCurAlias;
  41. pCurAlias = pCurAlias->Next;
  42. }
  43. // If there is already an element by that name, clear it.
  44. if (pCurAlias != NULL &&
  45. !strcmp(SrcText, pCurAlias->Name))
  46. {
  47. PALIAS pTmpAlias = pCurAlias->Next;
  48. free(pCurAlias);
  49. pCurAlias = pTmpAlias;
  50. g_NumAliases--;
  51. }
  52. pNewAlias->Next = pCurAlias;
  53. if (pPrevAlias == NULL)
  54. {
  55. g_AliasListHead = pNewAlias;
  56. }
  57. else
  58. {
  59. pPrevAlias->Next = pNewAlias;
  60. }
  61. pNewAlias->Name = (PSTR)(pNewAlias + 1);
  62. pNewAlias->Value = pNewAlias->Name + strlen(SrcText) + 1;
  63. strcpy( pNewAlias->Name, SrcText );
  64. strcpy( pNewAlias->Value, DstText );
  65. g_NumAliases++;
  66. return S_OK;
  67. }
  68. /*** ParseSetAlias - Set an alias expression
  69. *
  70. * Purpose:
  71. * From the current command line position at g_CurCmd,
  72. * read the alias name and value tokens. Once obtained
  73. * perform an alias list lookup to see if it is a redefinition.
  74. * If not allocate a new alias element and place it on the
  75. * alias element list.
  76. *
  77. *
  78. * Input:
  79. * Global: g_CurCmd - command line position
  80. * Global: g_AliasListHead
  81. *
  82. * Returns:
  83. * Status
  84. *
  85. * Exceptions:
  86. * error exit: SYNTAX errors
  87. *
  88. *************************************************************************/
  89. void
  90. ParseSetAlias(void)
  91. {
  92. PSTR pAliasName;
  93. PSTR pAliasValue;
  94. UCHAR ch;
  95. //
  96. // Locate alias name
  97. //
  98. PeekChar();
  99. pAliasName = g_CurCmd;
  100. do
  101. {
  102. ch = *g_CurCmd++;
  103. } while (ch != ' ' && ch != '\t' && ch != '\0' && ch != ';');
  104. if ( (ULONG_PTR)(g_CurCmd-1) == (ULONG_PTR)pAliasName )
  105. {
  106. error(SYNTAX);
  107. }
  108. *--g_CurCmd = '\0'; // Back up and null terminate
  109. // the alias name token
  110. g_CurCmd++; // -> next char
  111. //
  112. // Locate alias value, take remaining cmd line as value
  113. //
  114. PeekChar();
  115. pAliasValue = g_CurCmd;
  116. do
  117. {
  118. ch = *g_CurCmd++;
  119. } while (ch != '\t' && ch != '\0');
  120. if ( (ULONG_PTR)(g_CurCmd-1) == (ULONG_PTR)pAliasValue )
  121. {
  122. error(SYNTAX);
  123. }
  124. *--g_CurCmd = '\0'; // Back up and Null terminate
  125. // the alias value token
  126. if (SetAlias(pAliasName, pAliasValue) != S_OK)
  127. {
  128. error(MEMORY);
  129. }
  130. }
  131. HRESULT
  132. DeleteAlias(PCSTR SrcText)
  133. {
  134. PALIAS pCurAlias;
  135. if (SrcText[0] == '*' && SrcText[1] == 0)
  136. {
  137. //
  138. // Delete all aliases
  139. //
  140. while ( g_AliasListHead != NULL )
  141. {
  142. //
  143. // Unchain the element and free it
  144. //
  145. pCurAlias = g_AliasListHead->Next;
  146. free(g_AliasListHead);
  147. g_AliasListHead = pCurAlias;
  148. }
  149. g_NumAliases = 0;
  150. }
  151. else
  152. {
  153. PALIAS pPrevAlias;
  154. //
  155. // Locate and delete the specified alias
  156. //
  157. pPrevAlias = NULL;
  158. pCurAlias = g_AliasListHead;
  159. while (( pCurAlias != NULL ) &&
  160. ( strcmp( SrcText, pCurAlias->Name )))
  161. {
  162. pPrevAlias = pCurAlias;
  163. pCurAlias = pCurAlias->Next;
  164. }
  165. if ( pCurAlias == NULL )
  166. {
  167. return E_NOINTERFACE;
  168. }
  169. //
  170. // Unchain the element and free it
  171. //
  172. if (pPrevAlias == NULL)
  173. {
  174. g_AliasListHead = pCurAlias->Next;
  175. }
  176. else
  177. {
  178. pPrevAlias->Next = pCurAlias->Next;
  179. }
  180. free( pCurAlias );
  181. g_NumAliases--;
  182. }
  183. return S_OK;
  184. }
  185. /*** ParseDeleteAlias - Delete an alias expression
  186. *
  187. * Purpose:
  188. * From the current command line position at g_CurCmd,
  189. * read the ALias name and perform an alias list lookup
  190. * to see if it exists and unlink and delete the element.
  191. *
  192. *
  193. * Input:
  194. * Global: g_CurCmd - command line position
  195. * Global: g_AliasListHead
  196. *
  197. * Returns:
  198. * Status
  199. *
  200. * Exceptions:
  201. * error exit: SYNTAX errors or non-existent element
  202. *
  203. *************************************************************************/
  204. void
  205. ParseDeleteAlias(void)
  206. {
  207. PSTR pAliasName;
  208. UCHAR ch;
  209. //
  210. // Locate alias name on cmd line
  211. //
  212. PeekChar();
  213. pAliasName = g_CurCmd;
  214. do
  215. {
  216. ch = *g_CurCmd++;
  217. } while (ch != ' ' && ch != '\t' && ch != '\0' && ch != ';');
  218. if ( (ULONG_PTR)(g_CurCmd-1) == (ULONG_PTR)pAliasName )
  219. {
  220. error(SYNTAX);
  221. }
  222. *--g_CurCmd = '\0'; // Null terminate the token
  223. if (ch != '\0')
  224. {
  225. g_CurCmd++;
  226. }
  227. if (DeleteAlias(pAliasName) != S_OK)
  228. {
  229. error(NOTFOUND);
  230. }
  231. }
  232. /*** ListAliases - List the alias structures
  233. *
  234. * Purpose:
  235. * Read and display all of the alias list elements.
  236. *
  237. *
  238. * Input:
  239. * Global: g_AliasListHead
  240. *
  241. * Returns:
  242. * Status
  243. *
  244. * Exceptions:
  245. * None
  246. *
  247. *************************************************************************/
  248. void
  249. ListAliases(void)
  250. {
  251. PALIAS pCurAlias;
  252. pCurAlias = g_AliasListHead;
  253. if ( pCurAlias == NULL )
  254. {
  255. dprintf( "No Alias entries to list. \n" );
  256. return;
  257. }
  258. dprintf (" Alias Value \n");
  259. dprintf (" ------- ------- \n");
  260. while ( pCurAlias != NULL )
  261. {
  262. dprintf(" %-16s %s \n", pCurAlias->Name, pCurAlias->Value );
  263. pCurAlias = pCurAlias->Next;
  264. }
  265. }
  266. /*** ReplaceAliases - Replace aliases in the given command string
  267. *
  268. * Purpose:
  269. * From the current command line position at g_CurCmd,
  270. * read each token and build a new command line, replacing
  271. * tokens with alias value data. A lookup is performed on
  272. * each original command line token to determine if it is
  273. * defined in the alias list. If so it is replaced on the
  274. * new command line, otherwise the original token is
  275. * placed on the new command line.
  276. *
  277. *
  278. * Input:
  279. * Global: g_CurCmd - command line position
  280. * Global: g_AliasListHead
  281. *
  282. *
  283. * Returns:
  284. * Global: g_CurCmd - command line position
  285. * Global: chCommand
  286. * Status
  287. *
  288. *************************************************************************/
  289. void
  290. ReplaceAliases(PSTR CommandString)
  291. {
  292. PSTR Command = CommandString;
  293. CHAR *pToken;
  294. CHAR ch;
  295. CHAR chdelim[2];
  296. CHAR chAliasCommand[MAX_COMMAND]; // Alias build command area
  297. CHAR *pchAliasCommand;
  298. ULONG TokenLen;
  299. PALIAS pPrevAlias;
  300. PALIAS pCurAlias;
  301. BOOLEAN LineEnd;
  302. // If the incoming command looks like an alias-manipulation
  303. // command don't replace aliases.
  304. if (CommandString[0] == 'a' &&
  305. (CommandString[1] == 'd' ||
  306. CommandString[1] == 'l' ||
  307. CommandString[1] == 's'))
  308. {
  309. return;
  310. }
  311. // If the incoming command is all spaces it's probably
  312. // the result of control characters getting mapped to
  313. // spaces. Don't process it as there can't be any
  314. // aliases and we don't want the trailing space trimming
  315. // to remove the input space.
  316. while (*Command == ' ')
  317. {
  318. Command++;
  319. }
  320. if (*Command == 0)
  321. {
  322. return;
  323. }
  324. Command = CommandString;
  325. pchAliasCommand = chAliasCommand;
  326. ZeroMemory( pchAliasCommand, sizeof(chAliasCommand) );
  327. LineEnd = FALSE;
  328. do
  329. {
  330. //
  331. // Locate command line token
  332. //
  333. while (isspace(*Command))
  334. {
  335. PSTR AliasCmdEnd =
  336. pchAliasCommand + strlen(pchAliasCommand);
  337. *AliasCmdEnd++ = *Command++;
  338. *AliasCmdEnd = 0;
  339. }
  340. pToken = Command;
  341. do
  342. {
  343. ch = *Command++;
  344. } while (ch != ' ' &&
  345. ch != '\'' &&
  346. ch != '"' &&
  347. ch != ';' &&
  348. ch != '\t' &&
  349. ch != '\0');
  350. //
  351. // Preserve the token delimiter
  352. //
  353. chdelim[0] = ch;
  354. chdelim[1] = '\0';
  355. if ( ch == '\0' )
  356. {
  357. LineEnd = TRUE;
  358. }
  359. TokenLen = (ULONG)((Command - 1) - pToken);
  360. if ( TokenLen != 0 )
  361. {
  362. *--Command = '\0'; // Null terminate the string
  363. Command++;
  364. ch = *Command;
  365. //
  366. // Locate Alias or end of list
  367. //
  368. pCurAlias = g_AliasListHead;
  369. while (( pCurAlias != NULL ) &&
  370. ( strcmp( pToken, pCurAlias->Name )))
  371. {
  372. pCurAlias = pCurAlias->Next;
  373. }
  374. if ( pCurAlias != NULL )
  375. {
  376. strcat( pchAliasCommand, pCurAlias->Value );
  377. }
  378. else
  379. {
  380. strcat( pchAliasCommand, pToken );
  381. }
  382. }
  383. strcat( pchAliasCommand, chdelim );
  384. } while( !LineEnd );
  385. //
  386. // Strip off any trailing blanks
  387. //
  388. pchAliasCommand += strlen( pchAliasCommand );
  389. ch = *pchAliasCommand;
  390. while ( ch == '\0' || ch == ' ' )
  391. {
  392. *pchAliasCommand = '\0';
  393. ch = *--pchAliasCommand;
  394. }
  395. //
  396. // Place the new command line in the command string buffer.
  397. //
  398. strcpy( CommandString, chAliasCommand );
  399. }