📄 clilib.c
字号:
/*****************************************************************************
File name : Clilib.c
Description : Command line interpreter
COPYRIGHT (C) ST-Microelectronics 1998.
This module contains the core support routines of the c language cli
Date Modification Name
---- ------------ ----
05 oct 1998 Ported to 5510 FR
25 jan 1999 Improvment : trace, stat, help x*, del x* FQ
29 mar 1998 Report.c replaced by ToolBox; print() removed FQ
06 sep 1999 Remove os20.h, add partitio.h FQ
06 sep 1999 change malloc() to memory_allocate() FQ
04 oct 1999 Change partitio.h to stlite.h FQ
05 oct 1999 Change 2 buffers sizes (120 to max_line_len) FQ
06 oct 1999 Pb: sttbx_print() is limited to 255 charac. FQ
24 dec 1999 do_log: new modes; print: filter; add do_close FQ
24 jan 2000 Add read_stdin() for cmd recall with ctrl keys FQ
06 mar 2000 New banner according to revision FQ
02 Oct 2001 Decrease stack use. HSdLM
08 Oct 2001 Fix DDTS GNBvd09368, 5960, 6055, allow HSdLM
* string = string + integer
28 Nov 2001 Remove 'hit a key to enter' as default HSdLM
* Add option to keep control variables.
* Fix DDTS GNBvd10196 evaluate comparison
15 May 2002 Fix DDTS GNBvd10434 tabulations in scripts HSdLM
23 Jul 2002 Fix DDTS GNBvd17434 memory leak CL
*****************************************************************************/
#ifdef __cplusplus
extern "C" {
#endif
/* Includes --------------------------------------------------------------- */
#include <stdio.h> /* standard inputs */
#include <stdlib.h> /* */
#include <string.h> /* for string manipulations */
#include <stdarg.h> /* for argv argc va_list */
#include <ctype.h> /* */
#ifndef STTBX_PRINT
#define STTBX_PRINT
#endif
#include "stddefs.h"
#include "clilib.h" /* local API */
#include "testtool.h" /* for testtool commands */
#ifndef STTBX_INPUT
#define STTBX_INPUT
#endif
/* Linux Porting */
#if defined(ST_OSLINUX)
#define STTBX_DirectPrint(x) printf x
#else
#ifndef STTBX_REPORT
#define STTBX_REPORT
#endif
#include "sttbx.h"
#endif
#ifdef ST_OS21
/* Include for OS21 Profiler */
#include <os21/profile.h>
#endif /* ST_OS21 */
/* Private Types ------------------------------------------------------------ */
typedef struct
{
S16 old_cmd; /* first command to be entered */
S16 last_cmd; /* last command to be entered */
char cmd_name[STTST_MAX_TOK_LEN][CLI_MAX_LINE_LENGTH];
} cmd_history_t; /* circular stack ; old==last==0 if empty ; fisrt item always empty */
typedef struct
{
char Slot[1]; /* just to say it's a table, memory allocation is done with greater size! */
} SlotTable_t;
/* Private Constants -------------------------------------------------------- */
/* Set following define to enable setting default I/O radix for integer input and output */
/* #define IO_RADIX_CONF */
#define KEY_BACKSP 0x8 /* backspace */
#define KEY_UP 0x9 /* ctrl-i */
#ifndef CONFIG_POSIX
#define KEY_DOWN 0xF /* ctrl-o */
#define KEY_RIGHT 0x10 /* ctrl-p */
#define KEY_LEFT 0x15 /* ctrl-u */
#else
#define KEY_DOWN 0x17 /* ctrl-o */
#define KEY_RIGHT 0x10 /*0x20*/ /* ctrl-p */
#define KEY_LEFT 0x25 /* ctrl-u */
#endif
#define UNIX_KEY_DOWN 0xA /* ctrl-o on Unix */
#define UNIX_KEY_BACKSP 0x7F /* backspace on Unix */
/* OS21 Profiler Default settings */
#define INSTRUCTIONS_PER_BUCKET (1)
#define SAMPLING_FREQ_IN_HERTZ (1000)
/* for gcc only ----------------------------------------------------------- */
#ifndef FILENAME_MAX
#define FILENAME_MAX 64
#endif
#define MAX_STTBX_LEN 512
#define DISPLAY_BUFFER_SIZE (CLI_MAX_LINE_LENGTH*5+1) /* five lines */
#define STRING_TABLE_INIT_SIZE 3 /* if not enough, table is extended with memory allocations */
#define TOKEN_TABLE_INIT_SIZE 10 /* if not enough, table is extended with memory allocations */
#define PARSE_TABLE_INIT_SIZE 10 /* if not enough, table is extended with memory allocations */
#define MAX_NUMBER_LENGTH 34 /* 32 bit word in binary base */
#define CONTROL_NAME_LENGTH 10 /* e.g : WHILE23 */
/* Private Variables (static)------------------------------------------------ */
static symtab_t **Symtab_p; /* symbol table pointer */
static S32 MaxSymbolCount; /* maximum number of symbols */
static S32 SymbolCount; /* number of symbols declared */
static S16 MacroDepth; /* macro invocation depth */
static U8 IfNameCount; /* used to define 'If' macro with unique name */
static U8 ElifNameCount; /* used to define 'Elif' macro with unique name */
static U8 ElseNameCount; /* used to define 'Else' macro with unique name */
static U8 ForNameCount; /* used to define 'For' macro with unique name */
static U8 WhileNameCount; /* used to define 'While' macro with unique name */
static S16 NumberBase; /* default inp/output base for ints */
static FILE *CurrentStream_p; /* current file ip stream */
static macro_t *CurrentMacro_p; /* current macro position */
static char *Prompt_p; /* input prompt */
static BOOL CurrentEcho; /* status of input echo */
static size_t TotalFreeSize;
static FILE *LogFile;
static BOOL LogOutput;
static BOOL LogResults;
static char CommandLineDelimiter[] = "= \\\t";
static char DelimiterSet[] = " ,\\\t";
static char LogicalOps[] = "><=!";
static char ComparisonOps[] = "|&";
static char ArithmeticOpsInt[] = "*/+-|&^%";
static char ArithmeticOpsFloat[] = "*/+-";
static char HexaChars[] = "0123456789ABCDEF";
static char *DisplayBuffer_p;
static SlotTable_t **StringTable_p;
static S16 StringTableIndex;
static U16 MaxSimultaneousStringReached;
static SlotTable_t **TokenTable_p;
static S16 TokenTableIndex;
static U16 MaxSimultaneousTokenReached;
static STTST_Parse_t **ParseTable_p;
static S16 ParseTableIndex;
static U16 MaxSimultaneousParseReached;
static cmd_history_t CommandHistory;
#ifdef ST_OS21
static BOOL is_profiler_initialized = FALSE;
static BOOL is_profiler_started = FALSE;
#endif /* ST_OS21 */
/* Global Variables --------------------------------------------------------- */
extern STTST_InitParams_t sttst_InitParams;
extern S16 STTST_RunMode;
/* Private Macros ----------------------------------------------------------- */
/* Private Function prototypes ---------------------------------------------- */
static BOOL do_define(STTST_Parse_t *Parse_p);
static BOOL define_macro(const char *const defline_p, char *name_p);
static BOOL evaluate_integer_expr(STTST_Parse_t*, S32*, S16);
static BOOL evaluate_float_expr(STTST_Parse_t *Parse_p, double *value_p);
static BOOL read_input(char *line_p, const char *const ip_prompt_p);
static BOOL command_loop(macro_t *macro_p, FILE *file_p, char *rtn_exp_p, BOOL echo);
static BOOL uncommand_loop(macro_t *macro_p, FILE *file_p, char *rtn_exp_p, BOOL echo);
static void InitDisplayBuffer(void);
/* Functions ---------------------------------------------------------------- */
/*******************************************************************************
Name : NewStringTableSlot
Description : give new memory slot in line table
Parameters : size to allocate
Assumptions :
Limitations :
Returns : pointer on allocated memory for Line.
*******************************************************************************/
static char * NewStringTableSlot(U16 LineSize)
{
SlotTable_t **Tmp_p = StringTable_p; /* make it not NULL */
StringTableIndex++;
if (StringTableIndex < STRING_TABLE_INIT_SIZE )
{
/* Index = 0 => 1 slot took, index=1 => 2 slots ... */
if (StringTableIndex+1 > MaxSimultaneousStringReached)
{
MaxSimultaneousStringReached = StringTableIndex+1;
}
}
else
{
if (StringTableIndex+1 > MaxSimultaneousStringReached)
{
MaxSimultaneousStringReached = StringTableIndex+1;
/* re-allocate with greater size print table and copy content to new @ */
Tmp_p = (SlotTable_t **)memory_allocate(sttst_InitParams.CPUPartition_p, sizeof(SlotTable_t*)*(MaxSimultaneousStringReached));
if (Tmp_p != NULL)
{
/* copy content from StringTable_p to Tmp_p :
* keep (StringTableIndex+1)-1 old values, -1 because as been incremented yet */
memcpy(Tmp_p, StringTable_p, sizeof(SlotTable_t*)*(StringTableIndex));
memory_deallocate(sttst_InitParams.CPUPartition_p, StringTable_p);
StringTable_p = Tmp_p;
}
else
{
/* allocation failed : use last slot, crunch it ...*/
STTBX_Print(("\n ******* NewStringTableSlot : not enough memory ! Last slot crunched ****** \n\n" ));
StringTableIndex--;
}
}
if (Tmp_p != NULL)
{
StringTable_p[StringTableIndex] = (SlotTable_t *)memory_allocate(sttst_InitParams.CPUPartition_p, LineSize);
}
}
return(StringTable_p[StringTableIndex]->Slot);
}
/*******************************************************************************
Name : FreeStringTableSlot
Description : free memory slot for print
Parameters :
Assumptions :
Limitations :
Returns : nothing
*******************************************************************************/
static void FreeStringTableSlot(void)
{
if (StringTableIndex >= STRING_TABLE_INIT_SIZE )
{
memory_deallocate(sttst_InitParams.CPUPartition_p, StringTable_p[StringTableIndex]);
}
StringTableIndex--;
}
/*******************************************************************************
Name : NewTokenTableSlot
Description : give new memory slot in token table
Parameters : size to allocate
Assumptions :
Limitations :
Returns : pointer on allocated memory for Token.
*******************************************************************************/
static char * NewTokenTableSlot(U16 TokenSize)
{
SlotTable_t **Tmp_p = TokenTable_p; /* make it not NULL */
TokenTableIndex++;
if (TokenTableIndex < TOKEN_TABLE_INIT_SIZE )
{
/* Index = 0 => 1 slot took, index=1 => 2 slots ... */
if (TokenTableIndex+1 > MaxSimultaneousTokenReached)
{
MaxSimultaneousTokenReached = TokenTableIndex+1;
}
}
else
{
if (TokenTableIndex+1 > MaxSimultaneousTokenReached)
{
MaxSimultaneousTokenReached = TokenTableIndex+1;
/* re-allocate with greater size print table and copy content to new @ */
Tmp_p = (SlotTable_t **)memory_allocate(sttst_InitParams.CPUPartition_p, sizeof(SlotTable_t*)*(MaxSimultaneousTokenReached));
if (Tmp_p != NULL)
{
/* copy content from TokenTable_p to Tmp_p :
* keep (TokenTableIndex+1)-1 old values, -1 because as been incremented yet */
memcpy(Tmp_p, TokenTable_p, sizeof(SlotTable_t*)*(TokenTableIndex));
memory_deallocate(sttst_InitParams.CPUPartition_p, TokenTable_p);
TokenTable_p = Tmp_p;
}
else
{
/* allocation failed : use last slot, crunch it ...*/
STTBX_Print(("\n ******* NewTokenTableSlot : not enough memory ! Last slot crunched ****** \n\n" ));
TokenTableIndex--;
}
}
if (Tmp_p != NULL)
{
TokenTable_p[TokenTableIndex] = (SlotTable_t *)memory_allocate(sttst_InitParams.CPUPartition_p, TokenSize);
}
}
return(TokenTable_p[TokenTableIndex]->Slot);
}
/*******************************************************************************
Name : FreeTokenTableSlot
Description : free memory slot for print
Parameters :
Assumptions :
Limitations :
Returns : nothing
*******************************************************************************/
static void FreeTokenTableSlot(void)
{
if (TokenTableIndex >= TOKEN_TABLE_INIT_SIZE )
{
memory_deallocate(sttst_InitParams.CPUPartition_p, TokenTable_p[TokenTableIndex]);
}
TokenTableIndex--;
}
/*******************************************************************************
Name : NewParseTableSlot
Description : give new memory slot in token table
Parameters :
Assumptions :
Limitations :
Returns : pointer on allocated memory for Parse
*******************************************************************************/
static STTST_Parse_t * NewParseTableSlot(U16 TokenSize)
{
STTST_Parse_t **Tmp_p = ParseTable_p; /* make it not NULL */
U16 AllocSize;
ParseTableIndex++;
if (ParseTableIndex < PARSE_TABLE_INIT_SIZE )
{
/* Index = 0 => 1 slot took, index=1 => 2 slots ... */
if (ParseTableIndex+1 > MaxSimultaneousParseReached)
{
MaxSimultaneousParseReached = ParseTableIndex+1;
}
}
else
{
if (ParseTableIndex+1 > MaxSimultaneousParseReached)
{
MaxSimultaneousParseReached = ParseTableIndex+1;
/* re-allocate with greater size print table and copy content to new @ */
Tmp_p = (STTST_Parse_t **)memory_allocate(sttst_InitParams.CPUPartition_p, sizeof(STTST_Parse_t*)*(MaxSimultaneousParseReached));
if (Tmp_p != NULL)
{
/* copy content from ParseTable_p to Tmp_p :
* keep (ParseTableIndex+1)-1 old values, -1 because as been incremented yet */
memcpy(Tmp_p, ParseTable_p, sizeof(STTST_Parse_t*)*(ParseTableIndex));
memory_deallocate(sttst_InitParams.CPUPartition_p, ParseTable_p);
ParseTable_p = Tmp_p;
}
else
{
/* allocation failed : use last slot, crunch it ...*/
STTBX_Print(("\n ******* NewParseTableSlot : not enough memory ! Last slot crunched ****** \n\n" ));
ParseTableIndex--;
}
}
if (Tmp_p != NULL)
{
AllocSize = sizeof(STTST_Parse_t) + TokenSize;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -