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 46static ConEntry_t *p_mon_root; 47static ConEntry_t *p_cur_dir; 48static char *p_inbuf; 49static 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 */ 56static void console_allocRoot( void ); 57static void console_displayDir( ConEntry_t *p_dir ); 58static t_TokenType console_getWord( char *name, U16 len ); 59static t_TokenType console_getStrParam( char *buf, ConParm_t *param ); 60static t_TokenType console_analizeToken( char *name ); 61static U16 console_getNParms( ConEntry_t *p_token ); 62static int console_parseParms( ConEntry_t *p_token, U16 *pnParms ); 63static ConEntry_t *console_searchToken( ConEntry_t *p_dir, char *name ); 64static void console_dirHelp( void ); 65static void console_displayHelp( ConEntry_t *p_token ); 66static 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***************************************************************/ 79int 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***************************************************************/ 117handle_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***************************************************************/ 176consoleErr 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 */ 272void 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*/ 384void 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 */ 487void consoleStop( void ) 488{ 489 stop_UI_Monitor = TRUE; 490} 491 492 493/*********************************************************/ 494/* Internal functions */ 495/*********************************************************/ 496 497/* Allocate root directory */ 498void 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 */ 512void 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*/ 540static 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 559static 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*/ 616t_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*/ 643static 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*/ 662int 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 */ 802ConEntry_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 */ 832void 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 */ 855void 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 */ 892int 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 */ 958char * 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 */ 973int 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 */ 987char * 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