Remove C Style Command Shell

This commit is contained in:
马志远 2021-08-23 17:30:05 +08:00
parent a280fb8f2a
commit 221da7f464
55 changed files with 550 additions and 5927 deletions

View File

@ -18,8 +18,8 @@
#include "board.h"
#ifdef RT_USING_LWIP
#include <lwip/sys.h>
#include <netif/ethernetif.h>
#include <lwip/sys.h>
#include <netif/ethernetif.h>
#endif
/**
@ -30,8 +30,8 @@ extern void rt_hw_serial_init(void);
/*@{*/
#ifdef RT_USING_FINSH
extern int finsh_system_init(void);
extern void finsh_set_device(char* device);
extern int finsh_system_init(void);
extern void finsh_set_device(const char *device);
#endif
extern int rt_application_init(void);
@ -39,11 +39,11 @@ extern void rt_hw_sdcard_init(void);
extern int rt_hw_luminaryif_init(void);
#ifdef __CC_ARM
extern int Image$$RW_IRAM1$$ZI$$Limit;
extern int Image$$RW_IRAM1$$ZI$$Limit;
#elif __ICCARM__
#pragma section="HEAP"
#pragma section="HEAP"
#else
extern int __bss_end;
extern int __bss_end;
#endif
#ifdef DEBUG
@ -56,13 +56,13 @@ extern int __bss_end;
* Output : None
* Return : None
*******************************************************************************/
void assert_failed(u8* file, u32 line)
void assert_failed(u8 *file, u32 line)
{
rt_kprintf("\n\r Wrong parameter value detected on\r\n");
rt_kprintf(" file %s\r\n", file);
rt_kprintf(" line %d\r\n", line);
rt_kprintf("\n\r Wrong parameter value detected on\r\n");
rt_kprintf(" file %s\r\n", file);
rt_kprintf(" line %d\r\n", line);
while (1) ;
while (1) ;
}
#endif
@ -71,76 +71,76 @@ void assert_failed(u8* file, u32 line)
*/
void rtthread_startup(void)
{
/* init board */
rt_hw_board_init();
/* init board */
rt_hw_board_init();
/* show version */
rt_show_version();
/* show version */
rt_show_version();
/* init timer system */
rt_system_timer_init();
/* init timer system */
rt_system_timer_init();
#ifdef RT_USING_HEAP
#ifdef __CC_ARM
rt_system_heap_init((void*)&Image$$RW_IRAM1$$ZI$$Limit, (void*)LM3S_SRAM_END);
rt_system_heap_init((void *)&Image$$RW_IRAM1$$ZI$$Limit, (void *)LM3S_SRAM_END);
#elif __ICCARM__
rt_system_heap_init(__segment_end("HEAP"), (void*)LM3S_SRAM_END);
rt_system_heap_init(__segment_end("HEAP"), (void *)LM3S_SRAM_END);
#else
/* init memory system */
rt_system_heap_init((void*)&__bss_end, (void*)LM3S_SRAM_END);
/* init memory system */
rt_system_heap_init((void *)&__bss_end, (void *)LM3S_SRAM_END);
#endif
#endif
#ifdef RT_USING_MODULE
/* init module system */
rt_system_module_init();
#ifdef RT_USING_MODULE
/* init module system */
rt_system_module_init();
#endif
/* init scheduler system */
rt_system_scheduler_init();
/* init scheduler system */
rt_system_scheduler_init();
#ifdef RT_USING_LWIP
eth_system_device_init();
eth_system_device_init();
/* register ethernetif device */
rt_hw_luminaryif_init();
/* register ethernetif device */
rt_hw_luminaryif_init();
#endif
/* init hardware serial device */
rt_hw_serial_init();
/* init hardware serial device */
rt_hw_serial_init();
#ifdef RT_USING_DFS
/* init sd card device */
rt_hw_sdcard_init();
/* init sd card device */
rt_hw_sdcard_init();
#endif
/* init application */
rt_application_init();
/* init application */
rt_application_init();
#ifdef RT_USING_FINSH
/* init finsh */
finsh_system_init();
/* init finsh */
finsh_system_init();
#ifdef RT_USING_DEVICE
finsh_set_device("uart1");
finsh_set_device("uart1");
#endif
#endif
/* init idle thread */
rt_thread_idle_init();
/* init idle thread */
rt_thread_idle_init();
/* start scheduler */
rt_system_scheduler_start();
/* start scheduler */
rt_system_scheduler_start();
/* never reach here */
return ;
/* never reach here */
return ;
}
int main(void)
{
/* disable interrupt first */
rt_hw_interrupt_disable();
rtthread_startup();
return 0;
/* disable interrupt first */
rt_hw_interrupt_disable();
rtthread_startup();
return 0;
}
/*@}*/

View File

@ -18,8 +18,8 @@
#include "board.h"
#ifdef RT_USING_LWIP
#include <lwip/sys.h>
#include <netif/ethernetif.h>
#include <lwip/sys.h>
#include <netif/ethernetif.h>
#endif
/**
@ -30,8 +30,8 @@ extern void rt_hw_serial_init(void);
/*@{*/
#ifdef RT_USING_FINSH
extern int finsh_system_init(void);
extern void finsh_set_device(char* device);
extern int finsh_system_init(void);
extern void finsh_set_device(const char *device);
#endif
extern int rt_application_init(void);
@ -39,11 +39,11 @@ extern void rt_hw_sdcard_init(void);
extern int rt_hw_luminaryif_init(void);
#ifdef __CC_ARM
extern int Image$$RW_IRAM1$$ZI$$Limit;
extern int Image$$RW_IRAM1$$ZI$$Limit;
#elif __ICCARM__
#pragma section="HEAP"
#pragma section="HEAP"
#else
extern int __bss_end;
extern int __bss_end;
#endif
#ifdef DEBUG
@ -56,13 +56,13 @@ extern int __bss_end;
* Output : None
* Return : None
*******************************************************************************/
void __error__(char* file, unsigned long line)
void __error__(char *file, unsigned long line)
{
rt_kprintf("\n\r Wrong parameter value detected on\r\n");
rt_kprintf(" file %s\r\n", file);
rt_kprintf(" line %d\r\n", line);
rt_kprintf("\n\r Wrong parameter value detected on\r\n");
rt_kprintf(" file %s\r\n", file);
rt_kprintf(" line %d\r\n", line);
while (1) ;
while (1) ;
}
#endif
@ -71,77 +71,77 @@ void __error__(char* file, unsigned long line)
*/
void rtthread_startup(void)
{
/* init board */
rt_hw_board_init();
/* init board */
rt_hw_board_init();
/* show version */
rt_show_version();
/* show version */
rt_show_version();
/* init timer system */
rt_system_timer_init();
/* init timer system */
rt_system_timer_init();
#ifdef RT_USING_HEAP
#if LM3S_EXT_SRAM == 1
/* init sdram */
rt_system_heap_init((void*)LM3S_EXT_SRAM_BEGIN, (void*)LM3S_EXT_SRAM_END);
/* init sdram */
rt_system_heap_init((void *)LM3S_EXT_SRAM_BEGIN, (void *)LM3S_EXT_SRAM_END);
#else
#ifdef __CC_ARM
rt_system_heap_init((void*)&Image$$RW_IRAM1$$ZI$$Limit, (void*)LM3S_SRAM_END);
rt_system_heap_init((void *)&Image$$RW_IRAM1$$ZI$$Limit, (void *)LM3S_SRAM_END);
#elif __ICCARM__
rt_system_heap_init(__segment_end("HEAP"), (void*)LM3S_SRAM_END);
rt_system_heap_init(__segment_end("HEAP"), (void *)LM3S_SRAM_END);
#else
/* init memory system */
rt_system_heap_init((void*)&__bss_end, (void*)LM3S_SRAM_END);
/* init memory system */
rt_system_heap_init((void *)&__bss_end, (void *)LM3S_SRAM_END);
#endif
#endif
#endif
/* init scheduler system */
rt_system_scheduler_init();
/* init scheduler system */
rt_system_scheduler_init();
#ifdef RT_USING_LWIP
eth_system_device_init();
eth_system_device_init();
/* register ethernetif device */
rt_hw_luminaryif_init();
/* register ethernetif device */
rt_hw_luminaryif_init();
#endif
/* init hardware serial device */
rt_hw_serial_init();
/* init hardware serial device */
rt_hw_serial_init();
#ifdef RT_USING_DFS
/* init sd card device */
rt_hw_sdcard_init();
/* init sd card device */
rt_hw_sdcard_init();
#endif
/* init application */
rt_application_init();
/* init application */
rt_application_init();
#ifdef RT_USING_FINSH
/* init finsh */
finsh_system_init();
/* init finsh */
finsh_system_init();
#ifdef RT_USING_DEVICE
finsh_set_device("uart1");
finsh_set_device("uart1");
#endif
#endif
/* init idle thread */
rt_thread_idle_init();
/* init idle thread */
rt_thread_idle_init();
/* start scheduler */
rt_system_scheduler_start();
/* start scheduler */
rt_system_scheduler_start();
/* never reach here */
return ;
/* never reach here */
return ;
}
int main(void)
{
/* disable interrupt first */
/* disable interrupt first */
rt_hw_interrupt_disable();
rtthread_startup();
rtthread_startup();
return 0;
return 0;
}
/*@}*/

View File

@ -18,8 +18,8 @@
#include "board.h"
#ifdef RT_USING_LWIP
#include <lwip/sys.h>
#include <netif/ethernetif.h>
#include <lwip/sys.h>
#include <netif/ethernetif.h>
#endif
/**
@ -30,8 +30,8 @@ extern void rt_hw_serial_init(void);
/*@{*/
#ifdef RT_USING_FINSH
extern int finsh_system_init(void);
extern void finsh_set_device(char* device);
extern int finsh_system_init(void);
extern void finsh_set_device(const char *device);
#endif
extern int rt_application_init(void);
@ -39,11 +39,11 @@ extern void rt_hw_sdcard_init(void);
extern int rt_hw_luminaryif_init(void);
#ifdef __CC_ARM
extern int Image$$ER_ZI$$ZI$$Limit;
extern int Image$$ER_ZI$$ZI$$Limit;
#elif __ICCARM__
#pragma section="HEAP"
#pragma section="HEAP"
#else
extern int __bss_end;
extern int __bss_end;
#endif
#ifdef DEBUG
@ -56,13 +56,13 @@ extern int __bss_end;
* Output : None
* Return : None
*******************************************************************************/
void __error__(char* file, unsigned long line)
void __error__(char *file, unsigned long line)
{
rt_kprintf("\n\r Wrong parameter value detected on\r\n");
rt_kprintf(" file %s\r\n", file);
rt_kprintf(" line %d\r\n", line);
rt_kprintf("\n\r Wrong parameter value detected on\r\n");
rt_kprintf(" file %s\r\n", file);
rt_kprintf(" line %d\r\n", line);
while (1) ;
while (1) ;
}
#endif
@ -71,77 +71,77 @@ void __error__(char* file, unsigned long line)
*/
void rtthread_startup(void)
{
/* init board */
rt_hw_board_init();
/* init board */
rt_hw_board_init();
/* show version */
rt_show_version();
/* show version */
rt_show_version();
/* init timer system */
rt_system_timer_init();
/* init timer system */
rt_system_timer_init();
#ifdef RT_USING_HEAP
#if LM3S_EXT_SRAM == 1
/* init sdram */
rt_system_heap_init((void*)LM3S_EXT_SRAM_BEGIN, (void*)LM3S_EXT_SRAM_END);
/* init sdram */
rt_system_heap_init((void *)LM3S_EXT_SRAM_BEGIN, (void *)LM3S_EXT_SRAM_END);
#else
#ifdef __CC_ARM
rt_system_heap_init((void*)&Image$$ER_ZI$$ZI$$Limit, (void*)LM3S_SRAM_END);
rt_system_heap_init((void *)&Image$$ER_ZI$$ZI$$Limit, (void *)LM3S_SRAM_END);
#elif __ICCARM__
rt_system_heap_init(__segment_end("HEAP"), (void*)LM3S_SRAM_END);
rt_system_heap_init(__segment_end("HEAP"), (void *)LM3S_SRAM_END);
#else
/* init memory system */
rt_system_heap_init((void*)&__bss_end, (void*)LM3S_SRAM_END);
/* init memory system */
rt_system_heap_init((void *)&__bss_end, (void *)LM3S_SRAM_END);
#endif
#endif
#endif
/* init scheduler system */
rt_system_scheduler_init();
/* init scheduler system */
rt_system_scheduler_init();
#ifdef RT_USING_LWIP
eth_system_device_init();
eth_system_device_init();
/* register ethernetif device */
rt_hw_luminaryif_init();
/* register ethernetif device */
rt_hw_luminaryif_init();
#endif
/* init hardware serial device */
rt_hw_serial_init();
/* init hardware serial device */
rt_hw_serial_init();
#ifdef RT_USING_DFS
/* init sd card device */
rt_hw_sdcard_init();
/* init sd card device */
rt_hw_sdcard_init();
#endif
/* init application */
rt_application_init();
/* init application */
rt_application_init();
#ifdef RT_USING_FINSH
/* init finsh */
finsh_system_init();
/* init finsh */
finsh_system_init();
#ifdef RT_USING_DEVICE
finsh_set_device("uart1");
finsh_set_device("uart1");
#endif
#endif
/* init idle thread */
rt_thread_idle_init();
/* init idle thread */
rt_thread_idle_init();
/* start scheduler */
rt_system_scheduler_start();
/* start scheduler */
rt_system_scheduler_start();
/* never reach here */
return ;
/* never reach here */
return ;
}
int main(void)
{
/* disable interrupt first */
/* disable interrupt first */
rt_hw_interrupt_disable();
rtthread_startup();
rtthread_startup();
return 0;
return 0;
}
/*@}*/

View File

@ -144,7 +144,7 @@ rt_err_t rt_adc_disable(rt_adc_device_t dev, rt_uint32_t channel)
return result;
}
#ifdef FINSH_USING_MSH
#ifdef RT_USING_FINSH
static int adc(int argc, char **argv)
{
@ -232,4 +232,4 @@ static int adc(int argc, char **argv)
}
MSH_CMD_EXPORT(adc, adc function);
#endif /* FINSH_USING_MSH */
#endif /* RT_USING_FINSH */

View File

@ -141,7 +141,7 @@ rt_err_t rt_dac_disabled(rt_dac_device_t dev, rt_uint32_t channel)
return result;
}
#ifdef FINSH_USING_MSH
#ifdef RT_USING_FINSH
static int dac(int argc, char **argv)
{
@ -228,4 +228,4 @@ static int dac(int argc, char **argv)
}
MSH_CMD_EXPORT(dac, dac function);
#endif /* FINSH_USING_MSH */
#endif /* RT_USING_FINSH */

View File

@ -198,7 +198,7 @@ rt_err_t rt_pwm_get(struct rt_device_pwm *device, struct rt_pwm_configuration *c
FINSH_FUNCTION_EXPORT_ALIAS(rt_pwm_enable, pwm_enable, enable pwm by channel.);
FINSH_FUNCTION_EXPORT_ALIAS(rt_pwm_set, pwm_set, set pwm.);
#ifdef FINSH_USING_MSH
#ifdef RT_USING_FINSH
static int pwm_enable(int argc, char **argv)
{
int result = 0;
@ -323,5 +323,5 @@ _exit:
}
MSH_CMD_EXPORT(pwm_get, pwm_get <pwm_dev> <channel>);
#endif /* FINSH_USING_MSH */
#endif /* RT_USING_FINSH */
#endif /* RT_USING_FINSH */

View File

@ -278,7 +278,7 @@ int mtd_nand_erase_all(const char *name)
return 0;
}
#ifdef FINSH_USING_MSH
#ifdef RT_USING_FINSH
static void mtd_nand(int argc, char **argv)
{
/* If the number of arguments less than 2 */
@ -346,16 +346,16 @@ help:
}
}
MSH_CMD_EXPORT(mtd_nand, MTD nand device test function);
#endif /* FINSH_USING_MSH */
#endif /* RT_USING_FINSH */
#ifndef FINSH_USING_MSH_ONLY
#ifndef RT_USING_FINSH_ONLY
FINSH_FUNCTION_EXPORT_ALIAS(mtd_nandid, nand_id, read ID - nandid(name));
FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_read, nand_read, read page in nand - nand_read(name, block, page));
FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_readoob, nand_readoob, read spare data in nand - nand_readoob(name, block, page));
FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_write, nand_write, write dump data to nand - nand_write(name, block, page));
FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_erase, nand_erase, nand_erase(name, block));
FINSH_FUNCTION_EXPORT_ALIAS(mtd_nand_erase_all, nand_erase_all, erase all of nand device - nand_erase_all(name, block));
#endif /* FINSH_USING_MSH_ONLY */
#endif /* RT_USING_FINSH_ONLY */
#endif /* defined(RT_MTD_NAND_DEBUG) && defined(RT_USING_FINSH) */

View File

@ -218,7 +218,7 @@ rt_err_t set_time(rt_uint32_t hour, rt_uint32_t minute, rt_uint32_t second)
return ret;
}
#ifdef FINSH_USING_MSH
#ifdef RT_USING_FINSH
#include <finsh.h>
/**
* get date and time or set (local timezone) [year month day hour min sec]
@ -283,6 +283,6 @@ static void date(uint8_t argc, char **argv)
}
}
MSH_CMD_EXPORT(date, get date and time or set (local timezone) [year month day hour min sec])
#endif /* FINSH_USING_MSH */
#endif /* RT_USING_FINSH */
#endif /* RT_USING_RTC */

View File

@ -155,7 +155,7 @@ static void sensor_fifo(int argc, char **argv)
rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)20);
}
#ifdef FINSH_USING_MSH
#ifdef RT_USING_FINSH
MSH_CMD_EXPORT(sensor_fifo, Sensor fifo mode test function);
#endif
@ -219,7 +219,7 @@ static void sensor_int(int argc, char **argv)
}
rt_device_control(dev, RT_SENSOR_CTRL_SET_ODR, (void *)20);
}
#ifdef FINSH_USING_MSH
#ifdef RT_USING_FINSH
MSH_CMD_EXPORT(sensor_int, Sensor interrupt mode test function);
#endif
@ -268,7 +268,7 @@ static void sensor_polling(int argc, char **argv)
}
rt_device_close(dev);
}
#ifdef FINSH_USING_MSH
#ifdef RT_USING_FINSH
MSH_CMD_EXPORT(sensor_polling, Sensor polling mode test function);
#endif
@ -496,6 +496,6 @@ static void sensor(int argc, char **argv)
LOG_W("Unknown command, please enter 'sensor' get help information!");
}
}
#ifdef FINSH_USING_MSH
#ifdef RT_USING_FINSH
MSH_CMD_EXPORT(sensor, sensor test function);
#endif

View File

@ -9,6 +9,7 @@
*/
#include <stdint.h>
#include <string.h>
#include <rtdevice.h>
#include "spi_flash.h"
#include "spi_flash_sfud.h"
@ -508,7 +509,7 @@ __error:
return RT_NULL;
}
#if defined(RT_USING_FINSH) && defined(FINSH_USING_MSH)
#if defined(RT_USING_FINSH)
#include <finsh.h>
@ -773,6 +774,6 @@ static void sf(uint8_t argc, char **argv) {
}
}
MSH_CMD_EXPORT(sf, SPI Flash operate.);
#endif /* defined(RT_USING_FINSH) && defined(FINSH_USING_MSH) */
#endif /* defined(RT_USING_FINSH) */
#endif /* RT_USING_SFUD */

View File

@ -586,7 +586,7 @@ static int wifi_msh(int argc, char *argv[])
return 0;
}
#if defined(RT_USING_FINSH) && defined(FINSH_USING_MSH)
#if defined(RT_USING_FINSH)
FINSH_FUNCTION_EXPORT_ALIAS(wifi_msh, __cmd_wifi, wifi command.);
#endif

View File

@ -1,13 +1,18 @@
menu "Command shell"
config RT_USING_FINSH
bool "finsh shell"
bool
default n
config RT_USING_MSH
bool "msh shell"
select RT_USING_FINSH
default y
if RT_USING_FINSH
if RT_USING_MSH
config FINSH_THREAD_NAME
string "The finsh thread name"
string "The msh thread name"
default "tshell"
config FINSH_USING_HISTORY
bool "Enable command history feature"
@ -31,11 +36,11 @@ config FINSH_ECHO_DISABLE_DEFAULT
default n
config FINSH_THREAD_PRIORITY
int "The priority level value of finsh thread"
int "The priority level value of thread"
default 20
config FINSH_THREAD_STACK_SIZE
int "The stack size for finsh thread"
int "The stack size for thread"
default 4096
config FINSH_CMD_SIZE
@ -58,23 +63,9 @@ config FINSH_PASSWORD_MAX
default RT_NAME_MAX
endif
config FINSH_USING_MSH
bool "Using module shell"
default y
if FINSH_USING_MSH
config FINSH_USING_MSH_DEFAULT
bool "Using module shell in default"
default y
config FINSH_USING_MSH_ONLY
bool "Only using module shell"
default n
config FINSH_ARG_MAX
int "The command arg num for shell"
int "The number of arguments for a shell command"
default 10
endif
endif

View File

@ -1,39 +1,17 @@
Import('rtconfig')
from building import *
cwd = GetCurrentDir()
src = Split('''
shell.c
cmd.c
msh.c
''')
fsh_src = Split('''
finsh_compiler.c
finsh_error.c
finsh_heap.c
finsh_init.c
finsh_node.c
finsh_ops.c
finsh_parser.c
finsh_var.c
finsh_vm.c
finsh_token.c
''')
msh_src = Glob('msh.c')
if GetDepend('RT_USING_DFS'):
msh_src += ['msh_file.c']
if not GetDepend('FINSH_USING_SYMTAB'):
src += ['symbol.c']
if GetDepend('FINSH_USING_MSH'):
src = src + msh_src
if not GetDepend('FINSH_USING_MSH_ONLY'):
src = src + fsh_src
src += ['msh_file.c']
CPPPATH = [cwd]
group = DefineGroup('finsh', src, depend = ['RT_USING_FINSH'], CPPPATH = CPPPATH)
group = DefineGroup('msh', src, depend = ['RT_USING_FINSH'], CPPPATH = CPPPATH)
Return('group')

View File

