1*10465441SEvalZero /* 2*10465441SEvalZero * Copyright (c) 2006-2018, RT-Thread Development Team 3*10465441SEvalZero * 4*10465441SEvalZero * SPDX-License-Identifier: Apache-2.0 5*10465441SEvalZero * 6*10465441SEvalZero * Change Logs: 7*10465441SEvalZero * Date Author Notes 8*10465441SEvalZero * 2010-03-22 Bernard first version 9*10465441SEvalZero */ 10*10465441SEvalZero #ifndef __FINSH_H__ 11*10465441SEvalZero #define __FINSH_H__ 12*10465441SEvalZero 13*10465441SEvalZero #include <rtthread.h> 14*10465441SEvalZero #include "finsh_api.h" 15*10465441SEvalZero 16*10465441SEvalZero /* -- the beginning of option -- */ 17*10465441SEvalZero #define FINSH_NAME_MAX 16 /* max length of identifier */ 18*10465441SEvalZero #define FINSH_NODE_MAX 16 /* max number of node */ 19*10465441SEvalZero 20*10465441SEvalZero #define FINSH_HEAP_MAX 128 /* max length of heap */ 21*10465441SEvalZero #define FINSH_STRING_MAX 128 /* max length of string */ 22*10465441SEvalZero #define FINSH_VARIABLE_MAX 8 /* max number of variable */ 23*10465441SEvalZero 24*10465441SEvalZero #define FINSH_STACK_MAX 64 /* max stack size */ 25*10465441SEvalZero #define FINSH_TEXT_MAX 128 /* max text segment size */ 26*10465441SEvalZero 27*10465441SEvalZero #define HEAP_ALIGNMENT 4 /* heap alignment */ 28*10465441SEvalZero 29*10465441SEvalZero #define FINSH_GET16(x) (*(x)) | (*((x)+1) << 8) 30*10465441SEvalZero #define FINSH_GET32(x) (rt_uint32_t)(*(x)) | ((rt_uint32_t)*((x)+1) << 8) | \ 31*10465441SEvalZero ((rt_uint32_t)*((x)+2) << 16) | ((rt_uint32_t)*((x)+3) << 24) 32*10465441SEvalZero 33*10465441SEvalZero #define FINSH_SET16(x, v) \ 34*10465441SEvalZero do \ 35*10465441SEvalZero { \ 36*10465441SEvalZero *(x) = (v) & 0x00ff; \ 37*10465441SEvalZero (*((x)+1)) = (v) >> 8; \ 38*10465441SEvalZero } while ( 0 ) 39*10465441SEvalZero 40*10465441SEvalZero #define FINSH_SET32(x, v) \ 41*10465441SEvalZero do \ 42*10465441SEvalZero { \ 43*10465441SEvalZero *(x) = (rt_uint32_t)(v) & 0x000000ff; \ 44*10465441SEvalZero (*((x)+1)) = ((rt_uint32_t)(v) >> 8) & 0x000000ff; \ 45*10465441SEvalZero (*((x)+2)) = ((rt_uint32_t)(v) >> 16) & 0x000000ff; \ 46*10465441SEvalZero (*((x)+3)) = ((rt_uint32_t)(v) >> 24); \ 47*10465441SEvalZero } while ( 0 ) 48*10465441SEvalZero 49*10465441SEvalZero /* -- the end of option -- */ 50*10465441SEvalZero 51*10465441SEvalZero /* std header file */ 52*10465441SEvalZero #include <stdio.h> 53*10465441SEvalZero #include <ctype.h> 54*10465441SEvalZero #include <stdlib.h> 55*10465441SEvalZero #include <stdint.h> 56*10465441SEvalZero #include <string.h> 57*10465441SEvalZero 58*10465441SEvalZero #define FINSH_VERSION_MAJOR 1 59*10465441SEvalZero #define FINSH_VERSION_MINOR 0 60*10465441SEvalZero 61*10465441SEvalZero /** 62*10465441SEvalZero * @addtogroup finsh 63*10465441SEvalZero */ 64*10465441SEvalZero /*@{*/ 65*10465441SEvalZero #define FINSH_ERROR_OK 0 /**< No error */ 66*10465441SEvalZero #define FINSH_ERROR_INVALID_TOKEN 1 /**< Invalid token */ 67*10465441SEvalZero #define FINSH_ERROR_EXPECT_TYPE 2 /**< Expect a type */ 68*10465441SEvalZero #define FINSH_ERROR_UNKNOWN_TYPE 3 /**< Unknown type */ 69*10465441SEvalZero #define FINSH_ERROR_VARIABLE_EXIST 4 /**< Variable exist */ 70*10465441SEvalZero #define FINSH_ERROR_EXPECT_OPERATOR 5 /**< Expect a operator */ 71*10465441SEvalZero #define FINSH_ERROR_MEMORY_FULL 6 /**< Memory full */ 72*10465441SEvalZero #define FINSH_ERROR_UNKNOWN_OP 7 /**< Unknown operator */ 73*10465441SEvalZero #define FINSH_ERROR_UNKNOWN_NODE 8 /**< Unknown node */ 74*10465441SEvalZero #define FINSH_ERROR_EXPECT_CHAR 9 /**< Expect a character */ 75*10465441SEvalZero #define FINSH_ERROR_UNEXPECT_END 10 /**< Unexpect end */ 76*10465441SEvalZero #define FINSH_ERROR_UNKNOWN_TOKEN 11 /**< Unknown token */ 77*10465441SEvalZero #define FINSH_ERROR_NO_FLOAT 12 /**< Float not supported */ 78*10465441SEvalZero #define FINSH_ERROR_UNKNOWN_SYMBOL 13 /**< Unknown symbol */ 79*10465441SEvalZero #define FINSH_ERROR_NULL_NODE 14 /**< Null node */ 80*10465441SEvalZero /*@}*/ 81*10465441SEvalZero 82*10465441SEvalZero /* system call item */ 83*10465441SEvalZero struct finsh_syscall_item 84*10465441SEvalZero { 85*10465441SEvalZero struct finsh_syscall_item* next; /* next item */ 86*10465441SEvalZero struct finsh_syscall syscall; /* syscall */ 87*10465441SEvalZero }; 88*10465441SEvalZero extern struct finsh_syscall_item *global_syscall_list; 89*10465441SEvalZero 90*10465441SEvalZero /* system variable table */ 91*10465441SEvalZero struct finsh_sysvar 92*10465441SEvalZero { 93*10465441SEvalZero const char* name; /* the name of variable */ 94*10465441SEvalZero #if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB) 95*10465441SEvalZero const char* desc; /* description of system variable */ 96*10465441SEvalZero #endif 97*10465441SEvalZero uint8_t type; /* the type of variable */ 98*10465441SEvalZero void* var ; /* the address of variable */ 99*10465441SEvalZero }; 100*10465441SEvalZero 101*10465441SEvalZero #if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__)) 102*10465441SEvalZero struct finsh_syscall* finsh_syscall_next(struct finsh_syscall* call); 103*10465441SEvalZero struct finsh_sysvar* finsh_sysvar_next(struct finsh_sysvar* call); 104*10465441SEvalZero #define FINSH_NEXT_SYSCALL(index) index=finsh_syscall_next(index) 105*10465441SEvalZero #define FINSH_NEXT_SYSVAR(index) index=finsh_sysvar_next(index) 106*10465441SEvalZero #else 107*10465441SEvalZero #define FINSH_NEXT_SYSCALL(index) index++ 108*10465441SEvalZero #define FINSH_NEXT_SYSVAR(index) index++ 109*10465441SEvalZero #endif 110*10465441SEvalZero 111*10465441SEvalZero /* system variable item */ 112*10465441SEvalZero struct finsh_sysvar_item 113*10465441SEvalZero { 114*10465441SEvalZero struct finsh_sysvar_item *next; /* next item */ 115*10465441SEvalZero struct finsh_sysvar sysvar; /* system variable */ 116*10465441SEvalZero }; 117*10465441SEvalZero extern struct finsh_sysvar *_sysvar_table_begin, *_sysvar_table_end; 118*10465441SEvalZero extern struct finsh_sysvar_item* global_sysvar_list; 119*10465441SEvalZero 120*10465441SEvalZero /* find out system variable, which should be implemented in user program */ 121*10465441SEvalZero struct finsh_sysvar* finsh_sysvar_lookup(const char* name); 122*10465441SEvalZero 123*10465441SEvalZero 124*10465441SEvalZero struct finsh_token 125*10465441SEvalZero { 126*10465441SEvalZero char eof; 127*10465441SEvalZero char replay; 128*10465441SEvalZero 129*10465441SEvalZero int position; 130*10465441SEvalZero uint8_t current_token; 131*10465441SEvalZero 132*10465441SEvalZero union { 133*10465441SEvalZero char char_value; 134*10465441SEvalZero int int_value; 135*10465441SEvalZero long long_value; 136*10465441SEvalZero } value; 137*10465441SEvalZero uint8_t string[FINSH_STRING_MAX]; 138*10465441SEvalZero 139*10465441SEvalZero uint8_t* line; 140*10465441SEvalZero }; 141*10465441SEvalZero 142*10465441SEvalZero #define FINSH_IDTYPE_VAR 0x01 143*10465441SEvalZero #define FINSH_IDTYPE_SYSVAR 0x02 144*10465441SEvalZero #define FINSH_IDTYPE_SYSCALL 0x04 145*10465441SEvalZero #define FINSH_IDTYPE_ADDRESS 0x08 146*10465441SEvalZero struct finsh_node 147*10465441SEvalZero { 148*10465441SEvalZero uint8_t node_type; /* node node_type */ 149*10465441SEvalZero uint8_t data_type; /* node data node_type */ 150*10465441SEvalZero uint8_t idtype; /* id node information */ 151*10465441SEvalZero 152*10465441SEvalZero union { /* value node */ 153*10465441SEvalZero char char_value; 154*10465441SEvalZero short short_value; 155*10465441SEvalZero int int_value; 156*10465441SEvalZero long long_value; 157*10465441SEvalZero void* ptr; 158*10465441SEvalZero } value; 159*10465441SEvalZero union 160*10465441SEvalZero { 161*10465441SEvalZero /* point to variable identifier or function identifier */ 162*10465441SEvalZero struct finsh_var *var; 163*10465441SEvalZero struct finsh_sysvar *sysvar; 164*10465441SEvalZero struct finsh_syscall*syscall; 165*10465441SEvalZero }id; 166*10465441SEvalZero 167*10465441SEvalZero /* sibling and child node */ 168*10465441SEvalZero struct finsh_node *sibling, *child; 169*10465441SEvalZero }; 170*10465441SEvalZero 171*10465441SEvalZero struct finsh_parser 172*10465441SEvalZero { 173*10465441SEvalZero uint8_t* parser_string; 174*10465441SEvalZero 175*10465441SEvalZero struct finsh_token token; 176*10465441SEvalZero struct finsh_node* root; 177*10465441SEvalZero }; 178*10465441SEvalZero 179*10465441SEvalZero /** 180*10465441SEvalZero * @ingroup finsh 181*10465441SEvalZero * 182*10465441SEvalZero * The basic data type in finsh shell 183*10465441SEvalZero */ 184*10465441SEvalZero enum finsh_type { 185*10465441SEvalZero finsh_type_unknown = 0, /**< unknown data type */ 186*10465441SEvalZero finsh_type_void, /**< void */ 187*10465441SEvalZero finsh_type_voidp, /**< void pointer */ 188*10465441SEvalZero finsh_type_char, /**< char */ 189*10465441SEvalZero finsh_type_uchar, /**< unsigned char */ 190*10465441SEvalZero finsh_type_charp, /**< char pointer */ 191*10465441SEvalZero finsh_type_short, /**< short */ 192*10465441SEvalZero finsh_type_ushort, /**< unsigned short */ 193*10465441SEvalZero finsh_type_shortp, /**< short pointer */ 194*10465441SEvalZero finsh_type_int, /**< int */ 195*10465441SEvalZero finsh_type_uint, /**< unsigned int */ 196*10465441SEvalZero finsh_type_intp, /**< int pointer */ 197*10465441SEvalZero finsh_type_long, /**< long */ 198*10465441SEvalZero finsh_type_ulong, /**< unsigned long */ 199*10465441SEvalZero finsh_type_longp /**< long pointer */ 200*10465441SEvalZero }; 201*10465441SEvalZero 202*10465441SEvalZero /* init finsh environment */ 203*10465441SEvalZero int finsh_init(struct finsh_parser* parser); 204*10465441SEvalZero /* flush finsh node, text segment */ 205*10465441SEvalZero int finsh_flush(struct finsh_parser* parser); 206*10465441SEvalZero /* reset all of finsh */ 207*10465441SEvalZero int finsh_reset(struct finsh_parser* parser); 208*10465441SEvalZero #ifdef RT_USING_DEVICE 209*10465441SEvalZero void finsh_set_device(const char* device_name); 210*10465441SEvalZero #endif 211*10465441SEvalZero 212*10465441SEvalZero /* run finsh parser to generate abstract synatx tree */ 213*10465441SEvalZero void finsh_parser_run (struct finsh_parser* parser, const unsigned char* string); 214*10465441SEvalZero /* run compiler to compile abstract syntax tree */ 215*10465441SEvalZero int finsh_compiler_run(struct finsh_node* node); 216*10465441SEvalZero /* run finsh virtual machine */ 217*10465441SEvalZero void finsh_vm_run(void); 218*10465441SEvalZero 219*10465441SEvalZero /* get variable value */ 220*10465441SEvalZero struct finsh_var* finsh_var_lookup(const char* name); 221*10465441SEvalZero /* get bottom value of stack */ 222*10465441SEvalZero long finsh_stack_bottom(void); 223*10465441SEvalZero 224*10465441SEvalZero /* get error number of finsh */ 225*10465441SEvalZero uint8_t finsh_errno(void); 226*10465441SEvalZero /* get error string */ 227*10465441SEvalZero const char* finsh_error_string(uint8_t type); 228*10465441SEvalZero 229*10465441SEvalZero #ifdef RT_USING_HEAP 230*10465441SEvalZero /** 231*10465441SEvalZero * @ingroup finsh 232*10465441SEvalZero * 233*10465441SEvalZero * This function appends a system call to finsh runtime environment 234*10465441SEvalZero * @param name the name of system call 235*10465441SEvalZero * @param func the function pointer of system call 236*10465441SEvalZero */ 237*10465441SEvalZero void finsh_syscall_append(const char* name, syscall_func func); 238*10465441SEvalZero 239*10465441SEvalZero /** 240*10465441SEvalZero * @ingroup finsh 241*10465441SEvalZero * 242*10465441SEvalZero * This function appends a system variable to finsh runtime environment 243*10465441SEvalZero * @param name the name of system variable 244*10465441SEvalZero * @param type the data type of system variable 245*10465441SEvalZero * @param addr the address of system variable 246*10465441SEvalZero */ 247*10465441SEvalZero void finsh_sysvar_append(const char* name, uint8_t type, void* addr); 248*10465441SEvalZero #endif 249*10465441SEvalZero #endif 250