Merge pull request #1242 from RT-Thread/feature_shell

[Kernel] include finsh.h file in rtthread.h when RT_USING_FINSH enable
This commit is contained in:
Bernard Xiong 2018-03-01 23:02:28 +08:00 committed by GitHub
commit f0ff224954
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 2337 additions and 2296 deletions

View File

@ -106,11 +106,11 @@ static long _list_thread(struct rt_list_node *list)
rt_kprintf( " --- ------- ---------- ---------- ------ ---------- ---\n"); rt_kprintf( " --- ------- ---------- ---------- ------ ---------- ---\n");
for (node = list->next; node != list; node = node->next) for (node = list->next; node != list; node = node->next)
{ {
rt_uint8_t stat; rt_uint8_t stat;
thread = rt_list_entry(node, struct rt_thread, list); thread = rt_list_entry(node, struct rt_thread, list);
rt_kprintf("%-*.*s %3d ", maxlen, RT_NAME_MAX, thread->name, thread->current_priority); rt_kprintf("%-*.*s %3d ", maxlen, RT_NAME_MAX, thread->name, thread->current_priority);
stat = (thread->stat & RT_THREAD_STAT_MASK); stat = (thread->stat & RT_THREAD_STAT_MASK);
if (stat == RT_THREAD_READY) rt_kprintf(" ready "); if (stat == RT_THREAD_READY) rt_kprintf(" ready ");
else if (stat == RT_THREAD_SUSPEND) rt_kprintf(" suspend"); else if (stat == RT_THREAD_SUSPEND) rt_kprintf(" suspend");
else if (stat == RT_THREAD_INIT) rt_kprintf(" init "); else if (stat == RT_THREAD_INIT) rt_kprintf(" init ");
@ -634,14 +634,14 @@ int list_mod_detail(const char *name)
/* list main thread in module */ /* list main thread in module */
if (module->module_thread != RT_NULL) if (module->module_thread != RT_NULL)
{ {
rt_uint8_t stat; rt_uint8_t stat;
rt_kprintf("main thread pri status sp stack size max used left tick error\n"); rt_kprintf("main thread pri status sp stack size max used left tick error\n");
rt_kprintf("------------- ---- ------- ---------- ---------- ---------- ---------- ---\n"); rt_kprintf("------------- ---- ------- ---------- ---------- ---------- ---------- ---\n");
thread = module->module_thread; thread = module->module_thread;
rt_kprintf("%-8.*s 0x%02x", RT_NAME_MAX, thread->name, thread->current_priority); rt_kprintf("%-8.*s 0x%02x", RT_NAME_MAX, thread->name, thread->current_priority);
stat = (thread->stat & RT_THREAD_STAT_MASK); stat = (thread->stat & RT_THREAD_STAT_MASK);
if (stat == RT_THREAD_READY) rt_kprintf(" ready "); if (stat == RT_THREAD_READY) rt_kprintf(" ready ");
else if (stat == RT_THREAD_SUSPEND) rt_kprintf(" suspend"); else if (stat == RT_THREAD_SUSPEND) rt_kprintf(" suspend");
else if (stat == RT_THREAD_INIT) rt_kprintf(" init "); else if (stat == RT_THREAD_INIT) rt_kprintf(" init ");

View File

@ -1,11 +1,20 @@
/* /*
* File : finsh.h * File : finsh.h
* This file is part of RT-Thread RTOS * COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
* COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
* *
* The license and distribution terms for this file may be * This program is free software; you can redistribute it and/or modify
* found in the file LICENSE in this distribution or at * it under the terms of the GNU General Public License as published by
* http://www.rt-thread.org/license/LICENSE * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
* *
* Change Logs: * Change Logs:
* Date Author Notes * Date Author Notes
@ -15,11 +24,7 @@
#define __FINSH_H__ #define __FINSH_H__
#include <rtthread.h> #include <rtthread.h>
#include "finsh_api.h"
#if defined(_MSC_VER)
#pragma section("FSymTab$f",read)
#pragma section("VSymTab",read)
#endif
/* -- the beginning of option -- */ /* -- the beginning of option -- */
#define FINSH_NAME_MAX 16 /* max length of identifier */ #define FINSH_NAME_MAX 16 /* max length of identifier */
@ -63,63 +68,47 @@
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#define FINSH_VERSION_MAJOR 1 #define FINSH_VERSION_MAJOR 1
#define FINSH_VERSION_MINOR 0 #define FINSH_VERSION_MINOR 0
/** /**
* @addtogroup finsh * @addtogroup finsh
*/ */
/*@{*/ /*@{*/
#define FINSH_ERROR_OK 0 /**< No error */ #define FINSH_ERROR_OK 0 /**< No error */
#define FINSH_ERROR_INVALID_TOKEN 1 /**< Invalid token */ #define FINSH_ERROR_INVALID_TOKEN 1 /**< Invalid token */
#define FINSH_ERROR_EXPECT_TYPE 2 /**< Expect a type */ #define FINSH_ERROR_EXPECT_TYPE 2 /**< Expect a type */
#define FINSH_ERROR_UNKNOWN_TYPE 3 /**< Unknown type */ #define FINSH_ERROR_UNKNOWN_TYPE 3 /**< Unknown type */
#define FINSH_ERROR_VARIABLE_EXIST 4 /**< Variable exist */ #define FINSH_ERROR_VARIABLE_EXIST 4 /**< Variable exist */
#define FINSH_ERROR_EXPECT_OPERATOR 5 /**< Expect a operator */ #define FINSH_ERROR_EXPECT_OPERATOR 5 /**< Expect a operator */
#define FINSH_ERROR_MEMORY_FULL 6 /**< Memory full */ #define FINSH_ERROR_MEMORY_FULL 6 /**< Memory full */
#define FINSH_ERROR_UNKNOWN_OP 7 /**< Unknown operator */ #define FINSH_ERROR_UNKNOWN_OP 7 /**< Unknown operator */
#define FINSH_ERROR_UNKNOWN_NODE 8 /**< Unknown node */ #define FINSH_ERROR_UNKNOWN_NODE 8 /**< Unknown node */
#define FINSH_ERROR_EXPECT_CHAR 9 /**< Expect a character */ #define FINSH_ERROR_EXPECT_CHAR 9 /**< Expect a character */
#define FINSH_ERROR_UNEXPECT_END 10 /**< Unexpect end */ #define FINSH_ERROR_UNEXPECT_END 10 /**< Unexpect end */
#define FINSH_ERROR_UNKNOWN_TOKEN 11 /**< Unknown token */ #define FINSH_ERROR_UNKNOWN_TOKEN 11 /**< Unknown token */
#define FINSH_ERROR_NO_FLOAT 12 /**< Float not supported */ #define FINSH_ERROR_NO_FLOAT 12 /**< Float not supported */
#define FINSH_ERROR_UNKNOWN_SYMBOL 13 /**< Unknown symbol */ #define FINSH_ERROR_UNKNOWN_SYMBOL 13 /**< Unknown symbol */
#define FINSH_ERROR_NULL_NODE 14 /**< Null node */ #define FINSH_ERROR_NULL_NODE 14 /**< Null node */
/*@}*/ /*@}*/
typedef long (*syscall_func)();
/* 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 */ /* system call item */
struct finsh_syscall_item struct finsh_syscall_item
{ {
struct finsh_syscall_item* next; /* next item */ struct finsh_syscall_item* next; /* next item */
struct finsh_syscall syscall; /* syscall */ struct finsh_syscall syscall; /* syscall */
}; };
extern struct finsh_syscall *_syscall_table_begin, *_syscall_table_end;
extern struct finsh_syscall_item *global_syscall_list; extern struct finsh_syscall_item *global_syscall_list;
/* find out system call, which should be implemented in user program */
struct finsh_syscall* finsh_syscall_lookup(const char* name);
/* system variable table */ /* system variable table */
struct finsh_sysvar struct finsh_sysvar
{ {
const char* name; /* the name of variable */ const char* name; /* the name of variable */
#if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB) #if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
const char* desc; /* description of system variable */ const char* desc; /* description of system variable */
#endif #endif
uint8_t type; /* the type of variable */ uint8_t type; /* the type of variable */
void* var ; /* the address of variable */ void* var ; /* the address of variable */
}; };
#if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__)) #if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__))
@ -135,8 +124,8 @@ struct finsh_sysvar* finsh_sysvar_next(struct finsh_sysvar* call);
/* system variable item */ /* system variable item */
struct finsh_sysvar_item struct finsh_sysvar_item
{ {
struct finsh_sysvar_item *next; /* next item */ struct finsh_sysvar_item *next; /* next item */
struct finsh_sysvar sysvar; /* system variable */ struct finsh_sysvar sysvar; /* system variable */
}; };
extern struct finsh_sysvar *_sysvar_table_begin, *_sysvar_table_end; extern struct finsh_sysvar *_sysvar_table_begin, *_sysvar_table_end;
extern struct finsh_sysvar_item* global_sysvar_list; extern struct finsh_sysvar_item* global_sysvar_list;
@ -144,243 +133,60 @@ extern struct finsh_sysvar_item* global_sysvar_list;
/* find out system variable, which should be implemented in user program */ /* find out system variable, which should be implemented in user program */
struct finsh_sysvar* finsh_sysvar_lookup(const char* name); struct finsh_sysvar* finsh_sysvar_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[] SECTION(".rodata.name") = #cmd; \
const char __fsym_##cmd##_desc[] SECTION(".rodata.name") = #desc; \
const struct finsh_syscall __fsym_##cmd SECTION("FSymTab")= \
{ \
__fsym_##cmd##_name, \
__fsym_##cmd##_desc, \
(syscall_func)&name \
};
#define FINSH_VAR_EXPORT(name, type, desc) \
const char __vsym_##name##_name[] SECTION(".rodata.name") = #name; \
const char __vsym_##name##_desc[] SECTION(".rodata.name") = #desc; \
const struct finsh_sysvar __vsym_##name 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; \
const struct finsh_syscall __fsym_##cmd SECTION("FSymTab")= \
{ \
__fsym_##cmd##_name, \
(syscall_func)&name \
};
#define FINSH_VAR_EXPORT(name, type, desc) \
const char __vsym_##name##_name[] = #name; \
const struct finsh_sysvar __vsym_##name 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
struct finsh_token struct finsh_token
{ {
char eof; char eof;
char replay; char replay;
int position; int position;
uint8_t current_token; uint8_t current_token;
union { union {
char char_value; char char_value;
int int_value; int int_value;
long long_value; long long_value;
} value; } value;
uint8_t string[FINSH_STRING_MAX]; uint8_t string[FINSH_STRING_MAX];
uint8_t* line; uint8_t* line;
}; };
#define FINSH_IDTYPE_VAR 0x01 #define FINSH_IDTYPE_VAR 0x01
#define FINSH_IDTYPE_SYSVAR 0x02 #define FINSH_IDTYPE_SYSVAR 0x02
#define FINSH_IDTYPE_SYSCALL 0x04 #define FINSH_IDTYPE_SYSCALL 0x04
#define FINSH_IDTYPE_ADDRESS 0x08 #define FINSH_IDTYPE_ADDRESS 0x08
struct finsh_node struct finsh_node
{ {
uint8_t node_type; /* node node_type */ uint8_t node_type; /* node node_type */
uint8_t data_type; /* node data node_type */ uint8_t data_type; /* node data node_type */
uint8_t idtype; /* id node information */ uint8_t idtype; /* id node information */
union { /* value node */ union { /* value node */
char char_value; char char_value;
short short_value; short short_value;
int int_value; int int_value;
long long_value; long long_value;
void* ptr; void* ptr;
} value; } value;
union union
{ {
/* point to variable identifier or function identifier */ /* point to variable identifier or function identifier */
struct finsh_var *var; struct finsh_var *var;
struct finsh_sysvar *sysvar; struct finsh_sysvar *sysvar;
struct finsh_syscall*syscall; struct finsh_syscall*syscall;
}id; }id;
/* sibling and child node */ /* sibling and child node */
struct finsh_node *sibling, *child; struct finsh_node *sibling, *child;
}; };
struct finsh_parser struct finsh_parser
{ {
uint8_t* parser_string; uint8_t* parser_string;
struct finsh_token token; struct finsh_token token;
struct finsh_node* root; struct finsh_node* root;
}; };
/** /**
@ -389,21 +195,21 @@ struct finsh_parser
* The basic data type in finsh shell * The basic data type in finsh shell
*/ */
enum finsh_type { enum finsh_type {
finsh_type_unknown = 0, /**< unknown data type */ finsh_type_unknown = 0, /**< unknown data type */
finsh_type_void, /**< void */ finsh_type_void, /**< void */
finsh_type_voidp, /**< void pointer */ finsh_type_voidp, /**< void pointer */
finsh_type_char, /**< char */ finsh_type_char, /**< char */
finsh_type_uchar, /**< unsigned char */ finsh_type_uchar, /**< unsigned char */
finsh_type_charp, /**< char pointer */ finsh_type_charp, /**< char pointer */
finsh_type_short, /**< short */ finsh_type_short, /**< short */
finsh_type_ushort, /**< unsigned short */ finsh_type_ushort, /**< unsigned short */
finsh_type_shortp, /**< short pointer */ finsh_type_shortp, /**< short pointer */
finsh_type_int, /**< int */ finsh_type_int, /**< int */
finsh_type_uint, /**< unsigned int */ finsh_type_uint, /**< unsigned int */
finsh_type_intp, /**< int pointer */ finsh_type_intp, /**< int pointer */
finsh_type_long, /**< long */ finsh_type_long, /**< long */
finsh_type_ulong, /**< unsigned long */ finsh_type_ulong, /**< unsigned long */
finsh_type_longp /**< long pointer */ finsh_type_longp /**< long pointer */
}; };
/* init finsh environment */ /* init finsh environment */

View File

@ -0,0 +1,231 @@
/*
* File : finsh_api.h
* COPYRIGHT (C) 2006 - 2018, RT-Thread Development Team
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* 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[] SECTION(".rodata.name") = #cmd; \
const char __fsym_##cmd##_desc[] SECTION(".rodata.name") = #desc; \
const struct finsh_syscall __fsym_##cmd SECTION("FSymTab")= \
{ \
__fsym_##cmd##_name, \
__fsym_##cmd##_desc, \
(syscall_func)&name \
};
#define FINSH_VAR_EXPORT(name, type, desc) \
const char __vsym_##name##_name[] SECTION(".rodata.name") = #name; \
const char __vsym_##name##_desc[] SECTION(".rodata.name") = #desc; \
const struct finsh_sysvar __vsym_##name 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; \
const struct finsh_syscall __fsym_##cmd SECTION("FSymTab")= \
{ \
__fsym_##cmd##_name, \
(syscall_func)&name \
};
#define FINSH_VAR_EXPORT(name, type, desc) \
const char __vsym_##name##_name[] = #name; \
const struct finsh_sysvar __vsym_##name 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

@ -33,42 +33,42 @@ uint8_t global_errno;
static const char * finsh_error_string_table[] = static const char * finsh_error_string_table[] =
{ {
"No error", "No error",
"Invalid token", "Invalid token",
"Expect a type", "Expect a type",
"Unknown type", "Unknown type",
"Variable exist", "Variable exist",
"Expect a operater", "Expect a operater",
"Memory full", "Memory full",
"Unknown operator", "Unknown operator",
"Unknown node", "Unknown node",
"Expect a character", "Expect a character",
"Unexpect end", "Unexpect end",
"Unknown token", "Unknown token",
"Float not supported", "Float not supported",
"Unknown symbol", "Unknown symbol",
"Null node" "Null node"
}; };
int finsh_error_init() int finsh_error_init()
{ {
global_errno = FINSH_ERROR_OK; global_errno = FINSH_ERROR_OK;
return 0; return 0;
} }
int finsh_error_set(uint8_t type) int finsh_error_set(uint8_t type)
{ {
global_errno = type; global_errno = type;
return 0; return 0;
} }
uint8_t finsh_errno() uint8_t finsh_errno()
{ {
return global_errno; return global_errno;
} }
const char* finsh_error_string(uint8_t type) const char* finsh_error_string(uint8_t type)
{ {
return finsh_error_string_table[type]; return finsh_error_string_table[type];
} }

View File

@ -34,13 +34,13 @@ ALIGN(RT_ALIGN_SIZE)
uint8_t finsh_heap[FINSH_HEAP_MAX]; uint8_t finsh_heap[FINSH_HEAP_MAX];
struct finsh_block_header struct finsh_block_header
{ {
uint32_t length; uint32_t length;
struct finsh_block_header* next; struct finsh_block_header* next;
}; };
#define BLOCK_HEADER(x) (struct finsh_block_header*)(x) #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_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 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)) #define HEAP_ALIGN_SIZE(size) (((size) + HEAP_ALIGNMENT - 1) & ~(HEAP_ALIGNMENT-1))
static struct finsh_block_header* free_list; static struct finsh_block_header* free_list;
static struct finsh_block_header* allocate_list; static struct finsh_block_header* allocate_list;
@ -54,12 +54,12 @@ static void finsh_block_merge(struct finsh_block_header** list, struct finsh_blo
int finsh_heap_init(void) int finsh_heap_init(void)
{ {
/* clear heap to zero */ /* clear heap to zero */
memset(&finsh_heap[0], 0, sizeof(finsh_heap)); memset(&finsh_heap[0], 0, sizeof(finsh_heap));
/* init free and alloc list */ /* init free and alloc list */
free_list = BLOCK_HEADER(&finsh_heap[0]); free_list = BLOCK_HEADER(&finsh_heap[0]);
free_list->length = FINSH_HEAP_MAX - sizeof(struct finsh_block_header); free_list->length = FINSH_HEAP_MAX - sizeof(struct finsh_block_header);
free_list->next = NULL; free_list->next = NULL;
allocate_list = NULL; allocate_list = NULL;
@ -72,41 +72,41 @@ int finsh_heap_init(void)
*/ */
void* finsh_heap_allocate(size_t size) void* finsh_heap_allocate(size_t size)
{ {
struct finsh_block_header* header; struct finsh_block_header* header;
size = HEAP_ALIGN_SIZE(size); size = HEAP_ALIGN_SIZE(size);
/* find the first fit block */ /* find the first fit block */
for (header = free_list; for (header = free_list;
((header != NULL) && (header->length <= size + sizeof(struct finsh_block_header))); ((header != NULL) && (header->length <= size + sizeof(struct finsh_block_header)));
header = header->next) ; header = header->next) ;
if (header == NULL) if (header == NULL)
{ {
finsh_heap_gc(); finsh_heap_gc();
/* find the first fit block */ /* find the first fit block */
for (header = free_list; for (header = free_list;
((header != NULL) && (header->length < size + sizeof(struct finsh_block_header))); ((header != NULL) && (header->length < size + sizeof(struct finsh_block_header)));
header = header->next) ; header = header->next) ;
/* there is no memory */ /* there is no memory */
if (header == NULL) return NULL; if (header == NULL) return NULL;
} }
/* split block */ /* split block */
finsh_block_split(header, size); finsh_block_split(header, size);
/* remove from free list */ /* remove from free list */
finsh_block_remove(&free_list, header); finsh_block_remove(&free_list, header);
header->next = NULL; header->next = NULL;
/* insert to allocate list */ /* insert to allocate list */
finsh_block_insert(&allocate_list, header); finsh_block_insert(&allocate_list, header);
memset(finsh_block_get_data(header), 0, size); memset(finsh_block_get_data(header), 0, size);
return finsh_block_get_data(header); return finsh_block_get_data(header);
} }
/** /**
@ -117,14 +117,14 @@ void finsh_heap_free(void*ptr)
struct finsh_block_header* header; struct finsh_block_header* header;
/* get block header */ /* get block header */
header = finsh_block_get_header(ptr); header = finsh_block_get_header(ptr);
/* remove from allocate list */ /* remove from allocate list */
finsh_block_remove(&allocate_list, header); finsh_block_remove(&allocate_list, header);
/* insert to free list */ /* insert to free list */
finsh_block_insert(&free_list, header); finsh_block_insert(&free_list, header);
finsh_block_merge(&free_list, header); finsh_block_merge(&free_list, header);
} }
/** /**
@ -132,31 +132,31 @@ void finsh_heap_free(void*ptr)
*/ */
static void finsh_heap_gc(void) static void finsh_heap_gc(void)
{ {
int i; int i;
struct finsh_block_header *header, *temp; struct finsh_block_header *header, *temp;
temp = NULL; temp = NULL;
/* find the first fit block */ /* find the first fit block */
for (header = allocate_list; header != NULL; ) for (header = allocate_list; header != NULL; )
{ {
for (i = 0; i < FINSH_VARIABLE_MAX; i ++) for (i = 0; i < FINSH_VARIABLE_MAX; i ++)
{ {
if (global_variable[i].type != finsh_type_unknown) if (global_variable[i].type != finsh_type_unknown)
{ {
if (global_variable[i].value.ptr == finsh_block_get_data(header)) if (global_variable[i].value.ptr == finsh_block_get_data(header))
break; break;
} }
} }
temp = header; temp = header;
header = header->next; header = header->next;
/* this block is an unused block, release it */ /* this block is an unused block, release it */
if (i == FINSH_VARIABLE_MAX) if (i == FINSH_VARIABLE_MAX)
{ {
finsh_heap_free(finsh_block_get_data(temp)); finsh_heap_free(finsh_block_get_data(temp));
} }
} }
} }
@ -174,25 +174,25 @@ void finsh_block_insert(struct finsh_block_header** list, struct finsh_block_hea
} }
/* find out insert point */ /* find out insert point */
node = *list; node = *list;
if (node > header) if (node > header)
{ {
/* insert node in the header of list */ /* insert node in the header of list */
header->next = node; header->next = node;
*list = header; *list = header;
return; return;
} }
else else
{ {
for (node = *list; node; node = node->next) for (node = *list; node; node = node->next)
{ {
if (node->next > header) break; if (node->next > header) break;
if (node->next == NULL) break; if (node->next == NULL) break;
} }
} }
/* insert node */ /* insert node */
if (node->next != NULL) header->next = node->next; if (node->next != NULL) header->next = node->next;
@ -276,7 +276,7 @@ void finsh_block_merge(struct finsh_block_header** list, struct finsh_block_head
== (uint8_t*)next_node)) == (uint8_t*)next_node))
{ {
/* merge three node */ /* merge three node */
prev_node->length += header->length + next_node->length + prev_node->length += header->length + next_node->length +
2 * sizeof(struct finsh_block_header); 2 * sizeof(struct finsh_block_header);
prev_node->next = next_node->next; prev_node->next = next_node->next;

View File

@ -37,15 +37,15 @@
int finsh_init(struct finsh_parser* parser) int finsh_init(struct finsh_parser* parser)
{ {
finsh_parser_init(parser); finsh_parser_init(parser);
/* finsh init */ /* finsh init */
finsh_node_init(); finsh_node_init();
finsh_var_init(); finsh_var_init();
finsh_error_init(); finsh_error_init();
finsh_heap_init(); finsh_heap_init();
return 0; return 0;
} }
long finsh_stack_bottom() long finsh_stack_bottom()
@ -55,22 +55,22 @@ long finsh_stack_bottom()
int finsh_flush(struct finsh_parser* parser) int finsh_flush(struct finsh_parser* parser)
{ {
finsh_parser_init(parser); finsh_parser_init(parser);
/* finsh init */ /* finsh init */
finsh_node_init(); finsh_node_init();
finsh_error_init(); finsh_error_init();
return 0; return 0;
} }
int finsh_reset(struct finsh_parser* parser) int finsh_reset(struct finsh_parser* parser)
{ {
/* finsh init */ /* finsh init */
finsh_node_init(); finsh_node_init();
finsh_var_init(); finsh_var_init();
finsh_error_init(); finsh_error_init();
finsh_heap_init(); finsh_heap_init();
return 0; return 0;
} }

View File

@ -37,166 +37,166 @@ struct finsh_node global_node_table[FINSH_NODE_MAX];
int finsh_node_init() int finsh_node_init()
{ {
memset(global_node_table, 0, sizeof(global_node_table)); memset(global_node_table, 0, sizeof(global_node_table));
return 0; return 0;
} }
struct finsh_node* finsh_node_allocate(uint8_t type) struct finsh_node* finsh_node_allocate(uint8_t type)
{ {
int i; int i;
/* find an empty entry */ /* find an empty entry */
for (i = 0; i < FINSH_NODE_MAX; i ++) for (i = 0; i < FINSH_NODE_MAX; i ++)
{ {
if (global_node_table[i].node_type == FINSH_NODE_UNKNOWN) break; if (global_node_table[i].node_type == FINSH_NODE_UNKNOWN) break;
} }
if (i == FINSH_NODE_MAX) return NULL; if (i == FINSH_NODE_MAX) return NULL;
/* fill type field */ /* fill type field */
global_node_table[i].node_type = type; global_node_table[i].node_type = type;
/* return this allocated node */ /* return this allocated node */
return &global_node_table[i]; return &global_node_table[i];
} }
struct finsh_node* finsh_node_new_id(char* id) struct finsh_node* finsh_node_new_id(char* id)
{ {
struct finsh_node* node; struct finsh_node* node;
void* symbol; void* symbol;
unsigned char type; unsigned char type;
symbol = NULL; symbol = NULL;
type = 0; type = 0;
node = NULL; node = NULL;
/* lookup variable firstly */ /* lookup variable firstly */
symbol = (void*)finsh_var_lookup(id); symbol = (void*)finsh_var_lookup(id);
if (symbol == NULL) if (symbol == NULL)
{ {
/* then lookup system variable */ /* then lookup system variable */
symbol = (void*)finsh_sysvar_lookup(id); symbol = (void*)finsh_sysvar_lookup(id);
if (symbol == NULL) if (symbol == NULL)
{ {
/* then lookup system call */ /* then lookup system call */
symbol = (void*)finsh_syscall_lookup(id); symbol = (void*)finsh_syscall_lookup(id);
if (symbol != NULL) type = FINSH_IDTYPE_SYSCALL; if (symbol != NULL) type = FINSH_IDTYPE_SYSCALL;
} }
else type = FINSH_IDTYPE_SYSVAR; else type = FINSH_IDTYPE_SYSVAR;
} }
else type = FINSH_IDTYPE_VAR; else type = FINSH_IDTYPE_VAR;
if (symbol != NULL) if (symbol != NULL)
{ {
/* allocate a new node */ /* allocate a new node */
node = finsh_node_allocate(FINSH_NODE_ID); node = finsh_node_allocate(FINSH_NODE_ID);
/* allocate node error */ /* allocate node error */
if (node == NULL) if (node == NULL)
{ {
finsh_error_set(FINSH_ERROR_MEMORY_FULL); finsh_error_set(FINSH_ERROR_MEMORY_FULL);
return NULL; return NULL;
} }
/* fill node value according type */ /* fill node value according type */
switch (type) switch (type)
{ {
case FINSH_IDTYPE_VAR: case FINSH_IDTYPE_VAR:
node->id.var = (struct finsh_var*)symbol; node->id.var = (struct finsh_var*)symbol;
break; break;
case FINSH_IDTYPE_SYSVAR: case FINSH_IDTYPE_SYSVAR:
node->id.sysvar = (struct finsh_sysvar*)symbol; node->id.sysvar = (struct finsh_sysvar*)symbol;
break; break;
case FINSH_IDTYPE_SYSCALL: case FINSH_IDTYPE_SYSCALL:
node->id.syscall = (struct finsh_syscall*)symbol; node->id.syscall = (struct finsh_syscall*)symbol;
break; break;
} }
/* fill identifier type */ /* fill identifier type */
node->idtype = type; node->idtype = type;
} }
else finsh_error_set(FINSH_ERROR_UNKNOWN_SYMBOL); else finsh_error_set(FINSH_ERROR_UNKNOWN_SYMBOL);
return node; return node;
} }
struct finsh_node* finsh_node_new_char(char c) struct finsh_node* finsh_node_new_char(char c)
{ {
struct finsh_node* node; struct finsh_node* node;
node = finsh_node_allocate(FINSH_NODE_VALUE_CHAR); node = finsh_node_allocate(FINSH_NODE_VALUE_CHAR);
if (node == NULL) if (node == NULL)
{ {
finsh_error_set(FINSH_ERROR_MEMORY_FULL); finsh_error_set(FINSH_ERROR_MEMORY_FULL);
return NULL; return NULL;
} }
node->value.char_value = c; node->value.char_value = c;
return node; return node;
} }
struct finsh_node* finsh_node_new_int(int i) struct finsh_node* finsh_node_new_int(int i)
{ {
struct finsh_node* node; struct finsh_node* node;
node = finsh_node_allocate(FINSH_NODE_VALUE_INT); node = finsh_node_allocate(FINSH_NODE_VALUE_INT);
if (node == NULL) if (node == NULL)
{ {
finsh_error_set(FINSH_ERROR_MEMORY_FULL); finsh_error_set(FINSH_ERROR_MEMORY_FULL);
return NULL; return NULL;
} }
node->value.int_value = i; node->value.int_value = i;
return node; return node;
} }
struct finsh_node* finsh_node_new_long(long l) struct finsh_node* finsh_node_new_long(long l)
{ {
struct finsh_node* node; struct finsh_node* node;
node = finsh_node_allocate(FINSH_NODE_VALUE_LONG); node = finsh_node_allocate(FINSH_NODE_VALUE_LONG);
if (node == NULL) if (node == NULL)
{ {
finsh_error_set(FINSH_ERROR_MEMORY_FULL); finsh_error_set(FINSH_ERROR_MEMORY_FULL);
return NULL; return NULL;
} }
node->value.long_value = l; node->value.long_value = l;
return node; return node;
} }
struct finsh_node* finsh_node_new_string(char* s) struct finsh_node* finsh_node_new_string(char* s)
{ {
struct finsh_node* node; struct finsh_node* node;
node = finsh_node_allocate(FINSH_NODE_VALUE_STRING); node = finsh_node_allocate(FINSH_NODE_VALUE_STRING);
if (node == NULL) if (node == NULL)
{ {
finsh_error_set(FINSH_ERROR_MEMORY_FULL); finsh_error_set(FINSH_ERROR_MEMORY_FULL);
return NULL; return NULL;
} }
/* make string */ /* make string */
node->value.ptr = finsh_heap_allocate(strlen(s) + 1); node->value.ptr = finsh_heap_allocate(strlen(s) + 1);
strncpy(node->value.ptr, s, strlen(s)); strncpy(node->value.ptr, s, strlen(s));
((uint8_t*)node->value.ptr)[strlen(s)] = '\0'; ((uint8_t*)node->value.ptr)[strlen(s)] = '\0';
return node; return node;
} }
struct finsh_node* finsh_node_new_ptr(void* ptr) struct finsh_node* finsh_node_new_ptr(void* ptr)
{ {
struct finsh_node* node; struct finsh_node* node;
node = finsh_node_allocate(FINSH_NODE_VALUE_NULL); node = finsh_node_allocate(FINSH_NODE_VALUE_NULL);
if (node == NULL) if (node == NULL)
{ {
finsh_error_set(FINSH_ERROR_MEMORY_FULL); finsh_error_set(FINSH_ERROR_MEMORY_FULL);
return NULL; return NULL;
} }
node->value.ptr = ptr; node->value.ptr = ptr;
return node; return node;
} }

View File

@ -31,46 +31,46 @@
#include <finsh.h> #include <finsh.h>
#define FINSH_NODE_UNKNOWN 0 #define FINSH_NODE_UNKNOWN 0
#define FINSH_NODE_ID 1 #define FINSH_NODE_ID 1
#define FINSH_NODE_VALUE_CHAR 2 #define FINSH_NODE_VALUE_CHAR 2
#define FINSH_NODE_VALUE_INT 3 #define FINSH_NODE_VALUE_INT 3
#define FINSH_NODE_VALUE_LONG 4 #define FINSH_NODE_VALUE_LONG 4
#define FINSH_NODE_VALUE_STRING 5 #define FINSH_NODE_VALUE_STRING 5
#define FINSH_NODE_VALUE_NULL 6 #define FINSH_NODE_VALUE_NULL 6
#define FINSH_NODE_SYS_ADD 7 #define FINSH_NODE_SYS_ADD 7
#define FINSH_NODE_SYS_SUB 8 #define FINSH_NODE_SYS_SUB 8
#define FINSH_NODE_SYS_MUL 9 #define FINSH_NODE_SYS_MUL 9
#define FINSH_NODE_SYS_DIV 10 #define FINSH_NODE_SYS_DIV 10
#define FINSH_NODE_SYS_MOD 11 #define FINSH_NODE_SYS_MOD 11
#define FINSH_NODE_SYS_AND 12 #define FINSH_NODE_SYS_AND 12
#define FINSH_NODE_SYS_OR 13 #define FINSH_NODE_SYS_OR 13
#define FINSH_NODE_SYS_XOR 14 #define FINSH_NODE_SYS_XOR 14
#define FINSH_NODE_SYS_BITWISE 15 #define FINSH_NODE_SYS_BITWISE 15
#define FINSH_NODE_SYS_SHL 16 #define FINSH_NODE_SYS_SHL 16
#define FINSH_NODE_SYS_SHR 17 #define FINSH_NODE_SYS_SHR 17
#define FINSH_NODE_SYS_FUNC 18 #define FINSH_NODE_SYS_FUNC 18
#define FINSH_NODE_SYS_ASSIGN 19 #define FINSH_NODE_SYS_ASSIGN 19
#define FINSH_NODE_SYS_CAST 20 #define FINSH_NODE_SYS_CAST 20
#define FINSH_NODE_SYS_PREINC 21 #define FINSH_NODE_SYS_PREINC 21
#define FINSH_NODE_SYS_PREDEC 22 #define FINSH_NODE_SYS_PREDEC 22
#define FINSH_NODE_SYS_INC 23 #define FINSH_NODE_SYS_INC 23
#define FINSH_NODE_SYS_DEC 24 #define FINSH_NODE_SYS_DEC 24
#define FINSH_NODE_SYS_GETVALUE 25 #define FINSH_NODE_SYS_GETVALUE 25
#define FINSH_NODE_SYS_GETADDR 26 #define FINSH_NODE_SYS_GETADDR 26
#define FINSH_NODE_SYS_NULL 27 #define FINSH_NODE_SYS_NULL 27
#define FINSH_DATA_TYPE_VOID 0x00 #define FINSH_DATA_TYPE_VOID 0x00
#define FINSH_DATA_TYPE_BYTE 0x01 #define FINSH_DATA_TYPE_BYTE 0x01
#define FINSH_DATA_TYPE_WORD 0x02 #define FINSH_DATA_TYPE_WORD 0x02
#define FINSH_DATA_TYPE_DWORD 0x03 #define FINSH_DATA_TYPE_DWORD 0x03
#define FINSH_DATA_TYPE_PTR 0x10 #define FINSH_DATA_TYPE_PTR 0x10
#define FINSH_NODE_VALUE 0 #define FINSH_NODE_VALUE 0
#define FINSH_NODE_ADDRESS 1 #define FINSH_NODE_ADDRESS 1
#define FINSH_NODE_FUNCTION 2 #define FINSH_NODE_FUNCTION 2
int finsh_node_init(void); int finsh_node_init(void);
@ -82,7 +82,7 @@ struct finsh_node* finsh_node_new_long(long l);
struct finsh_node* finsh_node_new_string(char* s); struct finsh_node* finsh_node_new_string(char* s);
struct finsh_node* finsh_node_new_ptr(void* ptr); struct finsh_node* finsh_node_new_ptr(void* ptr);
#define finsh_node_sibling(node) ((node)->sibling) #define finsh_node_sibling(node) ((node)->sibling)
#define finsh_node_child(node) ((node)->child) #define finsh_node_child(node) ((node)->child)
#endif #endif

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -33,42 +33,42 @@
enum finsh_token_type enum finsh_token_type
{ {
finsh_token_type_left_paren = 1, /* ( */ finsh_token_type_left_paren = 1, /* ( */
finsh_token_type_right_paren , /* ) */ finsh_token_type_right_paren , /* ) */
finsh_token_type_comma , /* , */ finsh_token_type_comma , /* , */
finsh_token_type_semicolon , /* ; */ finsh_token_type_semicolon , /* ; */
finsh_token_type_mul , /* * */ finsh_token_type_mul , /* * */
finsh_token_type_add , /* + */ finsh_token_type_add , /* + */
finsh_token_type_inc , /* ++ */ finsh_token_type_inc , /* ++ */
finsh_token_type_sub , /* - */ finsh_token_type_sub , /* - */
finsh_token_type_dec , /* -- */ finsh_token_type_dec , /* -- */
finsh_token_type_div , /* / */ finsh_token_type_div , /* / */
finsh_token_type_mod , /* % */ finsh_token_type_mod , /* % */
finsh_token_type_assign , /* = */ finsh_token_type_assign , /* = */
finsh_token_type_and, /* & */ finsh_token_type_and, /* & */
finsh_token_type_or, /* | */ finsh_token_type_or, /* | */
finsh_token_type_xor, /* ^ */ finsh_token_type_xor, /* ^ */
finsh_token_type_bitwise, /* ~ */ finsh_token_type_bitwise, /* ~ */
finsh_token_type_shl, /* << */ finsh_token_type_shl, /* << */
finsh_token_type_shr, /* >> */ finsh_token_type_shr, /* >> */
finsh_token_type_comments, /* // */ finsh_token_type_comments, /* // */
/*-- data type --*/ /*-- data type --*/
finsh_token_type_void, /* void */ finsh_token_type_void, /* void */
finsh_token_type_char, /* char */ finsh_token_type_char, /* char */
finsh_token_type_short, /* short */ finsh_token_type_short, /* short */
finsh_token_type_int, /* int */ finsh_token_type_int, /* int */
finsh_token_type_long, /* long */ finsh_token_type_long, /* long */
finsh_token_type_unsigned, /* unsigned */ finsh_token_type_unsigned, /* unsigned */
/* data value type */ /* data value type */
finsh_token_type_value_char, /* v:char */ finsh_token_type_value_char, /* v:char */
finsh_token_type_value_int, /* v:int */ finsh_token_type_value_int, /* v:int */
finsh_token_type_value_long, /* v:long */ finsh_token_type_value_long, /* v:long */
finsh_token_type_value_string, /* v:string */ finsh_token_type_value_string, /* v:string */
finsh_token_type_value_null, /* NULL */ finsh_token_type_value_null, /* NULL */
/*-- others --*/ /*-- others --*/
finsh_token_type_identifier, /* ID */ finsh_token_type_identifier, /* ID */
finsh_token_type_bad, /* bad token */ finsh_token_type_bad, /* bad token */
finsh_token_type_eof finsh_token_type_eof
}; };
#define finsh_token_position(self) (self)->position #define finsh_token_position(self) (self)->position

View File

@ -36,126 +36,126 @@ struct finsh_sysvar_item* global_sysvar_list;
int finsh_var_init() int finsh_var_init()
{ {
memset(global_variable, 0, sizeof(global_variable)); memset(global_variable, 0, sizeof(global_variable));
return 0; return 0;
} }
int finsh_var_insert(const char* name, int type) int finsh_var_insert(const char* name, int type)
{ {
int i, empty; int i, empty;
empty = -1; empty = -1;
for (i = 0; i < FINSH_VARIABLE_MAX; i ++) for (i = 0; i < FINSH_VARIABLE_MAX; i ++)
{ {
/* there is a same name variable exist. */ /* there is a same name variable exist. */
if (strncmp(global_variable[i].name, name, FINSH_NAME_MAX) == 0) if (strncmp(global_variable[i].name, name, FINSH_NAME_MAX) == 0)
return -1; return -1;
if (global_variable[i].type == finsh_type_unknown && empty == -1) if (global_variable[i].type == finsh_type_unknown && empty == -1)
{ {
empty = i; empty = i;
} }
} }
/* there is no empty entry */ /* there is no empty entry */
if (empty == -1) return -1; if (empty == -1) return -1;
/* insert entry */ /* insert entry */
strncpy(global_variable[empty].name, name, FINSH_NAME_MAX); strncpy(global_variable[empty].name, name, FINSH_NAME_MAX);
global_variable[empty].type = type; global_variable[empty].type = type;
/* return the offset */ /* return the offset */
return empty; return empty;
} }
int finsh_var_delete(const char* name) int finsh_var_delete(const char* name)
{ {
int i; int i;
for (i = 0; i < FINSH_VARIABLE_MAX; i ++) for (i = 0; i < FINSH_VARIABLE_MAX; i ++)
{ {
if (strncmp(global_variable[i].name, name, FINSH_NAME_MAX) == 0) if (strncmp(global_variable[i].name, name, FINSH_NAME_MAX) == 0)
break; break;
} }
/* can't find variable */ /* can't find variable */
if (i == FINSH_VARIABLE_MAX) return -1; if (i == FINSH_VARIABLE_MAX) return -1;
memset(&global_variable[i], 0, sizeof(struct finsh_var)); memset(&global_variable[i], 0, sizeof(struct finsh_var));
return 0; return 0;
} }
struct finsh_var* finsh_var_lookup(const char* name) struct finsh_var* finsh_var_lookup(const char* name)
{ {
int i; int i;
for (i = 0; i < FINSH_VARIABLE_MAX; i ++) for (i = 0; i < FINSH_VARIABLE_MAX; i ++)
{ {
if (strncmp(global_variable[i].name, name, FINSH_NAME_MAX) == 0) if (strncmp(global_variable[i].name, name, FINSH_NAME_MAX) == 0)
break; break;
} }
/* can't find variable */ /* can't find variable */
if (i == FINSH_VARIABLE_MAX) return NULL; if (i == FINSH_VARIABLE_MAX) return NULL;
return &global_variable[i]; return &global_variable[i];
} }
#ifdef RT_USING_HEAP #ifdef RT_USING_HEAP
void finsh_sysvar_append(const char* name, uint8_t type, void* var_addr) void finsh_sysvar_append(const char* name, uint8_t type, void* var_addr)
{ {
/* create a sysvar */ /* create a sysvar */
struct finsh_sysvar_item* item; struct finsh_sysvar_item* item;
item = (struct finsh_sysvar_item*) rt_malloc (sizeof(struct finsh_sysvar_item)); item = (struct finsh_sysvar_item*) rt_malloc (sizeof(struct finsh_sysvar_item));
if (item != NULL) if (item != NULL)
{ {
item->next = NULL; item->next = NULL;
item->sysvar.name = rt_strdup(name); item->sysvar.name = rt_strdup(name);
item->sysvar.type = type; item->sysvar.type = type;
item->sysvar.var = var_addr; item->sysvar.var = var_addr;
if (global_sysvar_list == NULL) if (global_sysvar_list == NULL)
{ {
global_sysvar_list = item; global_sysvar_list = item;
} }
else else
{ {
item->next = global_sysvar_list; item->next = global_sysvar_list;
global_sysvar_list = item; global_sysvar_list = item;
} }
} }
} }
#endif #endif
struct finsh_sysvar* finsh_sysvar_lookup(const char* name) struct finsh_sysvar* finsh_sysvar_lookup(const char* name)
{ {
struct finsh_sysvar* index; struct finsh_sysvar* index;
struct finsh_sysvar_item* item; struct finsh_sysvar_item* item;
for (index = _sysvar_table_begin; for (index = _sysvar_table_begin;
index < _sysvar_table_end; index < _sysvar_table_end;
FINSH_NEXT_SYSVAR(index)) FINSH_NEXT_SYSVAR(index))
{ {
if (strcmp(index->name, name) == 0) if (strcmp(index->name, name) == 0)
return index; return index;
} }
/* find in sysvar list */ /* find in sysvar list */
item = global_sysvar_list; item = global_sysvar_list;
while (item != NULL) while (item != NULL)
{ {
if (strncmp(item->sysvar.name, name, strlen(name)) == 0) if (strncmp(item->sysvar.name, name, strlen(name)) == 0)
{ {
return &(item->sysvar); return &(item->sysvar);
} }
/* move to next item */ /* move to next item */
item = item->next; item = item->next;
} }
/* can't find variable */ /* can't find variable */
return NULL; return NULL;
} }

View File

@ -37,18 +37,18 @@
*/ */
struct finsh_var struct finsh_var
{ {
char name[FINSH_NAME_MAX + 1]; /* the name of variable */ char name[FINSH_NAME_MAX + 1]; /* the name of variable */
uint8_t type; /* the type of variable */ uint8_t type; /* the type of variable */
/* variable value */ /* variable value */
union { union {
char char_value; char char_value;
short short_value; short short_value;
int int_value; int int_value;
long long_value; long long_value;
void* ptr; void* ptr;
}value; }value;
}; };
extern struct finsh_var global_variable[]; extern struct finsh_var global_variable[];

View File

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

View File

@ -34,19 +34,19 @@
#include "finsh_var.h" #include "finsh_var.h"
union finsh_value { union finsh_value {
char char_value; char char_value;
short short_value; short short_value;
long long_value; long long_value;
void* ptr; void* ptr;
}; };
extern union finsh_value* finsh_sp; /* stack pointer */ extern union finsh_value* finsh_sp; /* stack pointer */
extern uint8_t* finsh_pc; /* PC */ extern uint8_t* finsh_pc; /* PC */
/* stack */ /* stack */
extern union finsh_value finsh_vm_stack[FINSH_STACK_MAX]; extern union finsh_value finsh_vm_stack[FINSH_STACK_MAX];
/* text segment */ /* text segment */
extern uint8_t text_segment[FINSH_TEXT_MAX]; extern uint8_t text_segment[FINSH_TEXT_MAX];
void finsh_vm_run(void); void finsh_vm_run(void);
//void finsh_disassemble(void); //void finsh_disassemble(void);

View File

@ -191,7 +191,7 @@ int cmd_cd(int argc, char **argv)
{ {
if (chdir(argv[1]) != 0) if (chdir(argv[1]) != 0)
{ {
rt_kprintf("No such directory: %s\n", argv[1]); rt_kprintf("No such directory: %s\n", argv[1]);
} }
} }
@ -280,31 +280,31 @@ FINSH_FUNCTION_EXPORT_ALIAS(cmd_df, __cmd_df, disk free);
int cmd_echo(int argc, char** argv) int cmd_echo(int argc, char** argv)
{ {
if (argc == 2) if (argc == 2)
{ {
rt_kprintf("%s\n", argv[1]); rt_kprintf("%s\n", argv[1]);
} }
else if (argc == 3) else if (argc == 3)
{ {
int fd; int fd;
fd = open(argv[2], O_RDWR | O_APPEND | O_CREAT, 0); fd = open(argv[2], O_RDWR | O_APPEND | O_CREAT, 0);
if (fd >= 0) if (fd >= 0)
{ {
write (fd, argv[1], strlen(argv[1])); write (fd, argv[1], strlen(argv[1]));
close(fd); close(fd);
} }
else else
{ {
rt_kprintf("open file:%s failed!\n", argv[2]); rt_kprintf("open file:%s failed!\n", argv[2]);
} }
} }
else else
{ {
rt_kprintf("Usage: echo \"string\" [filename]\n"); rt_kprintf("Usage: echo \"string\" [filename]\n");
} }
return 0; return 0;
} }
FINSH_FUNCTION_EXPORT_ALIAS(cmd_echo, __cmd_echo, echo string to file); FINSH_FUNCTION_EXPORT_ALIAS(cmd_echo, __cmd_echo, echo string to file);
#endif #endif

View File

@ -42,39 +42,39 @@ long list_mempool(void);
long list_timer(void); long list_timer(void);
#ifdef FINSH_USING_SYMTAB #ifdef FINSH_USING_SYMTAB
struct finsh_syscall *_syscall_table_begin = NULL; struct finsh_syscall *_syscall_table_begin = NULL;
struct finsh_syscall *_syscall_table_end = NULL; struct finsh_syscall *_syscall_table_end = NULL;
struct finsh_sysvar *_sysvar_table_begin = NULL; struct finsh_sysvar *_sysvar_table_begin = NULL;
struct finsh_sysvar *_sysvar_table_end = NULL; struct finsh_sysvar *_sysvar_table_end = NULL;
#else #else
struct finsh_syscall _syscall_table[] = struct finsh_syscall _syscall_table[] =
{ {
{"hello", hello}, {"hello", hello},
{"version", version}, {"version", version},
{"list", list}, {"list", list},
{"list_thread", list_thread}, {"list_thread", list_thread},
#ifdef RT_USING_SEMAPHORE #ifdef RT_USING_SEMAPHORE
{"list_sem", list_sem}, {"list_sem", list_sem},
#endif #endif
#ifdef RT_USING_MUTEX #ifdef RT_USING_MUTEX
{"list_mutex", list_mutex}, {"list_mutex", list_mutex},
#endif #endif
#ifdef RT_USING_FEVENT #ifdef RT_USING_FEVENT
{"list_fevent", list_fevent}, {"list_fevent", list_fevent},
#endif #endif
#ifdef RT_USING_EVENT #ifdef RT_USING_EVENT
{"list_event", list_event}, {"list_event", list_event},
#endif #endif
#ifdef RT_USING_MAILBOX #ifdef RT_USING_MAILBOX
{"list_mb", list_mailbox}, {"list_mb", list_mailbox},
#endif #endif
#ifdef RT_USING_MESSAGEQUEUE #ifdef RT_USING_MESSAGEQUEUE
{"list_mq", list_msgqueue}, {"list_mq", list_msgqueue},
#endif #endif
#ifdef RT_USING_MEMPOOL #ifdef RT_USING_MEMPOOL
{"list_memp", list_mempool}, {"list_memp", list_mempool},
#endif #endif
{"list_timer", list_timer}, {"list_timer", list_timer},
}; };
struct finsh_syscall *_syscall_table_begin = &_syscall_table[0]; 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_syscall *_syscall_table_end = &_syscall_table[sizeof(_syscall_table) / sizeof(struct finsh_syscall)];

View File

@ -563,6 +563,10 @@ void rt_assert_set_hook(void (*hook)(const char *ex, const char *func, rt_size_t
void rt_assert_handler(const char *ex, const char *func, rt_size_t line); void rt_assert_handler(const char *ex, const char *func, rt_size_t line);
#endif /* RT_DEBUG */ #endif /* RT_DEBUG */
#ifdef RT_USING_FINSH
#include <finsh_api.h>
#endif
/**@}*/ /**@}*/
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -141,7 +141,7 @@ def PrepareBuilding(env, root_directory, has_libcpu=False, remove_components = [
env['LIBDIRPREFIX'] = '--userlibpath ' env['LIBDIRPREFIX'] = '--userlibpath '
if rtconfig.PLATFORM == 'gcc': if rtconfig.PLATFORM == 'gcc':
if env['LINKFLAGS'].find('nano.specs'): if str(env['LINKFLAGS']).find('nano.specs'):
env.AppendUnique(CPPDEFINES = ['_REENT_SMALL']) env.AppendUnique(CPPDEFINES = ['_REENT_SMALL'])
# patch for win32 spawn # patch for win32 spawn