@ -33,10 +33,10 @@
#include <rthw.h>
#include <rtthread.h>
#include <string.h>
#ifdef RT_USING_FINSH
#include "finsh.h"
#include <finsh.h>
#define LIST_FIND_OBJ_NR 8
@ -46,7 +46,7 @@ long hello(void)
return 0;
}
FINSH_FUNCTION_EXPORT(hello, say hello world);
MSH_CMD_EXPORT(hello, say hello world);
static long clear(void)
{
@ -54,8 +54,7 @@ static long clear(void)
return 0;
}
FINSH_FUNCTION_EXPORT(clear,clear the terminal screen);
MSH_CMD_EXPORT(clear,clear the terminal screen);
MSH_CMD_EXPORT(clear, clear the terminal screen);
extern void rt_show_version(void);
long version(void)
@ -64,8 +63,7 @@ long version(void)
return 0;
}
FINSH_FUNCTION_EXPORT(version, show RT-Thread version information);
MSH_CMD_EXPORT(version, show RT-Thread version information);
MSH_CMD_EXPORT(version, show RT - Thread version information);
rt_inline void object_split(int len)
{
@ -166,20 +164,22 @@ long list_thread(void)
rt_ubase_t level;
list_get_next_t find_arg;
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t*)RT_NULL;
rt_list_t *next = (rt_list_t *)RT_NULL;
const char *item_title = "thread";
int maxlen;
list_find_init(&find_arg, RT_Object_Class_Thread, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
list_find_init(&find_arg, RT_Object_Class_Thread, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
maxlen = RT_NAME_MAX;
#ifdef RT_USING_SMP
rt_kprintf("%-*.s cpu bind pri status sp stack size max used left tick error\n", maxlen, item_title); object_split(maxlen);
rt_kprintf( " --- ---- --- ------- ---------- ---------- ------ ---------- ---\n");
rt_kprintf("%-*.s cpu bind pri status sp stack size max used left tick error\n", maxlen, item_title);
object_split(maxlen);
rt_kprintf(" --- ---- --- ------- ---------- ---------- ------ ---------- ---\n");
#else
rt_kprintf("%-*.s pri status sp stack size max used left tick error\n", maxlen, item_title); object_split(maxlen);
rt_kprintf( " --- ------- ---------- ---------- ------ ---------- ---\n");
rt_kprintf("%-*.s pri status sp stack size max used left tick error\n", maxlen, item_title);
object_split(maxlen);
rt_kprintf(" --- ------- ---------- ---------- ------ ---------- ---\n");
#endif /*RT_USING_SMP*/
do
@ -201,10 +201,10 @@ long list_thread(void)
continue;
}
/* copy info */
memcpy(&thread_info, obj, sizeof thread_info);
rt_memcpy(&thread_info, obj, sizeof thread_info);
rt_hw_interrupt_enable(level);
thread = (struct rt_thread*)obj;
thread = (struct rt_thread *)obj;
{
rt_uint8_t stat;
rt_uint8_t *ptr;
@ -230,32 +230,31 @@ long list_thread(void)
while (*ptr == '#')ptr --;
rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %03d\n",
((rt_ubase_t)thread->sp - (rt_ubase_t)thread->stack_addr),
thread->stack_size,
((rt_ubase_t)ptr - (rt_ubase_t)thread->stack_addr) * 100 / thread->stack_size,
thread->remaining_tick,
thread->error);
((rt_ubase_t)thread->sp - (rt_ubase_t)thread->stack_addr),
thread->stack_size,
((rt_ubase_t)ptr - (rt_ubase_t)thread->stack_addr) * 100 / thread->stack_size,
thread->remaining_tick,
thread->error);
#else
ptr = (rt_uint8_t *)thread->stack_addr;
while (*ptr == '#')ptr ++;
rt_kprintf(" 0x%08x 0x%08x %02d%% 0x%08x %03d\n",
thread->stack_size + ((rt_ubase_t)thread->stack_addr - (rt_ubase_t)thread->sp),
thread->stack_size,
(thread->stack_size - ((rt_ubase_t) ptr - (rt_ubase_t) thread->stack_addr)) * 100
/ thread->stack_size,
thread->remaining_tick,
thread->error);
thread->stack_size + ((rt_ubase_t)thread->stack_addr - (rt_ubase_t)thread->sp),
thread->stack_size,
(thread->stack_size - ((rt_ubase_t) ptr - (rt_ubase_t) thread->stack_addr)) * 100
/ thread->stack_size,
thread->remaining_tick,
thread->error);
#endif
}
}
}
}
while (next != (rt_list_t*)RT_NULL);
while (next != (rt_list_t *)RT_NULL);
return 0;
}
FINSH_FUNCTION_EXPORT(list_thread, list thread);
MSH_CMD_EXPORT(list_thread, list thread);
static void show_wait_queue(struct rt_list_node *list)
@ -266,7 +265,7 @@ static void show_wait_queue(struct rt_list_node *list)
for (node = list->next; node != list; node = node->next)
{
thread = rt_list_entry(node, struct rt_thread, tlist);
rt_kprintf("%s", thread->name);
rt_kprintf("%.*s", RT_NAME_MAX, thread->name);
if (node->next != list)
rt_kprintf("/");
@ -279,17 +278,18 @@ long list_sem(void)
rt_ubase_t level;
list_get_next_t find_arg;
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t*)RT_NULL;
rt_list_t *next = (rt_list_t *)RT_NULL;
int maxlen;
const char *item_title = "semaphore";
list_find_init(&find_arg, RT_Object_Class_Semaphore, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
list_find_init(&find_arg, RT_Object_Class_Semaphore, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
maxlen = RT_NAME_MAX;
rt_kprintf("%-*.s v suspend thread\n", maxlen, item_title); object_split(maxlen);
rt_kprintf( " --- --------------\n");
rt_kprintf("%-*.s v suspend thread\n", maxlen, item_title);
object_split(maxlen);
rt_kprintf(" --- --------------\n");
do
{
@ -310,33 +310,32 @@ long list_sem(void)
}
rt_hw_interrupt_enable(level);
sem = (struct rt_semaphore*)obj;
sem = (struct rt_semaphore *)obj;
if (!rt_list_isempty(&sem->parent.suspend_thread))
{
rt_kprintf("%-*.*s %03d %d:",
maxlen, RT_NAME_MAX,
sem->parent.parent.name,
sem->value,
rt_list_len(&sem->parent.suspend_thread));
maxlen, RT_NAME_MAX,
sem->parent.parent.name,
sem->value,
rt_list_len(&sem->parent.suspend_thread));
show_wait_queue(&(sem->parent.suspend_thread));
rt_kprintf("\n");
}
else
{
rt_kprintf("%-*.*s %03d %d\n",
maxlen, RT_NAME_MAX,
sem->parent.parent.name,
sem->value,
rt_list_len(&sem->parent.suspend_thread));
maxlen, RT_NAME_MAX,
sem->parent.parent.name,
sem->value,
rt_list_len(&sem->parent.suspend_thread));
}
}
}
}
while (next != (rt_list_t*)RT_NULL);
while (next != (rt_list_t *)RT_NULL);
return 0;
}
FINSH_FUNCTION_EXPORT(list_sem, list semaphore in system);
MSH_CMD_EXPORT(list_sem, list semaphore in system);
#endif
@ -346,17 +345,18 @@ long list_event(void)
rt_ubase_t level;
list_get_next_t find_arg;
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t*)RT_NULL;
rt_list_t *next = (rt_list_t *)RT_NULL;
int maxlen;
const char *item_title = "event";
list_find_init(&find_arg, RT_Object_Class_Event, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
list_find_init(&find_arg, RT_Object_Class_Event, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
maxlen = RT_NAME_MAX;
rt_kprintf("%-*.s set suspend thread\n", maxlen, item_title); object_split(maxlen);
rt_kprintf( " ---------- --------------\n");
rt_kprintf("%-*.s set suspend thread\n", maxlen, item_title);
object_split(maxlen);
rt_kprintf(" ---------- --------------\n");
do
{
@ -382,26 +382,25 @@ long list_event(void)
if (!rt_list_isempty(&e->parent.suspend_thread))
{
rt_kprintf("%-*.*s 0x%08x %03d:",
maxlen, RT_NAME_MAX,
e->parent.parent.name,
e->set,
rt_list_len(&e->parent.suspend_thread));
maxlen, RT_NAME_MAX,
e->parent.parent.name,
e->set,
rt_list_len(&e->parent.suspend_thread));
show_wait_queue(&(e->parent.suspend_thread));
rt_kprintf("\n");
}
else
{
rt_kprintf("%-*.*s 0x%08x 0\n",
maxlen, RT_NAME_MAX, e->parent.parent.name, e->set);
maxlen, RT_NAME_MAX, e->parent.parent.name, e->set);
}
}
}
}
while (next != (rt_list_t*)RT_NULL);
while (next != (rt_list_t *)RT_NULL);
return 0;
}
FINSH_FUNCTION_EXPORT(list_event, list event in system);
MSH_CMD_EXPORT(list_event, list event in system);
#endif
@ -411,17 +410,18 @@ long list_mutex(void)
rt_ubase_t level;
list_get_next_t find_arg;
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t*)RT_NULL;
rt_list_t *next = (rt_list_t *)RT_NULL;
int maxlen;
const char *item_title = "mutex";
list_find_init(&find_arg, RT_Object_Class_Mutex, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
list_find_init(&find_arg, RT_Object_Class_Mutex, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
maxlen = RT_NAME_MAX;
rt_kprintf("%-*.s owner hold suspend thread\n", maxlen, item_title); object_split(maxlen);
rt_kprintf( " -------- ---- --------------\n");
rt_kprintf("%-*.s owner hold suspend thread\n", maxlen, item_title);
object_split(maxlen);
rt_kprintf(" -------- ---- --------------\n");
do
{
@ -445,21 +445,20 @@ long list_mutex(void)
m = (struct rt_mutex *)obj;
rt_kprintf("%-*.*s %-8.*s %04d %d\n",
maxlen, RT_NAME_MAX,
m->parent.parent.name,
RT_NAME_MAX,
m->owner->name,
m->hold,
rt_list_len(&m->parent.suspend_thread));
maxlen, RT_NAME_MAX,
m->parent.parent.name,
RT_NAME_MAX,
m->owner->name,
m->hold,
rt_list_len(&m->parent.suspend_thread));
}
}
}
while (next != (rt_list_t*)RT_NULL);
while (next != (rt_list_t *)RT_NULL);
return 0;
}
FINSH_FUNCTION_EXPORT(list_mutex, list mutex in system);
MSH_CMD_EXPORT(list_mutex, list mutex in system);
#endif
@ -469,17 +468,18 @@ long list_mailbox(void)
rt_ubase_t level;
list_get_next_t find_arg;
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t*)RT_NULL;
rt_list_t *next = (rt_list_t *)RT_NULL;
int maxlen;
const char *item_title = "mailbox";
list_find_init(&find_arg, RT_Object_Class_MailBox, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
list_find_init(&find_arg, RT_Object_Class_MailBox, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
maxlen = RT_NAME_MAX;
rt_kprintf("%-*.s entry size suspend thread\n", maxlen, item_title); object_split(maxlen);
rt_kprintf( " ---- ---- --------------\n");
rt_kprintf("%-*.s entry size suspend thread\n", maxlen, item_title);
object_split(maxlen);
rt_kprintf(" ---- ---- --------------\n");
do
{
@ -505,32 +505,31 @@ long list_mailbox(void)
if (!rt_list_isempty(&m->parent.suspend_thread))
{
rt_kprintf("%-*.*s %04d %04d %d:",
maxlen, RT_NAME_MAX,
m->parent.parent.name,
m->entry,
m->size,
rt_list_len(&m->parent.suspend_thread));
maxlen, RT_NAME_MAX,
m->parent.parent.name,
m->entry,
m->size,
rt_list_len(&m->parent.suspend_thread));
show_wait_queue(&(m->parent.suspend_thread));
rt_kprintf("\n");
}
else
{
rt_kprintf("%-*.*s %04d %04d %d\n",
maxlen, RT_NAME_MAX,
m->parent.parent.name,
m->entry,
m->size,
rt_list_len(&m->parent.suspend_thread));
maxlen, RT_NAME_MAX,
m->parent.parent.name,
m->entry,
m->size,
rt_list_len(&m->parent.suspend_thread));
}
}
}
}
while (next != (rt_list_t*)RT_NULL);
while (next != (rt_list_t *)RT_NULL);
return 0;
}
FINSH_FUNCTION_EXPORT(list_mailbox, list mail box in system);
MSH_CMD_EXPORT(list_mailbox, list mail box in system);
#endif
@ -540,17 +539,18 @@ long list_msgqueue(void)
rt_ubase_t level;
list_get_next_t find_arg;
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t*)RT_NULL;
rt_list_t *next = (rt_list_t *)RT_NULL;
int maxlen;
const char *item_title = "msgqueue";
list_find_init(&find_arg, RT_Object_Class_MessageQueue, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
list_find_init(&find_arg, RT_Object_Class_MessageQueue, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
maxlen = RT_NAME_MAX;
rt_kprintf("%-*.s entry suspend thread\n", maxlen, item_title); object_split(maxlen);
rt_kprintf( " ---- --------------\n");
rt_kprintf("%-*.s entry suspend thread\n", maxlen, item_title);
object_split(maxlen);
rt_kprintf(" ---- --------------\n");
do
{
next = list_get_next(next, &find_arg);
@ -575,29 +575,28 @@ long list_msgqueue(void)
if (!rt_list_isempty(&m->parent.suspend_thread))
{
rt_kprintf("%-*.*s %04d %d:",
maxlen, RT_NAME_MAX,
m->parent.parent.name,
m->entry,
rt_list_len(&m->parent.suspend_thread));
maxlen, RT_NAME_MAX,
m->parent.parent.name,
m->entry,
rt_list_len(&m->parent.suspend_thread));
show_wait_queue(&(m->parent.suspend_thread));
rt_kprintf("\n");
}
else
{
rt_kprintf("%-*.*s %04d %d\n",
maxlen, RT_NAME_MAX,
m->parent.parent.name,
m->entry,
rt_list_len(&m->parent.suspend_thread));
maxlen, RT_NAME_MAX,
m->parent.parent.name,
m->entry,
rt_list_len(&m->parent.suspend_thread));
}
}
}
}
while (next != (rt_list_t*)RT_NULL);
while (next != (rt_list_t *)RT_NULL);
return 0;
}
FINSH_FUNCTION_EXPORT(list_msgqueue, list message queue in system);
MSH_CMD_EXPORT(list_msgqueue, list message queue in system);
#endif
@ -607,17 +606,18 @@ long list_memheap(void)
rt_ubase_t level;
list_get_next_t find_arg;
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t*)RT_NULL;
rt_list_t *next = (rt_list_t *)RT_NULL;
int maxlen;
const char *item_title = "memheap";
list_find_init(&find_arg, RT_Object_Class_MemHeap, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
list_find_init(&find_arg, RT_Object_Class_MemHeap, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
maxlen = RT_NAME_MAX;
rt_kprintf("%-*.s pool size max used size available size\n", maxlen, item_title); object_split(maxlen);
rt_kprintf( " ---------- ------------- --------------\n");
rt_kprintf("%-*.s pool size max used size available size\n", maxlen, item_title);
object_split(maxlen);
rt_kprintf(" ---------- ------------- --------------\n");
do
{
next = list_get_next(next, &find_arg);
@ -641,20 +641,19 @@ long list_memheap(void)
mh = (struct rt_memheap *)obj;
rt_kprintf("%-*.*s %-010d %-013d %-05d\n",
maxlen, RT_NAME_MAX,
mh->parent.name,
mh->pool_size,
mh->max_used_size,
mh->available_size);
maxlen, RT_NAME_MAX,
mh->parent.name,
mh->pool_size,
mh->max_used_size,
mh->available_size);
}
}
}
while (next != (rt_list_t*)RT_NULL);
while (next != (rt_list_t *)RT_NULL);
return 0;
}
FINSH_FUNCTION_EXPORT(list_memheap, list memory heap in system);
MSH_CMD_EXPORT(list_memheap, list memory heap in system);
#endif
@ -664,17 +663,18 @@ long list_mempool(void)
rt_ubase_t level;
list_get_next_t find_arg;
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t*)RT_NULL;
rt_list_t *next = (rt_list_t *)RT_NULL;
int maxlen;
const char *item_title = "mempool";
list_find_init(&find_arg, RT_Object_Class_MemPool, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
list_find_init(&find_arg, RT_Object_Class_MemPool, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
maxlen = RT_NAME_MAX;
rt_kprintf("%-*.s block total free suspend thread\n", maxlen, item_title); object_split(maxlen);
rt_kprintf( " ---- ---- ---- --------------\n");
rt_kprintf("%-*.s block total free suspend thread\n", maxlen, item_title);
object_split(maxlen);
rt_kprintf(" ---- ---- ---- --------------\n");
do
{
next = list_get_next(next, &find_arg);
@ -708,33 +708,32 @@ long list_mempool(void)
if (suspend_thread_count > 0)
{
rt_kprintf("%-*.*s %04d %04d %04d %d:",
maxlen, RT_NAME_MAX,
mp->parent.name,
mp->block_size,
mp->block_total_count,
mp->block_free_count,
suspend_thread_count);
maxlen, RT_NAME_MAX,
mp->parent.name,
mp->block_size,
mp->block_total_count,
mp->block_free_count,
suspend_thread_count);
show_wait_queue(&(mp->suspend_thread));
rt_kprintf("\n");
}
else
{
rt_kprintf("%-*.*s %04d %04d %04d %d\n",
maxlen, RT_NAME_MAX,
mp->parent.name,
mp->block_size,
mp->block_total_count,
mp->block_free_count,
suspend_thread_count);
maxlen, RT_NAME_MAX,
mp->parent.name,
mp->block_size,
mp->block_total_count,
mp->block_free_count,
suspend_thread_count);
}
}
}
}
while (next != (rt_list_t*)RT_NULL);
while (next != (rt_list_t *)RT_NULL);
return 0;
}
FINSH_FUNCTION_EXPORT(list_mempool, list memory pool in system)
MSH_CMD_EXPORT(list_mempool, list memory pool in system);
#endif
@ -743,18 +742,20 @@ long list_timer(void)
rt_ubase_t level;
list_get_next_t find_arg;
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t*)RT_NULL;
rt_list_t *next = (rt_list_t *)RT_NULL;
int maxlen;
const char *item_title = "timer";
list_find_init(&find_arg, RT_Object_Class_Timer, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
list_find_init(&find_arg, RT_Object_Class_Timer, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
maxlen = RT_NAME_MAX;
rt_kprintf("%-*.s periodic timeout flag\n", maxlen, item_title); object_split(maxlen);
rt_kprintf( " ---------- ---------- -----------\n");
do {
rt_kprintf("%-*.s periodic timeout flag\n", maxlen, item_title);
object_split(maxlen);
rt_kprintf(" ---------- ---------- -----------\n");
do
{
next = list_get_next(next, &find_arg);
{
int i;
@ -775,10 +776,10 @@ long list_timer(void)
timer = (struct rt_timer *)obj;
rt_kprintf("%-*.*s 0x%08x 0x%08x ",
maxlen, RT_NAME_MAX,
timer->parent.name,
timer->init_tick,
timer->timeout_tick);
maxlen, RT_NAME_MAX,
timer->parent.name,
timer->init_tick,
timer->timeout_tick);
if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
rt_kprintf("activated\n");
else
@ -787,13 +788,12 @@ long list_timer(void)
}
}
}
while (next != (rt_list_t*)RT_NULL);
while (next != (rt_list_t *)RT_NULL);
rt_kprintf("current tick:0x%08x\n", rt_tick_get());
return 0;
}
FINSH_FUNCTION_EXPORT(list_timer, list timer in system);
MSH_CMD_EXPORT(list_timer, list timer in system);
#ifdef RT_USING_DEVICE
@ -831,17 +831,18 @@ long list_device(void)
rt_ubase_t level;
list_get_next_t find_arg;
rt_list_t *obj_list[LIST_FIND_OBJ_NR];
rt_list_t *next = (rt_list_t*)RT_NULL;
rt_list_t *next = (rt_list_t *)RT_NULL;
int maxlen;
const char *item_title = "device";
list_find_init(&find_arg, RT_Object_Class_Device, obj_list, sizeof(obj_list)/sizeof(obj_list[0]));
list_find_init(&find_arg, RT_Object_Class_Device, obj_list, sizeof(obj_list) / sizeof(obj_list[0]));
maxlen = RT_NAME_MAX;
rt_kprintf("%-*.s type ref count\n", maxlen, item_title); object_split(maxlen);
rt_kprintf( " -------------------- ----------\n");
rt_kprintf("%-*.s type ref count\n", maxlen, item_title);
object_split(maxlen);
rt_kprintf(" -------------------- ----------\n");
do
{
next = list_get_next(next, &find_arg);
@ -864,31 +865,25 @@ long list_device(void)
device = (struct rt_device *)obj;
rt_kprintf("%-*.*s %-20s %-8d\n",
maxlen, RT_NAME_MAX,
device->parent.name,
(device->type <= RT_Device_Class_Unknown) ?
device_type_str[device->type] :
device_type_str[RT_Device_Class_Unknown],
device->ref_count);
maxlen, RT_NAME_MAX,
device->parent.name,
(device->type <= RT_Device_Class_Unknown) ?
device_type_str[device->type] :
device_type_str[RT_Device_Class_Unknown],
device->ref_count);
}
}
}
while (next != (rt_list_t*)RT_NULL);
while (next != (rt_list_t *)RT_NULL);
return 0;
}
FINSH_FUNCTION_EXPORT(list_device, list device in system);
MSH_CMD_EXPORT(list_device, list device in system);
#endif
long list(void)
{
#ifndef FINSH_USING_MSH_ONLY
struct finsh_syscall_item *syscall_item;
struct finsh_sysvar_item *sysvar_item;
#endif
rt_kprintf("--Function List:\n");
{
struct finsh_syscall *index;
@ -907,247 +902,8 @@ long list(void)
}
}
#ifndef FINSH_USING_MSH_ONLY
/* list syscall list */
syscall_item = global_syscall_list;
while (syscall_item != NULL)
{
rt_kprintf("[l] %s\n", syscall_item->syscall.name);
syscall_item = syscall_item->next;
}
rt_kprintf("--Variable List:\n");
{
struct finsh_sysvar *index;
for (index = _sysvar_table_begin;
index < _sysvar_table_end;
FINSH_NEXT_SYSVAR(index))
{
#ifdef FINSH_USING_DESCRIPTION
rt_kprintf("%-16s -- %s\n", index->name, index->desc);
#else
rt_kprintf("%s\n", index->name);
#endif
}
}
sysvar_item = global_sysvar_list;
while (sysvar_item != NULL)
{
rt_kprintf("[l] %s\n", sysvar_item->sysvar.name);
sysvar_item = sysvar_item->next;
}
#endif
return 0;
}
FINSH_FUNCTION_EXPORT(list, list all symbol in system)
#ifndef FINSH_USING_MSH_ONLY
static int str_is_prefix(const char *prefix, const char *str)
{
while ((*prefix) && (*prefix == *str))
{
prefix ++;
str ++;
}
if (*prefix == 0)
return 0;
return -1;
}
static int str_common(const char *str1, const char *str2)
{
const char *str = str1;
while ((*str != 0) && (*str2 != 0) && (*str == *str2))
{
str ++;
str2 ++;
}
return (str - str1);
}
void list_prefix(char *prefix)
{
struct finsh_syscall_item *syscall_item;
struct finsh_sysvar_item *sysvar_item;
rt_uint16_t func_cnt, var_cnt;
int length, min_length;
const char *name_ptr;
func_cnt = 0;
var_cnt = 0;
min_length = 0;
name_ptr = RT_NULL;
/* checks in system function call */
{
struct finsh_syscall *index;
for (index = _syscall_table_begin;
index < _syscall_table_end;
FINSH_NEXT_SYSCALL(index))
{
/* skip internal command */
if (str_is_prefix("__", index->name) == 0) continue;
if (str_is_prefix(prefix, index->name) == 0)
{
if (func_cnt == 0)
{
rt_kprintf("--function:\n");
if (*prefix != 0)
{
/* set name_ptr */
name_ptr = index->name;
/* set initial length */
min_length = strlen(name_ptr);
}
}
func_cnt ++;
if (*prefix != 0)
{
length = str_common(name_ptr, index->name);
if (length < min_length)
min_length = length;
}
#ifdef FINSH_USING_DESCRIPTION
rt_kprintf("%-16s -- %s\n", index->name, index->desc);
#else
rt_kprintf("%s\n", index->name);
#endif
}
}
}
/* checks in dynamic system function call */
syscall_item = global_syscall_list;
while (syscall_item != NULL)
{
if (str_is_prefix(prefix, syscall_item->syscall.name) == 0)
{
if (func_cnt == 0)
{
rt_kprintf("--function:\n");
if (*prefix != 0 && name_ptr == NULL)
{
/* set name_ptr */
name_ptr = syscall_item->syscall.name;
/* set initial length */
min_length = strlen(name_ptr);
}
}
func_cnt ++;
if (*prefix != 0)
{
length = str_common(name_ptr, syscall_item->syscall.name);
if (length < min_length)
min_length = length;
}
rt_kprintf("[l] %s\n", syscall_item->syscall.name);
}
syscall_item = syscall_item->next;
}
/* checks in system variable */
{
struct finsh_sysvar *index;
for (index = _sysvar_table_begin;
index < _sysvar_table_end;
FINSH_NEXT_SYSVAR(index))
{
if (str_is_prefix(prefix, index->name) == 0)
{
if (var_cnt == 0)
{
rt_kprintf("--variable:\n");
if (*prefix != 0 && name_ptr == NULL)
{
/* set name_ptr */
name_ptr = index->name;
/* set initial length */
min_length = strlen(name_ptr);
}
}
var_cnt ++;
if (*prefix != 0)
{
length = str_common(name_ptr, index->name);
if (length < min_length)
min_length = length;
}
#ifdef FINSH_USING_DESCRIPTION
rt_kprintf("%-16s -- %s\n", index->name, index->desc);
#else
rt_kprintf("%s\n", index->name);
#endif
}
}
}
/* checks in dynamic system variable */
sysvar_item = global_sysvar_list;
while (sysvar_item != NULL)
{
if (str_is_prefix(prefix, sysvar_item->sysvar.name) == 0)
{
if (var_cnt == 0)
{
rt_kprintf("--variable:\n");
if (*prefix != 0 && name_ptr == NULL)
{
/* set name_ptr */
name_ptr = sysvar_item->sysvar.name;
/* set initial length */
min_length = strlen(name_ptr);
}
}
var_cnt ++;
if (*prefix != 0)
{
length = str_common(name_ptr, sysvar_item->sysvar.name);
if (length < min_length)
min_length = length;
}
rt_kprintf("[v] %s\n", sysvar_item->sysvar.name);
}
sysvar_item = sysvar_item->next;
}
/* only one matched */
if (name_ptr != NULL)
{
rt_strncpy(prefix, name_ptr, min_length);
}
}
#endif
#if defined(FINSH_USING_SYMTAB) && !defined(FINSH_USING_MSH_ONLY)
static int dummy = 0;
FINSH_VAR_EXPORT(dummy, finsh_type_int, dummy variable for finsh)
#endif
MSH_CMD_EXPORT(list, list all symbol in system)
#endif /* RT_USING_FINSH */

View File

@ -11,239 +11,157 @@
#define __FINSH_H__
#include <rtthread.h>
#include "finsh_api.h"
/* -- the beginning of option -- */
#define FINSH_NAME_MAX 16 /* max length of identifier */
#define FINSH_NODE_MAX 16 /* max number of node */
#if defined(_MSC_VER)
#pragma section("FSymTab$f",read)
#endif
#define FINSH_HEAP_MAX 128 /* max length of heap */
#define FINSH_STRING_MAX 128 /* max length of string */
#define FINSH_VARIABLE_MAX 8 /* max number of variable */
typedef long (*syscall_func)(void);
#ifdef FINSH_USING_SYMTAB
#ifdef __TI_COMPILER_VERSION__
#define __TI_FINSH_EXPORT_FUNCTION(f) PRAGMA(DATA_SECTION(f,"FSymTab"))
#endif
#ifdef FINSH_USING_DESCRIPTION
#ifdef _MSC_VER
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
const char __fsym_##cmd##_name[] = #cmd; \
const char __fsym_##cmd##_desc[] = #desc; \
__declspec(allocate("FSymTab$f")) \
const struct finsh_syscall __fsym_##cmd = \
{ \
__fsym_##cmd##_name, \
__fsym_##cmd##_desc, \
(syscall_func)&name \
};
#pragma comment(linker, "/merge:FSymTab=mytext")
#define FINSH_STACK_MAX 64 /* max stack size */
#define FINSH_TEXT_MAX 128 /* max text segment size */
#elif defined(__TI_COMPILER_VERSION__)
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
__TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \
const char __fsym_##cmd##_name[] = #cmd; \
const char __fsym_##cmd##_desc[] = #desc; \
const struct finsh_syscall __fsym_##cmd = \
{ \
__fsym_##cmd##_name, \
__fsym_##cmd##_desc, \
(syscall_func)&name \
};
#define HEAP_ALIGNMENT 4 /* heap alignment */
#else
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
const char __fsym_##cmd##_name[] RT_SECTION(".rodata.name") = #cmd; \
const char __fsym_##cmd##_desc[] RT_SECTION(".rodata.name") = #desc; \
RT_USED const struct finsh_syscall __fsym_##cmd RT_SECTION("FSymTab")= \
{ \
__fsym_##cmd##_name, \
__fsym_##cmd##_desc, \
(syscall_func)&name \
};
#define FINSH_GET16(x) (*(x)) | (*((x)+1) << 8)
#define FINSH_GET32(x) (rt_ubase_t)(*(x)) | ((rt_ubase_t)*((x)+1) << 8) | \
((rt_ubase_t)*((x)+2) << 16) | ((rt_ubase_t)*((x)+3) << 24)
#endif
#else
#ifdef _MSC_VER
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
const char __fsym_##cmd##_name[] = #cmd; \
__declspec(allocate("FSymTab$f")) \
const struct finsh_syscall __fsym_##cmd = \
{ \
__fsym_##cmd##_name, \
(syscall_func)&name \
};
#pragma comment(linker, "/merge:FSymTab=mytext")
#define FINSH_SET16(x, v) \
do \
{ \
*(x) = (v) & 0x00ff; \
(*((x)+1)) = (v) >> 8; \
} while ( 0 )
#elif defined(__TI_COMPILER_VERSION__)
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
__TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \
const char __fsym_##cmd##_name[] = #cmd; \
const struct finsh_syscall __fsym_##cmd = \
{ \
__fsym_##cmd##_name, \
(syscall_func)&name \
};
#define FINSH_SET32(x, v) \
do \
{ \
*(x) = (rt_uint32_t)(v) & 0x000000ff; \
(*((x)+1)) = ((rt_uint32_t)(v) >> 8) & 0x000000ff; \
(*((x)+2)) = ((rt_uint32_t)(v) >> 16) & 0x000000ff; \
(*((x)+3)) = ((rt_uint32_t)(v) >> 24); \
} while ( 0 )
#else
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
const char __fsym_##cmd##_name[] = #cmd; \
RT_USED const struct finsh_syscall __fsym_##cmd RT_SECTION("FSymTab")= \
{ \
__fsym_##cmd##_name, \
(syscall_func)&name \
};
/* -- the end of option -- */
/* std header file */
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#define FINSH_VERSION_MAJOR 1
#define FINSH_VERSION_MINOR 0
#endif
#endif /* end of FINSH_USING_DESCRIPTION */
#endif /* end of FINSH_USING_SYMTAB */
/**
* @addtogroup finsh
* @ingroup finsh
*
* This macro exports a system function to finsh shell.
*
* @param name the name of function.
* @param desc the description of function, which will show in help.
*/
/*@{*/
#define FINSH_ERROR_OK 0 /**< No error */
#define FINSH_ERROR_INVALID_TOKEN 1 /**< Invalid token */
#define FINSH_ERROR_EXPECT_TYPE 2 /**< Expect a type */
#define FINSH_ERROR_UNKNOWN_TYPE 3 /**< Unknown type */
#define FINSH_ERROR_VARIABLE_EXIST 4 /**< Variable exist */
#define FINSH_ERROR_EXPECT_OPERATOR 5 /**< Expect a operator */
#define FINSH_ERROR_MEMORY_FULL 6 /**< Memory full */
#define FINSH_ERROR_UNKNOWN_OP 7 /**< Unknown operator */
#define FINSH_ERROR_UNKNOWN_NODE 8 /**< Unknown node */
#define FINSH_ERROR_EXPECT_CHAR 9 /**< Expect a character */
#define FINSH_ERROR_UNEXPECT_END 10 /**< Unexpect end */
#define FINSH_ERROR_UNKNOWN_TOKEN 11 /**< Unknown token */
#define FINSH_ERROR_NO_FLOAT 12 /**< Float not supported */
#define FINSH_ERROR_UNKNOWN_SYMBOL 13 /**< Unknown symbol */
#define FINSH_ERROR_NULL_NODE 14 /**< Null node */
/*@}*/
#define FINSH_FUNCTION_EXPORT(name, desc) \
FINSH_FUNCTION_EXPORT_CMD(name, name, desc)
/**
* @ingroup finsh
*
* This macro exports a system function with an alias name to finsh shell.
*
* @param name the name of function.
* @param alias the alias name of function.
* @param desc the description of function, which will show in help.
*/
#define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc) \
FINSH_FUNCTION_EXPORT_CMD(name, alias, desc)
/**
* @ingroup finsh
*
* This macro exports a command to module shell.
*
* @param command the name of command.
* @param desc the description of command, which will show in help.
*/
#define MSH_CMD_EXPORT(command, desc) \
FINSH_FUNCTION_EXPORT_CMD(command, __cmd_##command, desc)
#define MSH_CMD_EXPORT_ALIAS(command, alias, desc) \
FINSH_FUNCTION_EXPORT_ALIAS(command, __cmd_##alias, desc)
/* system call table */
struct finsh_syscall
{
const char *name; /* the name of system call */
#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
const char *desc; /* description of system call */
#endif
syscall_func func; /* the function address of system call */
};
/* system call item */
struct finsh_syscall_item
{
struct finsh_syscall_item* next; /* next item */
struct finsh_syscall_item *next; /* next item */
struct finsh_syscall syscall; /* syscall */
};
extern struct finsh_syscall_item *global_syscall_list;
/* system variable table */
struct finsh_sysvar
{
const char* name; /* the name of variable */
#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
const char* desc; /* description of system variable */
#endif
uint8_t type; /* the type of variable */
void* var ; /* the address of variable */
};
extern struct finsh_syscall_item *global_syscall_list;
extern struct finsh_syscall *_syscall_table_begin, *_syscall_table_end;
#if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__))
struct finsh_syscall* finsh_syscall_next(struct finsh_syscall* call);
struct finsh_sysvar* finsh_sysvar_next(struct finsh_sysvar* call);
#define FINSH_NEXT_SYSCALL(index) index=finsh_syscall_next(index)
#define FINSH_NEXT_SYSVAR(index) index=finsh_sysvar_next(index)
struct finsh_syscall *finsh_syscall_next(struct finsh_syscall *call);
#define FINSH_NEXT_SYSCALL(index) index=finsh_syscall_next(index)
#else
#define FINSH_NEXT_SYSCALL(index) index++
#define FINSH_NEXT_SYSVAR(index) index++
#define FINSH_NEXT_SYSCALL(index) index++
#endif
/* system variable item */
struct finsh_sysvar_item
{
struct finsh_sysvar_item *next; /* next item */
struct finsh_sysvar sysvar; /* system variable */
};
extern struct finsh_sysvar *_sysvar_table_begin, *_sysvar_table_end;
extern struct finsh_sysvar_item* global_sysvar_list;
/* find out system call, which should be implemented in user program */
struct finsh_syscall *finsh_syscall_lookup(const char *name);
/* find out system variable, which should be implemented in user program */
struct finsh_sysvar* finsh_sysvar_lookup(const char* name);
struct finsh_token
{
char eof;
char replay;
int position;
uint8_t current_token;
union {
char char_value;
int int_value;
long long_value;
} value;
uint8_t string[FINSH_STRING_MAX];
uint8_t* line;
};
#define FINSH_IDTYPE_VAR 0x01
#define FINSH_IDTYPE_SYSVAR 0x02
#define FINSH_IDTYPE_SYSCALL 0x04
#define FINSH_IDTYPE_ADDRESS 0x08
struct finsh_node
{
uint8_t node_type; /* node node_type */
uint8_t data_type; /* node data node_type */
uint8_t idtype; /* id node information */
union { /* value node */
char char_value;
short short_value;
int int_value;
long long_value;
void* ptr;
} value;
union
{
/* point to variable identifier or function identifier */
struct finsh_var *var;
struct finsh_sysvar *sysvar;
struct finsh_syscall*syscall;
}id;
/* sibling and child node */
struct finsh_node *sibling, *child;
};
struct finsh_parser
{
uint8_t* parser_string;
struct finsh_token token;
struct finsh_node* root;
};
/**
* @ingroup finsh
*
* The basic data type in finsh shell
*/
enum finsh_type {
finsh_type_unknown = 0, /**< unknown data type */
finsh_type_void, /**< void */
finsh_type_voidp, /**< void pointer */
finsh_type_char, /**< char */
finsh_type_uchar, /**< unsigned char */
finsh_type_charp, /**< char pointer */
finsh_type_short, /**< short */
finsh_type_ushort, /**< unsigned short */
finsh_type_shortp, /**< short pointer */
finsh_type_int, /**< int */
finsh_type_uint, /**< unsigned int */
finsh_type_intp, /**< int pointer */
finsh_type_long, /**< long */
finsh_type_ulong, /**< unsigned long */
finsh_type_longp /**< long pointer */
};
/* init finsh environment */
int finsh_init(struct finsh_parser* parser);
/* flush finsh node, text segment */
int finsh_flush(struct finsh_parser* parser);
/* reset all of finsh */
int finsh_reset(struct finsh_parser* parser);
#ifdef RT_USING_DEVICE
void finsh_set_device(const char* device_name);
void finsh_set_device(const char *device_name);
#endif
/* run finsh parser to generate abstract synatx tree */
void finsh_parser_run (struct finsh_parser* parser, const unsigned char* string);
/* run compiler to compile abstract syntax tree */
int finsh_compiler_run(struct finsh_node* node);
/* run finsh virtual machine */
void finsh_vm_run(void);
/* get variable value */
struct finsh_var* finsh_var_lookup(const char* name);
/* get bottom value of stack */
long finsh_stack_bottom(void);
/* get error number of finsh */
uint8_t finsh_errno(void);
/* get error string */
const char* finsh_error_string(uint8_t type);
#ifdef RT_USING_HEAP
/**
* @ingroup finsh
*
* This function appends a system call to finsh runtime environment
* @param name the name of system call
* @param func the function pointer of system call
*/
void finsh_syscall_append(const char* name, syscall_func func);
/**
* @ingroup finsh
*
* This function appends a system variable to finsh runtime environment
* @param name the name of system variable
* @param type the data type of system variable
* @param addr the address of system variable
*/
void finsh_sysvar_append(const char* name, uint8_t type, void* addr);
#endif
#endif

View File

@ -1,218 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#ifndef FINSH_API_H__
#define FINSH_API_H__
#if defined(_MSC_VER)
#pragma section("FSymTab$f",read)
#pragma section("VSymTab",read)
#endif
typedef long (*syscall_func)(void);
/* system call table */
struct finsh_syscall
{
const char* name; /* the name of system call */
#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
const char* desc; /* description of system call */
#endif
syscall_func func; /* the function address of system call */
};
extern struct finsh_syscall *_syscall_table_begin, *_syscall_table_end;
/* find out system call, which should be implemented in user program */
struct finsh_syscall* finsh_syscall_lookup(const char* name);
#ifdef FINSH_USING_SYMTAB
#ifdef __TI_COMPILER_VERSION__
#define __TI_FINSH_EXPORT_FUNCTION(f) PRAGMA(DATA_SECTION(f,"FSymTab"))
#define __TI_FINSH_EXPORT_VAR(v) PRAGMA(DATA_SECTION(v,"VSymTab"))
#endif
#ifdef FINSH_USING_DESCRIPTION
#ifdef _MSC_VER
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
const char __fsym_##cmd##_name[] = #cmd; \
const char __fsym_##cmd##_desc[] = #desc; \
__declspec(allocate("FSymTab$f")) \
const struct finsh_syscall __fsym_##cmd = \
{ \
__fsym_##cmd##_name, \
__fsym_##cmd##_desc, \
(syscall_func)&name \
};
#pragma comment(linker, "/merge:FSymTab=mytext")
#define FINSH_VAR_EXPORT(name, type, desc) \
const char __vsym_##name##_name[] = #name; \
const char __vsym_##name##_desc[] = #desc; \
__declspec(allocate("VSymTab")) \
const struct finsh_sysvar __vsym_##name = \
{ \
__vsym_##name##_name, \
__vsym_##name##_desc, \
type, \
(void*)&name \
};
#elif defined(__TI_COMPILER_VERSION__)
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
__TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \
const char __fsym_##cmd##_name[] = #cmd; \
const char __fsym_##cmd##_desc[] = #desc; \
const struct finsh_syscall __fsym_##cmd = \
{ \
__fsym_##cmd##_name, \
__fsym_##cmd##_desc, \
(syscall_func)&name \
};
#define FINSH_VAR_EXPORT(name, type, desc) \
__TI_FINSH_EXPORT_VAR(__vsym_##name); \
const char __vsym_##name##_name[] = #name; \
const char __vsym_##name##_desc[] = #desc; \
const struct finsh_sysvar __vsym_##name = \
{ \
__vsym_##name##_name, \
__vsym_##name##_desc, \
type, \
(void*)&name \
};
#else
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
const char __fsym_##cmd##_name[] RT_SECTION(".rodata.name") = #cmd; \
const char __fsym_##cmd##_desc[] RT_SECTION(".rodata.name") = #desc; \
RT_USED const struct finsh_syscall __fsym_##cmd RT_SECTION("FSymTab")= \
{ \
__fsym_##cmd##_name, \
__fsym_##cmd##_desc, \
(syscall_func)&name \
};
#define FINSH_VAR_EXPORT(name, type, desc) \
const char __vsym_##name##_name[] RT_SECTION(".rodata.name") = #name; \
const char __vsym_##name##_desc[] RT_SECTION(".rodata.name") = #desc; \
RT_USED const struct finsh_sysvar __vsym_##name RT_SECTION("VSymTab")= \
{ \
__vsym_##name##_name, \
__vsym_##name##_desc, \
type, \
(void*)&name \
};
#endif
#else
#ifdef _MSC_VER
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
const char __fsym_##cmd##_name[] = #cmd; \
__declspec(allocate("FSymTab$f")) \
const struct finsh_syscall __fsym_##cmd = \
{ \
__fsym_##cmd##_name, \
(syscall_func)&name \
};
#pragma comment(linker, "/merge:FSymTab=mytext")
#define FINSH_VAR_EXPORT(name, type, desc) \
const char __vsym_##name##_name[] = #name; \
__declspec(allocate("VSymTab")) const struct finsh_sysvar __vsym_##name = \
{ \
__vsym_##name##_name, \
type, \
(void*)&name \
};
#elif defined(__TI_COMPILER_VERSION__)
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
__TI_FINSH_EXPORT_FUNCTION(__fsym_##cmd); \
const char __fsym_##cmd##_name[] = #cmd; \
const struct finsh_syscall __fsym_##cmd = \
{ \
__fsym_##cmd##_name, \
(syscall_func)&name \
};
#define FINSH_VAR_EXPORT(name, type, desc) \
__TI_FINSH_EXPORT_VAR(__vsym_##name); \
const char __vsym_##name##_name[] = #name; \
const struct finsh_sysvar __vsym_##name = \
{ \
__vsym_##name##_name, \
type, \
(void*)&name \
};
#else
#define FINSH_FUNCTION_EXPORT_CMD(name, cmd, desc) \
const char __fsym_##cmd##_name[] = #cmd; \
RT_USED const struct finsh_syscall __fsym_##cmd RT_SECTION("FSymTab")= \
{ \
__fsym_##cmd##_name, \
(syscall_func)&name \
};
#define FINSH_VAR_EXPORT(name, type, desc) \
const char __vsym_##name##_name[] = #name; \
RT_USED const struct finsh_sysvar __vsym_##name RT_SECTION("VSymTab")= \
{ \
__vsym_##name##_name, \
type, \
(void*)&name \
};
#endif
#endif /* end of FINSH_USING_DESCRIPTION */
#endif /* end of FINSH_USING_SYMTAB */
/**
* @ingroup finsh
*
* This macro exports a system function to finsh shell.
*
* @param name the name of function.
* @param desc the description of function, which will show in help.
*/
#define FINSH_FUNCTION_EXPORT(name, desc) \
FINSH_FUNCTION_EXPORT_CMD(name, name, desc)
/**
* @ingroup finsh
*
* This macro exports a system function with an alias name to finsh shell.
*
* @param name the name of function.
* @param alias the alias name of function.
* @param desc the description of function, which will show in help.
*/
#define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc) \
FINSH_FUNCTION_EXPORT_CMD(name, alias, desc)
/**
* @ingroup finsh
*
* This macro exports a command to module shell.
*
* @param command the name of command.
* @param desc the description of command, which will show in help.
*/
#ifdef FINSH_USING_MSH
#define MSH_CMD_EXPORT(command, desc) \
FINSH_FUNCTION_EXPORT_CMD(command, __cmd_##command, desc)
#define MSH_CMD_EXPORT_ALIAS(command, alias, desc) \
FINSH_FUNCTION_EXPORT_ALIAS(command, __cmd_##alias, desc)
#else
#define MSH_CMD_EXPORT(command, desc)
#define MSH_CMD_EXPORT_ALIAS(command, alias, desc)
#endif
#endif

View File

@ -1,918 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#include <finsh.h>
#include "finsh_node.h"
#include "finsh_error.h"
#include "finsh_var.h"
#include "finsh_ops.h"
union finsh_value* finsh_compile_sp; /* stack pointer */
uint8_t* finsh_compile_pc; /* PC */
#define finsh_code_byte(x) do { *finsh_compile_pc = (x); finsh_compile_pc ++; } while(0)
#define finsh_code_word(x) do { FINSH_SET16(finsh_compile_pc, x); finsh_compile_pc +=2; } while(0)
#define finsh_code_dword(x) do { FINSH_SET32(finsh_compile_pc, x); finsh_compile_pc +=4; } while(0)
static int finsh_compile(struct finsh_node* node)
{
if (node != NULL)
{
/* compile child node */
if (finsh_node_child(node) != NULL)
finsh_compile(finsh_node_child(node));
/* compile current node */
switch (node->node_type)
{
case FINSH_NODE_ID:
{
/* identifier::syscall */
if (node->idtype & FINSH_IDTYPE_SYSCALL)
{
/* load address */
finsh_code_byte(FINSH_OP_LD_DWORD);
finsh_code_dword((long)node->id.syscall->func);
}
/* identifier::sysvar */
else if (node->idtype & FINSH_IDTYPE_SYSVAR)
{
struct finsh_sysvar* sysvar;
sysvar = node->id.sysvar;
if (sysvar != NULL)
{
switch (sysvar->type)
{
case finsh_type_char:
case finsh_type_uchar:
if (node->idtype & FINSH_IDTYPE_ADDRESS)
{
/* load address */
finsh_code_byte(FINSH_OP_LD_DWORD);
}
else
{
/* load value */
finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
}
finsh_code_dword((long)(sysvar->var));
break;
case finsh_type_short:
case finsh_type_ushort:
if (node->idtype & FINSH_IDTYPE_ADDRESS)
{
/* load address */
finsh_code_byte(FINSH_OP_LD_DWORD);
}
else
{
/* load value */
finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
}
finsh_code_dword((long)(sysvar->var));
break;
case finsh_type_int:
case finsh_type_uint:
case finsh_type_long:
case finsh_type_ulong:
case finsh_type_charp:
case finsh_type_shortp:
case finsh_type_intp:
case finsh_type_longp:
if (node->idtype & FINSH_IDTYPE_ADDRESS)
{
/* load address */
finsh_code_byte(FINSH_OP_LD_DWORD);
}
else
{
/* load value */
finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
}
finsh_code_dword((long)(sysvar->var));
break;
}
}
}
/* identifier::var */
else
{
struct finsh_var* var;
var = node->id.var;
if (var != NULL)
{
switch (var->type)
{
case finsh_type_char:
case finsh_type_uchar:
if (node->idtype & FINSH_IDTYPE_ADDRESS)
{
/* load address */
finsh_code_byte(FINSH_OP_LD_DWORD);
}
else
{
/* load value */
finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
}
finsh_code_dword((long)&(var->value.char_value));
break;
case finsh_type_short:
case finsh_type_ushort:
if (node->idtype & FINSH_IDTYPE_ADDRESS)
{
/* load address */
finsh_code_byte(FINSH_OP_LD_DWORD);
}
else
{
/* load value */
finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
}
finsh_code_dword((long)&(var->value.short_value));
break;
case finsh_type_int:
case finsh_type_uint:
case finsh_type_long:
case finsh_type_ulong:
case finsh_type_charp:
case finsh_type_shortp:
case finsh_type_intp:
case finsh_type_longp:
if (node->idtype & FINSH_IDTYPE_ADDRESS)
{
/* load address */
finsh_code_byte(FINSH_OP_LD_DWORD);
}
else
{
/* load value */
finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
}
finsh_code_dword((long)&(var->value.long_value));
break;
}
}
}
}
break;
/* load const */
case FINSH_NODE_VALUE_CHAR:
finsh_code_byte(FINSH_OP_LD_BYTE);
finsh_code_byte(node->value.char_value);
break;
case FINSH_NODE_VALUE_INT:
case FINSH_NODE_VALUE_LONG:
finsh_code_byte(FINSH_OP_LD_DWORD);
finsh_code_dword(node->value.long_value);
break;
case FINSH_NODE_VALUE_NULL:
case FINSH_NODE_VALUE_STRING:
finsh_code_byte(FINSH_OP_LD_DWORD);
finsh_code_dword((rt_ubase_t)node->value.ptr);
break;
/* arithmetic operation */
case FINSH_NODE_SYS_ADD:
if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_ADD_BYTE);
else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_ADD_WORD);
else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_ADD_DWORD);
break;
case FINSH_NODE_SYS_SUB:
if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_SUB_BYTE);
else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_SUB_WORD);
else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_SUB_DWORD);
break;
case FINSH_NODE_SYS_MUL:
if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_MUL_BYTE);
else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_MUL_WORD);
else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_MUL_DWORD);
break;
case FINSH_NODE_SYS_DIV:
if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_DIV_BYTE);
else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_DIV_WORD);
else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_DIV_DWORD);
break;
case FINSH_NODE_SYS_MOD:
if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_MOD_BYTE);
else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_MOD_WORD);
else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_MOD_DWORD);
break;
/* bit operation */
case FINSH_NODE_SYS_AND:
if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_AND_BYTE);
else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_AND_WORD);
else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_AND_DWORD);
break;
case FINSH_NODE_SYS_OR:
if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_OR_BYTE);
else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_OR_WORD);
else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_OR_DWORD);
break;
case FINSH_NODE_SYS_XOR:
if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_XOR_BYTE);
else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_XOR_WORD);
else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_XOR_DWORD);
break;
case FINSH_NODE_SYS_BITWISE:
if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_BITWISE_BYTE);
else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_BITWISE_WORD);
else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_BITWISE_DWORD);
break;
case FINSH_NODE_SYS_SHL:
if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_SHL_BYTE);
else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_SHL_WORD);
else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_SHL_DWORD);
break;
case FINSH_NODE_SYS_SHR:
if (node->data_type == FINSH_DATA_TYPE_BYTE) finsh_code_byte(FINSH_OP_SHR_BYTE);
else if (node->data_type == FINSH_DATA_TYPE_WORD) finsh_code_byte(FINSH_OP_SHR_WORD);
else if (node->data_type == FINSH_DATA_TYPE_DWORD) finsh_code_byte(FINSH_OP_SHR_DWORD);
break;
/* syscall */
case FINSH_NODE_SYS_FUNC:
{
int parameters;
struct finsh_node* sibling;
parameters = 0;
if (finsh_node_child(node) != NULL)
{
sibling = finsh_node_sibling(finsh_node_child(node));
while (sibling != NULL)
{
parameters ++;
sibling = finsh_node_sibling(sibling);
}
/* load address of function */
// finsh_code_dword((long)&(node->var->value.ptr));
/* syscall parameters */
finsh_code_byte(FINSH_OP_SYSCALL);
finsh_code_byte(parameters);
}
}
break;
/* assign expression */
case FINSH_NODE_SYS_ASSIGN:
if (finsh_node_child(node) && finsh_node_child(node)->node_type == FINSH_NODE_ID)
{
switch (finsh_node_child(node)->data_type)
{
case FINSH_DATA_TYPE_BYTE:
finsh_code_byte(FINSH_OP_ST_BYTE);
/* load value again */
finsh_code_byte(FINSH_OP_LD_VALUE_BYTE_STACK);
break;
case FINSH_DATA_TYPE_WORD:
finsh_code_byte(FINSH_OP_ST_WORD);
/* load value again */
finsh_code_byte(FINSH_OP_LD_VALUE_WORD_STACK);
break;
case FINSH_DATA_TYPE_DWORD:
finsh_code_byte(FINSH_OP_ST_DWORD);
/* load value again */
finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
break;
default:
finsh_error_set(FINSH_ERROR_UNKNOWN_TYPE);
}
}
else if (finsh_node_child(node)->node_type == FINSH_NODE_SYS_GETVALUE)
{
switch ((finsh_node_child(node)->data_type) & 0x0F)
{
case FINSH_DATA_TYPE_BYTE:
finsh_code_byte(FINSH_OP_ST_BYTE);
/* load value again */
finsh_code_byte(FINSH_OP_LD_VALUE_BYTE_STACK);
break;
case FINSH_DATA_TYPE_WORD:
finsh_code_byte(FINSH_OP_ST_WORD);
/* load value again */
finsh_code_byte(FINSH_OP_LD_VALUE_WORD_STACK);
break;
case FINSH_DATA_TYPE_DWORD:
finsh_code_byte(FINSH_OP_ST_DWORD);
/* load value again */
finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
break;
default:
finsh_error_set(FINSH_ERROR_UNKNOWN_TYPE);
}
}
break;
/* pre-increase */
case FINSH_NODE_SYS_PREINC:
if (finsh_node_child(node) && finsh_node_child(node)->node_type == FINSH_NODE_ID)
{
struct finsh_var* var;
var = finsh_node_child(node)->id.var;
/* ld_dword &id */
// finsh_code_byte(FINSH_OP_LD_DWORD);
switch (node->data_type)
{
case FINSH_DATA_TYPE_BYTE:
/* address */
// finsh_code_dword((long)&(var->value.char_value));
/* ld_value_byte &id */
finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
finsh_code_dword((long)&(var->value.char_value));
/* ld_byte 1 */
finsh_code_byte(FINSH_OP_LD_BYTE);
finsh_code_byte(1);
/* add_byte */
finsh_code_byte(FINSH_OP_ADD_BYTE);
/* st_byte */
finsh_code_byte(FINSH_OP_ST_BYTE);
/* load value again */
finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
break;
case FINSH_DATA_TYPE_WORD:
/* address */
// finsh_code_dword((long)&(var->value.short_value));
/* ld_value_word &id */
finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
finsh_code_dword((long)&(var->value.short_value));
/* ld_word 1 */
finsh_code_byte(FINSH_OP_LD_WORD);
finsh_code_word(1);
/* add_word */
finsh_code_byte(FINSH_OP_ADD_WORD);
/* st_word */
finsh_code_byte(FINSH_OP_ST_WORD);
/* load value again */
finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
break;
case FINSH_DATA_TYPE_DWORD:
/* address */
// finsh_code_dword((long)&(var->value.long_value));
/* ld_dword &id */
finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
finsh_code_dword((long)&(var->value.long_value));
/* ld_dword 1 */
finsh_code_byte(FINSH_OP_LD_DWORD);
finsh_code_dword(1);
/* add_dword */
finsh_code_byte(FINSH_OP_ADD_DWORD);
/* st_dword */
finsh_code_byte(FINSH_OP_ST_DWORD);
/* load value again */
finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
break;
}
}
break;
/* pre-decrease */
case FINSH_NODE_SYS_PREDEC:
if (finsh_node_child(node) && finsh_node_child(node)->node_type == FINSH_NODE_ID)
{
struct finsh_var* var;
var = finsh_node_child(node)->id.var;
/* ld_dword &id */
// finsh_code_byte(FINSH_OP_LD_DWORD);
switch (node->data_type)
{
case FINSH_DATA_TYPE_BYTE:
/* address */
// finsh_code_dword((long)&(var->value.char_value));
/* ld_value_byte &id */
finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
finsh_code_dword((long)&(var->value.char_value));
/* ld_byte 1 */
finsh_code_byte(FINSH_OP_LD_BYTE);
finsh_code_byte(1);
/* add_byte */
finsh_code_byte(FINSH_OP_SUB_BYTE);
/* st_byte */
finsh_code_byte(FINSH_OP_ST_BYTE);
/* load value again */
finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
break;
case FINSH_DATA_TYPE_WORD:
/* address */
// finsh_code_dword((long)&(var->value.short_value));
/* ld_value_word &id */
finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
finsh_code_dword((long)&(var->value.short_value));
/* ld_word 1 */
finsh_code_byte(FINSH_OP_LD_WORD);
finsh_code_word(1);
/* add_word */
finsh_code_byte(FINSH_OP_SUB_WORD);
/* st_word */
finsh_code_byte(FINSH_OP_ST_WORD);
/* load value again */
finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
break;
case FINSH_DATA_TYPE_DWORD:
/* address */
// finsh_code_dword((long)&(var->value.long_value));
/* ld_dword &id */
finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
finsh_code_dword((long)&(var->value.long_value));
/* ld_dword 1 */
finsh_code_byte(FINSH_OP_LD_DWORD);
finsh_code_dword(1);
/* add_dword */
finsh_code_byte(FINSH_OP_SUB_DWORD);
/* st_dword */
finsh_code_byte(FINSH_OP_ST_DWORD);
/* load value again */
finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
break;
}
}
break;
/* increase */
case FINSH_NODE_SYS_INC:
if (finsh_node_child(node) && finsh_node_child(node)->node_type == FINSH_NODE_ID)
{
struct finsh_var* var;
var = finsh_node_child(node)->id.var;
switch (node->data_type)
{
case FINSH_DATA_TYPE_BYTE:
/* ld_value_byte &id */
// finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
// finsh_code_dword((long)&(var->value.char_value));
/* ld_dword &id */
finsh_code_byte(FINSH_OP_LD_DWORD);
finsh_code_dword((long)&(var->value.char_value));
/* ld_value_byte &id */
finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
finsh_code_dword((long)&(var->value.char_value));
/* ld_byte 1 */
finsh_code_byte(FINSH_OP_LD_BYTE);
finsh_code_byte(1);
/* add_byte */
finsh_code_byte(FINSH_OP_ADD_BYTE);
/* get byte */
finsh_code_byte(FINSH_OP_ST_BYTE);
/* pop */
finsh_code_byte(FINSH_OP_POP);
break;
case FINSH_DATA_TYPE_WORD:
/* ld_value_word &id */
// finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
// finsh_code_dword((long)&(var->value.short_value));
/* ld_dword &id */
finsh_code_byte(FINSH_OP_LD_DWORD);
finsh_code_dword((long)&(var->value.short_value));
/* ld_value_word &id */
finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
finsh_code_dword((long)&(var->value.short_value));
/* ld_word 1 */
finsh_code_byte(FINSH_OP_LD_WORD);
finsh_code_word(1);
/* add_byte */
finsh_code_byte(FINSH_OP_ADD_WORD);
/* get byte */
finsh_code_byte(FINSH_OP_ST_WORD);
/* pop */
finsh_code_byte(FINSH_OP_POP);
break;
case FINSH_DATA_TYPE_DWORD:
/* ld_value_dword &id */
// finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
// finsh_code_dword((long)&(var->value.long_value));
/* ld_dword &id */
finsh_code_byte(FINSH_OP_LD_DWORD);
finsh_code_dword((long)&(var->value.long_value));
/* ld_value_dword &id */
finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
finsh_code_dword((long)&(var->value.long_value));
/* ld_dword 1 */
finsh_code_byte(FINSH_OP_LD_DWORD);
finsh_code_dword(1);
/* add_byte */
finsh_code_byte(FINSH_OP_ADD_DWORD);
/* get byte */
finsh_code_byte(FINSH_OP_ST_DWORD);
/* pop */
finsh_code_byte(FINSH_OP_POP);
break;
}
}
break;
/* decrease */
case FINSH_NODE_SYS_DEC:
if (finsh_node_child(node) && finsh_node_child(node)->node_type == FINSH_NODE_ID)
{
struct finsh_var* var;
var = finsh_node_child(node)->id.var;
switch (node->data_type)
{
case FINSH_DATA_TYPE_BYTE:
/* ld_value_byte &id */
// finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
// finsh_code_dword((long)&(var->value.char_value));
/* ld_dword &id */
finsh_code_byte(FINSH_OP_LD_DWORD);
finsh_code_dword((long)&(var->value.char_value));
/* ld_value_byte &id */
finsh_code_byte(FINSH_OP_LD_VALUE_BYTE);
finsh_code_dword((long)&(var->value.char_value));
/* ld_byte 1 */
finsh_code_byte(FINSH_OP_LD_BYTE);
finsh_code_byte(1);
/* add_byte */
finsh_code_byte(FINSH_OP_SUB_BYTE);
/* get byte */
finsh_code_byte(FINSH_OP_ST_BYTE);
/* pop */
finsh_code_byte(FINSH_OP_POP);
break;
case FINSH_DATA_TYPE_WORD:
/* ld_value_word &id */
// finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
// finsh_code_dword((long)&(var->value.short_value));
/* ld_dword &id */
finsh_code_byte(FINSH_OP_LD_DWORD);
finsh_code_dword((long)&(var->value.short_value));
/* ld_value_word &id */
finsh_code_byte(FINSH_OP_LD_VALUE_WORD);
finsh_code_dword((long)&(var->value.short_value));
/* ld_word 1 */
finsh_code_byte(FINSH_OP_LD_WORD);
finsh_code_word(1);
/* add_byte */
finsh_code_byte(FINSH_OP_SUB_WORD);
/* get byte */
finsh_code_byte(FINSH_OP_ST_WORD);
/* pop */
finsh_code_byte(FINSH_OP_POP);
break;
case FINSH_DATA_TYPE_DWORD:
/* ld_value_dword &id */
// finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
// finsh_code_dword((long)&(var->value.long_value));
/* ld_dword &id */
finsh_code_byte(FINSH_OP_LD_DWORD);
finsh_code_dword((long)&(var->value.long_value));
/* ld_value_dword &id */
finsh_code_byte(FINSH_OP_LD_VALUE_DWORD);
finsh_code_dword((long)&(var->value.long_value));
/* ld_dword 1 */
finsh_code_byte(FINSH_OP_LD_DWORD);
finsh_code_dword(1);
/* add_byte */
finsh_code_byte(FINSH_OP_SUB_DWORD);
/* get byte */
finsh_code_byte(FINSH_OP_ST_DWORD);
/* pop */
finsh_code_byte(FINSH_OP_POP);
break;
}
}
break;
case FINSH_NODE_SYS_NULL:
finsh_code_dword(0);
break;
case FINSH_NODE_SYS_GETVALUE:
if (node->idtype & FINSH_IDTYPE_ADDRESS)
{
/* nothing will be generated */
}
else
{
switch (node->data_type)
{
case FINSH_DATA_TYPE_BYTE:
finsh_code_byte(FINSH_OP_LD_VALUE_BYTE_STACK);
break;
case FINSH_DATA_TYPE_WORD:
finsh_code_byte(FINSH_OP_LD_VALUE_WORD_STACK);
break;
case FINSH_DATA_TYPE_DWORD:
finsh_code_byte(FINSH_OP_LD_VALUE_DWORD_STACK);
break;
default:
break;
}
}
break;
case FINSH_NODE_SYS_GETADDR:
/* nothing will be generated */
break;
default:
finsh_error_set(FINSH_ERROR_UNKNOWN_NODE);
break;
}
/* compile sibling node */
if (finsh_node_sibling(node) != NULL)
finsh_compile(finsh_node_sibling(node));
}
return 0;
}
static int finsh_type_check(struct finsh_node* node, uint8_t is_addr)
{
if (node != NULL)
{
/* address & value */
if (node->node_type == FINSH_NODE_SYS_ASSIGN ||
node->node_type == FINSH_NODE_SYS_PREINC ||
node->node_type == FINSH_NODE_SYS_PREDEC ||
node->node_type == FINSH_NODE_SYS_GETADDR)
{
/* address */
finsh_type_check(finsh_node_child(node), FINSH_IDTYPE_ADDRESS);
}
else if (node->node_type == FINSH_NODE_SYS_GETVALUE && is_addr)
{
/* change the attribute of getvalue in left expr */
finsh_type_check(finsh_node_child(node), 0);
}
else
{
/* transfer 'av' to child node */
finsh_type_check(finsh_node_child(node), is_addr);
}
/* always does not load address in sibling */
finsh_type_check(finsh_node_sibling(node), FINSH_NODE_VALUE);
/** set attribute of current node */
/* make sure the current node is address or value */
if (node->idtype != FINSH_IDTYPE_SYSCALL) node->idtype |= is_addr;
if (finsh_node_child(node) != NULL)
{
node->data_type = finsh_node_child(node)->data_type;
return 0;
}
if (node->node_type == FINSH_NODE_ID)
{
if (node->idtype & FINSH_IDTYPE_VAR)
{
struct finsh_var* var;
var = node->id.var;
if (var != NULL)
{
switch (var->type)
{
case finsh_type_void:
node->data_type = FINSH_DATA_TYPE_VOID;
break;
case finsh_type_char:
case finsh_type_uchar:
node->data_type = FINSH_DATA_TYPE_BYTE;
break;
case finsh_type_short:
case finsh_type_ushort:
node->data_type = FINSH_DATA_TYPE_WORD;
break;
case finsh_type_int:
case finsh_type_uint:
case finsh_type_long:
case finsh_type_ulong:
node->data_type = FINSH_DATA_TYPE_DWORD;
break;
case finsh_type_charp:
case finsh_type_voidp:
case finsh_type_shortp:
case finsh_type_intp:
case finsh_type_longp:
node->data_type = FINSH_DATA_TYPE_DWORD;
break;
default:
finsh_error_set(FINSH_ERROR_UNKNOWN_TYPE);
break;
}
}
}
else if (node->idtype & FINSH_IDTYPE_SYSVAR)
{
struct finsh_sysvar *sysvar;
sysvar = node->id.sysvar;
if (sysvar != NULL)
{
switch (sysvar->type)
{
case finsh_type_void:
node->data_type = FINSH_DATA_TYPE_VOID;
break;
case finsh_type_char:
case finsh_type_uchar:
node->data_type = FINSH_DATA_TYPE_BYTE;
break;
case finsh_type_short:
case finsh_type_ushort:
node->data_type = FINSH_DATA_TYPE_WORD;
break;
case finsh_type_int:
case finsh_type_uint:
case finsh_type_long:
case finsh_type_ulong:
node->data_type = FINSH_DATA_TYPE_DWORD;
break;
case finsh_type_charp:
case finsh_type_voidp:
case finsh_type_shortp:
case finsh_type_intp:
case finsh_type_longp:
node->data_type = FINSH_DATA_TYPE_DWORD;
break;
default:
finsh_error_set(FINSH_ERROR_UNKNOWN_TYPE);
break;
}
}
}
}
else if (node->node_type == FINSH_NODE_VALUE_CHAR)
{
node->data_type = FINSH_DATA_TYPE_BYTE;
}
else if (node->node_type == FINSH_NODE_VALUE_INT ||
node->node_type == FINSH_NODE_VALUE_LONG ||
node->node_type == FINSH_NODE_VALUE_STRING ||
node->node_type == FINSH_NODE_VALUE_NULL)
{
node->data_type = FINSH_DATA_TYPE_DWORD;
}
}
return 0;
}
int finsh_compiler_run(struct finsh_node* node)
{
struct finsh_node* sibling;
/* type check */
finsh_type_check(node, FINSH_NODE_VALUE);
/* clean text segment and vm stack */
memset(&text_segment[0], 0, sizeof(text_segment));
memset(&finsh_vm_stack[0], 0, sizeof(finsh_vm_stack));
/* reset compile stack pointer and pc */
finsh_compile_sp = &finsh_vm_stack[0];
finsh_compile_pc = &text_segment[0];
/* compile node */
sibling = node;
while (sibling != NULL)
{
struct finsh_node* current_node;
current_node = sibling;
/* get sibling node */
sibling = current_node->sibling;
/* clean sibling node */
current_node->sibling = NULL;
finsh_compile(current_node);
/* pop current value */
if (sibling != NULL) finsh_code_byte(FINSH_OP_POP);
}
return 0;
}

