PageRenderTime 51ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/net/wireless/tiwlan1251/CUDK/CLI/console.c

https://bitbucket.org/cyanogenmod/cm-kernel
C | 996 lines | 686 code | 163 blank | 147 comment | 145 complexity | 306def0252338c7621240bb638b7fc39 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  1. /*******************************************************************************
  2. **+--------------------------------------------------------------------------+**
  3. **| |**
  4. **| Copyright 1998-2008 Texas Instruments, Inc. - http://www.ti.com/ |**
  5. **| |**
  6. **| Licensed under the Apache License, Version 2.0 (the "License"); |**
  7. **| you may not use this file except in compliance with the License. |**
  8. **| You may obtain a copy of the License at |**
  9. **| |**
  10. **| http://www.apache.org/licenses/LICENSE-2.0 |**
  11. **| |**
  12. **| Unless required by applicable law or agreed to in writing, software |**
  13. **| distributed under the License is distributed on an "AS IS" BASIS, |**
  14. **| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |**
  15. **| See the License for the specific language governing permissions and |**
  16. **| limitations under the License. |**
  17. **| |**
  18. **+--------------------------------------------------------------------------+**
  19. *******************************************************************************/
  20. #ifndef _WINDOWS
  21. #include <sys/select.h>
  22. #include <unistd.h>
  23. #include <signal.h>
  24. #include "ipc.h"
  25. #include "g_tester.h"
  26. #include "wipp_ctrl.h"
  27. #endif /* __LINUX__ */
  28. #ifdef _WINDOWS
  29. #else
  30. #include <errno.h>
  31. #endif
  32. #include <string.h>
  33. #include <stdlib.h>
  34. #include <stdio.h>
  35. #include <ctype.h>
  36. #include "ticon.h"
  37. #include "console.h"
  38. #include "cu_cmd.h"
  39. static ConEntry_t *p_mon_root;
  40. static ConEntry_t *p_cur_dir;
  41. static char *p_inbuf;
  42. static volatile int stop_UI_Monitor;
  43. #define INBUF_LENGTH 1024
  44. /*#define PRINT_LEN_PER_PARM 40*/
  45. #define ROOT_NAME "/"
  46. /* Internal functions */
  47. static void console_allocRoot( void );
  48. static void console_displayDir( ConEntry_t *p_dir );
  49. static t_TokenType console_getWord( char *name, U16 len );
  50. static t_TokenType console_getStrParam( char *buf, ConParm_t *param );
  51. static t_TokenType console_analizeToken( char *name );
  52. static U16 console_getNParms( ConEntry_t *p_token );
  53. static int console_parseParms( ConEntry_t *p_token, U16 *pnParms );
  54. static ConEntry_t *console_searchToken( ConEntry_t *p_dir, char *name );
  55. static void console_dirHelp( void );
  56. static void console_displayHelp( ConEntry_t *p_token );
  57. static int console_chooseAlias( ConEntry_t *p_dir, ConEntry_t *p_new_token );
  58. /***************************************************************
  59. Function : consoleRunScript
  60. Description: Execute command from file
  61. Parameters: script_file - name of script file
  62. Output: !NULL - if 'quit' command was executed
  63. ***************************************************************/
  64. int consoleRunScript( char *script_file )
  65. {
  66. FILE *hfile = fopen(script_file, "r" );
  67. if( hfile )
  68. {
  69. char buf[INBUF_LENGTH];
  70. stop_UI_Monitor = FALSE;
  71. while( fgets(buf, sizeof(buf), hfile ) )
  72. {
  73. console_printf_terminal("script <%s>\n", script_file);
  74. console_ParseString( buf );
  75. if( stop_UI_Monitor )
  76. break;
  77. }
  78. fclose(hfile);
  79. }
  80. else
  81. perror( script_file );
  82. return stop_UI_Monitor;
  83. }
  84. /***************************************************************
  85. Function : consoleAddDirExt
  86. Description: Add subdirectory
  87. Parameters: p_root - root directory handle (might be NULL)
  88. name - directory name
  89. Output: the new created directory handle
  90. =NULL - failure
  91. ***************************************************************/
  92. handle_t consoleAddDirExt(
  93. handle_t hRoot, /* Upper directory handle. NULL=root */
  94. const char *name, /* New directory name */
  95. const char *desc ) /* Optional dir description */
  96. {
  97. ConEntry_t *p_root = (ConEntry_t *)hRoot;
  98. ConEntry_t *p_dir;
  99. ConEntry_t **p_e;
  100. if (!p_mon_root)
  101. console_allocRoot( );
  102. if (!p_root)
  103. p_root = p_mon_root;
  104. ASSERT( p_root && (p_root->sel == Dir) );
  105. if ( (p_dir=(ConEntry_t *)malloc( sizeof( ConEntry_t )) ) == NULL)
  106. return NULL;
  107. memset( p_dir, 0, sizeof( ConEntry_t ) );
  108. strncpy( p_dir->name, name, MAX_NAME_LEN );
  109. strncpy( p_dir->help, desc, MAX_HELP_LEN );
  110. p_dir->sel = Dir;
  111. console_chooseAlias( p_root, p_dir );
  112. /* Add new directory to the root's list */
  113. p_dir->u.dir.upper = p_root;
  114. p_e = &(p_root->u.dir.first);
  115. while (*p_e)
  116. p_e = &((*p_e)->next);
  117. *p_e = p_dir;
  118. return p_dir;
  119. }
  120. /***************************************************************
  121. Function : consoleAddToken
  122. Description: Add token
  123. Parameters: p_dir - directory handle (might be NULL=root)
  124. name - token name
  125. help - help string
  126. p_func - token handler
  127. p_parms- array of parameter descriptions.
  128. Must be terminated with {0}.
  129. Each parm descriptor is a struct
  130. { "myname", - name
  131. 10, - low value
  132. 20, - high value
  133. 0 } - default value =-1 no default
  134. or address for string parameter
  135. Output: E_OK - OK
  136. !=0 - error
  137. ***************************************************************/
  138. consoleErr consoleAddToken( handle_t hDir,
  139. const char *name,
  140. const char *help,
  141. FuncToken_t p_func,
  142. ConParm_t p_parms[] )
  143. {
  144. ConEntry_t *p_dir = (ConEntry_t *)hDir;
  145. ConEntry_t *p_token;
  146. ConEntry_t **p_e;
  147. U16 i;
  148. if (!p_mon_root)
  149. console_allocRoot( );
  150. if (!p_dir)
  151. p_dir = p_mon_root;
  152. ASSERT( p_dir && (p_dir->sel == Dir) );
  153. /* Initialize token structure */
  154. if ((p_token=(ConEntry_t *)calloc( 1, sizeof(ConEntry_t) )) == NULL)
  155. {
  156. fprintf(stderr, "** no memory **\n");
  157. return E_NOMEMORY;
  158. }
  159. /* Copy name */
  160. strncpy( p_token->name, name, MAX_NAME_LEN );
  161. strncpy( p_token->help, help, MAX_HELP_LEN );
  162. p_token->sel = Token;
  163. p_token->u.token.f_tokenFunc = p_func;
  164. /* Convert name to lower case and choose alias */
  165. console_chooseAlias( p_dir, p_token );
  166. /* Copy parameters */
  167. if ( p_parms )
  168. {
  169. for(i = 0; p_parms->name && p_parms->name[0] && ( i < MAX_NUM_OF_PARMS); i++ )
  170. {
  171. ConParm_t *p_token_parm = &p_token->u.token.parm[i];
  172. /* String parameter must have an address */
  173. if(p_parms->flags & (CON_PARM_STRING | CON_PARM_LINE))
  174. {
  175. if ( p_parms->hi_val >= INBUF_LENGTH )
  176. {
  177. fprintf(stderr, "** buffer too big: %s/%s\n", p_dir->name, name);
  178. free( p_token );
  179. return E_NOMEMORY;
  180. }
  181. if (p_parms->hi_val == 0 || (p_parms->flags & CON_PARM_RANGE) )
  182. {
  183. fprintf(stderr, "** Bad string param definition: %s/%s\n", p_dir->name, name );
  184. free( p_token );
  185. return E_BADPARM;
  186. }
  187. p_parms->value = (U32) calloc(1, p_parms->hi_val+1);
  188. if( !p_parms->value )
  189. {
  190. fprintf(stderr, "** No memory: %s/%s (max.size=%ld)\n", p_dir->name, name, p_parms->hi_val );
  191. free( p_token );
  192. return E_NOMEMORY;
  193. }
  194. }
  195. /* Copy parameter */
  196. *p_token_parm = *p_parms;
  197. if( p_token_parm->hi_val || p_token_parm->low_val )
  198. p_token_parm->flags |= CON_PARM_RANGE;
  199. p_token_parm->name = (const char *)p_token->u.token.name[i];
  200. strncpy( p_token->u.token.name[i], p_parms->name, MAX_NAME_LEN );
  201. ++p_parms;
  202. }
  203. if ((i == MAX_NUM_OF_PARMS) && p_parms->name[0])
  204. {
  205. fprintf(stderr, "** Too many params: %s/%s\n", p_dir->name, name );
  206. free( p_token );
  207. return E_TOOMANY;
  208. }
  209. }
  210. /* Add token to the directory */
  211. p_e = &(p_dir->u.dir.first);
  212. while (*p_e)
  213. p_e = &((*p_e)->next);
  214. *p_e = p_token;
  215. return E_OK;
  216. }
  217. /* Monitor driver */
  218. void consoleStart( void )
  219. {
  220. #ifndef _WINDOWS
  221. fd_set read_set;
  222. int max_fd_index;
  223. int result;
  224. int pid;
  225. #endif /* __LINUX__ */
  226. char inbuf[INBUF_LENGTH];
  227. if (!p_mon_root)
  228. return;
  229. stop_UI_Monitor = FALSE;
  230. console_displayDir( p_cur_dir );
  231. while(!stop_UI_Monitor)
  232. {
  233. #ifndef _WINDOWS
  234. /***********************************************************************************/
  235. /* Wait for one of two external events: */
  236. /* ----------------------------------- */
  237. /* */
  238. /* 1. Data received from STDIN */
  239. /* 2. Data received from one of the TCP clients */
  240. /* 3. Data received from iperf process stdout (if enabled) */
  241. /****************************************************************************/
  242. /* Prepare the read set fields */
  243. FD_ZERO(&read_set);
  244. FD_SET(0, &read_set);
  245. FD_SET(ipc_pipe[0], &read_set);
  246. FD_SET(wipp_control_general_process_out_pipe[0], &read_set);
  247. /* Determine the maximum index of the file descriptor */
  248. max_fd_index = (max(wipp_control_general_process_out_pipe[0], max(0, ipc_pipe[0])) + 1);
  249. /* Wait for event - blocking */
  250. result = select(max_fd_index, &read_set, NULL, NULL, NULL);
  251. if (result > 0)
  252. {
  253. if (FD_ISSET(0, &read_set))
  254. {
  255. /*****************************/
  256. /* Data received from STDIN */
  257. /***************************/
  258. if ( fgets( inbuf, sizeof(inbuf), stdin ) <= 0 )
  259. return;
  260. console_ParseString( inbuf );
  261. }
  262. if (FD_ISSET(ipc_pipe[0], &read_set))
  263. {
  264. /**********************************/
  265. /* Data received from TCP client */
  266. /********************************/
  267. result = read(ipc_pipe[0], (U8 *)inbuf, (U16)sizeof(inbuf));
  268. /* Get the pid of the calling process */
  269. pid = *(inbuf + 0) | (*(inbuf + 1) << 8);
  270. /* Signal the calling process (tell him that we have
  271. received the command, and he can send us another one */
  272. if (pid != 0xFFFF)
  273. {
  274. kill(pid, SIGUSR1);
  275. }
  276. if (result > 0)
  277. {
  278. console_ParseString(inbuf + 2);
  279. }
  280. }
  281. if (FD_ISSET(wipp_control_general_process_out_pipe[0], &read_set))
  282. {
  283. /*****************************************/
  284. /* Data received general process stdout */
  285. /***************************************/
  286. result = read(wipp_control_general_process_out_pipe[0], (U8 *)inbuf + 3, sizeof(inbuf) - 3);
  287. if (result > 0)
  288. {
  289. wipp_control_send_iperf_results_to_host(WIPP_CONTROL_EVT_RUN_PROCESS_STDOUT, inbuf, result);
  290. }
  291. }
  292. }
  293. else
  294. {
  295. /* Error */
  296. console_printf_terminal("Input selection mismatch...\n");
  297. return;
  298. }
  299. #else /* __LINUX__ */
  300. #endif /* __LINUX__ */
  301. }
  302. }
  303. /* Parse the given input string and exit.
  304. All commands in the input string are executed one by one.
  305. */
  306. void console_ParseString(char *input_string )
  307. {
  308. ConEntry_t *p_token;
  309. char name[MAX_NAME_LEN];
  310. t_TokenType tType;
  311. U16 nParms;
  312. #ifndef _WINDOWS
  313. /* Check if this is WIPP control command, if it is - process it */
  314. if (wipp_control_check_command(input_string))
  315. {
  316. return;
  317. }
  318. /* Check if this is g_tester control command, if it is - process it */
  319. if (g_tester_check_command((unsigned char*) input_string))
  320. {
  321. return;
  322. }
  323. #endif /* __LINUX__ */
  324. if (!p_mon_root)
  325. return;
  326. if( input_string[strlen(input_string)-1] == '\n' )
  327. {
  328. char *s = (char *) &input_string[strlen(input_string)-1];
  329. *s = 0;
  330. }
  331. p_inbuf = (char *)input_string;
  332. stop_UI_Monitor = FALSE;
  333. /* Interpret empty string as "display directory" */
  334. if ( p_inbuf && !*p_inbuf )
  335. console_displayDir( p_cur_dir );
  336. while(!stop_UI_Monitor && p_inbuf && *p_inbuf)
  337. {
  338. tType = console_getWord( name, MAX_NAME_LEN );
  339. switch( tType )
  340. {
  341. case NameToken:
  342. p_token = console_searchToken( p_cur_dir, name );
  343. if (p_token == NULL)
  344. {
  345. fprintf( stderr, "**Error: '%s'**\n", name);
  346. p_inbuf = NULL;
  347. }
  348. else if (p_token->sel == Dir)
  349. {
  350. p_cur_dir = p_token;
  351. console_displayDir( p_cur_dir );
  352. }
  353. else
  354. { /* Function token */
  355. if (!console_parseParms( p_token, &nParms ))
  356. console_displayHelp( p_token );
  357. else
  358. p_token->u.token.f_tokenFunc( p_token->u.token.parm, nParms );
  359. }
  360. break;
  361. case UpToken: /* Go to upper directory */
  362. if (p_cur_dir->u.dir.upper)
  363. p_cur_dir = p_cur_dir->u.dir.upper;
  364. console_displayDir( p_cur_dir );
  365. break;
  366. case RootToken: /* Go to the root directory */
  367. if (p_cur_dir->u.dir.upper)
  368. p_cur_dir = p_mon_root;
  369. console_displayDir( p_cur_dir );
  370. break;
  371. case HelpToken: /* Display help */
  372. if (( console_getWord( name, MAX_NAME_LEN ) == NameToken ) &&
  373. ((p_token = console_searchToken( p_cur_dir, name )) != NULL ) &&
  374. (p_token->sel == Token) )
  375. console_displayHelp( p_token );
  376. else
  377. console_dirHelp( );
  378. break;
  379. case DirHelpToken:
  380. console_displayDir( p_cur_dir );
  381. console_printf_terminal("Type ? <name> for command help, \"/\"-root, \"..\"-upper\n" );
  382. break;
  383. case BreakToken: /* Clear buffer */
  384. p_inbuf = NULL;
  385. break;
  386. case EmptyToken:
  387. break;
  388. }
  389. }
  390. }
  391. /* Stop monitor driver */
  392. void consoleStop( void )
  393. {
  394. stop_UI_Monitor = TRUE;
  395. }
  396. /*********************************************************/
  397. /* Internal functions */
  398. /*********************************************************/
  399. /* Allocate root directory */
  400. void console_allocRoot( void )
  401. {
  402. /* The very first call. Allocate root structure */
  403. if ((p_mon_root=(ConEntry_t *)calloc( 1, sizeof( ConEntry_t ) ) ) == NULL)
  404. {
  405. ASSERT( p_mon_root );
  406. return;
  407. }
  408. strcpy( p_mon_root->name, ROOT_NAME );
  409. p_mon_root->sel = Dir;
  410. p_cur_dir = p_mon_root;
  411. }
  412. /* Display directory */
  413. void console_displayDir( ConEntry_t *p_dir )
  414. {
  415. char out_buf[512];
  416. ConEntry_t *p_token;
  417. sprintf( out_buf, "%s%s> ", (p_dir==p_mon_root)? "" : ".../", p_dir->name );
  418. p_token = p_dir->u.dir.first;
  419. while( p_token )
  420. {
  421. if( (strlen(out_buf) + strlen(p_token->name) + 2)>= sizeof(out_buf) )
  422. {
  423. fprintf(stderr, "** console_displayDir(): buffer too small....\n");
  424. break;
  425. }
  426. strcat( out_buf, p_token->name );
  427. if ( p_token->sel == Dir )
  428. strcat( out_buf, "/" );
  429. p_token = p_token->next;
  430. if (p_token)
  431. strcat( out_buf, ", " );
  432. }
  433. console_printf_terminal("%s\n", out_buf );
  434. }
  435. /* Cut the first U16 from <p_inbuf>.
  436. Return the U16 in <name> and updated <p_inbuf>
  437. */
  438. static t_TokenType console_getWord( char *name, U16 len )
  439. {
  440. U16 i=0;
  441. t_TokenType tType;
  442. p_inbuf = console_ltrim(p_inbuf);
  443. while( *p_inbuf && *p_inbuf!=' ' && i<len )
  444. name[i++] = *(p_inbuf++);
  445. if (i<len)
  446. name[i] = 0;
  447. tType = console_analizeToken( name );
  448. return tType;
  449. }
  450. static t_TokenType console_getStrParam( char *buf, ConParm_t *param )
  451. {
  452. t_TokenType tType;
  453. U32 i, len = param->hi_val;
  454. char *end_buf;
  455. p_inbuf = console_ltrim(p_inbuf);
  456. if( param->flags & CON_PARM_LINE )
  457. {
  458. strcpy(buf, p_inbuf );
  459. p_inbuf += strlen(p_inbuf);
  460. }
  461. else
  462. {
  463. if( *p_inbuf == '\"' )
  464. {
  465. end_buf = strchr(p_inbuf+1, '\"' );
  466. if( !end_buf )
  467. {
  468. fprintf(stderr, "** invalid string param: '%s'\n", p_inbuf );
  469. p_inbuf += strlen(p_inbuf);
  470. return EmptyToken;
  471. }
  472. if( (end_buf - p_inbuf - 1) > (int)len )
  473. {
  474. fprintf(stderr, "** param is too long: '%s'\n", p_inbuf );
  475. p_inbuf += strlen(p_inbuf);
  476. return EmptyToken;
  477. }
  478. *end_buf = 0;
  479. strcpy( buf, p_inbuf+1 );
  480. p_inbuf = end_buf + 1;
  481. }
  482. else
  483. {
  484. for( i=0; *p_inbuf && *p_inbuf!=' ' && i<len; i++ )
  485. buf[i] = *(p_inbuf++);
  486. buf[i] = 0;
  487. if( *p_inbuf && *p_inbuf != ' ' )
  488. {
  489. fprintf(stderr, "** param is too long: '%s'\n", p_inbuf-strlen(buf) );
  490. p_inbuf += strlen(p_inbuf);
  491. return EmptyToken;
  492. }
  493. }
  494. }
  495. tType = console_analizeToken( buf );
  496. return tType;
  497. }
  498. /* Make a preliminary analizis of <name> token.
  499. Returns a token type (Empty, Up, Root, Break, Name)
  500. */
  501. t_TokenType console_analizeToken( char *name )
  502. {
  503. if (!name[0])
  504. return EmptyToken;
  505. if (!strcmp( name, TOKEN_UP ) )
  506. return UpToken;
  507. if (!strcmp( name, TOKEN_ROOT ) )
  508. return RootToken;
  509. if (!strcmp( name, TOKEN_BREAK ) )
  510. return BreakToken;
  511. if (!strcmp( name, TOKEN_HELP ) )
  512. return HelpToken;
  513. if (!strcmp( name, TOKEN_DIRHELP ) )
  514. return DirHelpToken;
  515. return NameToken;
  516. }
  517. /* Returns number of parameters of the given token
  518. */
  519. static U16 console_getNParms( ConEntry_t *p_token )
  520. {
  521. U16 i;
  522. if ( !p_token->u.token.parm )
  523. return 0;
  524. for( i=0;
  525. (i<MAX_NUM_OF_PARMS-1) &&
  526. p_token->u.token.parm[i].name &&
  527. p_token->u.token.parm[i].name[0];
  528. i++ )
  529. ;
  530. return i;
  531. }
  532. /* Parse p_inbuf string based on parameter descriptions in <p_token>.
  533. Fill parameter values in <p_token>.
  534. Returns the number of parameters filled.
  535. To Do: add a option of one-by-one user input of missing parameters.
  536. */
  537. int console_parseParms( ConEntry_t *p_token, U16 *pnParms )
  538. {
  539. U16 nTotalParms = console_getNParms( p_token );
  540. U16 nParms=0;
  541. char *end_buf = NULL, parm[INBUF_LENGTH];
  542. U16 i, print_params = 0;
  543. U32 val = 0;
  544. S32 sval = 0;
  545. /* Mark all parameters as don't having an explicit value */
  546. for( i=0; i<nTotalParms; i++ )
  547. p_token->u.token.parm[i].flags |= CON_PARM_NOVAL;
  548. /* ----------------- */
  549. p_inbuf = console_ltrim(p_inbuf);
  550. if( p_inbuf[0] == '!' && p_inbuf[1] == '!' )
  551. {
  552. p_inbuf += 2; print_params = 1;
  553. }
  554. /* ----------------- */
  555. /* Build a format string */
  556. for( i=0; i<nTotalParms; i++ )
  557. {
  558. if (p_token->u.token.parm[i].flags & (CON_PARM_STRING | CON_PARM_LINE) )
  559. {
  560. /* For a string parameter value is the string address */
  561. /* and hi_val is the string length */
  562. if (console_getStrParam( parm, &p_token->u.token.parm[i] ) != NameToken)
  563. break;
  564. if( strlen(parm) > p_token->u.token.parm[i].hi_val ||
  565. (p_token->u.token.parm[i].low_val && p_token->u.token.parm[i].low_val > strlen(parm) ) )
  566. {
  567. fprintf(stderr, "param '%s' must be %ld..%ld chars\n", p_token->u.token.parm[i].name,
  568. p_token->u.token.parm[i].low_val, p_token->u.token.parm[i].hi_val);
  569. return FALSE;
  570. }
  571. strcpy( (char *)p_token->u.token.parm[i].value, parm );
  572. }
  573. else
  574. {
  575. if (console_getWord( parm, MAX_PARM_LEN ) != NameToken)
  576. break;
  577. if (p_token->u.token.parm[i].flags & CON_PARM_SIGN)
  578. sval = strtol( parm, &end_buf, 0 );
  579. else
  580. val = strtoul( parm, &end_buf, 0 );
  581. if( /*errno || */end_buf <= parm )
  582. break;
  583. /* if (sscanf( parm, "%i", &val ) != 1)*/
  584. /* break;*/
  585. /* Check value */
  586. if (p_token->u.token.parm[i].flags & CON_PARM_RANGE)
  587. {
  588. if (p_token->u.token.parm[i].flags & CON_PARM_SIGN)
  589. {
  590. if ((sval < (S32)p_token->u.token.parm[i].low_val) ||
  591. (sval > (S32)p_token->u.token.parm[i].hi_val) )
  592. {
  593. fprintf( stderr, "%s: %d out of range (%d, %d)\n",
  594. p_token->u.token.parm[i].name, (int)sval,
  595. (int)p_token->u.token.parm[i].low_val, (int)p_token->u.token.parm[i].hi_val );
  596. return FALSE;
  597. }
  598. }
  599. else
  600. {
  601. if ((val < p_token->u.token.parm[i].low_val) ||
  602. (val > p_token->u.token.parm[i].hi_val) )
  603. {
  604. fprintf( stderr, "%s: %ld out of range (%ld, %ld)\n",
  605. p_token->u.token.parm[i].name, val,
  606. p_token->u.token.parm[i].low_val, p_token->u.token.parm[i].hi_val );
  607. return FALSE;
  608. }
  609. }
  610. }
  611. if (p_token->u.token.parm[i].flags & CON_PARM_SIGN)
  612. p_token->u.token.parm[i].value = sval;
  613. else
  614. p_token->u.token.parm[i].value = val;
  615. }
  616. p_token->u.token.parm[i].flags &= ~CON_PARM_NOVAL;
  617. ++nParms;
  618. }
  619. /* Process default values */
  620. for( ; i<nTotalParms; i++ )
  621. {
  622. if ((p_token->u.token.parm[i].flags & CON_PARM_DEFVAL) != 0)
  623. {
  624. p_token->u.token.parm[i].flags &= ~CON_PARM_NOVAL;
  625. ++nParms;
  626. }
  627. else if (!(p_token->u.token.parm[i].flags & CON_PARM_OPTIONAL) )
  628. {
  629. /* Mandatory parameter missing */
  630. return FALSE;
  631. }
  632. }
  633. if( print_params )
  634. {
  635. printf("Params: %d\n", nParms );
  636. for (i=0; i<nParms; i++ )
  637. {
  638. console_printf_terminal("%d: %s - flags:%d",
  639. i+1, p_token->u.token.parm[i].name,
  640. p_token->u.token.parm[i].flags);
  641. if (p_token->u.token.parm[i].flags & CON_PARM_SIGN)
  642. console_printf_terminal("min:%d, max:%d, value:%d ",p_token->u.token.parm[i].low_val, p_token->u.token.parm[i].hi_val,
  643. p_token->u.token.parm[i].value);
  644. else
  645. console_printf_terminal("min:%ld, max:%ld, value:%ld ",p_token->u.token.parm[i].low_val, p_token->u.token.parm[i].hi_val,
  646. p_token->u.token.parm[i].value);
  647. console_printf_terminal("(%#lx)",p_token->u.token.parm[i].value );
  648. if( p_token->u.token.parm[i].flags & (CON_PARM_LINE | CON_PARM_STRING ))
  649. {
  650. printf(" - '%s'", (char *) p_token->u.token.parm[i].value );
  651. }
  652. printf("\n");
  653. }
  654. }
  655. *pnParms = nParms;
  656. return TRUE;
  657. }
  658. /* Serach a token by name in the current directory */
  659. ConEntry_t *console_searchToken( ConEntry_t *p_dir, char *name )
  660. {
  661. ConEntry_t *p_token;
  662. U16 name_len = (U16)strlen( name );
  663. /* Check alias */
  664. p_token = p_dir->u.dir.first;
  665. while( p_token )
  666. {
  667. if (p_token->alias &&
  668. (name_len == ALIAS_LEN) &&
  669. !console_stricmp( p_token->alias, name, ALIAS_LEN ) )
  670. return p_token;
  671. p_token = p_token->next;
  672. }
  673. /* Check name */
  674. p_token = p_dir->u.dir.first;
  675. while( p_token )
  676. {
  677. if (!console_stricmp( p_token->name, name, name_len ) )
  678. break;
  679. p_token = p_token->next;
  680. }
  681. return p_token;
  682. }
  683. /* Display help for each entry in the current directory */
  684. void console_dirHelp( void )
  685. {
  686. ConEntry_t *p_token;
  687. char print_str[80];
  688. p_token = p_cur_dir->u.dir.first;
  689. while( p_token )
  690. {
  691. if (p_token->sel == Dir)
  692. sprintf( print_str, "%s: directory\n", p_token->name );
  693. else
  694. sprintf( print_str, "%s(%d parms): %s\n",
  695. p_token->name, console_getNParms(p_token), p_token->help );
  696. console_printf_terminal( print_str );
  697. p_token = p_token->next;
  698. }
  699. console_printf_terminal( "Type ? <name> for command help, \"/\"-root, \"..\"-upper\n" );
  700. }
  701. /* Display help a token */
  702. void console_displayHelp( ConEntry_t *p_token )
  703. {
  704. char bra, ket;
  705. U16 nTotalParms = console_getNParms( p_token );
  706. U16 i;
  707. console_printf_terminal( "%s: %s ", p_token->help, p_token->name );
  708. for( i=0; i<nTotalParms; i++ )
  709. {
  710. if (p_token->u.token.parm[i].flags & CON_PARM_OPTIONAL)
  711. {
  712. bra = '['; ket=']';
  713. }
  714. else
  715. {
  716. bra = '<'; ket='>';
  717. }
  718. console_printf_terminal( "%c%s", bra, p_token->u.token.parm[i].name );
  719. if (p_token->u.token.parm[i].flags & CON_PARM_DEFVAL)
  720. {
  721. console_printf_terminal("=%lu", p_token->u.token.parm[i].value);
  722. }
  723. if (p_token->u.token.parm[i].flags & CON_PARM_RANGE)
  724. {
  725. console_printf_terminal( (p_token->u.token.parm[i].flags & CON_PARM_SIGN) ? " (%d..%d%s)" : " (%lu..%lu%s)",
  726. p_token->u.token.parm[i].low_val,
  727. p_token->u.token.parm[i].hi_val,
  728. (p_token->u.token.parm[i].flags & (CON_PARM_STRING | CON_PARM_LINE)) ? " chars" : "" );
  729. }
  730. console_printf_terminal( "%c \n",ket );
  731. }
  732. }
  733. /* Choose unique alias for <name> in <p_dir> */
  734. /* Currently only single-character aliases are supported */
  735. int console_chooseAlias( ConEntry_t *p_dir, ConEntry_t *p_new_token )
  736. {
  737. ConEntry_t *p_token;
  738. int i;
  739. char c;
  740. char *new_alias = NULL;
  741. /* find alias given from user */
  742. for(i=0; p_new_token->name[i]; i++ )
  743. {
  744. if( isupper(p_new_token->name[i]) )
  745. {
  746. new_alias = &p_new_token->name[i];
  747. break;
  748. }
  749. }
  750. console_strlwr( p_new_token->name );
  751. if( new_alias )
  752. {
  753. p_token = p_dir->u.dir.first;
  754. while( p_token )
  755. {
  756. if (p_token->alias && (tolower( *p_token->alias ) == *new_alias) )
  757. {
  758. /* *new_alias = toupper(*new_alias);*/
  759. fprintf( stderr, "**Error: duplicated alias '%c' in <%s> and <%s>**\n", *new_alias,
  760. p_token->name, p_new_token->name );
  761. return 0;
  762. }
  763. p_token = p_token->next;
  764. }
  765. *new_alias = toupper(*new_alias);
  766. p_new_token->alias = new_alias;
  767. return 1;
  768. }
  769. i = 0;
  770. while( p_new_token->name[i] )
  771. {
  772. c = p_new_token->name[i];
  773. p_token = p_dir->u.dir.first;
  774. while( p_token )
  775. {
  776. if (p_token->alias &&
  777. (tolower( *p_token->alias ) == c) )
  778. break;
  779. p_token = p_token->next;
  780. }
  781. if (p_token)
  782. ++i;
  783. else
  784. {
  785. p_new_token->name[i] = toupper( c );
  786. p_new_token->alias = &p_new_token->name[i];
  787. break;
  788. }
  789. }
  790. return 1;
  791. }
  792. /* Convert string s to lower case. Return pointer to s */
  793. char * console_strlwr( char *s )
  794. {
  795. char *s0=s;
  796. while( *s )
  797. {
  798. *s = tolower( *s );
  799. ++s;
  800. }
  801. return s0;
  802. }
  803. /* Compare strings case insensitive */
  804. int console_stricmp( char *s1, char *s2, U16 len )
  805. {
  806. int i;
  807. for( i=0; i<len && s1[i] && s2[i]; i++ )
  808. {
  809. if (tolower( s1[i]) != tolower( s2[i] ))
  810. break;
  811. }
  812. return ( (len - i) * (s1[i] - s2[i]) );
  813. }
  814. /* Remove leading blanks */
  815. char * console_ltrim(char *s )
  816. {
  817. while( *s == ' ' || *s == '\t' ) s++;
  818. return s;
  819. }
  820. #ifdef _WINDOWS
  821. #endif /* _WINDOWS*/