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