View File

@ -1,55 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#include "finsh_error.h"
uint8_t global_errno;
static const char * finsh_error_string_table[] =
{
"No error",
"Invalid token",
"Expect a type",
"Unknown type",
"Variable exist",
"Expect a operater",
"Memory full",
"Unknown operator",
"Unknown node",
"Expect a character",
"Unexpect end",
"Unknown token",
"Float not supported",
"Unknown symbol",
"Null node"
};
int finsh_error_init()
{
global_errno = FINSH_ERROR_OK;
return 0;
}
int finsh_error_set(uint8_t type)
{
global_errno = type;
return 0;
}
uint8_t finsh_errno()
{
return global_errno;
}
const char* finsh_error_string(uint8_t type)
{
return finsh_error_string_table[type];
}

View File

@ -1,23 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#ifndef __FINSH_ERROR_H__
#define __FINSH_ERROR_H__
#include <finsh.h>
int finsh_error_init(void);
/* get error number */
uint8_t finsh_errno(void);
int finsh_error_set(uint8_t type);
const char* finsh_error_string(uint8_t type);
#endif

View File

@ -1,279 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#include <finsh.h>
#include "finsh_var.h"
ALIGN(RT_ALIGN_SIZE)
uint8_t finsh_heap[FINSH_HEAP_MAX];
struct finsh_block_header
{
uint32_t length;
struct finsh_block_header* next;
};
#define BLOCK_HEADER(x) (struct finsh_block_header*)(x)
#define finsh_block_get_header(data) (struct finsh_block_header*)((uint8_t*)data - sizeof(struct finsh_block_header))
#define finsh_block_get_data(header) (uint8_t*)((struct finsh_block_header*)header + 1)
#define HEAP_ALIGN_SIZE(size) (((size) + HEAP_ALIGNMENT - 1) & ~(HEAP_ALIGNMENT-1))
static struct finsh_block_header* free_list;
static struct finsh_block_header* allocate_list;
static void finsh_heap_gc(void);
static void finsh_block_insert(struct finsh_block_header** list, struct finsh_block_header* header);
static void finsh_block_remove(struct finsh_block_header** list, struct finsh_block_header* header);
static void finsh_block_split(struct finsh_block_header* header, size_t size);
static void finsh_block_merge(struct finsh_block_header** list, struct finsh_block_header* header);
int finsh_heap_init(void)
{
/* clear heap to zero */
memset(&finsh_heap[0], 0, sizeof(finsh_heap));
/* init free and alloc list */
free_list = BLOCK_HEADER(&finsh_heap[0]);
free_list->length = FINSH_HEAP_MAX - sizeof(struct finsh_block_header);
free_list->next = NULL;
allocate_list = NULL;
return 0;
}
/**
* allocate a block from heap
*/
void* finsh_heap_allocate(size_t size)
{
struct finsh_block_header* header;
size = HEAP_ALIGN_SIZE(size);
/* find the first fit block */
for (header = free_list;
((header != NULL) && (header->length <= size + sizeof(struct finsh_block_header)));
header = header->next) ;
if (header == NULL)
{
finsh_heap_gc();
/* find the first fit block */
for (header = free_list;
((header != NULL) && (header->length < size + sizeof(struct finsh_block_header)));
header = header->next) ;
/* there is no memory */
if (header == NULL) return NULL;
}
/* split block */
finsh_block_split(header, size);
/* remove from free list */
finsh_block_remove(&free_list, header);
header->next = NULL;
/* insert to allocate list */
finsh_block_insert(&allocate_list, header);
memset(finsh_block_get_data(header), 0, size);
return finsh_block_get_data(header);
}
/**
* release the allocated block
*/
void finsh_heap_free(void*ptr)
{
struct finsh_block_header* header;
/* get block header */
header = finsh_block_get_header(ptr);
/* remove from allocate list */
finsh_block_remove(&allocate_list, header);
/* insert to free list */
finsh_block_insert(&free_list, header);
finsh_block_merge(&free_list, header);
}
/**
* garbage collector
*/
static void finsh_heap_gc(void)
{
int i;
struct finsh_block_header *header, *temp;
temp = NULL;
/* find the first fit block */
for (header = allocate_list; header != NULL; )
{
for (i = 0; i < FINSH_VARIABLE_MAX; i ++)
{
if (global_variable[i].type != finsh_type_unknown)
{
if (global_variable[i].value.ptr == finsh_block_get_data(header))
break;
}
}
temp = header;
header = header->next;
/* this block is an unused block, release it */
if (i == FINSH_VARIABLE_MAX)
{
finsh_heap_free(finsh_block_get_data(temp));
}
}
}
/**
* insert a block to list
*/
void finsh_block_insert(struct finsh_block_header** list, struct finsh_block_header* header)
{
struct finsh_block_header* node;
if (*list == NULL)
{
*list = header;
return;
}
/* find out insert point */
node = *list;
if (node > header)
{
/* insert node in the header of list */
header->next = node;
*list = header;
return;
}
else
{
for (node = *list; node; node = node->next)
{
if (node->next > header) break;
if (node->next == NULL) break;
}
}
/* insert node */
if (node->next != NULL) header->next = node->next;
node->next = header;
}
/**
* remove block from list
*/
void finsh_block_remove(struct finsh_block_header** list, struct finsh_block_header* header)
{
struct finsh_block_header* node;
node = *list;
if (node == header)
{
/* remove list header */
*list = header->next;
header->next = NULL;
return;
}
for (node = *list; node != NULL; node = node->next)
{
if (node->next == header)
{
node->next = header->next;
break;
}
}
}
/**
* split block
*/
void finsh_block_split(struct finsh_block_header* header, size_t size)
{
struct finsh_block_header* next;
/*
* split header into two node:
* header->next->...
*/
next = BLOCK_HEADER((uint8_t*)header + sizeof(struct finsh_block_header) + size);
next->length = header->length - sizeof(struct finsh_block_header) - size;
header->length = size;
next->next = header->next;
header->next = next;
}
void finsh_block_merge(struct finsh_block_header** list, struct finsh_block_header* header)
{
struct finsh_block_header* prev_node;
struct finsh_block_header* next_node;
next_node = header->next;
if (*list == header) prev_node = NULL;
else
{
/* find out the previous header */
for (prev_node = *list; prev_node; prev_node =prev_node->next)
{
if (prev_node->next == header)
break;
}
}
/* try merge node */
/* merge to previous node */
if (prev_node != NULL &&
((uint8_t*)prev_node + prev_node->length + sizeof(struct finsh_block_header)
== (uint8_t*)header))
{
/* is it close to next node? */
if ((next_node != NULL) &&
((uint8_t*)header + header->length + sizeof(struct finsh_block_header)
== (uint8_t*)next_node))
{
/* merge three node */
prev_node->length += header->length + next_node->length +
2 * sizeof(struct finsh_block_header);
prev_node->next = next_node->next;
}
else
{
prev_node->length += header->length + sizeof(struct finsh_block_header);
prev_node->next = header->next;
}
}
else /* merge to last node */
if ( (next_node != NULL) &&
((uint8_t*)header + header->length + sizeof(struct finsh_block_header)
== (uint8_t*)next_node))
{
header->length += next_node->length + sizeof(struct finsh_block_header);
header->next = next_node->next;
}
}

View File

@ -1,19 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#include <finsh.h>
#ifndef __FINSH_HEAP_H__
#define __FINSH_HEAP_H__
int finsh_heap_init(void);
void* finsh_heap_allocate(size_t size);
void finsh_heap_free(void*ptr);
#endif

View File

