blob: eb4689a1cd1ae33c6759b93c1defe2287c618bc3 [file] [log] [blame]
/*******************************************************************************
**+--------------------------------------------------------------------------+**
**| |**
**| Copyright 1998-2008 Texas Instruments, Inc. - http://www.ti.com/ |**
**| |**
**| Licensed under the Apache License, Version 2.0 (the "License"); |**
**| you may not use this file except in compliance with the License. |**
**| You may obtain a copy of the License at |**
**| |**
**| http://www.apache.org/licenses/LICENSE-2.0 |**
**| |**
**| Unless required by applicable law or agreed to in writing, software |**
**| distributed under the License is distributed on an "AS IS" BASIS, |**
**| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |**
**| See the License for the specific language governing permissions and |**
**| limitations under the License. |**
**| |**
**+--------------------------------------------------------------------------+**
*******************************************************************************/
#ifndef _WINDOWS
#include <sys/select.h>
#include <unistd.h>
#include <signal.h>
#include "ipc.h"
#include "g_tester.h"
#include "wipp_ctrl.h"
#endif /* __LINUX__ */
#ifdef _WINDOWS
#else
#include <errno.h>
#endif
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include "ticon.h"
#include "console.h"
#include "cu_cmd.h"
static ConEntry_t *p_mon_root;
static ConEntry_t *p_cur_dir;
static char *p_inbuf;
static volatile int stop_UI_Monitor;
#define INBUF_LENGTH 1024
/*#define PRINT_LEN_PER_PARM 40*/
#define ROOT_NAME "/"
/* Internal functions */
static void console_allocRoot( void );
static void console_displayDir( ConEntry_t *p_dir );
static t_TokenType console_getWord( char *name, U16 len );
static t_TokenType console_getStrParam( char *buf, ConParm_t *param );
static t_TokenType console_analizeToken( char *name );
static U16 console_getNParms( ConEntry_t *p_token );
static int console_parseParms( ConEntry_t *p_token, U16 *pnParms );
static ConEntry_t *console_searchToken( ConEntry_t *p_dir, char *name );
static void console_dirHelp( void );
static void console_displayHelp( ConEntry_t *p_token );
static int console_chooseAlias( ConEntry_t *p_dir, ConEntry_t *p_new_token );
/***************************************************************
Function : consoleRunScript
Description: Execute command from file
Parameters: script_file - name of script file
Output: !NULL - if 'quit' command was executed
***************************************************************/
int consoleRunScript( char *script_file )
{
FILE *hfile = fopen(script_file, "r" );
if( hfile )
{
char buf[INBUF_LENGTH];
stop_UI_Monitor = FALSE;
while( fgets(buf, sizeof(buf), hfile ) )
{
console_printf_terminal("script <%s>\n", script_file);
console_ParseString( buf );
if( stop_UI_Monitor )
break;
}
fclose(hfile);
}
else
perror( script_file );
return stop_UI_Monitor;
}
/***************************************************************
Function : consoleAddDirExt
Description: Add subdirectory
Parameters: p_root - root directory handle (might be NULL)
name - directory name
Output: the new created directory handle
=NULL - failure
***************************************************************/
handle_t consoleAddDirExt(
handle_t hRoot, /* Upper directory handle. NULL=root */
const char *name, /* New directory name */
const char *desc ) /* Optional dir description */
{
ConEntry_t *p_root = (ConEntry_t *)hRoot;
ConEntry_t *p_dir;
ConEntry_t **p_e;
if (!p_mon_root)
console_allocRoot( );
if (!p_root)
p_root = p_mon_root;
ASSERT( p_root && (p_root->sel == Dir) );
if ( (p_dir=(ConEntry_t *)malloc( sizeof( ConEntry_t )) ) == NULL)
return NULL;
memset( p_dir, 0, sizeof( ConEntry_t ) );
strncpy( p_dir->name, name, MAX_NAME_LEN );
strncpy( p_dir->help, desc, MAX_HELP_LEN );
p_dir->sel = Dir;
console_chooseAlias( p_root, p_dir );
/* Add new directory to the root's list */
p_dir->u.dir.upper = p_root;
p_e = &(p_root->u.dir.first);
while (*p_e)
p_e = &((*p_e)->next);
*p_e = p_dir;
return p_dir;
}
/***************************************************************
Function : consoleAddToken
Description: Add token
Parameters: p_dir - directory handle (might be NULL=root)
name - token name
help - help string
p_func - token handler
p_parms- array of parameter descriptions.
Must be terminated with {0}.
Each parm descriptor is a struct
{ "myname", - name
10, - low value
20, - high value
0 } - default value =-1 no default
or address for string parameter
Output: E_OK - OK
!=0 - error
***************************************************************/
consoleErr consoleAddToken( handle_t hDir,
const char *name,
const char *help,
FuncToken_t p_func,
ConParm_t p_parms[] )
{
ConEntry_t *p_dir = (ConEntry_t *)hDir;
ConEntry_t *p_token;
ConEntry_t **p_e;
U16 i;
if (!p_mon_root)
console_allocRoot( );
if (!p_dir)
p_dir = p_mon_root;
ASSERT( p_dir && (p_dir->sel == Dir) );
/* Initialize token structure */
if ((p_token=(ConEntry_t *)calloc( 1, sizeof(ConEntry_t) )) == NULL)
{
fprintf(stderr, "** no memory **\n");
return E_NOMEMORY;
}
/* Copy name */
strncpy( p_token->name, name, MAX_NAME_LEN );
strncpy( p_token->help, help, MAX_HELP_LEN );
p_token->sel = Token;
p_token->u.token.f_tokenFunc = p_func;
/* Convert name to lower case and choose alias */
console_chooseAlias( p_dir, p_token );
/* Copy parameters */
if ( p_parms )
{
for(i = 0; p_parms->name && p_parms->name[0] && ( i < MAX_NUM_OF_PARMS); i++ )
{
ConParm_t *p_token_parm = &p_token->u.token.parm[i];
/* String parameter must have an address */
if(p_parms->flags & (CON_PARM_STRING | CON_PARM_LINE))
{
if ( p_parms->hi_val >= INBUF_LENGTH )
{
fprintf(stderr, "** buffer too big: %s/%s\n", p_dir->name, name);
free( p_token );
return E_NOMEMORY;
}
if (p_parms->hi_val == 0 || (p_parms->flags & CON_PARM_RANGE) )
{
fprintf(stderr, "** Bad string param definition: %s/%s\n", p_dir->name, name );
free( p_token );
return E_BADPARM;
}
p_parms->value = (U32) calloc(1, p_parms->hi_val+1);
if( !p_parms->value )
{
fprintf(stderr, "** No memory: %s/%s (max.size=%ld)\n", p_dir->name, name, p_parms->hi_val );
free( p_token );
return E_NOMEMORY;
}
}
/* Copy parameter */
*p_token_parm = *p_parms;
if( p_token_parm->hi_val || p_token_parm->low_val )
p_token_parm->flags |= CON_PARM_RANGE;
p_token_parm->name = (const char *)p_token->u.token.name[i];
strncpy( p_token->u.token.name[i], p_parms->name, MAX_NAME_LEN );
++p_parms;
}
if ((i == MAX_NUM_OF_PARMS) && p_parms->name[0])
{
fprintf(stderr, "** Too many params: %s/%s\n", p_dir->name, name );
free( p_token );
return E_TOOMANY;
}
}
/* Add token to the directory */
p_e = &(p_dir->u.dir.first);
while (*p_e)
p_e = &((*p_e)->next);
*p_e = p_token;
return E_OK;
}
/* Monitor driver */
void consoleStart( void )
{
#ifndef _WINDOWS
fd_set read_set;
int max_fd_index;
int result;
int pid;
#endif /* __LINUX__ */
char inbuf[INBUF_LENGTH];
if (!p_mon_root)
return;
stop_UI_Monitor = FALSE;
console_displayDir( p_cur_dir );
while(!stop_UI_Monitor)
{
#ifndef _WINDOWS
/***********************************************************************************/
/* Wait for one of two external events: */
/* ----------------------------------- */
/* */
/* 1. Data received from STDIN */
/* 2. Data received from one of the TCP clients */
/* 3. Data received from iperf process stdout (if enabled) */
/****************************************************************************/
/* Prepare the read set fields */
FD_ZERO(&read_set);
FD_SET(0, &read_set);
FD_SET(ipc_pipe[0], &read_set);
FD_SET(wipp_control_general_process_out_pipe[0], &read_set);
/* Determine the maximum index of the file descriptor */
max_fd_index = (max(wipp_control_general_process_out_pipe[0], max(0, ipc_pipe[0])) + 1);
/* Wait for event - blocking */
result = select(max_fd_index, &read_set, NULL, NULL, NULL);
if (result > 0)
{
if (FD_ISSET(0, &read_set))
{
/*****************************/
/* Data received from STDIN */
/***************************/
if ( fgets( inbuf, sizeof(inbuf), stdin ) <= 0 )
return;
console_ParseString( inbuf );
}
if (FD_ISSET(ipc_pipe[0], &read_set))
{
/**********************************/
/* Data received from TCP client */
/********************************/
result = read(ipc_pipe[0], (U8 *)inbuf, (U16)sizeof(inbuf));
/* Get the pid of the calling process */
pid = *(inbuf + 0) | (*(inbuf + 1) << 8);
/* Signal the calling process (tell him that we have
received the command, and he can send us another one */
if (pid != 0xFFFF)
{
kill(pid, SIGUSR1);
}
if (result > 0)
{
console_ParseString(inbuf + 2);
}
}
if (FD_ISSET(wipp_control_general_process_out_pipe[0], &read_set))
{
/*****************************************/
/* Data received general process stdout */
/***************************************/
result = read(wipp_control_general_process_out_pipe[0], (U8 *)inbuf + 3, sizeof(inbuf) - 3);
if (result > 0)
{
wipp_control_send_iperf_results_to_host(WIPP_CONTROL_EVT_RUN_PROCESS_STDOUT, inbuf, result);
}
}
}
else
{
/* Error */
console_printf_terminal("Input selection mismatch...\n");
return;
}
#else /* __LINUX__ */
#endif /* __LINUX__ */
}
}
/* Parse the given input string and exit.
All commands in the input string are executed one by one.
*/
void console_ParseString(char *input_string )
{
ConEntry_t *p_token;
char name[MAX_NAME_LEN];
t_TokenType tType;
U16 nParms;
#ifndef _WINDOWS
/* Check if this is WIPP control command, if it is - process it */
if (wipp_control_check_command(input_string))
{
return;
}
/* Check if this is g_tester control command, if it is - process it */
if (g_tester_check_command((unsigned char*) input_string))
{
return;
}
#endif /* __LINUX__ */
if (!p_mon_root)
return;
if( input_string[strlen(input_string)-1] == '\n' )
{
char *s = (char *) &input_string[strlen(input_string)-1];
*s = 0;
}
p_inbuf = (char *)input_string;
stop_UI_Monitor = FALSE;
/* Interpret empty string as "display directory" */
if ( p_inbuf && !*p_inbuf )
console_displayDir( p_cur_dir );
while(!stop_UI_Monitor && p_inbuf && *p_inbuf)
{
tType = console_getWord( name, MAX_NAME_LEN );
switch( tType )
{
case NameToken:
p_token = console_searchToken( p_cur_dir, name );
if (p_token == NULL)
{
fprintf( stderr, "**Error: '%s'**\n", name);
p_inbuf = NULL;
}
else if (p_token->sel == Dir)
{
p_cur_dir = p_token;
console_displayDir( p_cur_dir );
}
else
{ /* Function token */
if (!console_parseParms( p_token, &nParms ))
console_displayHelp( p_token );
else
p_token->u.token.f_tokenFunc( p_token->u.token.parm, nParms );
}
break;
case UpToken: /* Go to upper directory */
if (p_cur_dir->u.dir.upper)
p_cur_dir = p_cur_dir->u.dir.upper;
console_displayDir( p_cur_dir );
break;
case RootToken: /* Go to the root directory */
if (p_cur_dir->u.dir.upper)
p_cur_dir = p_mon_root;
console_displayDir( p_cur_dir );
break;
case HelpToken: /* Display help */
if (( console_getWord( name, MAX_NAME_LEN ) == NameToken ) &&
((p_token = console_searchToken( p_cur_dir, name )) != NULL ) &&
(p_token->sel == Token) )
console_displayHelp( p_token );
else
console_dirHelp( );
break;
case DirHelpToken:
console_displayDir( p_cur_dir );
console_printf_terminal("Type ? <name> for command help, \"/\"-root, \"..\"-upper\n" );
break;
case BreakToken: /* Clear buffer */
p_inbuf = NULL;
break;
case EmptyToken:
break;
}
}
}
/* Stop monitor driver */
void consoleStop( void )
{
stop_UI_Monitor = TRUE;
}
/*********************************************************/
/* Internal functions */
/*********************************************************/
/* Allocate root directory */
void console_allocRoot( void )
{
/* The very first call. Allocate root structure */
if ((p_mon_root=(ConEntry_t *)calloc( 1, sizeof( ConEntry_t ) ) ) == NULL)
{
ASSERT( p_mon_root );
return;
}
strcpy( p_mon_root->name, ROOT_NAME );
p_mon_root->sel = Dir;
p_cur_dir = p_mon_root;
}
/* Display directory */
void console_displayDir( ConEntry_t *p_dir )
{
char out_buf[512];
ConEntry_t *p_token;
sprintf( out_buf, "%s%s> ", (p_dir==p_mon_root)? "" : ".../", p_dir->name );
p_token = p_dir->u.dir.first;
while( p_token )
{
if( (strlen(out_buf) + strlen(p_token->name) + 2)>= sizeof(out_buf) )
{
fprintf(stderr, "** console_displayDir(): buffer too small....\n");
break;
}
strcat( out_buf, p_token->name );
if ( p_token->sel == Dir )
strcat( out_buf, "/" );
p_token = p_token->next;
if (p_token)
strcat( out_buf, ", " );
}
console_printf_terminal("%s\n", out_buf );
}
/* Cut the first U16 from <p_inbuf>.
Return the U16 in <name> and updated <p_inbuf>
*/
static t_TokenType console_getWord( char *name, U16 len )
{
U16 i=0;
t_TokenType tType;
p_inbuf = console_ltrim(p_inbuf);
while( *p_inbuf && *p_inbuf!=' ' && i<len )
name[i++] = *(p_inbuf++);
if (i<len)
name[i] = 0;
tType = console_analizeToken( name );
return tType;
}
static t_TokenType console_getStrParam( char *buf, ConParm_t *param )
{
t_TokenType tType;
U32 i, len = param->hi_val;
char *end_buf;
p_inbuf = console_ltrim(p_inbuf);
if( param->flags & CON_PARM_LINE )
{
strcpy(buf, p_inbuf );
p_inbuf += strlen(p_inbuf);
}
else
{
if( *p_inbuf == '\"' )
{
end_buf = strchr(p_inbuf+1, '\"' );
if( !end_buf )
{
fprintf(stderr, "** invalid string param: '%s'\n", p_inbuf );
p_inbuf += strlen(p_inbuf);
return EmptyToken;
}
if( (end_buf - p_inbuf - 1) > (int)len )
{
fprintf(stderr, "** param is too long: '%s'\n", p_inbuf );
p_inbuf += strlen(p_inbuf);
return EmptyToken;
}
*end_buf = 0;
strcpy( buf, p_inbuf+1 );
p_inbuf = end_buf + 1;
}
else
{
for( i=0; *p_inbuf && *p_inbuf!=' ' && i<len; i++ )
buf[i] = *(p_inbuf++);
buf[i] = 0;
if( *p_inbuf && *p_inbuf != ' ' )
{
fprintf(stderr, "** param is too long: '%s'\n", p_inbuf-strlen(buf) );
p_inbuf += strlen(p_inbuf);
return EmptyToken;
}
}
}
tType = console_analizeToken( buf );
return tType;
}
/* Make a preliminary analizis of <name> token.
Returns a token type (Empty, Up, Root, Break, Name)
*/
t_TokenType console_analizeToken( char *name )
{
if (!name[0])
return EmptyToken;
if (!strcmp( name, TOKEN_UP ) )
return UpToken;
if (!strcmp( name, TOKEN_ROOT ) )
return RootToken;
if (!strcmp( name, TOKEN_BREAK ) )
return BreakToken;
if (!strcmp( name, TOKEN_HELP ) )
return HelpToken;
if (!strcmp( name, TOKEN_DIRHELP ) )
return DirHelpToken;
return NameToken;
}
/* Returns number of parameters of the given token
*/
static U16 console_getNParms( ConEntry_t *p_token )
{
U16 i;
if ( !p_token->u.token.parm )
return 0;
for( i=0;
(i<MAX_NUM_OF_PARMS-1) &&
p_token->u.token.parm[i].name &&
p_token->u.token.parm[i].name[0];
i++ )
;
return i;
}
/* Parse p_inbuf string based on parameter descriptions in <p_token>.
Fill parameter values in <p_token>.
Returns the number of parameters filled.
To Do: add a option of one-by-one user input of missing parameters.
*/
int console_parseParms( ConEntry_t *p_token, U16 *pnParms )
{
U16 nTotalParms = console_getNParms( p_token );
U16 nParms=0;
char *end_buf = NULL, parm[INBUF_LENGTH];
U16 i, print_params = 0;
U32 val = 0;
S32 sval = 0;
/* Mark all parameters as don't having an explicit value */
for( i=0; i<nTotalParms; i++ )
p_token->u.token.parm[i].flags |= CON_PARM_NOVAL;
/* ----------------- */
p_inbuf = console_ltrim(p_inbuf);
if( p_inbuf[0] == '!' && p_inbuf[1] == '!' )
{
p_inbuf += 2; print_params = 1;
}
/* ----------------- */
/* Build a format string */
for( i=0; i<nTotalParms; i++ )
{
if (p_token->u.token.parm[i].flags & (CON_PARM_STRING | CON_PARM_LINE) )
{
/* For a string parameter value is the string address */
/* and hi_val is the string length */
if (console_getStrParam( parm, &p_token->u.token.parm[i] ) != NameToken)
break;
if( strlen(parm) > p_token->u.token.parm[i].hi_val ||
(p_token->u.token.parm[i].low_val && p_token->u.token.parm[i].low_val > strlen(parm) ) )
{
fprintf(stderr, "param '%s' must be %ld..%ld chars\n", p_token->u.token.parm[i].name,
p_token->u.token.parm[i].low_val, p_token->u.token.parm[i].hi_val);
return FALSE;
}
strcpy( (char *)p_token->u.token.parm[i].value, parm );
}
else
{
if (console_getWord( parm, MAX_PARM_LEN ) != NameToken)
break;
if (p_token->u.token.parm[i].flags & CON_PARM_SIGN)
sval = strtol( parm, &end_buf, 0 );
else
val = strtoul( parm, &end_buf, 0 );
if( /*errno || */end_buf <= parm )
break;
/* if (sscanf( parm, "%i", &val ) != 1)*/
/* break;*/
/* Check value */
if (p_token->u.token.parm[i].flags & CON_PARM_RANGE)
{
if (p_token->u.token.parm[i].flags & CON_PARM_SIGN)
{
if ((sval < (S32)p_token->u.token.parm[i].low_val) ||
(sval > (S32)p_token->u.token.parm[i].hi_val) )
{
fprintf( stderr, "%s: %d out of range (%d, %d)\n",
p_token->u.token.parm[i].name, (int)sval,
(int)p_token->u.token.parm[i].low_val, (int)p_token->u.token.parm[i].hi_val );
return FALSE;
}
}
else
{
if ((val < p_token->u.token.parm[i].low_val) ||
(val > p_token->u.token.parm[i].hi_val) )
{
fprintf( stderr, "%s: %ld out of range (%ld, %ld)\n",
p_token->u.token.parm[i].name, val,
p_token->u.token.parm[i].low_val, p_token->u.token.parm[i].hi_val );
return FALSE;
}
}
}
if (p_token->u.token.parm[i].flags & CON_PARM_SIGN)
p_token->u.token.parm[i].value = sval;
else
p_token->u.token.parm[i].value = val;
}
p_token->u.token.parm[i].flags &= ~CON_PARM_NOVAL;
++nParms;
}
/* Process default values */
for( ; i<nTotalParms; i++ )
{
if ((p_token->u.token.parm[i].flags & CON_PARM_DEFVAL) != 0)
{
p_token->u.token.parm[i].flags &= ~CON_PARM_NOVAL;
++nParms;
}
else if (!(p_token->u.token.parm[i].flags & CON_PARM_OPTIONAL) )
{
/* Mandatory parameter missing */
return FALSE;
}
}
if( print_params )
{
printf("Params: %d\n", nParms );
for (i=0; i<nParms; i++ )
{
console_printf_terminal("%d: %s - flags:%d",
i+1, p_token->u.token.parm[i].name,
p_token->u.token.parm[i].flags);
if (p_token->u.token.parm[i].flags & CON_PARM_SIGN)
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,
p_token->u.token.parm[i].value);
else
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,
p_token->u.token.parm[i].value);
console_printf_terminal("(%#lx)",p_token->u.token.parm[i].value );
if( p_token->u.token.parm[i].flags & (CON_PARM_LINE | CON_PARM_STRING ))
{
printf(" - '%s'", (char *) p_token->u.token.parm[i].value );
}
printf("\n");
}
}
*pnParms = nParms;
return TRUE;
}
/* Serach a token by name in the current directory */
ConEntry_t *console_searchToken( ConEntry_t *p_dir, char *name )
{
ConEntry_t *p_token;
U16 name_len = (U16)strlen( name );
/* Check alias */
p_token = p_dir->u.dir.first;
while( p_token )
{
if (p_token->alias &&
(name_len == ALIAS_LEN) &&
!console_stricmp( p_token->alias, name, ALIAS_LEN ) )
return p_token;
p_token = p_token->next;
}
/* Check name */
p_token = p_dir->u.dir.first;
while( p_token )
{
if (!console_stricmp( p_token->name, name, name_len ) )
break;
p_token = p_token->next;
}
return p_token;
}
/* Display help for each entry in the current directory */
void console_dirHelp( void )
{
ConEntry_t *p_token;
char print_str[80];
p_token = p_cur_dir->u.dir.first;
while( p_token )
{
if (p_token->sel == Dir)
sprintf( print_str, "%s: directory\n", p_token->name );
else
sprintf( print_str, "%s(%d parms): %s\n",
p_token->name, console_getNParms(p_token), p_token->help );
console_printf_terminal( print_str );
p_token = p_token->next;
}
console_printf_terminal( "Type ? <name> for command help, \"/\"-root, \"..\"-upper\n" );
}
/* Display help a token */
void console_displayHelp( ConEntry_t *p_token )
{
char bra, ket;
U16 nTotalParms = console_getNParms( p_token );
U16 i;
console_printf_terminal( "%s: %s ", p_token->help, p_token->name );
for( i=0; i<nTotalParms; i++ )
{
if (p_token->u.token.parm[i].flags & CON_PARM_OPTIONAL)
{
bra = '['; ket=']';
}
else
{
bra = '<'; ket='>';
}
console_printf_terminal( "%c%s", bra, p_token->u.token.parm[i].name );
if (p_token->u.token.parm[i].flags & CON_PARM_DEFVAL)
{
console_printf_terminal("=%lu", p_token->u.token.parm[i].value);
}
if (p_token->u.token.parm[i].flags & CON_PARM_RANGE)
{
console_printf_terminal( (p_token->u.token.parm[i].flags & CON_PARM_SIGN) ? " (%d..%d%s)" : " (%lu..%lu%s)",
p_token->u.token.parm[i].low_val,
p_token->u.token.parm[i].hi_val,
(p_token->u.token.parm[i].flags & (CON_PARM_STRING | CON_PARM_LINE)) ? " chars" : "" );
}
console_printf_terminal( "%c \n",ket );
}
}
/* Choose unique alias for <name> in <p_dir> */
/* Currently only single-character aliases are supported */
int console_chooseAlias( ConEntry_t *p_dir, ConEntry_t *p_new_token )
{
ConEntry_t *p_token;
int i;
char c;
char *new_alias = NULL;
/* find alias given from user */
for(i=0; p_new_token->name[i]; i++ )
{
if( isupper(p_new_token->name[i]) )
{
new_alias = &p_new_token->name[i];
break;
}
}
console_strlwr( p_new_token->name );
if( new_alias )
{
p_token = p_dir->u.dir.first;
while( p_token )
{
if (p_token->alias && (tolower( *p_token->alias ) == *new_alias) )
{
/* *new_alias = toupper(*new_alias);*/
fprintf( stderr, "**Error: duplicated alias '%c' in <%s> and <%s>**\n", *new_alias,
p_token->name, p_new_token->name );
return 0;
}
p_token = p_token->next;
}
*new_alias = toupper(*new_alias);
p_new_token->alias = new_alias;
return 1;
}
i = 0;
while( p_new_token->name[i] )
{
c = p_new_token->name[i];
p_token = p_dir->u.dir.first;
while( p_token )
{
if (p_token->alias &&
(tolower( *p_token->alias ) == c) )
break;
p_token = p_token->next;
}
if (p_token)
++i;
else
{
p_new_token->name[i] = toupper( c );
p_new_token->alias = &p_new_token->name[i];
break;
}
}
return 1;
}
/* Convert string s to lower case. Return pointer to s */
char * console_strlwr( char *s )
{
char *s0=s;
while( *s )
{
*s = tolower( *s );
++s;
}
return s0;
}
/* Compare strings case insensitive */
int console_stricmp( char *s1, char *s2, U16 len )
{
int i;
for( i=0; i<len && s1[i] && s2[i]; i++ )
{
if (tolower( s1[i]) != tolower( s2[i] ))
break;
}
return ( (len - i) * (s1[i] - s2[i]) );
}
/* Remove leading blanks */
char * console_ltrim(char *s )
{
while( *s == ' ' || *s == '\t' ) s++;
return s;
}
#ifdef _WINDOWS
#endif /* _WINDOWS*/