• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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