| /* |
| * console.c |
| * |
| * Copyright 2001-2009 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. |
| */ |
| |
| /**************************************************************************** |
| * |
| * MODULE: console.c |
| * |
| * PURPOSE: |
| * |
| * DESCRIPTION: |
| * ============ |
| * |
| * |
| ****************************************************************************/ |
| |
| /* includes */ |
| /************/ |
| #include <stdio.h> |
| #include "cu_osapi.h" |
| #include "console.h" |
| #include "cu_cmd.h" |
| |
| /* defines */ |
| /***********/ |
| #define INBUF_LENGTH 2100 |
| #define MAX_NAME_LEN 64 |
| #define MAX_HELP_LEN 40 |
| #define MAX_PARM_LEN 20 |
| #define ALIAS_LEN 1 |
| |
| #define TOKEN_UP ".." |
| #define TOKEN_ROOT "/" |
| #define TOKEN_BREAK "#" |
| #define TOKEN_HELP "?" |
| #define TOKEN_DIRHELP "help" |
| #define TOKEN_QUIT "q1" |
| |
| /* local types */ |
| /***************/ |
| |
| typedef enum |
| { |
| Dir, |
| Token |
| } ConEntry_type_t; |
| |
| /* Token types */ |
| typedef enum |
| { |
| EmptyToken, |
| UpToken, |
| RootToken, |
| BreakToken, |
| HelpToken, |
| DirHelpToken, |
| QuitToken, |
| NameToken |
| } TokenType_t; |
| |
| |
| /* Monitor token structure */ |
| typedef struct ConEntry_t |
| { |
| struct ConEntry_t *next; |
| S8 name[MAX_NAME_LEN+1]; /* Entry name */ |
| S8 help[MAX_HELP_LEN+1]; /* Help string */ |
| PS8 alias; /* Alias - always in upper case*/ |
| ConEntry_type_t sel; /* Entry selector */ |
| |
| union |
| { |
| struct |
| { |
| struct ConEntry_t *upper; /* Upper directory */ |
| struct ConEntry_t *first; /* First entry */ |
| } dir; |
| struct t_Token |
| { |
| FuncToken_t f_tokenFunc; /* Token handler */ |
| S32 totalParams; |
| ConParm_t *parm; /* Parameters array with totalParams size */ |
| PS8 *name; /* Parameter name with totalParams size */ |
| } token; |
| } u; |
| } ConEntry_t; |
| |
| /* Module control block */ |
| typedef struct Console_t |
| { |
| THandle hCuCmd; |
| |
| S32 isDeviceOpen; |
| |
| ConEntry_t *p_mon_root; |
| ConEntry_t *p_cur_dir; |
| PS8 p_inbuf; |
| volatile S32 stop_UI_Monitor; |
| } Console_t; |
| |
| /* local variables */ |
| /*******************/ |
| |
| /* local fucntions */ |
| /*******************/ |
| static VOID Console_allocRoot(Console_t* pConsole); |
| int consoleRunScript( char *script_file, THandle hConsole); |
| |
| |
| /* Remove leading blanks */ |
| static PS8 Console_ltrim(PS8 s) |
| { |
| while( *s == ' ' || *s == '\t' ) s++; |
| return s; |
| } |
| |
| /* |
| Make a preliminary analizis of <name> token. |
| Returns a token type (Empty, Up, Root, Break, Name) |
| */ |
| static TokenType_t Console_analizeToken( PS8 name ) |
| { |
| if (!name[0]) |
| return EmptyToken; |
| |
| if (!os_strcmp(name, (PS8)TOKEN_UP ) ) |
| return UpToken; |
| |
| if (!os_strcmp(name, (PS8)TOKEN_ROOT ) ) |
| return RootToken; |
| |
| if (!os_strcmp(name, (PS8)TOKEN_BREAK ) ) |
| return BreakToken; |
| |
| if (!os_strcmp(name, (PS8)TOKEN_HELP ) ) |
| return HelpToken; |
| |
| if (!os_strcmp(name, (PS8)TOKEN_DIRHELP ) ) |
| return DirHelpToken; |
| |
| if (!os_strcmp(name, (PS8)TOKEN_QUIT ) ) |
| return QuitToken; |
| |
| return NameToken; |
| |
| } |
| |
| /* Compare strings case insensitive */ |
| static S32 Console_stricmp( PS8 s1, PS8 s2, U16 len ) |
| { |
| S32 i; |
| |
| for( i=0; i<len && s1[i] && s2[i]; i++ ) |
| { |
| if (os_tolower(s1[i]) != os_tolower(s2[i] )) |
| break; |
| } |
| |
| return ( (len - i) * (s1[i] - s2[i]) ); |
| } |
| |
| /* Convert string s to lower case. Return pointer to s */ |
| static PS8 Console_strlwr( PS8 s ) |
| { |
| PS8 s0=s; |
| |
| while( *s ) |
| { |
| *s = (S8)os_tolower(*s ); |
| ++s; |
| } |
| |
| return s0; |
| } |
| |
| /* free the entries tree */ |
| static VOID Console_FreeEntry(ConEntry_t *pEntry) |
| { |
| ConEntry_t *pEntryTemp,*pEntryTemp1; |
| |
| if(pEntry->sel == Dir) |
| { |
| pEntryTemp = pEntry->u.dir.first; |
| |
| while (pEntryTemp) |
| { |
| pEntryTemp1 = pEntryTemp->next; |
| Console_FreeEntry(pEntryTemp); |
| pEntryTemp = pEntryTemp1; |
| } |
| } |
| |
| /* free the current entry */ |
| os_MemoryFree(pEntry); |
| } |
| |
| |
| /* Allocate root directory */ |
| static VOID Console_allocRoot(Console_t* pConsole) |
| { |
| /* The very first call. Allocate root structure */ |
| if ((pConsole->p_mon_root=(ConEntry_t *)os_MemoryCAlloc(sizeof( ConEntry_t ), 1) ) == NULL) |
| { |
| os_error_printf(CU_MSG_ERROR, (PS8)( "ERROR - Console_allocRoot(): cant allocate root\n") ); |
| return; |
| } |
| os_strcpy((PS8)pConsole->p_mon_root->name, (PS8)("\\") ); |
| pConsole->p_mon_root->sel = Dir; |
| pConsole->p_cur_dir = pConsole->p_mon_root; |
| } |
| |
| /* Display current directory */ |
| static VOID Console_displayDir(Console_t* pConsole) |
| { |
| S8 out_buf[512]; |
| ConEntry_t *p_token; |
| ConEntry_t *p_dir = pConsole->p_cur_dir; |
| |
| os_sprintf((PS8)out_buf, (PS8)("%s%s> "), (PS8)(p_dir==pConsole->p_mon_root)? (PS8)("") : (PS8)(".../"), (PS8)p_dir->name ); |
| p_token = p_dir->u.dir.first; |
| while( p_token ) |
| { |
| if( (os_strlen(out_buf) + os_strlen(p_token->name) + 2)>= sizeof(out_buf) ) |
| { |
| os_error_printf(CU_MSG_ERROR, ( (PS8)"ERROR - Console_displayDir(): buffer too small....\n") ); |
| break; |
| } |
| os_strcat(out_buf, p_token->name ); |
| if ( p_token->sel == Dir ) |
| os_strcat((PS8)out_buf, (PS8)("/" ) ); |
| p_token = p_token->next; |
| if (p_token) |
| os_strcat((PS8)out_buf, (PS8)(", ") ); |
| } |
| |
| os_error_printf(CU_MSG_INFO2, (PS8)("%s\n"), (PS8)out_buf ); |
| } |
| |
| |
| /* |
| Cut the first U16 from <p_inbuf>. |
| Return the U16 in <name> and updated <p_inbuf> |
| */ |
| static TokenType_t Console_getWord(Console_t* pConsole, PS8 name, U16 len ) |
| { |
| U16 i=0; |
| TokenType_t tType; |
| |
| pConsole->p_inbuf = Console_ltrim(pConsole->p_inbuf); |
| |
| while( *pConsole->p_inbuf && *pConsole->p_inbuf!=' ' && i<len ) |
| name[i++] = *(pConsole->p_inbuf++); |
| |
| if (i<len) |
| name[i] = 0; |
| |
| tType = Console_analizeToken( name ); |
| |
| return tType; |
| } |
| |
| static TokenType_t Console_getStrParam(Console_t* pConsole, PS8 buf, ConParm_t *param ) |
| { |
| TokenType_t tType; |
| U32 i, len = param->hi_val; |
| PS8 end_buf; |
| |
| pConsole->p_inbuf = Console_ltrim(pConsole->p_inbuf); |
| |
| if( param->flags & CON_PARM_LINE ) |
| { |
| os_strcpy(buf, (PS8)pConsole->p_inbuf ); |
| pConsole->p_inbuf += os_strlen(pConsole->p_inbuf); |
| } |
| else |
| { |
| if( *pConsole->p_inbuf == '\"' ) |
| { |
| end_buf = os_strchr(pConsole->p_inbuf+1, '\"' ); |
| if( !end_buf ) |
| { |
| os_error_printf(CU_MSG_ERROR, (PS8)("ERROR - invalid string param: '%s'\n"), (PS8)pConsole->p_inbuf ); |
| pConsole->p_inbuf += os_strlen(pConsole->p_inbuf); |
| return EmptyToken; |
| } |
| if( (end_buf - pConsole->p_inbuf - 1) > (int)len ) |
| { |
| os_error_printf(CU_MSG_ERROR, (PS8)("ERROR - param is too long: '%s'\n"), (PS8)pConsole->p_inbuf ); |
| pConsole->p_inbuf += os_strlen(pConsole->p_inbuf); |
| return EmptyToken; |
| } |
| *end_buf = 0; |
| os_strcpy( buf, (PS8)(pConsole->p_inbuf+1 ) ); |
| pConsole->p_inbuf = end_buf + 1; |
| } |
| else |
| { |
| for( i=0; *pConsole->p_inbuf && *pConsole->p_inbuf!=' ' && i<len; i++ ) |
| buf[i] = *(pConsole->p_inbuf++); |
| |
| buf[i] = 0; |
| if( *pConsole->p_inbuf && *pConsole->p_inbuf != ' ' ) |
| { |
| os_error_printf(CU_MSG_ERROR, (PS8)("ERROR - param is too long: '%s'\n"), (PS8)( pConsole->p_inbuf-os_strlen( buf) ) ); |
| pConsole->p_inbuf += os_strlen(pConsole->p_inbuf); |
| return EmptyToken; |
| } |
| } |
| } |
| |
| tType = Console_analizeToken( buf ); |
| |
| return tType; |
| } |
| |
| /* 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<p_token->u.token.totalParams) && |
| 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. |
| */ |
| static S32 Console_parseParms(Console_t* pConsole, ConEntry_t *p_token, U16 *pnParms ) |
| { |
| U16 nTotalParms = Console_getNParms( p_token ); |
| U16 nParms=0; |
| PS8 end_buf = NULL; |
| S8 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; |
| |
| /* ----------------- */ |
| pConsole->p_inbuf = Console_ltrim(pConsole->p_inbuf); |
| if( pConsole->p_inbuf[0] == '!' && pConsole->p_inbuf[1] == '!' ) |
| { |
| pConsole->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(pConsole, parm, &p_token->u.token.parm[i] ) != NameToken) |
| break; |
| if( os_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 > os_strlen( parm) ) ) |
| { |
| os_error_printf(CU_MSG_ERROR, (PS8)("ERROR - param '%s' must be %ld..%ld chars\n"), (PS8)p_token->u.token.parm[i].name, |
| (PS8)p_token->u.token.parm[i].low_val, (PS8)p_token->u.token.parm[i].hi_val); |
| return FALSE; |
| } |
| os_strcpy((PS8)(char *)p_token->u.token.parm[i].value, (PS8)parm); |
| } |
| else |
| { |
| if (Console_getWord(pConsole, parm, MAX_PARM_LEN ) != NameToken) |
| break; |
| |
| if (p_token->u.token.parm[i].flags & CON_PARM_SIGN) |
| { |
| sval = os_strtol( parm, &end_buf, 0 ); |
| } |
| else |
| { |
| val = os_strtoul( parm, &end_buf, 0 ); |
| } |
| if( end_buf <= parm ) |
| 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) ) |
| { |
| os_error_printf(CU_MSG_ERROR, (PS8)("%s: %d out of range (%d, %d)\n"), |
| (PS8)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) ) |
| { |
| os_error_printf(CU_MSG_ERROR , (PS8)("%s: %ld out of range (%ld, %ld)\n"), |
| (PS8)p_token->u.token.parm[i].name, (PS8)val, |
| (PS8)p_token->u.token.parm[i].low_val, (PS8)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 ) |
| { |
| os_error_printf((S32)CU_MSG_INFO2, (PS8)("Params: %d\n"), nParms ); |
| for (i=0; i<nParms; i++ ) |
| { |
| os_error_printf(CU_MSG_INFO2, (PS8)("%d: %s - flags:%d"), |
| i+1, (PS8)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) |
| os_error_printf(CU_MSG_INFO2, (PS8)("min:%d, max:%d, value:%d "),(PS8)p_token->u.token.parm[i].low_val, (PS8)p_token->u.token.parm[i].hi_val, |
| (PS8)p_token->u.token.parm[i].value); |
| else |
| os_error_printf(CU_MSG_INFO2, (PS8)("min:%ld, max:%ld, value:%ld "),(PS8)p_token->u.token.parm[i].low_val, (PS8)p_token->u.token.parm[i].hi_val, |
| (PS8)p_token->u.token.parm[i].value); |
| |
| os_error_printf(CU_MSG_INFO2, (PS8)("(%#lx)"),(PS8)p_token->u.token.parm[i].value ); |
| |
| if( p_token->u.token.parm[i].flags & (CON_PARM_LINE | CON_PARM_STRING )) |
| { |
| os_error_printf(CU_MSG_INFO2, (PS8)(" - '%s'"), (PS8)(char *) p_token->u.token.parm[i].value ); |
| } |
| os_error_printf(CU_MSG_INFO2, (PS8)("\n") ); |
| } |
| |
| } |
| *pnParms = nParms; |
| |
| return TRUE; |
| } |
| |
| /* Serach a token by name in the current directory */ |
| static ConEntry_t *Console_searchToken( ConEntry_t *p_dir, PS8 name ) |
| { |
| ConEntry_t *p_token; |
| U16 name_len = (U16)os_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(Console_t* pConsole) |
| { |
| ConEntry_t *p_token; |
| S8 print_str[80]; |
| |
| p_token = pConsole->p_cur_dir->u.dir.first; |
| |
| while( p_token ) |
| { |
| if (p_token->sel == Dir) |
| os_sprintf( print_str, (PS8)"%s: directory\n", (PS8)p_token->name ); |
| else |
| os_sprintf( print_str, (PS8)("%s(%d parms): %s\n"), |
| (PS8)p_token->name, Console_getNParms(p_token), p_token->help ); |
| os_error_printf(CU_MSG_INFO2, (PS8)print_str ); |
| p_token = p_token->next; |
| } |
| |
| os_error_printf(CU_MSG_INFO2, (PS8)("Type ? <name> for command help, \"/\"-root, \"..\"-upper\n") ); |
| } |
| |
| |
| /* Display help a token */ |
| static VOID Console_displayHelp(Console_t* pConsole, ConEntry_t *p_token ) |
| { |
| S8 bra, ket; |
| U16 nTotalParms = Console_getNParms( p_token ); |
| U16 i; |
| |
| |
| os_error_printf(CU_MSG_INFO2, (PS8)("%s: %s "), (PS8)p_token->help, (PS8)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='>'; |
| } |
| os_error_printf(CU_MSG_INFO2, (PS8)("%c%s"), bra, (PS8)p_token->u.token.parm[i].name ); |
| if (p_token->u.token.parm[i].flags & CON_PARM_DEFVAL) |
| { |
| os_error_printf(CU_MSG_INFO2, (PS8)("=%lu"), (PS8)p_token->u.token.parm[i].value); |
| } |
| if (p_token->u.token.parm[i].flags & CON_PARM_RANGE) |
| { |
| os_error_printf(CU_MSG_INFO2, (PS8)(p_token->u.token.parm[i].flags & CON_PARM_SIGN) ? (PS8)(" (%d..%d%s)") : (PS8)(" (%lu..%lu%s)"), |
| (PS8)p_token->u.token.parm[i].low_val, |
| (PS8)p_token->u.token.parm[i].hi_val, |
| (PS8)(p_token->u.token.parm[i].flags & (CON_PARM_STRING | CON_PARM_LINE)) ? (PS8)(" chars") : (PS8)("") ); |
| |
| } |
| os_error_printf(CU_MSG_INFO2, (PS8)("%c \n"),ket ); |
| } |
| } |
| |
| /* Choose unique alias for <name> in <p_dir> */ |
| /* Currently only single-character aliases are supported */ |
| static S32 Console_chooseAlias( ConEntry_t *p_dir, ConEntry_t *p_new_token ) |
| { |
| ConEntry_t *p_token; |
| S32 i; |
| S8 c; |
| PS8 new_alias = NULL; |
| |
| /* find alias given from user */ |
| for(i=0; p_new_token->name[i]; i++ ) |
| { |
| if( os_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 && (os_tolower(*p_token->alias ) == *new_alias) ) |
| { |
| os_error_printf(CU_MSG_ERROR, (PS8)("Error - duplicated alias '%c' in <%s> and <%s>**\n"), *new_alias, |
| (PS8)p_token->name, (PS8)p_new_token->name ); |
| return 0; |
| } |
| p_token = p_token->next; |
| } |
| *new_alias = (S8)os_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 && |
| (os_tolower(*p_token->alias ) == c) ) |
| break; |
| p_token = p_token->next; |
| } |
| if (p_token) |
| ++i; |
| else |
| { |
| p_new_token->name[i] = (S8)os_toupper( c ); |
| p_new_token->alias = &p_new_token->name[i]; |
| break; |
| } |
| } |
| return 1; |
| } |
| |
| /* Parse the given input string and exit. |
| All commands in the input string are executed one by one. |
| */ |
| static U8 Console_ParseString(Console_t* pConsole, PS8 input_string ) |
| { |
| ConEntry_t *p_token; |
| S8 name[MAX_NAME_LEN]; |
| TokenType_t tType; |
| U16 nParms; |
| |
| if (!pConsole->p_mon_root) |
| return 1; |
| |
| if(!pConsole->isDeviceOpen) |
| { |
| Console_GetDeviceStatus(pConsole); |
| if(!pConsole->isDeviceOpen) |
| { |
| os_error_printf(CU_MSG_ERROR, (PS8)("ERROR - Console_ParseString - Device isn't loaded !!!\n") ); |
| return 1; |
| } |
| } |
| |
| if( input_string[os_strlen( input_string)-1] == '\n' ) |
| { |
| PS8 s = &input_string[os_strlen( input_string)-1]; |
| *s = 0; |
| } |
| pConsole->p_inbuf = input_string; |
| pConsole->stop_UI_Monitor = FALSE; |
| |
| /* Interpret empty string as "display directory" */ |
| if ( pConsole->p_inbuf && !*pConsole->p_inbuf ) |
| Console_displayDir(pConsole); |
| |
| while(!pConsole->stop_UI_Monitor && pConsole->p_inbuf && *pConsole->p_inbuf) |
| { |
| tType = Console_getWord(pConsole, name, MAX_NAME_LEN ); |
| switch( tType ) |
| { |
| |
| case NameToken: |
| p_token = Console_searchToken( pConsole->p_cur_dir, name ); |
| if (p_token == NULL) |
| { |
| os_error_printf(CU_MSG_ERROR, (PS8)("**Error: '%s'**\n"),name); |
| pConsole->p_inbuf = NULL; |
| } |
| else if (p_token->sel == Dir) |
| { |
| pConsole->p_cur_dir = p_token; |
| Console_displayDir(pConsole); |
| } |
| else |
| { /* Function token */ |
| if (!Console_parseParms(pConsole, p_token, &nParms )) |
| { |
| Console_displayHelp(pConsole, p_token ); |
| } |
| else |
| { |
| p_token->u.token.f_tokenFunc(pConsole->hCuCmd, p_token->u.token.parm, nParms ); |
| } |
| } |
| break; |
| |
| case UpToken: /* Go to upper directory */ |
| if (pConsole->p_cur_dir->u.dir.upper) |
| pConsole->p_cur_dir = pConsole->p_cur_dir->u.dir.upper; |
| Console_displayDir(pConsole); |
| break; |
| |
| case RootToken: /* Go to the root directory */ |
| if (pConsole->p_cur_dir->u.dir.upper) |
| pConsole->p_cur_dir = pConsole->p_mon_root; |
| Console_displayDir(pConsole); |
| break; |
| |
| case HelpToken: /* Display help */ |
| if (( Console_getWord(pConsole, name, MAX_NAME_LEN ) == NameToken ) && |
| ((p_token = Console_searchToken( pConsole->p_cur_dir, name )) != NULL ) && |
| (p_token->sel == Token) ) |
| Console_displayHelp(pConsole, p_token); |
| else |
| Console_dirHelp(pConsole); |
| break; |
| |
| case DirHelpToken: |
| Console_displayDir(pConsole); |
| os_error_printf(CU_MSG_INFO2, (PS8)("Type ? <name> for command help, \"/\"-root, \"..\"-upper\n") ); |
| break; |
| |
| case BreakToken: /* Clear buffer */ |
| pConsole->p_inbuf = NULL; |
| break; |
| |
| case QuitToken: /* Go to upper directory */ |
| return 1; |
| |
| case EmptyToken: |
| break; |
| |
| } |
| } |
| return 0; |
| } |
| |
| /* functions */ |
| /*************/ |
| |
| THandle Console_Create(const PS8 device_name, S32 BypassSupplicant, PS8 pSupplIfFile) |
| { |
| Console_t* pConsole = (Console_t*)os_MemoryCAlloc(sizeof(Console_t), sizeof(U8)); |
| if(pConsole == NULL) |
| { |
| os_error_printf(CU_MSG_ERROR, (PS8)("Error - Console_Create - cant allocate control block\n") ); |
| return NULL; |
| } |
| |
| pConsole->hCuCmd = CuCmd_Create(device_name, pConsole, BypassSupplicant, pSupplIfFile); |
| if(pConsole->hCuCmd == NULL) |
| { |
| Console_Destroy(pConsole); |
| return NULL; |
| } |
| |
| Console_allocRoot(pConsole); |
| |
| pConsole->isDeviceOpen = FALSE; |
| |
| return pConsole; |
| } |
| |
| VOID Console_Destroy(THandle hConsole) |
| { |
| Console_t* pConsole = (Console_t*)hConsole; |
| |
| if(pConsole->hCuCmd) |
| { |
| CuCmd_Destroy(pConsole->hCuCmd); |
| } |
| if (pConsole->p_mon_root) |
| { |
| Console_FreeEntry(pConsole->p_mon_root); |
| } |
| os_MemoryFree(pConsole); |
| } |
| |
| VOID Console_Stop(THandle hConsole) |
| { |
| ((Console_t*)hConsole)->stop_UI_Monitor = TRUE; |
| } |
| |
| /* Monitor driver */ |
| VOID Console_Start(THandle hConsole) |
| { |
| Console_t* pConsole = (Console_t*)hConsole; |
| S8 inbuf[INBUF_LENGTH]; |
| S32 res; |
| |
| if (!pConsole->p_mon_root) |
| return; |
| |
| pConsole->stop_UI_Monitor = FALSE; |
| Console_displayDir(pConsole); |
| |
| while(!pConsole->stop_UI_Monitor) |
| { |
| /* get input string */ |
| res = os_getInputString(inbuf, sizeof(inbuf)); |
| if (res == FALSE) |
| { |
| if(pConsole->stop_UI_Monitor) |
| { |
| continue; |
| } |
| else |
| { |
| return; |
| } |
| } |
| |
| if(res == OS_GETINPUTSTRING_CONTINUE) |
| continue; |
| |
| /* change to NULL terminated strings */ |
| if( inbuf[os_strlen(inbuf)-1] == '\n' ) |
| inbuf[os_strlen(inbuf)-1] = 0; |
| |
| /* parse the string */ |
| Console_ParseString(pConsole, inbuf); |
| } |
| |
| } |
| |
| VOID Console_GetDeviceStatus(THandle hConsole) |
| { |
| Console_t* pConsole = (Console_t*)hConsole; |
| |
| if(OK == CuCmd_GetDeviceStatus(pConsole->hCuCmd)) |
| { |
| pConsole->isDeviceOpen = TRUE; |
| } |
| } |
| |
| |
| /*************************************************************** |
| |
| 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 |
| ***************************************************************/ |
| THandle Console_AddDirExt(THandle hConsole, |
| THandle hRoot, /* Upper directory handle. NULL=root */ |
| const PS8 name, /* New directory name */ |
| const PS8 desc ) /* Optional dir description */ |
| { |
| Console_t* pConsole = (Console_t*)hConsole; |
| ConEntry_t *p_root = (ConEntry_t *)hRoot; |
| ConEntry_t *p_dir; |
| ConEntry_t **p_e; |
| |
| if (!p_root) |
| p_root = pConsole->p_mon_root; |
| |
| if(!( p_root && (p_root->sel == Dir))) |
| return NULL; |
| |
| if ( (p_dir=(ConEntry_t *)os_MemoryAlloc(sizeof( ConEntry_t )) ) == NULL) |
| return NULL; |
| |
| os_memset( p_dir, 0, sizeof( ConEntry_t ) ); |
| os_strncpy( p_dir->name, name, MAX_NAME_LEN ); |
| os_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 Console_AddToken( THandle hConsole, |
| THandle hDir, |
| const PS8 name, |
| const PS8 help, |
| FuncToken_t p_func, |
| ConParm_t p_parms[] ) |
| { |
| Console_t* pConsole = (Console_t*)hConsole; |
| ConEntry_t *p_dir = (ConEntry_t *)hDir; |
| ConEntry_t *p_token; |
| ConEntry_t **p_e; |
| U16 i; |
| |
| if (!pConsole->p_mon_root) |
| Console_allocRoot(pConsole); |
| |
| if (!p_dir) |
| p_dir = pConsole->p_mon_root; |
| |
| if(!( p_dir && (p_dir->sel == Dir))) |
| return E_ERROR; |
| |
| |
| /* Initialize token structure */ |
| if((p_token = (ConEntry_t *)os_MemoryCAlloc(1,sizeof(ConEntry_t))) == NULL) |
| { |
| os_error_printf(CU_MSG_ERROR, (PS8)("** no memory **\n") ); |
| return E_NOMEMORY; |
| } |
| |
| |
| /* Copy name */ |
| os_strncpy( p_token->name, name, MAX_NAME_LEN ); |
| os_strncpy( p_token->help, help, MAX_HELP_LEN ); |
| p_token->sel = Token; |
| p_token->u.token.f_tokenFunc = p_func; |
| p_token->u.token.totalParams = 0; |
| |
| /* Convert name to lower case and choose alias */ |
| Console_chooseAlias( p_dir, p_token ); |
| |
| /* Copy parameters */ |
| if ( p_parms ) |
| { |
| ConParm_t *p_tmpParms = p_parms; |
| |
| /* find the number of params */ |
| while( p_tmpParms->name && p_tmpParms->name[0] ) |
| { |
| p_token->u.token.totalParams++; |
| p_tmpParms++; |
| } |
| /* allocate the parameters info */ |
| p_token->u.token.parm = (ConParm_t *)os_MemoryAlloc(p_token->u.token.totalParams * sizeof(ConParm_t)); |
| p_token->u.token.name = (PS8*)os_MemoryAlloc(p_token->u.token.totalParams * sizeof(PS8)); |
| if ((p_token->u.token.parm == NULL) || (p_token->u.token.name == NULL)) |
| { |
| os_error_printf(CU_MSG_ERROR, (PS8)("** no memory for params\n") ); |
| os_MemoryFree(p_token); |
| return E_NOMEMORY; |
| } |
| for (i=0; i < p_token->u.token.totalParams; 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 ) |
| { |
| os_error_printf(CU_MSG_ERROR, (PS8)("** buffer too big: %s/%s\n"), p_dir->name, name); |
| os_MemoryFree(p_token->u.token.parm); |
| os_MemoryFree(p_token->u.token.name); |
| os_MemoryFree(p_token); |
| return E_NOMEMORY; |
| |
| } |
| if (p_parms->hi_val == 0 || (p_parms->flags & CON_PARM_RANGE) ) |
| { |
| os_error_printf(CU_MSG_ERROR, (PS8)("** Bad string param definition: %s/%s\n"), p_dir->name, name ); |
| os_MemoryFree(p_token->u.token.parm); |
| os_MemoryFree(p_token->u.token.name); |
| os_MemoryFree(p_token); |
| return E_BADPARM; |
| } |
| p_parms->value = (U32)os_MemoryCAlloc(1,p_parms->hi_val+1); |
| if( !p_parms->value ) |
| { |
| os_error_printf(CU_MSG_ERROR, (PS8)("** No memory: %s/%s (max.size=%ld)\n"), p_dir->name, name, p_parms->hi_val ); |
| os_MemoryFree(p_token->u.token.parm); |
| os_MemoryFree(p_token->u.token.name); |
| os_MemoryFree(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->u.token.name[i] = os_MemoryAlloc(os_strlen(p_parms->name)); |
| if (p_token->u.token.name[i] == NULL) |
| { |
| os_error_printf(CU_MSG_ERROR, (PS8)("** Error allocate param name\n")); |
| os_MemoryFree(p_token->u.token.parm); |
| os_MemoryFree(p_token->u.token.name); |
| os_MemoryFree(p_token); |
| return E_NOMEMORY; |
| } |
| p_token_parm->name = (PS8)p_token->u.token.name[i]; |
| os_strncpy( p_token->u.token.name[i], p_parms->name, os_strlen(p_parms->name) ); |
| ++p_parms; |
| } /*end of for loop*/ |
| } |
| |
| /* 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; |
| } |
| |
| int consoleRunScript( char *script_file, THandle hConsole) |
| { |
| FILE *hfile = fopen(script_file, "r" ); |
| U8 status = 0; |
| Console_t* pConsole = (Console_t*)hConsole; |
| |
| if( hfile ) |
| { |
| char buf[INBUF_LENGTH]; |
| pConsole->stop_UI_Monitor = FALSE; |
| |
| while( fgets(buf, sizeof(buf), hfile ) ) |
| { |
| status = Console_ParseString(pConsole, buf); |
| if (status == 1) |
| return TRUE; |
| if( pConsole->stop_UI_Monitor ) |
| break; |
| } |
| |
| fclose(hfile); |
| } |
| else |
| { |
| os_error_printf(CU_MSG_ERROR, (PS8)("ERROR in script: %s \n"), (PS8)script_file); |
| } |
| return pConsole->stop_UI_Monitor; |
| } |