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