@ -1,57 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#include <finsh.h>
#include "finsh_node.h"
#include "finsh_vm.h"
#include "finsh_parser.h"
#include "finsh_var.h"
#include "finsh_error.h"
#include "finsh_heap.h"
int finsh_init(struct finsh_parser* parser)
{
finsh_parser_init(parser);
/* finsh init */
finsh_node_init();
finsh_var_init();
finsh_error_init();
finsh_heap_init();
return 0;
}
long finsh_stack_bottom()
{
return finsh_vm_stack[0].long_value;
}
int finsh_flush(struct finsh_parser* parser)
{
finsh_parser_init(parser);
/* finsh init */
finsh_node_init();
finsh_error_init();
return 0;
}
int finsh_reset(struct finsh_parser* parser)
{
/* finsh init */
finsh_node_init();
finsh_var_init();
finsh_error_init();
finsh_heap_init();
return 0;
}

View File

@ -1,183 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#include <finsh.h>
#include "finsh_node.h"
#include "finsh_error.h"
#include "finsh_var.h"
#include "finsh_heap.h"
struct finsh_node global_node_table[FINSH_NODE_MAX];
int finsh_node_init()
{
memset(global_node_table, 0, sizeof(global_node_table));
return 0;
}
struct finsh_node* finsh_node_allocate(uint8_t type)
{
int i;
/* find an empty entry */
for (i = 0; i < FINSH_NODE_MAX; i ++)
{
if (global_node_table[i].node_type == FINSH_NODE_UNKNOWN) break;
}
if (i == FINSH_NODE_MAX) return NULL;
/* fill type field */
global_node_table[i].node_type = type;
/* return this allocated node */
return &global_node_table[i];
}
struct finsh_node* finsh_node_new_id(char* id)
{
struct finsh_node* node;
void* symbol;
unsigned char type;
symbol = NULL;
type = 0;
node = NULL;
/* lookup variable firstly */
symbol = (void*)finsh_var_lookup(id);
if (symbol == NULL)
{
/* then lookup system variable */
symbol = (void*)finsh_sysvar_lookup(id);
if (symbol == NULL)
{
/* then lookup system call */
symbol = (void*)finsh_syscall_lookup(id);
if (symbol != NULL) type = FINSH_IDTYPE_SYSCALL;
}
else type = FINSH_IDTYPE_SYSVAR;
}
else type = FINSH_IDTYPE_VAR;
if (symbol != NULL)
{
/* allocate a new node */
node = finsh_node_allocate(FINSH_NODE_ID);
/* allocate node error */
if (node == NULL)
{
finsh_error_set(FINSH_ERROR_MEMORY_FULL);
return NULL;
}
/* fill node value according type */
switch (type)
{
case FINSH_IDTYPE_VAR:
node->id.var = (struct finsh_var*)symbol;
break;
case FINSH_IDTYPE_SYSVAR:
node->id.sysvar = (struct finsh_sysvar*)symbol;
break;
case FINSH_IDTYPE_SYSCALL:
node->id.syscall = (struct finsh_syscall*)symbol;
break;
}
/* fill identifier type */
node->idtype = type;
}
else finsh_error_set(FINSH_ERROR_UNKNOWN_SYMBOL);
return node;
}
struct finsh_node* finsh_node_new_char(char c)
{
struct finsh_node* node;
node = finsh_node_allocate(FINSH_NODE_VALUE_CHAR);
if (node == NULL)
{
finsh_error_set(FINSH_ERROR_MEMORY_FULL);
return NULL;
}
node->value.char_value = c;
return node;
}
struct finsh_node* finsh_node_new_int(int i)
{
struct finsh_node* node;
node = finsh_node_allocate(FINSH_NODE_VALUE_INT);
if (node == NULL)
{
finsh_error_set(FINSH_ERROR_MEMORY_FULL);
return NULL;
}
node->value.int_value = i;
return node;
}
struct finsh_node* finsh_node_new_long(long l)
{
struct finsh_node* node;
node = finsh_node_allocate(FINSH_NODE_VALUE_LONG);
if (node == NULL)
{
finsh_error_set(FINSH_ERROR_MEMORY_FULL);
return NULL;
}
node->value.long_value = l;
return node;
}
struct finsh_node* finsh_node_new_string(char* s)
{
struct finsh_node* node;
node = finsh_node_allocate(FINSH_NODE_VALUE_STRING);
if (node == NULL)
{
finsh_error_set(FINSH_ERROR_MEMORY_FULL);
return NULL;
}
/* make string */
node->value.ptr = finsh_heap_allocate(strlen(s) + 1);
strncpy(node->value.ptr, s, strlen(s));
((uint8_t*)node->value.ptr)[strlen(s)] = '\0';
return node;
}
struct finsh_node* finsh_node_new_ptr(void* ptr)
{
struct finsh_node* node;
node = finsh_node_allocate(FINSH_NODE_VALUE_NULL);
if (node == NULL)
{
finsh_error_set(FINSH_ERROR_MEMORY_FULL);
return NULL;
}
node->value.ptr = ptr;
return node;
}

View File

@ -1,69 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#ifndef __FINSH_NODE_H__
#define __FINSH_NODE_H__
#include <finsh.h>
#define FINSH_NODE_UNKNOWN 0
#define FINSH_NODE_ID 1
#define FINSH_NODE_VALUE_CHAR 2
#define FINSH_NODE_VALUE_INT 3
#define FINSH_NODE_VALUE_LONG 4
#define FINSH_NODE_VALUE_STRING 5
#define FINSH_NODE_VALUE_NULL 6
#define FINSH_NODE_SYS_ADD 7
#define FINSH_NODE_SYS_SUB 8
#define FINSH_NODE_SYS_MUL 9
#define FINSH_NODE_SYS_DIV 10
#define FINSH_NODE_SYS_MOD 11
#define FINSH_NODE_SYS_AND 12
#define FINSH_NODE_SYS_OR 13
#define FINSH_NODE_SYS_XOR 14
#define FINSH_NODE_SYS_BITWISE 15
#define FINSH_NODE_SYS_SHL 16
#define FINSH_NODE_SYS_SHR 17
#define FINSH_NODE_SYS_FUNC 18
#define FINSH_NODE_SYS_ASSIGN 19
#define FINSH_NODE_SYS_CAST 20
#define FINSH_NODE_SYS_PREINC 21
#define FINSH_NODE_SYS_PREDEC 22
#define FINSH_NODE_SYS_INC 23
#define FINSH_NODE_SYS_DEC 24
#define FINSH_NODE_SYS_GETVALUE 25
#define FINSH_NODE_SYS_GETADDR 26
#define FINSH_NODE_SYS_NULL 27
#define FINSH_DATA_TYPE_VOID 0x00
#define FINSH_DATA_TYPE_BYTE 0x01
#define FINSH_DATA_TYPE_WORD 0x02
#define FINSH_DATA_TYPE_DWORD 0x03
#define FINSH_DATA_TYPE_PTR 0x10
#define FINSH_NODE_VALUE 0
#define FINSH_NODE_ADDRESS 1
#define FINSH_NODE_FUNCTION 2
int finsh_node_init(void);
struct finsh_node* finsh_node_allocate(uint8_t type);
struct finsh_node* finsh_node_new_id(char* id);
struct finsh_node* finsh_node_new_char(char c);
struct finsh_node* finsh_node_new_int(int i);
struct finsh_node* finsh_node_new_long(long l);
struct finsh_node* finsh_node_new_string(char* s);
struct finsh_node* finsh_node_new_ptr(void* ptr);
#define finsh_node_sibling(node) ((node)->sibling)
#define finsh_node_child(node) ((node)->child)
#endif

View File

@ -1,603 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#include "finsh_ops.h"
#include "finsh_vm.h"
#define OP_BIN_BYTE(x) do {\
(finsh_sp - 2)->char_value = (finsh_sp - 2)->char_value x (finsh_sp - 1)->char_value; \
finsh_sp--; \
}while (0)
#define OP_BIN_WORD(x) do {\
(finsh_sp - 2)->short_value = (finsh_sp - 2)->short_value x (finsh_sp - 1)->short_value; \
finsh_sp--; \
}while (0)
#define OP_BIN_DWORD(x) do {\
(finsh_sp - 2)->long_value = (finsh_sp - 2)->long_value x (finsh_sp - 1)->long_value; \
finsh_sp--; \
}while (0)
/* --- noop --- */
void OP_no_op()
{
/* none */
return ;
}
/* --- add --- */
void OP_add_byte()
{
OP_BIN_BYTE(+);
return ;
}
void OP_add_word()
{
OP_BIN_WORD(+);
return ;
}
void OP_add_dword()
{
OP_BIN_DWORD(+);
return ;
}
/* --- sub --- */
void OP_sub_byte()
{
OP_BIN_BYTE(-);
return ;
}
void OP_sub_word()
{
OP_BIN_WORD(-);
return ;
}
void OP_sub_dword()
{
OP_BIN_DWORD(-);
return ;
}
/* --- div --- */
void OP_div_byte()
{
OP_BIN_BYTE(/);
return ;
}
void OP_div_word()
{
OP_BIN_WORD(/);
return ;
}
void OP_div_dword()
{
OP_BIN_DWORD(/);
return ;
}
/* --- mod --- */
void OP_mod_byte()
{
OP_BIN_BYTE(%);
return ;
}
void OP_mod_word()
{
OP_BIN_WORD(%);
return ;
}
void OP_mod_dword()
{
OP_BIN_DWORD(%);
return ;
}
/* --- mul --- */
void OP_mul_byte()
{
OP_BIN_BYTE(*);
return ;
}
void OP_mul_word()
{
OP_BIN_WORD(*);
return ;
}
void OP_mul_dword()
{
OP_BIN_DWORD(*);
return ;
}
/* --- and --- */
void OP_and_byte()
{
OP_BIN_BYTE(&);
return ;
}
void OP_and_word()
{
OP_BIN_WORD(&);
return ;
}
void OP_and_dword()
{
OP_BIN_DWORD(&);
return ;
}
/* --- or --- */
void OP_or_byte()
{
OP_BIN_BYTE(|);
return ;
}
void OP_or_word()
{
OP_BIN_WORD(|);
return ;
}
void OP_or_dword()
{
OP_BIN_DWORD(|);
return ;
}
/* --- xor --- */
void OP_xor_byte()
{
OP_BIN_BYTE(^);
return ;
}
void OP_xor_word()
{
OP_BIN_WORD(^);
return ;
}
void OP_xor_dword()
{
OP_BIN_DWORD(^);
return ;
}
/* --- bw --- */
void OP_bw_byte()
{
(finsh_sp - 1)->char_value = ~ ((finsh_sp - 1)->char_value);
return ;
}
void OP_bw_word()
{
(finsh_sp - 1)->short_value = ~ ((finsh_sp - 1)->short_value);
return ;
}
void OP_bw_dword()
{
(finsh_sp - 1)->long_value = ~ ((finsh_sp - 1)->long_value);
return ;
}
/* --- shl --- */
void OP_shl_byte()
{
OP_BIN_BYTE(<<);
return ;
}
void OP_shl_word()
{
OP_BIN_WORD(<<);
return ;
}
void OP_shl_dword()
{
OP_BIN_DWORD(<<);
return ;
}
/* --- shr --- */
void OP_shr_byte()
{
OP_BIN_BYTE(>>);
return ;
}
void OP_shr_word()
{
OP_BIN_WORD(>>);
return ;
}
void OP_shr_dword()
{
OP_BIN_DWORD(>>);
return ;
}
/* --- ld --- */
void OP_ld_byte()
{
finsh_sp->char_value = *finsh_pc;
finsh_sp++;
finsh_pc++;
return ;
}
void OP_ld_word()
{
finsh_sp->short_value = FINSH_GET16(finsh_pc);
finsh_sp ++;
finsh_pc += 2;
return ;
}
void OP_ld_dword()
{
finsh_sp->long_value = FINSH_GET32(finsh_pc);
finsh_sp ++;
finsh_pc += 4;
return ;
}
void OP_ld_value_byte()
{
char* c;
c = (char*) (FINSH_GET32(finsh_pc));
finsh_sp->char_value = *c;
finsh_sp ++;
finsh_pc += 4;
return;
}
void OP_ld_value_byte_stack()
{
char* c;
c = (char *)(finsh_sp - 1)->long_value;
(finsh_sp - 1)->char_value = *c;
return;
}
void OP_ld_value_word()
{
short* s;
s = (short*) (FINSH_GET32(finsh_pc));
finsh_sp->short_value = *s;
finsh_sp ++;
finsh_pc += 4;
return;
}
void OP_ld_value_word_stack()
{
short* s;
s = (short *)(finsh_sp - 1)->long_value;
(finsh_sp - 1)->short_value = *s;
return;
}
void OP_ld_value_dword()
{
long* l;
l = (long*) (FINSH_GET32(finsh_pc));
finsh_sp->long_value = *l;
finsh_sp ++;
finsh_pc += 4;
return;
}
void OP_ld_value_dword_stack()
{
long* l;
l = (long *)(finsh_sp - 1)->long_value;
(finsh_sp - 1)->long_value = *l;
return;
}
/* --- st --- */
/*
* 2006-4-16 bernard
* fixed the sp move bug
*/
void OP_st_byte()
{
*(char*)((finsh_sp - 2)->long_value) = (finsh_sp - 1)->char_value;
finsh_sp --;
return ;
}
/*
* 2006-4-16 bernard
* fixed the sp move bug
*/
void OP_st_word()
{
*(short*)((finsh_sp - 2)->long_value) = (finsh_sp - 1)->short_value;
finsh_sp --;
return ;
}
/*
* 2006-4-16 bernard
* fixed the sp move bug
*/
void OP_st_dword()
{
*(long*)((finsh_sp - 2)->long_value) = (finsh_sp - 1)->long_value;
finsh_sp --;
return ;
}
/* --- pop --- */
void OP_pop()
{
finsh_sp --;
return ;
}
/* --- call --- */
void OP_call()
{
/* the max number of arg*/
unsigned long parameterv[16];
unsigned int parameters, i;
typedef unsigned long var_t;
typedef var_t (*op_func)();
op_func f;
var_t r;
parameters = *finsh_pc ++;
i = 0; finsh_sp --;
while (i < parameters)
{
parameterv[parameters - 1 - i] = finsh_sp->long_value;
finsh_sp --;
i++;
}
f = (op_func)(finsh_sp->long_value);
switch (parameters)
{
case 0:
r = f(0);
break;
case 1:
r = f(parameterv[0]);
break;
case 2:
r = f(parameterv[0], parameterv[1]);
break;
case 3:
r = f(parameterv[0], parameterv[1], parameterv[2]);
break;
case 4:
r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3]);
break;
case 5:
r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
parameterv[4]);
break;
case 6:
r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
parameterv[4], parameterv[5]);
break;
case 7:
r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
parameterv[4], parameterv[5], parameterv[6]);
break;
case 8:
r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
parameterv[4], parameterv[5], parameterv[6], parameterv[7]);
break;
case 9:
r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
parameterv[4], parameterv[5], parameterv[6], parameterv[7],
parameterv[8]);
break;
case 10:
r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
parameterv[4], parameterv[5], parameterv[6], parameterv[7],
parameterv[8], parameterv[9]);
break;
case 11:
r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
parameterv[4], parameterv[5], parameterv[6], parameterv[7],
parameterv[8], parameterv[9], parameterv[10]);
break;
case 12:
r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
parameterv[4], parameterv[5], parameterv[6], parameterv[7],
parameterv[8], parameterv[9], parameterv[10], parameterv[11]);
break;
case 13:
r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
parameterv[4], parameterv[5], parameterv[6], parameterv[7],
parameterv[8], parameterv[9], parameterv[10], parameterv[11],
parameterv[12]);
break;
case 14:
r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
parameterv[4], parameterv[5], parameterv[6], parameterv[7],
parameterv[8], parameterv[9], parameterv[10], parameterv[11],
parameterv[12], parameterv[13]);
break;
case 15:
r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
parameterv[4], parameterv[5], parameterv[6], parameterv[7],
parameterv[8], parameterv[9], parameterv[10], parameterv[11],
parameterv[12], parameterv[13], parameterv[14]);
break;
case 16:
r = f(parameterv[0], parameterv[1], parameterv[2], parameterv[3],
parameterv[4], parameterv[5], parameterv[6], parameterv[7],
parameterv[8], parameterv[9], parameterv[10], parameterv[11],
parameterv[12], parameterv[13], parameterv[14], parameterv[15]);
break;
default:
r = 0;
break;
}
finsh_sp->long_value = r;
finsh_sp ++;
return ;
}
const op_func op_table[] =
{
/* 00 */ OP_no_op,
/* 01 */ OP_add_byte,
/* 02 */ OP_add_word,
/* 03 */ OP_add_dword,
/* 04 */ OP_sub_byte,
/* 05 */ OP_sub_word,
/* 06 */ OP_sub_dword,
/* 07 */ OP_div_byte,
/* 08 */ OP_div_word,
/* 09 */ OP_div_dword,
/* 10 */ OP_mod_byte,
/* 11 */ OP_mod_word,
/* 12 */ OP_mod_dword,
/* 13 */ OP_mul_byte,
/* 14 */ OP_mul_word,
/* 15 */ OP_mul_dword,
/* 16 */ OP_and_byte,
/* 17 */ OP_and_word,
/* 18 */ OP_and_dword,
/* 19 */ OP_or_byte,
/* 20 */ OP_or_word,
/* 21 */ OP_or_dword,
/* 22 */ OP_xor_byte,
/* 23 */ OP_xor_word,
/* 24 */ OP_xor_dword,
/* 25 */ OP_bw_byte,
/* 26 */ OP_bw_word,
/* 27 */ OP_bw_dword,
/* 28 */ OP_shl_byte,
/* 29 */ OP_shl_word,
/* 30 */ OP_shl_dword,
/* 31 */ OP_shr_byte,
/* 32 */ OP_shr_word,
/* 33 */ OP_shr_dword,
/* 34 */ OP_ld_byte,
/* 35 */ OP_ld_word,
/* 36 */ OP_ld_dword,
/* 37 */ OP_ld_value_byte,
/* 38 */ OP_ld_value_word,
/* 39 */ OP_ld_value_dword,
/* 40 */ OP_st_byte,
/* 41 */ OP_st_word,
/* 42 */ OP_st_dword,
/* 43 */ OP_pop,
/* 44 */ OP_call,
/* 45 */ OP_ld_value_byte_stack,
/* 46 */ OP_ld_value_word_stack,
/* 47 */ OP_ld_value_dword_stack,
NULL
};

View File

@ -1,116 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#ifndef __FINSH_OP_H__
#define __FINSH_OP_H__
#include "finsh_vm.h"
/*
* FinC VM specification
* Memory
* .VAR
*
* .STACK
*
* .HEAP
*
* .TEXT
* OP [op1]
*/
#define FINSH_OP_NOOP 0x00
/* add @ r1 = r2 + r3 */
#define FINSH_OP_ADD_BYTE 0x01
#define FINSH_OP_ADD_WORD 0x02
#define FINSH_OP_ADD_DWORD 0x03
/* sub @ r1 = r2 - r3 */
#define FINSH_OP_SUB_BYTE 0x04
#define FINSH_OP_SUB_WORD 0x05
#define FINSH_OP_SUB_DWORD 0x06
/* div @ r1 = r2 / r3 */
#define FINSH_OP_DIV_BYTE 0x07
#define FINSH_OP_DIV_WORD 0x08
#define FINSH_OP_DIV_DWORD 0x09
/* mod @ r1 = r2 % r3 */
#define FINSH_OP_MOD_BYTE 0x0A
#define FINSH_OP_MOD_WORD 0x0B
#define FINSH_OP_MOD_DWORD 0x0C
/* mul @ r1 = r2 * r3 */
#define FINSH_OP_MUL_BYTE 0x0D
#define FINSH_OP_MUL_WORD 0x0E
#define FINSH_OP_MUL_DWORD 0x0F
/* and @ r1 = r2 & r3 */
#define FINSH_OP_AND_BYTE 0x10
#define FINSH_OP_AND_WORD 0x11
#define FINSH_OP_AND_DWORD 0x12
/* or @ r1 = r2 | r3 */
#define FINSH_OP_OR_BYTE 0x13
#define FINSH_OP_OR_WORD 0x14
#define FINSH_OP_OR_DWORD 0x15
/* xor @ r1 = r2 ^ r3 */
#define FINSH_OP_XOR_BYTE 0x16
#define FINSH_OP_XOR_WORD 0x17
#define FINSH_OP_XOR_DWORD 0x18
/* bw @ r1 = ~r2 */
#define FINSH_OP_BITWISE_BYTE 0x19
#define FINSH_OP_BITWISE_WORD 0x1A
#define FINSH_OP_BITWISE_DWORD 0x1B
/* shl @ r1 = r2 << r3 */
#define FINSH_OP_SHL_BYTE 0x1C
#define FINSH_OP_SHL_WORD 0x1D
#define FINSH_OP_SHL_DWORD 0x1E
/* shr @ r1 = r2 >> r3 */
#define FINSH_OP_SHR_BYTE 0x1F
#define FINSH_OP_SHR_WORD 0x20
#define FINSH_OP_SHR_DWORD 0x21
/* ld @ r1 = [r2] */
#define FINSH_OP_LD_BYTE 0x22
#define FINSH_OP_LD_WORD 0x23
#define FINSH_OP_LD_DWORD 0x24
#define FINSH_OP_LD_VALUE_BYTE 0x25
#define FINSH_OP_LD_VALUE_WORD 0x26
#define FINSH_OP_LD_VALUE_DWORD 0x27
/* st @ [r2] = r1 */
#define FINSH_OP_ST_BYTE 0x28
#define FINSH_OP_ST_WORD 0x29
#define FINSH_OP_ST_DWORD 0x2A
/* pop */
#define FINSH_OP_POP 0x2B
/* call r1 @ [r1](stack) */
#define FINSH_OP_SYSCALL 0x2C
/* load value from stack */
#define FINSH_OP_LD_VALUE_BYTE_STACK 0x2D
#define FINSH_OP_LD_VALUE_WORD_STACK 0x2E
#define FINSH_OP_LD_VALUE_DWORD_STACK 0x2F
/* halt */
#define FINSH_OP_HALT 0xFF
typedef void (*op_func)();
extern const op_func op_table[];
#endif

View File

