cmdParser.c
上传用户:nvosite88
上传日期:2007-01-17
资源大小:4983k
文件大小:12k
源码类别:

VxWorks

开发平台:

C/C++

  1. /* cmdParser.c - Command line parser routines. */
  2. /* Copyright 2000 Wind River Systems, Inc. */
  3. /*
  4. Modification history
  5. --------------------
  6. 01f,18sep01,wef  merge from wrs.tor2_0.usb1_1-f for veloce, fixed formatting
  7. 01e,08aug01,dat  Removing warnings
  8. 01d,31jul01,wef  fix man page generation errors
  9. 01c,23nov99,rcb  Make KeywordMatch() function public.
  10. 01b,16aug99,rcb  Add option in CmdParserHelpFunc to display help only for
  11.  a specific command.
  12. 01a,01jun99,rcb  First.
  13. */
  14. /*
  15. DESCRIPTION
  16. This file includes a collection of command-line parsing functions which are
  17. useful in the creation of command line utilities, such as bus exercisers.
  18. There are three groups of functions defined by this library.  The first is
  19. a collection of general string parser functions, such as functions to eliminate
  20. white space, functions to strip tokens out of a string, and so forth.  
  21. The second set of functions drive the actual parsing process.  In order to 
  22. use this second set of functions, clients must construct a table of CMD_DESCR
  23. structures which define the commands to be recognized by the parser.  A 
  24. brief example of such a table is shown below.
  25. .CS
  26. CMD_DESCR Commands [] =
  27.     {
  28.     {"Help", 4, "Help/?", "Displays list of commands.", CmdParserHelpFunc},
  29.     {"?",    1, NULL,   NULL,      CmdParserHelpFunc},
  30.     {"Exit", 4, "Exit",   "Exits program.", CmdParserExitFunc},
  31.     {NULL,   0, NULL,   NULL,      NULL}
  32.     };
  33. .CE
  34. The first field is the keyword for the command.  The second field specifies
  35. the number of characters of the command which must match - allowing the user
  36. to enter only a portion of the keyword as a shortcut.  The third and fourth
  37. fields are strings giving the command usage and a brief help string.  A NULL
  38. in the Help field indicates that the corresponding keyword is a synonym for 
  39. another command its usage/help should not be shown.  The final field is a 
  40. pointer to a function of type CMD_EXEC_FUNC which will be invoked if the 
  41. parser encounters the corresponding command.
  42. The third group of functions provide standard CMD_EXEC_FUNCs for certain
  43. commonly used commands, such as CmdParserHelpFunc and CmdParserExitFunc as
  44. shown in the preceding example.
  45. The caller may pass a generic (pVOID) parameter to the command line parsing
  46. functions in the second group. This function is in turn passed to the
  47. CMD_EXEC_FUNCs.  In this way, the caller can specify context information
  48. for the command execution functions.
  49. Commands are executed after the user presses [enter].  Multiple commands may 
  50. be entered on the same command line separated by semicolons (';').  Each 
  51. command as if it had been entered on a separate line (unless a command 
  52. terminates with an error, in which case all remaining commands entered on the 
  53. same line will be ignored).
  54. */
  55. /* Include files */
  56. #include "stdio.h"
  57. #include "stdlib.h"
  58. #include "string.h"
  59. #include "ctype.h"
  60. #include "usb/usbPlatform.h"     /* Basic definitions */
  61. #include "usb/tools/cmdParser.h"    /* Our API */
  62. /* Constants */
  63. #define PAUSE_DISPLAY     22     /* Help display pauses every n lines */
  64. /*************************************************************************
  65. *
  66. * PromptAndExecCmd - Prompt for a command and execute it.
  67. *
  68. * Displays <pPrompt> to <fout> and prompts for input from <fin>. Then, 
  69. * parses/executes the command. <pCmdTable> points to an array of
  70. * CMD_DESCR structures defining the command to be recognized by the
  71. * parser, and <Param> is a generic parameter passed down to individual 
  72. * command execution functions.
  73. *
  74. * RETURNS:  RET_OK for normal termination
  75. * RET_ERROR for program failure.
  76. * RET_CONTINUE if execution should continue.
  77. */
  78. UINT16 PromptAndExecCmd
  79.     (
  80.     pVOID param, /* Generic parameter for exec funcs */
  81.     char *pPrompt, /* Prompt to display */
  82.     FILE *fin, /* Input stream */
  83.     FILE *fout,  /* Output stream */
  84.     CMD_DESCR *pCmdTable    /* CMD_DESCR table */
  85.     )
  86.     {
  87.     char cmd [MAX_CMD_LEN]; /* Buffer for input command */
  88.     /* Display prompt */
  89.     fprintf (fout, pPrompt);
  90.     /* Retrieve input */
  91.     if (fgets (cmd, sizeof (cmd), fin) != cmd)
  92.         return RET_ERROR;
  93.     /* Execute input */
  94.     return ExecCmd (param, cmd, fin, fout, pCmdTable);
  95.     }
  96. /*************************************************************************
  97. *
  98. * KeywordMatch - Compare keywords
  99. *
  100. * Compares <s1> and <s2> up to <len> characters, case insensitive.  
  101. * Returns 0 if strings are equal.  
  102. *
  103. * NOTE: This function is equivalent to strnicmp(), but that function is
  104. * not available in all libraries.
  105. *
  106. * RETURNS:  0 if s1 and s2 are the same
  107. * -n if s1 < s2
  108. * +n if s1 > s2
  109. */
  110. int KeywordMatch
  111.     (
  112.     char *s1,     /* string 1 */
  113.     char *s2,     /* string 2 */
  114.     int len /* max length to compare */
  115.     )
  116.     {
  117.     int n = 0;
  118.     for (; len > 0; len--)
  119. {
  120. if ((n = toupper (*s1) - toupper (*s2)) != 0 || *s1 == 0 || *s2 == 0) 
  121.     break;
  122. s1++;
  123. s2++;
  124. }
  125.     return n;
  126.     }
  127. /*************************************************************************
  128. *
  129. * ExecCmd - Execute the command line
  130. *
  131. * Parses and executes the commands in the <pCmd> buffer.  I/O - if any -
  132. * will go to <fin>/<fout>.  The <pCmd> may contain any number of commands
  133. * separated by CMD_SEPARATOR. <pCmdTable> points to an array of
  134. * CMD_DESCR structures defining the command to be recognized by the
  135. * parser, and <param> is a generic parameter passed down to individual 
  136. * command execution functions.
  137. *
  138. * RETURNS:  RET_OK for normal termination.
  139. * RET_ERROR for program failure.
  140. * RET_CONTINUE if execution should continue.
  141. */
  142. UINT16 ExecCmd
  143.     (
  144.     pVOID param, /* Generic parameter for exec funcs */
  145.     char *pCmd,  /* Cmd buffer to be parsed/executed */
  146.     FILE *fin, /* Stream for input */
  147.     FILE *fout,  /* Stream for output */
  148.     CMD_DESCR *pCmdTable    /* CMD_DESCR table */
  149.     )
  150.     {
  151.     UINT16 s = RET_CONTINUE;     /* Execution status */
  152.     char keyword [MAX_KEYWORD_LEN]; /* Bfr for command keyword */
  153.  
  154.     CMD_DESCR *pEntry; /* Pointer to entry in CmdTable */
  155.     /* Parse each command on the command line. */
  156.     TruncSpace (pCmd);
  157.     do
  158. {
  159. /* Retrieve keyword and match against known keywords. */
  160. pCmd = GetNextToken (pCmd, keyword, sizeof (keyword));
  161. if (strlen (keyword) > 0)
  162.     {
  163.     for (pEntry = pCmdTable; 
  164.  pEntry != NULL && pEntry->keyword != NULL;
  165.  pEntry++)
  166. {
  167. if (KeywordMatch (pEntry->keyword, 
  168.   keyword, 
  169.   max (strlen (keyword), 
  170.        (unsigned)pEntry->minMatch))
  171.        == 0)
  172.     {
  173.     /* 
  174.      * We found a matching keyword.  Execute the CMD_EXEC_FUNC
  175.      * for this command. 
  176.      */
  177.     if (pEntry->execFunc == CmdParserHelpFunc)
  178. s = (*pEntry->execFunc) (pCmdTable, &pCmd, fin, fout);
  179.     else
  180. s = (*pEntry->execFunc) (param, &pCmd, fin, fout);
  181.     break;
  182.     }
  183. }
  184.     if (pEntry == NULL || pEntry->keyword == NULL)
  185. {
  186. fprintf (fout, "Unrecognized command: %sn", keyword);
  187. break;
  188. }
  189.     }
  190. /* Skip over trailing CMD_SEPARATOR characters. */
  191. if (*pCmd != CMD_SEPARATOR)
  192.     while (*pCmd != CMD_SEPARATOR && *pCmd != 0)
  193. pCmd++;
  194. while (*pCmd == CMD_SEPARATOR)
  195.     pCmd++;
  196. }
  197. while (strlen (pCmd) > 0 && s == RET_CONTINUE);
  198.     return s;
  199.     }
  200. /*************************************************************************
  201. *
  202. * SkipSpace - Skips leading white space in a string
  203. *
  204. * Returns a pointer to the first non-white-space character in <pStr>.
  205. *
  206. * RETURNS: Ptr to first non-white-space character in <pStr>
  207. */
  208. #define IS_SPACE(c) (isspace ((int) (c)) || ((c) > 0 && (c) < 32))
  209. char *SkipSpace 
  210.     (
  211.     char *pStr /* Input string */
  212.     )
  213.     {
  214.     while (IS_SPACE (*pStr))
  215. pStr++;
  216.     return pStr;
  217.     }
  218. /*************************************************************************
  219. *
  220. * TruncSpace - Truncates string to eliminate trailing whitespace
  221. *
  222. * Trucates <pStr> to eliminate trailing white space.  Returns count
  223. * of characters left in <pStr> upon return.
  224. *
  225. * RETURNS: Number of characters in <pStr> after truncation.
  226. */
  227. UINT16 TruncSpace 
  228.     (
  229.     char *pStr /* Input string */
  230.     )
  231.     {
  232.     UINT16 len;
  233.     while ((len = strlen (pStr)) > 0 && IS_SPACE (pStr [len - 1]))
  234. pStr [len - 1] = 0;
  235.     return len;
  236.     }
  237. /*************************************************************************
  238. *
  239. * GetNextToken - Retrieves the next token from an input string
  240. *
  241. * Copies the next token from <pStr> to <pToken>.  White space before the
  242. * next token is discarded.  Tokens are delimited by white space and by
  243. * the command separator, CMD_SEPARATOR.  No more than <tokenLen> - 1
  244. * characters from <pStr> will be copied into <pToken>. <tokenLen> must be
  245. * at least one and <pToken> will be NULL terminated upon return.
  246. *
  247. * RETURNS: Pointer into <pStr> following end of copied <pToken>.
  248. */
  249. char *GetNextToken 
  250.     (
  251.     char *pStr,  /* Input string */
  252.     char *pToken, /* Bfr to receive token */
  253.     UINT16 tokenLen /* Max length of Token bfr */
  254.     )
  255.     {
  256.     UINT16 len;  /* Temporary length counter */
  257.     /* Skip leading white space */
  258.     pStr = SkipSpace (pStr);
  259.     /* Copy next token into Token bfr */
  260.     pToken [0] = 0;
  261.     while ((len = strlen (pToken)) < tokenLen && 
  262.    *pStr != 0 && 
  263.    !IS_SPACE (*pStr) && 
  264.    *pStr != CMD_SEPARATOR)
  265. {
  266. pToken [len] = *pStr;
  267. pToken [len+1] = 0;
  268. pStr++;
  269. }
  270.     return pStr;
  271.     }
  272. /*************************************************************************
  273. *
  274. * GetHexToken - Retrieves value of hex token
  275. *
  276. * Retrieves the next token from <pCmd> line, interprets it as a hex 
  277. * value, and stores the result in <pToken>.  If there are no remaining 
  278. * tokens, stores <defVal> in <pToken> instead.
  279. *
  280. * RETURNS: Pointer into <pStr> following end of copied <pToken>
  281. */
  282. char *GetHexToken
  283.     (
  284.     char *pStr,  /* input string */
  285.     long *pToken, /* buffer to receive token value */
  286.     long defVal  /* default value */
  287.     )
  288.     {
  289.     char temp [9]; /* Temp storage for token */
  290.     /* Retrieve next token */
  291.     pStr = GetNextToken (pStr, temp, sizeof (temp));
  292.     /* Evaluate Token value */
  293.     if (strlen (temp) == 0 || sscanf (temp, "%lx", pToken) == 0)
  294. *pToken = defVal;
  295.     return pStr;
  296.     }
  297. /*************************************************************************
  298. *
  299. * CmdParserHelpFunc - Displays list of supported commands
  300. *
  301. * Displays the list of commands in the parser command table to <fout>.
  302. * When the parser recognizes that this function is about to be executed, 
  303. * it substitutes a pointer to the current CMD_DESCR table in <param>. 
  304. * If this function is called directly, <param> should point to a table
  305. * of CMD_DESCR structures.
  306. *
  307. * RETURNS: RET_CONTINUE
  308. */
  309. UINT16 CmdParserHelpFunc
  310.     (
  311.     pVOID param,     /* Generic parameter passed down */
  312.     char **ppCmd,     /* Ptr to remainder of cmd line */
  313.     FILE *fin,     /* stream for input (if any) */
  314.     FILE *fout     /* stream for output (if any) */
  315.     )
  316.     {
  317.     CMD_DESCR *pCmdTable = (CMD_DESCR *) param;
  318.     char keyword [MAX_KEYWORD_LEN];
  319.     int lines = 0;
  320.     *ppCmd = GetNextToken (*ppCmd, keyword, sizeof (keyword));
  321.     if (strlen (keyword) == 0)
  322. fprintf (fout, "n");
  323.     for (; pCmdTable != NULL && pCmdTable->keyword != NULL; pCmdTable++) 
  324. {
  325. if (pCmdTable->help != NULL) 
  326.     {
  327.     /* If a parameter has been entered, display help only for 
  328.      * matching cmds */
  329.     if (strlen (keyword) > 0)
  330. if (KeywordMatch (pCmdTable->keyword, 
  331.   keyword, 
  332.   max (strlen (keyword), 
  333.        (unsigned)pCmdTable->minMatch)) 
  334.  != 0)
  335.     continue;
  336.     /* Pause the display every PAUSE_DISPLAY lines */
  337.     if (lines == PAUSE_DISPLAY) 
  338. {
  339. fprintf (fout,  "[Press a key to continue]");
  340. fgetc (fin);
  341. fprintf (fout, "r r");
  342. lines = 0;
  343. }
  344.     fprintf (fout, "%*s  %sn", 
  345.      (strlen (keyword) == 0) ? 22 : 0,
  346.      (pCmdTable->usage == NULL) ? 
  347. pCmdTable->keyword : pCmdTable->usage, 
  348.      pCmdTable->help);
  349.     ++lines;
  350.     }
  351. }
  352.     if (strlen (keyword) == 0)
  353. fprintf (fout, "nn");
  354.     return RET_CONTINUE;
  355.     }
  356. /*************************************************************************
  357. *
  358. * CmdParserExitFunc - Terminates parser execution
  359. *
  360. * Returns RET_OK, causing the parser to return RET_OK to the caller
  361. * signally normal termination of the parser.
  362. *
  363. * RETURNS: RET_OK
  364. */
  365. UINT16 CmdParserExitFunc
  366.     (
  367.     pVOID param,     /* Generic parameter passed down */
  368.     char **ppCmd,     /* Ptr to remainder of cmd line */
  369.     FILE *fin,     /* stream for input (if any) */
  370.     FILE *fout     /* stream for output (if any) */
  371.     )
  372.     {
  373.     return RET_OK;
  374.     }
  375. /* End of file. */