xref: /nrf52832-nimble/rt-thread/components/finsh/finsh.h (revision 104654410c56c573564690304ae786df310c91fc)
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