@ -1,986 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
* 2013-10-09 Bernard fix the command line too long issue.
*/
#include <finsh.h>
#include "finsh_token.h"
#include "finsh_node.h"
#include "finsh_error.h"
#include "finsh_parser.h"
#include "finsh_var.h"
/*
* the structure of abstract syntax tree:
* root____________
* | \
* child__ sibling__
* | \ | \
* child sibling child sibling
* ...
*/
static enum finsh_type proc_type(struct finsh_parser* self);
static int proc_identifier(struct finsh_parser* self, char* id);
static struct finsh_node* proc_variable_decl(struct finsh_parser* self);
static struct finsh_node* proc_expr(struct finsh_parser* self);
static struct finsh_node* proc_assign_expr(struct finsh_parser* self);
static struct finsh_node* proc_inclusive_or_expr(struct finsh_parser* self);
static struct finsh_node* proc_exclusive_or_expr(struct finsh_parser* self);
static struct finsh_node* proc_and_expr(struct finsh_parser* self);
static struct finsh_node* proc_shift_expr(struct finsh_parser* self);
static struct finsh_node* proc_additive_expr(struct finsh_parser* self);
static struct finsh_node* proc_multiplicative_expr(struct finsh_parser* self);
static struct finsh_node* proc_cast_expr(struct finsh_parser* self);
static struct finsh_node* proc_unary_expr(struct finsh_parser* self);
static struct finsh_node* proc_postfix_expr(struct finsh_parser* self);
static struct finsh_node* proc_primary_expr(struct finsh_parser* self);
static struct finsh_node* proc_param_list(struct finsh_parser* self);
static struct finsh_node* proc_expr_statement(struct finsh_parser* self);
static struct finsh_node* make_sys_node(uint8_t type, struct finsh_node* node1,
struct finsh_node* node2);
/* check token */
#define check_token(token, lex, type) if ( (token) != (type) ) \
{ \
finsh_error_set(FINSH_ERROR_INVALID_TOKEN); \
finsh_token_replay(lex); \
}
/* is the token a data type? */
#define is_base_type(token) ((token) == finsh_token_type_void \
|| (token) == finsh_token_type_char \
|| (token) == finsh_token_type_short \
|| (token) == finsh_token_type_int \
|| (token) == finsh_token_type_long)
/* get the next token */
#define next_token(token, lex) (token) = finsh_token_token(lex)
/* match a specified token */
#define match_token(token, lex, type) next_token(token, lex); \
check_token(token, lex, type)
/*
process for function and variable declaration.
decl_variable -> type declaration_list ';'
declarator_list -> declarator_list ',' declarator
| declarator
declarator -> identifier
| identifier ASSIGN expr_assign
*/
static struct finsh_node* proc_variable_decl(struct finsh_parser* self)
{
enum finsh_token_type token;
enum finsh_type type;
char id[FINSH_NAME_MAX + 1];
struct finsh_node *node;
struct finsh_node *end;
struct finsh_node *assign;
node = NULL;
end = NULL;
/* get type */
type = proc_type(self);
/*process id.*/
if (proc_identifier(self, id) == 0)
{
/* if add variable failed */
if (finsh_var_insert(id, type) < 0)
{
finsh_error_set(FINSH_ERROR_VARIABLE_EXIST);
}
}
next_token(token, &(self->token));
switch ( token )
{
case finsh_token_type_comma:/*',', it's a variable_list declaration.*/
if (proc_identifier(self, id) == 0)
{
/* if add variable failed */
if (finsh_var_insert(id, type) < 0)
{
finsh_error_set(FINSH_ERROR_VARIABLE_EXIST);
}
}
next_token(token, &(self->token));
if ( token == finsh_token_type_assign )
{
/* get the right side of assign expression */
assign = proc_assign_expr(self);
if (assign != NULL)
{
struct finsh_node* idnode;
idnode = finsh_node_new_id(id);
end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);
node = end;
next_token(token, &(self->token));
}
}
while ( token == finsh_token_type_comma )
{
if (proc_identifier(self, id) == 0)
{
/* if add variable failed */
if (finsh_var_insert(id, type) < 0)
{
finsh_error_set(FINSH_ERROR_VARIABLE_EXIST);
}
}
next_token(token, &(self->token));
if ( token == finsh_token_type_assign )
{
/* get the right side of assign expression */
assign = proc_assign_expr(self);
if (assign != NULL)
{
struct finsh_node* idnode;
idnode = finsh_node_new_id(id);
/* make assign expression node */
if (node != NULL)
{
finsh_node_sibling(end) = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);
end = finsh_node_sibling(end);
}
else
{
end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);
node = end;
}
next_token(token, &(self->token));
}
}
}
check_token(token, &(self->token), finsh_token_type_semicolon);
return node;
case finsh_token_type_assign:/*'=', it's a variable with assign declaration.*/
{
struct finsh_node *idnode;
assign = proc_assign_expr(self);
if (assign != NULL)
{
idnode = finsh_node_new_id(id);
/* make assign expression node */
end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);
node = end;
next_token(token, &(self->token));
}
while ( token == finsh_token_type_comma )
{
if (proc_identifier(self, id) == 0)
{
/* if add variable failed */
if (finsh_var_insert(id, type) < 0)
{
finsh_error_set(FINSH_ERROR_VARIABLE_EXIST);
}
}
next_token(token, &(self->token));
if (token == finsh_token_type_assign)
{
/* get the right side of assign expression */
assign = proc_assign_expr(self);
if (assign != NULL)
{
idnode = finsh_node_new_id(id);
/* make assign expression node */
if (node != NULL)
{
finsh_node_sibling(end) = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);
end = finsh_node_sibling(end);
}
else
{
end = make_sys_node(FINSH_NODE_SYS_ASSIGN, idnode, assign);
node = end;
}
next_token(token, &(self->token));
}
}
}
check_token(token, &(self->token), finsh_token_type_semicolon);
return node;
}
case finsh_token_type_semicolon:/*';', it's a variable declaration.*/
return node;
default:
finsh_error_set(FINSH_ERROR_EXPECT_TYPE);
return NULL;
}
}
/*
type -> type_prefix type_basic | type_basic
type_prefix -> UNSIGNED
type_basic -> VOID
| CHAR
| SHORT
| INT
| STRING
*/
static enum finsh_type proc_type(struct finsh_parser* self)
{
enum finsh_type type;
enum finsh_token_type token;
/* set init type */
type = finsh_type_unknown;
next_token(token, &(self->token));
if ( is_base_type(token) ) /* base_type */
{
switch (token)
{
case finsh_token_type_void:
type = finsh_type_void;
break;
case finsh_token_type_char:
type = finsh_type_char;
break;
case finsh_token_type_short:
type = finsh_type_short;
break;
case finsh_token_type_int:
type = finsh_type_int;
break;
case finsh_token_type_long:
type = finsh_type_long;
break;
default:
goto __return;
}
}
else if ( token == finsh_token_type_unsigned ) /* unsigned base_type */
{
next_token(token, &(self->token));
if ( is_base_type(token) )
{
switch (token)
{
case finsh_token_type_char:
type = finsh_type_uchar;
break;
case finsh_token_type_short:
type = finsh_type_ushort;
break;
case finsh_token_type_int:
type = finsh_type_uint;
break;
case finsh_token_type_long:
type = finsh_type_ulong;
break;
default:
goto __return;
}
}
else
{
finsh_token_replay(&(self->token));
finsh_error_set(FINSH_ERROR_EXPECT_TYPE);
}
}
else
{
goto __return;
}
/* parse for pointer */
next_token(token, &(self->token));
if (token == finsh_token_type_mul)
{
switch (type)
{
case finsh_type_void:
type = finsh_type_voidp;
break;
case finsh_type_char:
case finsh_type_uchar:
type = finsh_type_charp;
break;
case finsh_type_short:
case finsh_type_ushort:
type = finsh_type_shortp;
break;
case finsh_type_int:
case finsh_type_uint:
type = finsh_type_intp;
break;
case finsh_type_long:
case finsh_type_ulong:
type = finsh_type_longp;
break;
default:
type = finsh_type_voidp;
break;
}
}
else finsh_token_replay(&(self->token));
return type;
__return:
finsh_token_replay(&(self->token));
finsh_error_set(FINSH_ERROR_UNKNOWN_TYPE);
return type;
}
/*
identifier -> IDENTIFIER
*/
static int proc_identifier(struct finsh_parser* self, char* id)
{
enum finsh_token_type token;
match_token(token, &(self->token), finsh_token_type_identifier);
strncpy(id, (char*)self->token.string, FINSH_NAME_MAX);
return 0;
}
/*
statement_expr -> ';'
| expr ';'
*/
static struct finsh_node* proc_expr_statement(struct finsh_parser* self)
{
enum finsh_token_type token;
struct finsh_node* expr;
expr = NULL;
next_token(token, &(self->token));
if ( token != finsh_token_type_semicolon )
{
finsh_token_replay(&(self->token));
expr = proc_expr(self);
match_token(token, &(self->token), finsh_token_type_semicolon);
}
return expr;
}
/*
expr -> expr_assign
*/
static struct finsh_node* proc_expr(struct finsh_parser* self)
{
return proc_assign_expr(self);
}
/*
expr_assign -> expr_inclusive_or
| expr_unary ASSIGN expr_assign
*/
static struct finsh_node* proc_assign_expr(struct finsh_parser* self)
{
enum finsh_token_type token;
struct finsh_node* or;
struct finsh_node* assign;
or = proc_inclusive_or_expr(self);
next_token(token, &(self->token));
if (token == finsh_token_type_assign)
{
assign = proc_assign_expr(self);
return make_sys_node(FINSH_NODE_SYS_ASSIGN, or, assign);
}
else finsh_token_replay(&(self->token));
return or;
}
/*
expr_inclusive_or -> expr_exclusive_or
| expr_inclusive_or '|' expr_exclusive_or
*/
static struct finsh_node* proc_inclusive_or_expr(struct finsh_parser* self)
{
enum finsh_token_type token;
struct finsh_node* xor;
struct finsh_node* xor_new;
xor = proc_exclusive_or_expr(self);
next_token(token, &(self->token));
while ( token == finsh_token_type_or )
{
xor_new = proc_exclusive_or_expr(self);
if (xor_new == NULL) finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);
else xor = make_sys_node(FINSH_NODE_SYS_OR, xor, xor_new);
next_token(token, &(self->token));
}
finsh_token_replay(&(self->token));
return xor;
}
/*
expr_exclusive_or -> expr_and
| expr_exclusive '^' expr_and
*/
static struct finsh_node* proc_exclusive_or_expr(struct finsh_parser* self)
{
enum finsh_token_type token;
struct finsh_node* and;
struct finsh_node* and_new;
and = proc_and_expr(self);
next_token(token, &(self->token));
while ( token == finsh_token_type_xor )
{
and_new = proc_and_expr(self);
if (and_new == NULL) finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);
else and = make_sys_node(FINSH_NODE_SYS_XOR, and, and_new);
next_token(token, &(self->token));
}
finsh_token_replay(&(self->token));
return and;
}
/*
expr_and -> expr_shift
| expr_and '&' expr_shift
*/
static struct finsh_node* proc_and_expr(struct finsh_parser* self)
{
enum finsh_token_type token;
struct finsh_node* shift;
struct finsh_node* shift_new;
shift = proc_shift_expr(self);
next_token(token, &(self->token));
while ( token == finsh_token_type_and )
{
shift_new = proc_shift_expr(self);
if (shift_new == NULL) finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);
else shift = make_sys_node(FINSH_NODE_SYS_AND, shift, shift_new);
next_token(token, &(self->token));
}
finsh_token_replay(&(self->token));
return shift;
}
/*
expr_shift -> expr_additive
| expr_shift '<<' expr_additive
| expr_shift '>>' expr_additive
*/
static struct finsh_node* proc_shift_expr(struct finsh_parser* self)
{
enum finsh_token_type token;
struct finsh_node* add;
struct finsh_node* add_new;
add = proc_additive_expr(self);
next_token(token, &(self->token));
while ( token == finsh_token_type_shl || token == finsh_token_type_shr)
{
add_new = proc_additive_expr(self);
if (add_new == NULL) finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);
else
{
switch (token)
{
case finsh_token_type_shl:
add = make_sys_node(FINSH_NODE_SYS_SHL, add, add_new);
break;
case finsh_token_type_shr:
add = make_sys_node(FINSH_NODE_SYS_SHR, add, add_new);
break;
default:
finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);
break;
}
}
next_token(token, &(self->token));
}
finsh_token_replay(&(self->token));
return add;
}
/*
expr_additive -> expr_multiplicative
| expr_additive SUB expr_multiplicative
| expr_additive ADD expr_multiplicative
*/
static struct finsh_node* proc_additive_expr(struct finsh_parser* self)
{
enum finsh_token_type token;
struct finsh_node* mul;
struct finsh_node* mul_new;
mul = proc_multiplicative_expr(self);
next_token(token, &(self->token));
while ( token == finsh_token_type_sub || token == finsh_token_type_add )
{
mul_new = proc_multiplicative_expr(self);
if (mul_new == NULL) finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);
else
{
switch (token)
{
case finsh_token_type_sub:
mul = make_sys_node(FINSH_NODE_SYS_SUB, mul, mul_new);
break;
case finsh_token_type_add:
mul = make_sys_node(FINSH_NODE_SYS_ADD, mul, mul_new);
break;
default:
finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);
break;
}
}
next_token(token, &(self->token));
}
finsh_token_replay(&(self->token));
return mul;
}
/*
expr_multiplicative -> expr_cast
| expr_multiplicative '*' expr_cast
| expr_multiplicative '/' expr_cast
| expr_multiplicative '%' expr_cast
*/
static struct finsh_node* proc_multiplicative_expr(struct finsh_parser* self)
{
enum finsh_token_type token;
struct finsh_node* cast;
struct finsh_node* cast_new;
cast = proc_cast_expr(self);
next_token(token, &(self->token));
while (token == finsh_token_type_mul ||
token == finsh_token_type_div ||
token == finsh_token_type_mod )
{
cast_new = proc_cast_expr(self);
if (cast_new == NULL) finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);
else
{
switch (token)
{
case finsh_token_type_mul:
cast = make_sys_node(FINSH_NODE_SYS_MUL, cast, cast_new);
break;
case finsh_token_type_div:
cast = make_sys_node(FINSH_NODE_SYS_DIV, cast, cast_new);
break;
case finsh_token_type_mod:
cast = make_sys_node(FINSH_NODE_SYS_MOD, cast, cast_new);
break;
default:
finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);
break;
}
}
next_token(token, &(self->token));
}
finsh_token_replay(&(self->token));
return cast;
}
/*
20060313, add recast parse
expr_cast -> expr_unary
| '(' type ')' expr_cast
*/
static struct finsh_node* proc_cast_expr(struct finsh_parser* self)
{
enum finsh_token_type token;
enum finsh_type type;
struct finsh_node* cast;
next_token(token, &(self->token));
if (token == finsh_token_type_left_paren)
{
type = proc_type(self);
match_token(token, &(self->token), finsh_token_type_right_paren);
cast = proc_cast_expr(self);
if (cast != NULL)
{
cast->data_type = type;
return cast;
}
}
finsh_token_replay(&(self->token));
return proc_unary_expr(self);
}
/*
20050921, add '*' and '&'
expr_unary -> expr_postfix
| ADD expr_cast
| INC expr_cast
| SUB expr_cast
| DEC expr_cast
| '~' expr_cast
| '*' expr_cast
| '&' expr_cast
*/
static struct finsh_node* proc_unary_expr(struct finsh_parser* self)
{
enum finsh_token_type token;
struct finsh_node *cast;
next_token(token, &(self->token));
switch (token)
{
case finsh_token_type_add: /* + */
cast = proc_cast_expr(self);
return cast;
case finsh_token_type_inc: /* ++ */
cast = proc_cast_expr(self);
return make_sys_node(FINSH_NODE_SYS_PREINC, cast, NULL);
case finsh_token_type_sub: /* - */
cast = proc_cast_expr(self);
return make_sys_node(FINSH_NODE_SYS_SUB, finsh_node_new_long(0), cast);
case finsh_token_type_dec: /* -- */
cast = proc_cast_expr(self);
return make_sys_node(FINSH_NODE_SYS_PREDEC, cast, NULL);
case finsh_token_type_bitwise: /* ~ */
cast = proc_cast_expr(self);
return make_sys_node(FINSH_NODE_SYS_BITWISE, cast, NULL);
case finsh_token_type_mul: /* * */
cast = proc_cast_expr(self);
return make_sys_node(FINSH_NODE_SYS_GETVALUE, cast, NULL);
case finsh_token_type_and: /* & */
cast = proc_cast_expr(self);
return make_sys_node(FINSH_NODE_SYS_GETADDR, cast, NULL);
default:
finsh_token_replay(&(self->token));
return proc_postfix_expr(self);
}
}
/*
expr_postfix -> expr_primary
| expr_postfix INC
| expr_postfix DEC
| expr_postfix '(' param_list ')'
*/
static struct finsh_node* proc_postfix_expr(struct finsh_parser* self)
{
enum finsh_token_type token;
struct finsh_node* postfix;
postfix = proc_primary_expr(self);
next_token(token, &(self->token));
while ( token == finsh_token_type_inc ||
token == finsh_token_type_dec ||
token == finsh_token_type_left_paren )
{
switch (token)
{
case finsh_token_type_inc :/* '++' */
postfix = make_sys_node(FINSH_NODE_SYS_INC, postfix, NULL);
break;
case finsh_token_type_dec :/* '--' */
postfix = make_sys_node(FINSH_NODE_SYS_DEC, postfix, NULL);
break;
case finsh_token_type_left_paren :/* '(' */
{
struct finsh_node* param_list;
param_list = NULL;
next_token(token, &(self->token));
if (token != finsh_token_type_right_paren)
{
finsh_token_replay(&(self->token));
param_list = proc_param_list(self);
match_token(token, &(self->token), finsh_token_type_right_paren);
}
postfix = make_sys_node(FINSH_NODE_SYS_FUNC, postfix, param_list);
}
break;
default:
break;
}
next_token(token, &(self->token));
}
finsh_token_replay(&(self->token));
return postfix;
}
/*
expr_primary -> literal
| '(' expr ')'
| identifier
*/
static struct finsh_node* proc_primary_expr(struct finsh_parser* self)
{
enum finsh_token_type token;
struct finsh_node* expr;
next_token(token, &(self->token));
switch ( token )
{
case finsh_token_type_identifier:
{
char id[FINSH_NAME_MAX + 1];
finsh_token_replay(&(self->token));
proc_identifier(self, id);
return finsh_node_new_id(id);
}
case finsh_token_type_left_paren:
expr = proc_expr(self);
match_token(token, &(self->token), finsh_token_type_right_paren);
return expr;
case finsh_token_type_value_int:
return finsh_node_new_int(self->token.value.int_value);
case finsh_token_type_value_long:
return finsh_node_new_long(self->token.value.long_value);
case finsh_token_type_value_char:
return finsh_node_new_char(self->token.value.char_value);
case finsh_token_type_value_string:
return finsh_node_new_string((char*)self->token.string);
case finsh_token_type_value_null:
return finsh_node_new_ptr(NULL);
default:
finsh_error_set(FINSH_ERROR_INVALID_TOKEN);
break;
}
return NULL;
}
/*
param_list -> empty
| expr_assign
| param_list ',' expr_assign
*/
static struct finsh_node* proc_param_list(struct finsh_parser* self)
{
enum finsh_token_type token;
struct finsh_node *node, *assign;
assign = proc_assign_expr(self);
if (assign == NULL) return NULL;
node = assign;
next_token(token, &(self->token));
while (token == finsh_token_type_comma )
{
finsh_node_sibling(assign) = proc_assign_expr(self);
if (finsh_node_sibling(assign) != NULL) assign = finsh_node_sibling(assign);
else finsh_error_set(FINSH_ERROR_EXPECT_OPERATOR);
next_token(token, &(self->token));
}
finsh_token_replay(&(self->token));
return node;
}
/*
make a new node as following tree:
new_node
|
node1__
\
node2
*/
static struct finsh_node* make_sys_node(uint8_t type, struct finsh_node* node1, struct finsh_node* node2)
{
struct finsh_node* node;
node = finsh_node_allocate(type);
if ((node1 != NULL) && (node != NULL))
{
finsh_node_child(node) = node1;
finsh_node_sibling(node1) = node2;
}
else finsh_error_set(FINSH_ERROR_NULL_NODE);
return node;
}
/*
start -> statement_expr | decl_variable
*/
void finsh_parser_run(struct finsh_parser* self, const uint8_t* string)
{
enum finsh_token_type token;
struct finsh_node *node;
node = NULL;
/* init parser */
self->parser_string = (uint8_t*)string;
/* init token */
finsh_token_init(&(self->token), self->parser_string);
/* get next token */
next_token(token, &(self->token));
while (token != finsh_token_type_eof && token != finsh_token_type_bad)
{
switch (token)
{
case finsh_token_type_identifier:
/* process expr_statement */
finsh_token_replay(&(self->token));
if (self->root != NULL)
{
finsh_node_sibling(node) = proc_expr_statement(self);
if (finsh_node_sibling(node) != NULL)
node = finsh_node_sibling(node);
}
else
{
node = proc_expr_statement(self);
self->root = node;
}
break;
default:
if (is_base_type(token) || token == finsh_token_type_unsigned)
{
/* variable decl */
finsh_token_replay(&(self->token));
if (self->root != NULL)
{
finsh_node_sibling(node) = proc_variable_decl(self);
if (finsh_node_sibling(node) != NULL)
node = finsh_node_sibling(node);
}
else
{
node = proc_variable_decl(self);
self->root = node;
}
}
else
{
/* process expr_statement */
finsh_token_replay(&(self->token));
if (self->root != NULL)
{
finsh_node_sibling(node) = proc_expr_statement(self);
if (finsh_node_sibling(node) != NULL)
node = finsh_node_sibling(node);
else next_token(token, &(self->token));
}
else
{
node = proc_expr_statement(self);
self->root = node;
}
}
break;
}
/* no root found, break out */
if (self->root == NULL) break;
/* get next token */
next_token(token, &(self->token));
}
}
int finsh_parser_init(struct finsh_parser* self)
{
memset(self, 0, sizeof(struct finsh_parser));
return 0;
}

View File

@ -1,18 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#ifndef __FINSH_PARSER_H__
#define __FINSH_PARSER_H__
#include <finsh.h>
int finsh_parser_init(struct finsh_parser* self);
void finsh_parser_run(struct finsh_parser* self, const uint8_t* string);
#endif

View File

@ -1,598 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
* 2013-04-03 Bernard strip more characters.
*/
#include <finsh.h>
#include <stdlib.h>
#include "finsh_token.h"
#include "finsh_error.h"
#define is_alpha(ch) ((ch | 0x20) - 'a') < 26u
#define is_digit(ch) ((ch) >= '0' && (ch) <= '9')
#define is_xdigit(ch) (((ch) >= '0' && (ch) <= '9') || (((ch | 0x20) - 'a') < 6u))
#define is_separator(ch) !(((ch) >= 'a' && (ch) <= 'z') \
|| ((ch) >= 'A' && (ch) <= 'Z') || ((ch) >= '0' && (ch) <= '9') || ((ch) == '_'))
#define is_eof(self) (self)->eof
struct name_table
{
char* name;
enum finsh_token_type type;
};
/* keyword */
static const struct name_table finsh_name_table[] =
{
{"void", finsh_token_type_void},
{"char", finsh_token_type_char},
{"short", finsh_token_type_short},
{"int", finsh_token_type_int},
{"long", finsh_token_type_long},
{"unsigned", finsh_token_type_unsigned},
{"NULL", finsh_token_type_value_null},
{"null", finsh_token_type_value_null}
};
static char token_next_char(struct finsh_token* self);
static void token_prev_char(struct finsh_token* self);
static long token_spec_number(char* string, int length, int b);
static void token_run(struct finsh_token* self);
static int token_match_name(struct finsh_token* self, const char* str);
static void token_proc_number(struct finsh_token* self);
static uint8_t* token_proc_string(struct finsh_token* self);
static void token_trim_space(struct finsh_token* self);
static char token_proc_char(struct finsh_token* self);
static int token_proc_escape(struct finsh_token* self);
void finsh_token_init(struct finsh_token* self, uint8_t* line)
{
memset(self, 0, sizeof(struct finsh_token));
self->line = line;
}
enum finsh_token_type finsh_token_token(struct finsh_token* self)
{
if ( self->replay ) self->replay = 0;
else token_run(self);
return (enum finsh_token_type)self->current_token;
}
void finsh_token_get_token(struct finsh_token* self, uint8_t* token)
{
strncpy((char*)token, (char*)self->string, FINSH_NAME_MAX);
}
int token_get_string(struct finsh_token* self, uint8_t* str)
{
unsigned char *p=str;
char ch;
ch = token_next_char(self);
if (is_eof(self)) return -1;
str[0] = '\0';
if ( is_digit(ch) )/*the first character of identifier is not a digit.*/
{
token_prev_char(self);
return -1;
}
while (!is_separator(ch) && !is_eof(self))
{
*p++ = ch;
ch = token_next_char(self);
}
self->eof = 0;
token_prev_char(self);
*p = '\0';
return 0;
}
/*
get next character.
*/
static char token_next_char(struct finsh_token* self)
{
if (self->eof) return '\0';
if (self->position == (int)strlen((char*)self->line) || self->line[self->position] =='\n')
{
self->eof = 1;
self->position = 0;
return '\0';
}
return self->line[self->position++];
}
static void token_prev_char(struct finsh_token* self)
{
if ( self->eof ) return;
if ( self->position == 0 ) return;
else self->position--;
}
static void token_run(struct finsh_token* self)
{
char ch;
token_trim_space(self); /* first trim space and tab. */
token_get_string(self, &(self->string[0]));
if ( is_eof(self) ) /*if it is eof, break;*/
{
self->current_token = finsh_token_type_eof;
return ;
}
if (self->string[0] != '\0') /*It is a key word or a identifier.*/
{
if ( !token_match_name(self, (char*)self->string) )
{
self->current_token = finsh_token_type_identifier;
}
}
else/*It is a operator character.*/
{
ch = token_next_char(self);
switch ( ch )
{
case '(':
self->current_token = finsh_token_type_left_paren;
break;
case ')':
self->current_token = finsh_token_type_right_paren;
break;
case ',':
self->current_token = finsh_token_type_comma;
break;
case ';':
self->current_token = finsh_token_type_semicolon;
break;
case '&':
self->current_token = finsh_token_type_and;
break;
case '*':
self->current_token = finsh_token_type_mul;
break;
case '+':
ch = token_next_char(self);
if ( ch == '+' )
{
self->current_token = finsh_token_type_inc;
}
else
{
token_prev_char(self);
self->current_token = finsh_token_type_add;
}
break;
case '-':
ch = token_next_char(self);
if ( ch == '-' )
{
self->current_token = finsh_token_type_dec;
}
else
{
token_prev_char(self);
self->current_token = finsh_token_type_sub;
}
break;
case '/':
ch = token_next_char(self);
if (ch == '/')
{
/* line comments, set to end of file */
self->current_token = finsh_token_type_eof;
}
else
{
token_prev_char(self);
self->current_token = finsh_token_type_div;
}
break;
case '<':
ch = token_next_char(self);
if ( ch == '<' )
{
self->current_token = finsh_token_type_shl;
}
else
{
token_prev_char(self);
self->current_token = finsh_token_type_bad;
}
break;
case '>':
ch = token_next_char(self);
if ( ch == '>' )
{
self->current_token = finsh_token_type_shr;
}
else
{
token_prev_char(self);
self->current_token = finsh_token_type_bad;
}
break;
case '|':
self->current_token = finsh_token_type_or;
break;
case '%':
self->current_token = finsh_token_type_mod;
break;
case '~':
self->current_token = finsh_token_type_bitwise;
break;
case '^':
self->current_token = finsh_token_type_xor;
break;
case '=':
self->current_token = finsh_token_type_assign;
break;
case '\'':
self->value.char_value = token_proc_char(self);
self->current_token = finsh_token_type_value_char;
break;
case '"':
token_proc_string(self);
self->current_token = finsh_token_type_value_string;
break;
default:
if ( is_digit(ch) )
{
token_prev_char(self);
token_proc_number(self);
break;
}
finsh_error_set(FINSH_ERROR_UNKNOWN_TOKEN);
self->current_token = finsh_token_type_bad;
break;
}
}
}
static int token_match_name(struct finsh_token* self, const char* str)
{
int i;
for (i = 0; i < sizeof(finsh_name_table)/sizeof(struct name_table); i++)
{
if ( strcmp(finsh_name_table[i].name, str)==0 )
{
self->current_token = finsh_name_table[i].type;
return 1;
}
}
return 0;
}
static void token_trim_space(struct finsh_token* self)
{
char ch;
while ( (ch = token_next_char(self)) ==' ' ||
ch == '\t' ||
ch == '\r');
token_prev_char(self);
}
static char token_proc_char(struct finsh_token* self)
{
char ch;
char buf[4], *p;
p = buf;
ch = token_next_char(self);
if ( ch == '\\' )
{
ch = token_next_char(self);
switch ( ch )
{
case 'n': ch = '\n'; break;
case 't': ch = '\t'; break;
case 'v': ch = '\v'; break;
case 'b': ch = '\b'; break;
case 'r': ch = '\r'; break;
case '\\': ch = '\\'; break;
case '\'': ch = '\''; break;
default :
while ( is_digit(ch) )/*for '\113' char*/
{
ch = token_next_char(self);
*p++ = ch;
}
token_prev_char(self);
*p = '\0';
ch = atoi(p);
break;
}
}
if ( token_next_char(self) != '\'' )
{
token_prev_char(self);
finsh_error_set(FINSH_ERROR_EXPECT_CHAR);
return ch;
}
return ch;
}
static uint8_t* token_proc_string(struct finsh_token* self)
{
uint8_t* p;
for ( p = &self->string[0]; p - &(self->string[0]) < FINSH_STRING_MAX; )
{
char ch = token_next_char(self);
if ( is_eof(self) )
{
finsh_error_set(FINSH_ERROR_UNEXPECT_END);
return NULL;;
}
if ( ch == '\\' )
{
ch = token_proc_escape(self);
}
else if ( ch == '"' )/*end of string.*/
{
*p = '\0';
return self->string;
}
*p++ = ch;
}
return NULL;
}
static int token_proc_escape(struct finsh_token* self)
{
char ch;
int result=0;
ch = token_next_char(self);
switch (ch)
{
case 'n':
result = '\n';
break;
case 't':
result = '\t';
break;
case 'v':
result = '\v';
break;
case 'b':
result = '\b';
break;
case 'r':
result = '\r';
break;
case 'f':
result = '\f';
break;
case 'a':
result = '\007';
break;
case '"':
result = '"';
break;
case 'x':
case 'X':
result = 0;
ch = token_next_char(self);
while (is_xdigit(ch))
{
result = result * 16 + ((ch < 'A') ? (ch - '0') : (ch | 0x20) - 'a' + 10);
ch = token_next_char(self);
}
token_prev_char(self);
break;
default:
if ( (ch - '0') < 8u)
{
result = 0;
while ( (ch - '0') < 8u )
{
result = result*8 + ch - '0';
ch = token_next_char(self);
}
token_prev_char(self);
}
break;
}
return result;
}
/*
(0|0x|0X|0b|0B)number+(l|L)
*/
static void token_proc_number(struct finsh_token* self)
{
char ch;
char *p, buf[128];
long value;
value = 0;
p = buf;
ch = token_next_char(self);
if ( ch == '0' )
{
int b;
ch = token_next_char(self);
if ( ch == 'x' || ch == 'X' )/*it's a hex number*/
{
b = 16;
ch = token_next_char(self);
while ( is_digit(ch) || is_alpha(ch) )
{
*p++ = ch;
ch = token_next_char(self);
}
*p = '\0';
}
else if ( ch == 'b' || ch == 'B' )
{
b = 2;
ch = token_next_char(self);
while ( (ch=='0')||(ch=='1') )
{
*p++ = ch;
ch = token_next_char(self);
}
*p = '\0';
}
else if ( '0' <= ch && ch <= '7' )
{
b = 8;
while ( '0' <= ch && ch <= '7' )
{
*p++ = ch;
ch = token_next_char(self);
}
*p = '\0';
}
else
{
token_prev_char(self);
/* made as 0 value */
self->value.int_value = 0;
self->current_token = finsh_token_type_value_int;
return;
}
self->value.int_value = token_spec_number(buf, strlen(buf), b);
self->current_token = finsh_token_type_value_int;
}
else
{
while ( is_digit(ch) )
{
value = value*10 + ( ch - '0' );
ch = token_next_char(self);
}
self->value.int_value = value;
self->current_token = finsh_token_type_value_int;
}
switch ( ch )
{
case 'l':
case 'L':
self->current_token = finsh_token_type_value_long;
break;
default:
token_prev_char(self);
break;
}
}
/*use 64 bit number*/
#define BN_SIZE 2
static long token_spec_number(char* string, int length, int b)
{
char* p;
int t;
int i, j, shift=1;
unsigned int bn[BN_SIZE], v;
long d;
p = string;
i = 0;
switch ( b )
{
case 16: shift = 4;
break;
case 8: shift = 3;
break;
case 2: shift = 1;
break;
default: break;
}
for ( j=0; j<BN_SIZE ; j++) bn[j] = 0;
while ( i<length )
{
t = *p++;
if ( t>='a' && t <='f' )
{
t = t - 'a' +10;
}
else if ( t >='A' && t <='F' )
{
t = t - 'A' +10;
}
else t = t - '0';
for ( j=0; j<BN_SIZE ; j++)
{
v = bn[j];
bn[j] = (v<<shift) | t;
t = v >> (32 - shift);
}
i++;
}
d = (long)bn[0];
return d;
}

View File

@ -1,63 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#ifndef __FINSH_TOKEN_H__
#define __FINSH_TOKEN_H__
#include <finsh.h>
enum finsh_token_type
{
finsh_token_type_left_paren = 1, /* ( */
finsh_token_type_right_paren , /* ) */
finsh_token_type_comma , /* , */
finsh_token_type_semicolon , /* ; */
finsh_token_type_mul , /* * */
finsh_token_type_add , /* + */
finsh_token_type_inc , /* ++ */
finsh_token_type_sub , /* - */
finsh_token_type_dec , /* -- */
finsh_token_type_div , /* / */
finsh_token_type_mod , /* % */
finsh_token_type_assign , /* = */
finsh_token_type_and, /* & */
finsh_token_type_or, /* | */
finsh_token_type_xor, /* ^ */
finsh_token_type_bitwise, /* ~ */
finsh_token_type_shl, /* << */
finsh_token_type_shr, /* >> */
finsh_token_type_comments, /* // */
/*-- data type --*/
finsh_token_type_void, /* void */
finsh_token_type_char, /* char */
finsh_token_type_short, /* short */
finsh_token_type_int, /* int */
finsh_token_type_long, /* long */
finsh_token_type_unsigned, /* unsigned */
/* data value type */
finsh_token_type_value_char, /* v:char */
finsh_token_type_value_int, /* v:int */
finsh_token_type_value_long, /* v:long */
finsh_token_type_value_string, /* v:string */
finsh_token_type_value_null, /* NULL */
/*-- others --*/
finsh_token_type_identifier, /* ID */
finsh_token_type_bad, /* bad token */
finsh_token_type_eof
};
#define finsh_token_position(self) (self)->position
#define finsh_token_replay(self) (self)->replay = 1
void finsh_token_init(struct finsh_token* self, uint8_t* script);
enum finsh_token_type finsh_token_token(struct finsh_token* self);
void finsh_token_get_token(struct finsh_token* self, uint8_t* token);
#endif

View File

@ -1,142 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
* 2012-04-27 Bernard fixed finsh_var_delete issue which
* is found by Grissiom.
*/
#include <finsh.h>
#include "finsh_var.h"
struct finsh_var global_variable[FINSH_VARIABLE_MAX];
struct finsh_sysvar_item* global_sysvar_list;
int finsh_var_init()
{
memset(global_variable, 0, sizeof(global_variable));
return 0;
}
int finsh_var_insert(const char* name, int type)
{
int i, empty;
empty = -1;
for (i = 0; i < FINSH_VARIABLE_MAX; i ++)
{
/* there is a same name variable exist. */
if (strncmp(global_variable[i].name, name, FINSH_NAME_MAX) == 0)
return -1;
if (global_variable[i].type == finsh_type_unknown && empty == -1)
{
empty = i;
}
}
/* there is no empty entry */
if (empty == -1) return -1;
/* insert entry */
strncpy(global_variable[empty].name, name, FINSH_NAME_MAX);
global_variable[empty].type = type;
/* return the offset */
return empty;
}
int finsh_var_delete(const char* name)
{
int i;
for (i = 0; i < FINSH_VARIABLE_MAX; i ++)
{
if (strncmp(global_variable[i].name, name, FINSH_NAME_MAX) == 0)
break;
}
/* can't find variable */
if (i == FINSH_VARIABLE_MAX) return -1;
memset(&global_variable[i], 0, sizeof(struct finsh_var));
return 0;
}
struct finsh_var* finsh_var_lookup(const char* name)
{
int i;
for (i = 0; i < FINSH_VARIABLE_MAX; i ++)
{
if (strncmp(global_variable[i].name, name, FINSH_NAME_MAX) == 0)
break;
}
/* can't find variable */
if (i == FINSH_VARIABLE_MAX) return NULL;
return &global_variable[i];
}
#ifdef RT_USING_HEAP
void finsh_sysvar_append(const char* name, uint8_t type, void* var_addr)
{
/* create a sysvar */
struct finsh_sysvar_item* item;
item = (struct finsh_sysvar_item*) rt_malloc (sizeof(struct finsh_sysvar_item));
if (item != NULL)
{
item->next = NULL;
item->sysvar.name = rt_strdup(name);
item->sysvar.type = type;
item->sysvar.var = var_addr;
if (global_sysvar_list == NULL)
{
global_sysvar_list = item;
}
else
{
item->next = global_sysvar_list;
global_sysvar_list = item;
}
}
}
#endif
struct finsh_sysvar* finsh_sysvar_lookup(const char* name)
{
struct finsh_sysvar* index;
struct finsh_sysvar_item* item;
for (index = _sysvar_table_begin;
index < _sysvar_table_end;
FINSH_NEXT_SYSVAR(index))
{
if (strcmp(index->name, name) == 0)
return index;
}
/* find in sysvar list */
item = global_sysvar_list;
while (item != NULL)
{
if (strncmp(item->sysvar.name, name, strlen(name)) == 0)
{
return &(item->sysvar);
}
/* move to next item */
item = item->next;
}
/* can't find variable */
return NULL;
}

View File

@ -1,41 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#ifndef __FINSH_VAR_H__
#define __FINSH_VAR_H__
#include <finsh.h>
/*
* The variable in finsh is put in data segment as a global variable.
* The 'finsh_var' structure presents the structure of variable in data segment.
*/
struct finsh_var
{
char name[FINSH_NAME_MAX + 1]; /* the name of variable */
uint8_t type; /* the type of variable */
/* variable value */
union {
char char_value;
short short_value;
int int_value;
long long_value;
void* ptr;
}value;
};
extern struct finsh_var global_variable[];
int finsh_var_init(void);
int finsh_var_insert(const char* name, int type);
int finsh_var_delete(const char* name);
struct finsh_var* finsh_var_lookup(const char* name);
#endif

View File

@ -1,363 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#include <finsh.h>
#include "finsh_vm.h"
#include "finsh_ops.h"
#include "finsh_var.h"
/* stack */
union finsh_value finsh_vm_stack[FINSH_STACK_MAX];
/* text segment */
uint8_t text_segment[FINSH_TEXT_MAX];
union finsh_value* finsh_sp; /* stack pointer */
uint8_t* finsh_pc; /* PC */
/* syscall list, for dynamic system call register */
struct finsh_syscall_item* global_syscall_list = NULL;
// #define FINSH_VM_DISASSEMBLE
void finsh_vm_run()
{
uint8_t op;
/* if you want to disassemble the byte code, please define FINSH_VM_DISASSEMBLE */
#ifdef FINSH_VM_DISASSEMBLE
void finsh_disassemble();
finsh_disassemble();
#endif
/* set sp(stack pointer) to the beginning of stack */
finsh_sp = &finsh_vm_stack[0];
/* set pc to the beginning of text segment */
finsh_pc = &text_segment[0];
while ((finsh_pc - &text_segment[0] >= 0) &&
(finsh_pc - &text_segment[0] < FINSH_TEXT_MAX))
{
/* get op */
op = *finsh_pc++;
/* call op function */
op_table[op]();
}
}
#ifdef RT_USING_HEAP
void finsh_syscall_append(const char* name, syscall_func func)
{
/* create the syscall */
struct finsh_syscall_item* item;
item = (struct finsh_syscall_item*)rt_malloc(sizeof(struct finsh_syscall_item));
if (item != RT_NULL)
{
item->next = NULL;
item->syscall.name = rt_strdup(name);
item->syscall.func = func;
if (global_syscall_list == NULL)
{
global_syscall_list = item;
}
else
{
item->next = global_syscall_list;
global_syscall_list = item;
}
}
}
#endif
struct finsh_syscall* finsh_syscall_lookup(const char* name)
{
struct finsh_syscall* index;
struct finsh_syscall_item* item;
for (index = _syscall_table_begin; index < _syscall_table_end; FINSH_NEXT_SYSCALL(index))
{
if (strcmp(index->name, name) == 0)
return index;
}
/* find on syscall list */
item = global_syscall_list;
while (item != NULL)
{
if (strncmp(item->syscall.name, name, strlen(name)) == 0)
{
return &(item->syscall);
}
item = item->next;
}
return NULL;
}
#ifdef FINSH_VM_DISASSEMBLE
void finsh_disassemble()
{
uint8_t *pc, op;
pc = &text_segment[0];
while (*pc != 0)
{
op = *pc;
switch (op)
{
case FINSH_OP_ADD_BYTE:
pc ++;
rt_kprintf("addb\n");
break;
case FINSH_OP_SUB_BYTE:
pc ++;
rt_kprintf("subb\n");
break;
case FINSH_OP_DIV_BYTE:
pc ++;
rt_kprintf("divb\n");
break;
case FINSH_OP_MOD_BYTE:
pc ++;
rt_kprintf("modb\n");
break;
case FINSH_OP_MUL_BYTE:
pc ++;
rt_kprintf("mulb\n");
break;
case FINSH_OP_AND_BYTE:
pc ++;
rt_kprintf("andb\n");
break;
case FINSH_OP_OR_BYTE:
pc ++;
rt_kprintf("orb\n");
break;
case FINSH_OP_XOR_BYTE:
pc ++;
rt_kprintf("xorb\n");
break;
case FINSH_OP_BITWISE_BYTE:
pc ++;
rt_kprintf("bwb\n");
break;
case FINSH_OP_SHL_BYTE:
pc ++;
rt_kprintf("shlb\n");
break;
case FINSH_OP_SHR_BYTE:
pc ++;
rt_kprintf("shrb\n");
break;
case FINSH_OP_LD_BYTE:
pc ++;
rt_kprintf("ldb %d\n", *pc++);
break;
case FINSH_OP_LD_VALUE_BYTE:
pc ++;
rt_kprintf("ldb [0x%x]\n", FINSH_GET32(pc));
pc += 4;
break;
case FINSH_OP_ST_BYTE:
pc ++;
rt_kprintf("stb\n");
break;
case FINSH_OP_ADD_WORD:
pc ++;
rt_kprintf("addw\n");
break;
case FINSH_OP_SUB_WORD:
pc ++;
rt_kprintf("subw\n");
break;
case FINSH_OP_DIV_WORD:
pc ++;
rt_kprintf("divw\n");
break;
case FINSH_OP_MOD_WORD:
pc ++;
rt_kprintf("modw\n");
break;
case FINSH_OP_MUL_WORD:
pc ++;
rt_kprintf("mulw\n");
break;
case FINSH_OP_AND_WORD:
pc ++;
rt_kprintf("andw\n");
break;
case FINSH_OP_OR_WORD:
pc ++;
rt_kprintf("orw\n");
break;
case FINSH_OP_XOR_WORD:
pc ++;
rt_kprintf("xorw\n");
break;
case FINSH_OP_BITWISE_WORD:
pc ++;
rt_kprintf("bww\n");
break;
case FINSH_OP_SHL_WORD:
pc ++;
rt_kprintf("shlw\n");
break;
case FINSH_OP_SHR_WORD:
pc ++;
rt_kprintf("shrw\n");
break;
case FINSH_OP_LD_WORD:
pc ++;
rt_kprintf("ldw %d\n", FINSH_GET16(pc));
pc += 2;
break;
case FINSH_OP_LD_VALUE_WORD:
pc ++;
rt_kprintf("ldw [0x%x]\n", FINSH_GET32(pc));
pc += 4;
break;
case FINSH_OP_ST_WORD:
pc ++;
rt_kprintf("stw\n");
break;
case FINSH_OP_ADD_DWORD:
pc ++;
rt_kprintf("addd\n");
break;
case FINSH_OP_SUB_DWORD:
pc ++;
rt_kprintf("subd\n");
break;
case FINSH_OP_DIV_DWORD:
pc ++;
rt_kprintf("divd\n");
break;
case FINSH_OP_MOD_DWORD:
pc ++;
rt_kprintf("modd\n");
break;
case FINSH_OP_MUL_DWORD:
pc ++;
rt_kprintf("muld\n");
break;
case FINSH_OP_AND_DWORD:
pc ++;
rt_kprintf("andd\n");
break;
case FINSH_OP_OR_DWORD:
pc ++;
rt_kprintf("ord\n");
break;
case FINSH_OP_XOR_DWORD:
pc ++;
rt_kprintf("xord\n");
break;
case FINSH_OP_BITWISE_DWORD:
pc ++;
rt_kprintf("bwd\n");
break;
case FINSH_OP_SHL_DWORD:
pc ++;
rt_kprintf("shld\n");
break;
case FINSH_OP_SHR_DWORD:
pc ++;
rt_kprintf("shrd\n");
break;
case FINSH_OP_LD_DWORD:
pc ++;
rt_kprintf("ldd 0x%x\n", FINSH_GET32(pc));
pc += 4;
break;
case FINSH_OP_LD_VALUE_DWORD:
pc ++;
rt_kprintf("ldd [0x%x]\n", FINSH_GET32(pc));
pc += 4;
break;
case FINSH_OP_ST_DWORD:
pc ++;
rt_kprintf("std\n");
break;
case FINSH_OP_POP:
rt_kprintf("pop\n");
pc ++;
break;
case FINSH_OP_SYSCALL:
pc ++;
rt_kprintf("syscall %d\n", *pc++);
break;
case FINSH_OP_LD_VALUE_BYTE_STACK:
pc ++;
rt_kprintf("ldb [sp]\n");
break;
case FINSH_OP_LD_VALUE_WORD_STACK:
pc ++;
rt_kprintf("ldw [sp]\n");
break;
case FINSH_OP_LD_VALUE_DWORD_STACK:
pc ++;
rt_kprintf("ldd [sp]\n");
break;
default:
return;
}
}
}
#endif

View File

@ -1,35 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#ifndef __FINSH_VM_H__
#define __FINSH_VM_H__
#include <finsh.h>
#include "finsh_var.h"
union finsh_value {
char char_value;
short short_value;
long long_value;
void* ptr;
};
extern union finsh_value* finsh_sp; /* stack pointer */
extern uint8_t* finsh_pc; /* PC */
/* stack */
extern union finsh_value finsh_vm_stack[FINSH_STACK_MAX];
/* text segment */
extern uint8_t text_segment[FINSH_TEXT_MAX];
void finsh_vm_run(void);
//void finsh_disassemble(void);
#endif

View File

@ -10,61 +10,27 @@
* 2017-07-19 Aubr.Cool limit argc to RT_FINSH_ARG_MAX
*/
#include <rtthread.h>
#include <string.h>
#ifdef FINSH_USING_MSH
#ifdef RT_USING_FINSH
#ifndef FINSH_ARG_MAX
#define FINSH_ARG_MAX 8
#endif
#include "msh.h"
#include <finsh.h>
#include <shell.h>
#include "shell.h"
#ifdef RT_USING_DFS
#include <dfs_posix.h>
#include <dfs_posix.h>
#endif
#ifdef RT_USING_MODULE
#include <dlmodule.h>
#endif
#ifndef FINSH_ARG_MAX
#define FINSH_ARG_MAX 8
#include <dlmodule.h>
#endif
typedef int (*cmd_function_t)(int argc, char **argv);
#ifdef FINSH_USING_MSH
#ifdef FINSH_USING_MSH_ONLY
rt_bool_t msh_is_used(void)
{
return RT_TRUE;
}
#else
#ifdef FINSH_USING_MSH_DEFAULT
static rt_bool_t __msh_state = RT_TRUE;
#else
static rt_bool_t __msh_state = RT_FALSE;
#endif
rt_bool_t msh_is_used(void)
{
return __msh_state;
}
static int msh_exit(int argc, char **argv)
{
/* return to finsh shell mode */
__msh_state = RT_FALSE;
return 0;
}
FINSH_FUNCTION_EXPORT_ALIAS(msh_exit, __cmd_exit, return to RT-Thread shell mode.);
static int msh_enter(void)
{
/* enter module shell mode */
__msh_state = RT_TRUE;
return 0;
}
FINSH_FUNCTION_EXPORT_ALIAS(msh_enter, msh, use module shell);
#endif
int msh_help(int argc, char **argv)
{
rt_kprintf("RT-Thread shell commands:\n");
@ -87,7 +53,7 @@ int msh_help(int argc, char **argv)
return 0;
}
FINSH_FUNCTION_EXPORT_ALIAS(msh_help, __cmd_help, RT-Thread shell help.);
MSH_CMD_EXPORT_ALIAS(msh_help, help, RT - Thread shell help.);
int cmd_ps(int argc, char **argv)
{
@ -102,7 +68,7 @@ int cmd_ps(int argc, char **argv)
list_thread();
return 0;
}
FINSH_FUNCTION_EXPORT_ALIAS(cmd_ps, __cmd_ps, List threads in the system.);
MSH_CMD_EXPORT_ALIAS(cmd_ps, ps, List threads in the system.);
#ifdef RT_USING_HEAP
int cmd_free(int argc, char **argv)
@ -117,7 +83,7 @@ int cmd_free(int argc, char **argv)
#endif
return 0;
}
FINSH_FUNCTION_EXPORT_ALIAS(cmd_free, __cmd_free, Show the memory usage in the system.);
MSH_CMD_EXPORT_ALIAS(cmd_free, free, Show the memory usage in the system.);
#endif
static int msh_split(char *cmd, rt_size_t length, char *argv[FINSH_ARG_MAX])
@ -128,7 +94,8 @@ static int msh_split(char *cmd, rt_size_t length, char *argv[FINSH_ARG_MAX])
rt_size_t i;
ptr = cmd;
position = 0; argc = 0;
position = 0;
argc = 0;
while (position < length)
{
@ -136,13 +103,14 @@ static int msh_split(char *cmd, rt_size_t length, char *argv[FINSH_ARG_MAX])
while ((*ptr == ' ' || *ptr == '\t') && position < length)
{
*ptr = '\0';
ptr ++; position ++;
ptr ++;
position ++;
}
if(argc >= FINSH_ARG_MAX)
if (argc >= FINSH_ARG_MAX)
{
rt_kprintf("Too many args ! We only Use:\n");
for(i = 0; i < argc; i++)
for (i = 0; i < argc; i++)
{
rt_kprintf("%s ", argv[i]);
}
@ -155,8 +123,10 @@ static int msh_split(char *cmd, rt_size_t length, char *argv[FINSH_ARG_MAX])
/* handle string */
if (*ptr == '"')
{
ptr ++; position ++;
argv[argc] = ptr; argc ++;
ptr ++;
position ++;
argv[argc] = ptr;
argc ++;
/* skip this string */
while (*ptr != '"' && position < length)
@ -165,15 +135,19 @@ static int msh_split(char *cmd, rt_size_t length, char *argv[FINSH_ARG_MAX])
{
if (*(ptr + 1) == '"')
{
ptr ++; position ++;
ptr ++;
position ++;
}
}
ptr ++; position ++;
ptr ++;
position ++;
}
if (position >= length) break;
/* skip '"' */
*ptr = '\0'; ptr ++; position ++;
*ptr = '\0';
ptr ++;
position ++;
}
else
{
@ -181,7 +155,8 @@ static int msh_split(char *cmd, rt_size_t length, char *argv[FINSH_ARG_MAX])
argc ++;
while ((*ptr != ' ' && *ptr != '\t') && position < length)
{
ptr ++; position ++;
ptr ++;
position ++;
}
if (position >= length) break;
}
@ -340,7 +315,7 @@ static int _msh_exec_lwp(char *cmd, rt_size_t length)
int fd = -1;
char *pg_name;
extern int exec(char*, int, char**);
extern int exec(char *, int, char **);
/* find the size of first command */
while ((cmd[cmd0_size] != ' ' && cmd[cmd0_size] != '\t') && cmd0_size < length)
@ -642,6 +617,4 @@ void msh_auto_complete(char *prefix)
return ;
}
#endif
#endif /* FINSH_USING_MSH */
#endif /* RT_USING_FINSH */

View File

@ -13,7 +13,6 @@
#include <rtthread.h>
rt_bool_t msh_is_used(void);
int msh_exec(char *cmd, rt_size_t length);
void msh_auto_complete(char *prefix);

View File

@ -11,7 +11,7 @@
#include <rtthread.h>
#if defined(FINSH_USING_MSH) && defined(RT_USING_DFS)
#if defined(RT_USING_FINSH) && defined(RT_USING_DFS)
#include <finsh.h>
#include "msh.h"
@ -144,7 +144,7 @@ int msh_exec_script(const char *cmd_line, int size)
}
#ifdef DFS_USING_WORKDIR
extern char working_directory[];
extern char working_directory[];
#endif
static int cmd_ls(int argc, char **argv)
@ -614,19 +614,19 @@ static int cmd_tail(int argc, char **argv)
rt_uint32_t required_lines = 0;
rt_uint32_t after_xxx_line = 0;
if(argc < 2)
if (argc < 2)
{
rt_kprintf("Usage: tail [-n numbers] <filename>\n");
return -1;
}
else if(argc == 2)
else if (argc == 2)
{
required_lines = 10; /* default: 10 lines from tail */
file_name = argv[1];
}
else if(rt_strcmp(argv[1], "-n") == 0)
else if (rt_strcmp(argv[1], "-n") == 0)
{
if(argv[2][0] != '+')
if (argv[2][0] != '+')
{
required_lines = atoi(argv[2]);
}
@ -659,9 +659,9 @@ static int cmd_tail(int argc, char **argv)
rt_kprintf("\nTotal Number of lines:%d\n", total_lines);
if(after_xxx_line != 0)
if (after_xxx_line != 0)
{
if(total_lines > after_xxx_line)
if (total_lines > after_xxx_line)
{
required_lines = total_lines - after_xxx_line;
}
@ -700,7 +700,7 @@ static int cmd_tail(int argc, char **argv)
close(fd);
return 0;
}
MSH_CMD_EXPORT_ALIAS(cmd_tail, tail, print the last N-lines data of the given file);
MSH_CMD_EXPORT_ALIAS(cmd_tail, tail, print the last N - lines data of the given file);
#endif /* defined(FINSH_USING_MSH) && defined(RT_USING_DFS) */
#endif /* defined(RT_USING_FINSH) && defined(RT_USING_DFS) */

View File

@ -19,75 +19,62 @@
*/
#include <rthw.h>
#include <string.h>
#include <stdio.h>
#ifdef RT_USING_FINSH
#include "finsh.h"
#include "shell.h"
#ifdef FINSH_USING_MSH
#include "msh.h"
#endif
#ifdef _WIN32
#include <stdio.h> /* for putchar */
#endif
#if defined(RT_USING_DFS)
#include <dfs_posix.h>
#endif /* RT_USING_DFS */
/* finsh thread */
#ifndef RT_USING_HEAP
static struct rt_thread finsh_thread;
ALIGN(RT_ALIGN_SIZE)
static char finsh_thread_stack[FINSH_THREAD_STACK_SIZE];
struct finsh_shell _shell;
static struct rt_thread finsh_thread;
ALIGN(RT_ALIGN_SIZE)
static char finsh_thread_stack[FINSH_THREAD_STACK_SIZE];
struct finsh_shell _shell;
#endif
/* finsh symtab */
#ifdef FINSH_USING_SYMTAB
struct finsh_syscall *_syscall_table_begin = NULL;
struct finsh_syscall *_syscall_table_end = NULL;
struct finsh_sysvar *_sysvar_table_begin = NULL;
struct finsh_sysvar *_sysvar_table_end = NULL;
struct finsh_syscall *_syscall_table_begin = NULL;
struct finsh_syscall *_syscall_table_end = NULL;
#endif
struct finsh_shell *shell;
static char *finsh_prompt_custom = RT_NULL;
#if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__))
struct finsh_syscall* finsh_syscall_next(struct finsh_syscall* call)
struct finsh_syscall *finsh_syscall_next(struct finsh_syscall *call)
{
unsigned int *ptr;
ptr = (unsigned int*) (call + 1);
while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _syscall_table_end))
ptr = (unsigned int *)(call + 1);
while ((*ptr == 0) && ((unsigned int *)ptr < (unsigned int *) _syscall_table_end))
ptr ++;
return (struct finsh_syscall*)ptr;
return (struct finsh_syscall *)ptr;
}
struct finsh_sysvar* finsh_sysvar_next(struct finsh_sysvar* call)
{
unsigned int *ptr;
ptr = (unsigned int*) (call + 1);
while ((*ptr == 0) && ((unsigned int*)ptr < (unsigned int*) _sysvar_table_end))
ptr ++;
return (struct finsh_sysvar*)ptr;
}
#endif /* defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__)) */
#ifdef RT_USING_HEAP
int finsh_set_prompt(const char * prompt)
int finsh_set_prompt(const char *prompt)
{
if(finsh_prompt_custom)
if (finsh_prompt_custom)
{
rt_free(finsh_prompt_custom);
finsh_prompt_custom = RT_NULL;
}
/* strdup */
if(prompt)
if (prompt)
{
finsh_prompt_custom = (char *)rt_malloc(strlen(prompt)+1);
if(finsh_prompt_custom)
finsh_prompt_custom = (char *)rt_malloc(strlen(prompt) + 1);
if (finsh_prompt_custom)
{
strcpy(finsh_prompt_custom, prompt);
}
@ -97,14 +84,10 @@ int finsh_set_prompt(const char * prompt)
}
#endif /* RT_USING_HEAP */
#ifdef RT_USING_DFS
#include <dfs_posix.h>
#endif /* RT_USING_DFS */
#define _MSH_PROMPT "msh "
const char *finsh_get_prompt(void)
{
#define _MSH_PROMPT "msh "
#define _PROMPT "finsh "
static char finsh_prompt[RT_CONSOLEBUF_SIZE + 1] = {0};
/* check prompt mode */
@ -114,17 +97,12 @@ const char *finsh_get_prompt(void)
return finsh_prompt;
}
if(finsh_prompt_custom)
if (finsh_prompt_custom)
{
strncpy(finsh_prompt, finsh_prompt_custom, sizeof(finsh_prompt)-1);
strncpy(finsh_prompt, finsh_prompt_custom, sizeof(finsh_prompt) - 1);
return finsh_prompt;
}
#ifdef FINSH_USING_MSH
if (msh_is_used()) strcpy(finsh_prompt, _MSH_PROMPT);
else
#endif
strcpy(finsh_prompt, _PROMPT);
strcpy(finsh_prompt, _MSH_PROMPT);
#if defined(RT_USING_DFS) && defined(DFS_USING_WORKDIR)
/* get current working directory */
@ -288,7 +266,8 @@ rt_uint32_t finsh_get_echo()
* @return result, RT_EOK on OK, -RT_ERROR on the new password length is less than
* FINSH_PASSWORD_MIN or greater than FINSH_PASSWORD_MAX
*/
rt_err_t finsh_set_password(const char *password) {
rt_err_t finsh_set_password(const char *password)
{
rt_ubase_t level;
rt_size_t pw_len = rt_strlen(password);
@ -372,71 +351,12 @@ static void finsh_wait_auth(void)
static void shell_auto_complete(char *prefix)
{
rt_kprintf("\n");
#ifdef FINSH_USING_MSH
if (msh_is_used() == RT_TRUE)
{
msh_auto_complete(prefix);
}
else
#endif
{
#ifndef FINSH_USING_MSH_ONLY
extern void list_prefix(char * prefix);
list_prefix(prefix);
#endif
}
msh_auto_complete(prefix);
rt_kprintf("%s%s", FINSH_PROMPT, prefix);
}
#ifndef FINSH_USING_MSH_ONLY
void finsh_run_line(struct finsh_parser *parser, const char *line)
{
const char *err_str;
if(shell->echo_mode)
rt_kprintf("\n");
finsh_parser_run(parser, (unsigned char *)line);
/* compile node root */
if (finsh_errno() == 0)
{
finsh_compiler_run(parser->root);
}
else
{
err_str = finsh_error_string(finsh_errno());
rt_kprintf("%s\n", err_str);
}
/* run virtual machine */
if (finsh_errno() == 0)
{
char ch;
finsh_vm_run();
ch = (unsigned char)finsh_stack_bottom();
if (ch > 0x20 && ch < 0x7e)
{
rt_kprintf("\t'%c', %d, 0x%08x\n",
(unsigned char)finsh_stack_bottom(),
(unsigned int)finsh_stack_bottom(),
(unsigned int)finsh_stack_bottom());
}
else
{
rt_kprintf("\t%d, 0x%08x\n",
(unsigned int)finsh_stack_bottom(),
(unsigned int)finsh_stack_bottom());
}
}
finsh_flush(parser);
}
#endif
#ifdef FINSH_USING_HISTORY
static rt_bool_t shell_handle_history(struct finsh_shell *shell)
{
@ -508,10 +428,6 @@ void finsh_thread_entry(void *parameter)
shell->echo_mode = 0;
#endif
#ifndef FINSH_USING_MSH_ONLY
finsh_init(&shell->parser);
#endif
#if !defined(RT_USING_POSIX) && defined(RT_USING_DEVICE)
/* set console device as shell device */
if (shell->device == RT_NULL)
@ -694,26 +610,9 @@ void finsh_thread_entry(void *parameter)
#ifdef FINSH_USING_HISTORY
shell_push_history(shell);
#endif
#ifdef FINSH_USING_MSH
if (msh_is_used() == RT_TRUE)
{
if (shell->echo_mode)
rt_kprintf("\n");
msh_exec(shell->line, shell->line_position);
}
else
#endif
{
#ifndef FINSH_USING_MSH_ONLY
/* add ';' and run the command line */
shell->line[shell->line_position] = ';';
if (shell->line_position != 0) finsh_run_line(&shell->parser, shell->line);
else
if (shell->echo_mode) rt_kprintf("\n");
#endif
}
if (shell->echo_mode)
rt_kprintf("\n");
msh_exec(shell->line, shell->line_position);
rt_kprintf(FINSH_PROMPT);
memset(shell->line, 0, sizeof(shell->line));
@ -766,23 +665,14 @@ void finsh_system_function_init(const void *begin, const void *end)
_syscall_table_end = (struct finsh_syscall *) end;
}
void finsh_system_var_init(const void *begin, const void *end)
{
_sysvar_table_begin = (struct finsh_sysvar *) begin;
_sysvar_table_end = (struct finsh_sysvar *) end;
}
#if defined(__ICCARM__) || defined(__ICCRX__) /* for IAR compiler */
#ifdef FINSH_USING_SYMTAB
#pragma section="FSymTab"
#pragma section="VSymTab"
#pragma section="FSymTab"
#endif
#elif defined(__ADSPBLACKFIN__) /* for VisaulDSP++ Compiler*/
#ifdef FINSH_USING_SYMTAB
extern "asm" int __fsymtab_start;
extern "asm" int __fsymtab_end;
extern "asm" int __vsymtab_start;
extern "asm" int __vsymtab_end;
extern "asm" int __fsymtab_start;
extern "asm" int __fsymtab_end;
#endif
#elif defined(_MSC_VER)
#pragma section("FSymTab$a", read)
@ -820,32 +710,21 @@ int finsh_system_init(void)
#ifdef __ARMCC_VERSION /* ARM C Compiler */
extern const int FSymTab$$Base;
extern const int FSymTab$$Limit;
extern const int VSymTab$$Base;
extern const int VSymTab$$Limit;
finsh_system_function_init(&FSymTab$$Base, &FSymTab$$Limit);
#ifndef FINSH_USING_MSH_ONLY
finsh_system_var_init(&VSymTab$$Base, &VSymTab$$Limit);
#endif
#elif defined (__ICCARM__) || defined(__ICCRX__) /* for IAR Compiler */
finsh_system_function_init(__section_begin("FSymTab"),
__section_end("FSymTab"));
finsh_system_var_init(__section_begin("VSymTab"),
__section_end("VSymTab"));
#elif defined (__GNUC__) || defined(__TI_COMPILER_VERSION__) || defined(__TASKING__)
/* GNU GCC Compiler and TI CCS */
extern const int __fsymtab_start;
extern const int __fsymtab_end;
extern const int __vsymtab_start;
extern const int __vsymtab_end;
finsh_system_function_init(&__fsymtab_start, &__fsymtab_end);
finsh_system_var_init(&__vsymtab_start, &__vsymtab_end);
#elif defined(__ADSPBLACKFIN__) /* for VisualDSP++ Compiler */
finsh_system_function_init(&__fsymtab_start, &__fsymtab_end);
finsh_system_var_init(&__vsymtab_start, &__vsymtab_end);
#elif defined(_MSC_VER)
unsigned int *ptr_begin, *ptr_end;
if(shell)
if (shell)
{
rt_kprintf("finsh shell already init.\n");
return RT_EOK;

View File

@ -15,20 +15,20 @@
#include "finsh.h"
#ifndef FINSH_THREAD_PRIORITY
#define FINSH_THREAD_PRIORITY 20
#define FINSH_THREAD_PRIORITY 20
#endif
#ifndef FINSH_THREAD_STACK_SIZE
#define FINSH_THREAD_STACK_SIZE 2048
#define FINSH_THREAD_STACK_SIZE 2048
#endif
#ifndef FINSH_CMD_SIZE
#define FINSH_CMD_SIZE 80
#define FINSH_CMD_SIZE 80
#endif
#define FINSH_OPTION_ECHO 0x01
#define FINSH_PROMPT finsh_get_prompt()
const char* finsh_get_prompt(void);
int finsh_set_prompt(const char * prompt);
const char *finsh_get_prompt(void);
int finsh_set_prompt(const char *prompt);
#ifdef FINSH_USING_HISTORY
#ifndef FINSH_HISTORY_LINES
@ -49,7 +49,7 @@ int finsh_set_prompt(const char * prompt);
#endif /* FINSH_USING_AUTH */
#ifndef FINSH_THREAD_NAME
#define FINSH_THREAD_NAME "tshell"
#define FINSH_THREAD_NAME "tshell"
#endif
enum input_stat
@ -64,7 +64,7 @@ struct finsh_shell
enum input_stat stat;
rt_uint8_t echo_mode:1;
rt_uint8_t echo_mode: 1;
rt_uint8_t prompt_mode: 1;
#ifdef FINSH_USING_HISTORY
@ -74,10 +74,6 @@ struct finsh_shell
char cmd_history[FINSH_HISTORY_LINES][FINSH_CMD_SIZE];
#endif
#ifndef FINSH_USING_MSH_ONLY
struct finsh_parser parser;
#endif
char line[FINSH_CMD_SIZE + 1];
rt_uint16_t line_position;
rt_uint16_t line_curpos;
@ -95,16 +91,16 @@ void finsh_set_echo(rt_uint32_t echo);
rt_uint32_t finsh_get_echo(void);
int finsh_system_init(void);
void finsh_set_device(const char* device_name);
const char* finsh_get_device(void);
void finsh_set_device(const char *device_name);
const char *finsh_get_device(void);
char finsh_getchar(void);
rt_uint32_t finsh_get_prompt_mode(void);
void finsh_set_prompt_mode(rt_uint32_t prompt_mode);
#ifdef FINSH_USING_AUTH
rt_err_t finsh_set_password(const char *password);
const char *finsh_get_password(void);
rt_err_t finsh_set_password(const char *password);
const char *finsh_get_password(void);
#endif
#endif

View File

@ -1,66 +0,0 @@
/*
* Copyright (c) 2006-2021, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2010-03-22 Bernard first version
*/
#include <rtthread.h>
#if defined(RT_USING_FINSH) && !defined(FINSH_USING_SYMTAB)
#include "finsh.h"
long hello(void);
long version(void);
long list(void);
long list_thread(void);
long list_sem(void);
long list_mutex(void);
long list_fevent(void);
long list_event(void);
long list_mailbox(void);
long list_msgqueue(void);
long list_mempool(void);
long list_timer(void);
struct finsh_syscall _syscall_table[] =
{
{"hello", hello},
{"version", version},
{"list", list},
{"list_thread", list_thread},
#ifdef RT_USING_SEMAPHORE
{"list_sem", list_sem},
#endif
#ifdef RT_USING_MUTEX
{"list_mutex", list_mutex},
#endif
#ifdef RT_USING_FEVENT
{"list_fevent", list_fevent},
#endif
#ifdef RT_USING_EVENT
{"list_event", list_event},
#endif
#ifdef RT_USING_MAILBOX
{"list_mb", list_mailbox},
#endif
#ifdef RT_USING_MESSAGEQUEUE
{"list_mq", list_msgqueue},
#endif
#ifdef RT_USING_MEMPOOL
{"list_memp", list_mempool},
#endif
{"list_timer", list_timer},
};
struct finsh_syscall *_syscall_table_begin = &_syscall_table[0];
struct finsh_syscall *_syscall_table_end = &_syscall_table[sizeof(_syscall_table) / sizeof(struct finsh_syscall)];
struct finsh_sysvar *_sysvar_table_begin = NULL;
struct finsh_sysvar *_sysvar_table_end = NULL;
#endif /* RT_USING_FINSH && !FINSH_USING_SYMTAB */

View File

@ -302,7 +302,7 @@ int remove(const char *filename)
#endif
}
#if defined(RT_USING_FINSH) && defined(FINSH_USING_MSH) && defined(RT_USING_MODULE) && defined(RT_USING_DFS)
#if defined(RT_USING_FINSH) && defined(RT_USING_MODULE) && defined(RT_USING_DFS)
/* use system(const char *string) implementation in the msh */
#else
int system(const char *string)

View File

@ -68,7 +68,7 @@ if RT_USING_AT
config AT_USING_CLI
bool "Enable CLI(Command-Line Interface) for AT commands"
default y
depends on FINSH_USING_MSH
depends on RT_USING_FINSH
config AT_PRINT_RAW_CMD
bool "Enable print RAW format AT command communication data"

View File

@ -66,8 +66,6 @@ static void tftp_server(uint8_t argc, char **argv)
}
FINSH_FUNCTION_EXPORT(tftp_server, start tftp server.);
#if defined(FINSH_USING_MSH)
MSH_CMD_EXPORT(tftp_server, start tftp server.);
#endif /* defined(FINSH_USING_MSH) */
#endif /* defined(RT_USING_FINSH) */

View File

@ -66,8 +66,6 @@ static void tftp_server(uint8_t argc, char **argv)
}
FINSH_FUNCTION_EXPORT(tftp_server, start tftp server.);
#if defined(FINSH_USING_MSH)
MSH_CMD_EXPORT(tftp_server, start tftp server.);
#endif /* defined(FINSH_USING_MSH) */
#endif /* defined(RT_USING_FINSH) */

View File

@ -66,8 +66,6 @@ static void tftp_server(uint8_t argc, char **argv)
}
FINSH_FUNCTION_EXPORT(tftp_server, start tftp server.);
#if defined(FINSH_USING_MSH)
MSH_CMD_EXPORT(tftp_server, start tftp server.);
#endif /* defined(FINSH_USING_MSH) */
#endif /* defined(RT_USING_FINSH) */

View File

@ -1075,7 +1075,7 @@ const char *ulog_global_filter_kw_get(void)
return ulog.filter.keyword;
}
#if defined(RT_USING_FINSH) && defined(FINSH_USING_MSH)
#ifdef(RT_USING_FINSH)
#include <finsh.h>
static void _print_lvl_info(void)
@ -1250,7 +1250,7 @@ static void ulog_filter(uint8_t argc, char **argv)
}
}
MSH_CMD_EXPORT(ulog_filter, Show ulog filter settings);
#endif /* defined(RT_USING_FINSH) && defined(FINSH_USING_MSH) */
#endif defined(RT_USING_FINSH)
#endif /* ULOG_USING_FILTER */
rt_err_t ulog_backend_register(ulog_backend_t backend, const char *name, rt_bool_t support_color)

View File

@ -67,7 +67,6 @@ void list_dir(const char* path)
#include <finsh.h>
FINSH_FUNCTION_EXPORT(list_dir, list directory);
#ifdef FINSH_USING_MSH
static void cmd_list_dir(int argc, char *argv[])
{
char* filename;
@ -84,5 +83,4 @@ static void cmd_list_dir(int argc, char *argv[])
list_dir(filename);
}
MSH_CMD_EXPORT_ALIAS(cmd_list_dir, list_dir, list directory);
#endif /* FINSH_USING_MSH */
#endif /* RT_USING_FINSH */

View File

@ -58,7 +58,6 @@ void readspeed(const char* filename, int block_size)
#include <finsh.h>
FINSH_FUNCTION_EXPORT(readspeed, perform file read test);
#ifdef FINSH_USING_MSH
static void cmd_readspeed(int argc, char *argv[])
{
char* filename;
@ -83,5 +82,4 @@ static void cmd_readspeed(int argc, char *argv[])
readspeed(filename, block_size);
}
FINSH_FUNCTION_EXPORT_ALIAS(cmd_readspeed, __cmd_readspeed, test file system read speed);
#endif /* FINSH_USING_MSH */
#endif /* RT_USING_FINSH */

View File

@ -147,7 +147,6 @@ __exit:
/* export to finsh */
FINSH_FUNCTION_EXPORT(readwrite, perform file read and write test);
#ifdef FINSH_USING_MSH
static void cmd_readwrite(int argc, char *argv[])
{
char* filename;
@ -164,5 +163,4 @@ static void cmd_readwrite(int argc, char *argv[])
readwrite(filename);
}
FINSH_FUNCTION_EXPORT_ALIAS(cmd_readwrite, __cmd_readwrite, perform file read and write test);
#endif /* FINSH_USING_MSH */
#endif /* RT_USING_FINSH */

View File

@ -66,7 +66,6 @@ void writespeed(const char* filename, int total_length, int block_size)
#include <finsh.h>
FINSH_FUNCTION_EXPORT(writespeed, perform file write test);
#ifdef FINSH_USING_MSH
static void cmd_writespeed(int argc, char *argv[])
{
char* filename;
@ -94,5 +93,4 @@ static void cmd_writespeed(int argc, char *argv[])
writespeed(filename, length, block_size);
}
FINSH_FUNCTION_EXPORT_ALIAS(cmd_writespeed, __cmd_writespeed, test file system write speed);
#endif /* FINSH_USING_MSH */
#endif /* RT_USING_FINSH */

View File

@ -25,7 +25,6 @@ static const char* _tc_current;
static void (*_tc_cleanup)(void) = RT_NULL;
static rt_uint32_t _tc_scale = 1;
FINSH_VAR_EXPORT(_tc_scale, finsh_type_int, the testcase timer timeout scale)
static rt_uint32_t _tc_loop;

View File

@ -356,8 +356,8 @@ int termios_test(int argc, char **argv)
#ifdef RT_USING_FINSH
#include <finsh.h>
#ifdef FINSH_USING_MSH
#ifdef RT_USING_FINSH
MSH_CMD_EXPORT_ALIAS(termios_test, termtest, e.g: termtest /dev/uart4 115200);
#endif /* FINSH_USING_MSH */
#endif /* RT_USING_FINSH */
#endif /* RT_USING_FINSH */

View File

@ -105,7 +105,7 @@ EXIT:
return err;
}
#ifdef FINSH_USING_MSH
#ifdef RT_USING_FINSH
MSH_CMD_EXPORT(hwtimer, "Test hardware timer");
#endif
#endif /* RT_USING_HWTIMER */

View File

@ -277,7 +277,6 @@ typedef int (*init_fn_t)(void);
/* define these to empty, even if not include finsh.h file */
#define FINSH_FUNCTION_EXPORT(name, desc)
#define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc)
#define FINSH_VAR_EXPORT(name, type, desc)
#define MSH_CMD_EXPORT(command, desc)
#define MSH_CMD_EXPORT_ALIAS(command, alias, desc)

View File

@ -585,7 +585,7 @@ void rt_assert_handler(const char *ex, const char *func, rt_size_t line);
#endif /* RT_DEBUG */
#ifdef RT_USING_FINSH
#include <finsh_api.h>
#include <finsh.h>
#endif
/**@}*/