finsh.h 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. /*
  2. * File : finsh.h
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2010-03-22 Bernard first version
  13. */
  14. #ifndef __FINSH_H__
  15. #define __FINSH_H__
  16. #include <rtthread.h>
  17. #if defined(_MSC_VER)
  18. #pragma section("FSymTab$f",read)
  19. #pragma section("VSymTab",read)
  20. #endif
  21. /* -- the beginning of option -- */
  22. #define FINSH_NAME_MAX 16 /* max length of identifier */
  23. #define FINSH_NODE_MAX 16 /* max number of node */
  24. #define FINSH_HEAP_MAX 128 /* max length of heap */
  25. #define FINSH_STRING_MAX 128 /* max length of string */
  26. #define FINSH_VARIABLE_MAX 8 /* max number of variable */
  27. #define FINSH_STACK_MAX 64 /* max stack size */
  28. #define FINSH_TEXT_MAX 128 /* max text segment size */
  29. #define HEAP_ALIGNMENT 4 /* heap alignment */
  30. #define FINSH_GET16(x) (*(x)) | (*((x)+1) << 8)
  31. #define FINSH_GET32(x) (rt_uint32_t)(*(x)) | ((rt_uint32_t)*((x)+1) << 8) | \
  32. ((rt_uint32_t)*((x)+2) << 16) | ((rt_uint32_t)*((x)+3) << 24)
  33. #define FINSH_SET16(x, v) \
  34. do \
  35. { \
  36. *(x) = (v) & 0x00ff; \
  37. (*((x)+1)) = (v) >> 8; \
  38. } while ( 0 )
  39. #define FINSH_SET32(x, v) \
  40. do \
  41. { \
  42. *(x) = (rt_uint32_t)(v) & 0x000000ff; \
  43. (*((x)+1)) = ((rt_uint32_t)(v) >> 8) & 0x000000ff; \
  44. (*((x)+2)) = ((rt_uint32_t)(v) >> 16) & 0x000000ff; \
  45. (*((x)+3)) = ((rt_uint32_t)(v) >> 24); \
  46. } while ( 0 )
  47. /* -- the end of option -- */
  48. #if defined(RT_USING_NEWLIB) || defined (RT_USING_MINILIBC)
  49. #include <sys/types.h>
  50. #include <string.h>
  51. #else
  52. typedef unsigned char u_char;
  53. typedef unsigned short u_short;
  54. typedef unsigned long u_long;
  55. #if !defined(__CC_ARM) && \
  56. !defined(__IAR_SYSTEMS_ICC__) && \
  57. !defined(__ADSPBLACKFIN__) && \
  58. !defined(_MSC_VER)
  59. #if !(defined(__GNUC__) && defined(__x86_64__))
  60. typedef unsigned int size_t;
  61. #else
  62. #include <stdio.h>
  63. #endif
  64. #ifndef NULL
  65. #define NULL RT_NULL
  66. #endif
  67. #define memset rt_memset
  68. #define strlen rt_strlen
  69. #define strncpy rt_strncpy
  70. #define strncmp rt_strncmp
  71. int strcmp (const char *s1, const char *s2);
  72. char *strdup(const char *s);
  73. #else
  74. /* use libc of armcc */
  75. #include <ctype.h>
  76. #include <stdlib.h>
  77. #include <string.h>
  78. #endif
  79. #endif
  80. #define FINSH_VERSION_MAJOR 0
  81. #define FINSH_VERSION_MINOR 5
  82. /**
  83. * @addtogroup finsh
  84. */
  85. /*@{*/
  86. #define FINSH_ERROR_OK 0 /**< No error */
  87. #define FINSH_ERROR_INVALID_TOKEN 1 /**< Invalid token */
  88. #define FINSH_ERROR_EXPECT_TYPE 2 /**< Expect a type */
  89. #define FINSH_ERROR_UNKNOWN_TYPE 3 /**< Unknown type */
  90. #define FINSH_ERROR_VARIABLE_EXIST 4 /**< Variable exist */
  91. #define FINSH_ERROR_EXPECT_OPERATOR 5 /**< Expect a operator */
  92. #define FINSH_ERROR_MEMORY_FULL 6 /**< Memory full */
  93. #define FINSH_ERROR_UNKNOWN_OP 7 /**< Unknown operator */
  94. #define FINSH_ERROR_UNKNOWN_NODE 8 /**< Unknown node */
  95. #define FINSH_ERROR_EXPECT_CHAR 9 /**< Expect a character */
  96. #define FINSH_ERROR_UNEXPECT_END 10 /**< Unexpect end */
  97. #define FINSH_ERROR_UNKNOWN_TOKEN 11 /**< Unknown token */
  98. #define FINSH_ERROR_NO_FLOAT 12 /**< Float not supported */
  99. #define FINSH_ERROR_UNKNOWN_SYMBOL 13 /**< Unknown symbol */
  100. #define FINSH_ERROR_NULL_NODE 14 /**< Null node */
  101. /*@}*/
  102. typedef long (*syscall_func)();
  103. /* system call table */
  104. struct finsh_syscall
  105. {
  106. const char* name; /* the name of system call */
  107. #if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
  108. const char* desc; /* description of system call */
  109. #endif
  110. syscall_func func; /* the function address of system call */
  111. };
  112. /* system call item */
  113. struct finsh_syscall_item
  114. {
  115. struct finsh_syscall_item* next; /* next item */
  116. struct finsh_syscall syscall; /* syscall */
  117. };
  118. extern struct finsh_syscall *_syscall_table_begin, *_syscall_table_end;
  119. extern struct finsh_syscall_item *global_syscall_list;
  120. /* find out system call, which should be implemented in user program */
  121. struct finsh_syscall* finsh_syscall_lookup(const char* name);
  122. /* system variable table */
  123. struct finsh_sysvar
  124. {
  125. const char* name; /* the name of variable */
  126. #if defined(FINSH_USING_DESCRIPTION) && defined(FINSH_USING_SYMTAB)
  127. const char* desc; /* description of system variable */
  128. #endif
  129. u_char type; /* the type of variable */
  130. void* var ; /* the address of variable */
  131. };
  132. #if defined(_MSC_VER) || (defined(__GNUC__) && defined(__x86_64__))
  133. struct finsh_syscall* finsh_syscall_next(struct finsh_syscall* call);
  134. struct finsh_sysvar* finsh_sysvar_next(struct finsh_sysvar* call);
  135. #define FINSH_NEXT_SYSCALL(index) index=finsh_syscall_next(index)
  136. #define FINSH_NEXT_SYSVAR(index) index=finsh_sysvar_next(index)
  137. #else
  138. #define FINSH_NEXT_SYSCALL(index) index++
  139. #define FINSH_NEXT_SYSVAR(index) index++
  140. #endif
  141. /* system variable item */
  142. struct finsh_sysvar_item
  143. {
  144. struct finsh_sysvar_item *next; /* next item */
  145. struct finsh_sysvar sysvar; /* system variable */
  146. };
  147. extern struct finsh_sysvar *_sysvar_table_begin, *_sysvar_table_end;
  148. extern struct finsh_sysvar_item* global_sysvar_list;
  149. /* find out system variable, which should be implemented in user program */
  150. struct finsh_sysvar* finsh_sysvar_lookup(const char* name);
  151. #ifdef FINSH_USING_SYMTAB
  152. #ifdef __TI_COMPILER_VERSION__
  153. #define _EMIT_PRAGMA(x) _Pragma(#x)
  154. #define __TI_FINSH_EXPORT_FUNCTION(f) _EMIT_PRAGMA(DATA_SECTION(f,"FSymTab"))
  155. #define __TI_FINSH_EXPORT_VAR(v) _EMIT_PRAGMA(DATA_SECTION(v,"VSymTab"))
  156. #endif
  157. #ifdef FINSH_USING_DESCRIPTION
  158. /**
  159. * @ingroup finsh
  160. *
  161. * This macro exports a system function to finsh shell.
  162. *
  163. * @param name the name of function.
  164. * @param desc the description of function, which will show in help.
  165. */
  166. #ifdef _MSC_VER
  167. #define FINSH_FUNCTION_EXPORT(name, desc) \
  168. const char __fsym_##name##_name[] = #name; \
  169. const char __fsym_##name##_desc[] = #desc; \
  170. __declspec(allocate("FSymTab$f")) const struct finsh_syscall __fsym_##name = \
  171. { \
  172. __fsym_##name##_name, \
  173. __fsym_##name##_desc, \
  174. (syscall_func)&name \
  175. };
  176. #pragma comment(linker, "/merge:FSymTab=mytext")
  177. #elif defined(__TI_COMPILER_VERSION__)
  178. #define FINSH_FUNCTION_EXPORT(name, desc) \
  179. __TI_FINSH_EXPORT_FUNCTION(__fsym_##name); \
  180. const char __fsym_##name##_name[] = #name; \
  181. const char __fsym_##name##_desc[] = #desc; \
  182. const struct finsh_syscall __fsym_##name = \
  183. { \
  184. __fsym_##name##_name, \
  185. __fsym_##name##_desc, \
  186. (syscall_func)&name \
  187. };
  188. #else
  189. #define FINSH_FUNCTION_EXPORT(name, desc) \
  190. const char __fsym_##name##_name[] = #name; \
  191. const char __fsym_##name##_desc[] = #desc; \
  192. const struct finsh_syscall __fsym_##name SECTION("FSymTab")= \
  193. { \
  194. __fsym_##name##_name, \
  195. __fsym_##name##_desc, \
  196. (syscall_func)&name \
  197. };
  198. #endif /* FINSH_FUNCTION_EXPORT defines */
  199. /**
  200. * @ingroup finsh
  201. *
  202. * This macro exports a system function with an alias name to finsh shell.
  203. *
  204. * @param name the name of function.
  205. * @param alias the alias name of function.
  206. * @param desc the description of function, which will show in help.
  207. */
  208. #ifdef _MSC_VER
  209. #define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc) \
  210. const char __fsym_##alias##_name[] = #alias; \
  211. const char __fsym_##alias##_desc[] = #desc; \
  212. __declspec(allocate("FSymTab$f")) \
  213. const struct finsh_syscall __fsym_##alias = \
  214. { \
  215. __fsym_##alias##_name, \
  216. __fsym_##alias##_desc, \
  217. (syscall_func)&name \
  218. };
  219. #elif defined(__TI_COMPILER_VERSION__)
  220. #define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc) \
  221. __TI_FINSH_EXPORT_FUNCTION(__fsym_##alias); \
  222. const char __fsym_##alias##_name[] = #alias; \
  223. const char __fsym_##alias##_desc[] = #desc; \
  224. const struct finsh_syscall __fsym_##alias = \
  225. { \
  226. __fsym_##alias##_name, \
  227. __fsym_##alias##_desc, \
  228. (syscall_func)&name \
  229. };
  230. #else
  231. #define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc) \
  232. const char __fsym_##alias##_name[] = #alias; \
  233. const char __fsym_##alias##_desc[] = #desc; \
  234. const struct finsh_syscall __fsym_##alias SECTION("FSymTab")= \
  235. { \
  236. __fsym_##alias##_name, \
  237. __fsym_##alias##_desc, \
  238. (syscall_func)&name \
  239. };
  240. #endif /* FINSH_FUNCTION_EXPORT_ALIAS defines */
  241. /**
  242. * @ingroup finsh
  243. *
  244. * This macro exports a variable to finsh shell.
  245. *
  246. * @param name the name of function.
  247. * @param type the type of variable.
  248. * @param desc the description of function, which will show in help.
  249. */
  250. #ifdef _MSC_VER
  251. #define FINSH_VAR_EXPORT(name, type, desc) \
  252. const char __vsym_##name##_name[] = #name; \
  253. const char __vsym_##name##_desc[] = #desc; \
  254. __declspec(allocate("VSymTab")) const struct finsh_sysvar __vsym_##name = \
  255. { \
  256. __vsym_##name##_name, \
  257. __vsym_##name##_desc, \
  258. type, \
  259. (void*)&name \
  260. };
  261. #elif defined(__TI_COMPILER_VERSION__)
  262. #define FINSH_VAR_EXPORT(name, type, desc) \
  263. __TI_FINSH_EXPORT_VAR(__vsym_##name); \
  264. const char __vsym_##name##_name[] = #name; \
  265. const char __vsym_##name##_desc[] = #desc; \
  266. const struct finsh_sysvar __vsym_##name = \
  267. { \
  268. __vsym_##name##_name, \
  269. __vsym_##name##_desc, \
  270. type, \
  271. (void*)&name \
  272. };
  273. #else
  274. #define FINSH_VAR_EXPORT(name, type, desc) \
  275. const char __vsym_##name##_name[] = #name; \
  276. const char __vsym_##name##_desc[] = #desc; \
  277. const struct finsh_sysvar __vsym_##name SECTION("VSymTab")= \
  278. { \
  279. __vsym_##name##_name, \
  280. __vsym_##name##_desc, \
  281. type, \
  282. (void*)&name \
  283. };
  284. #endif /* FINSH_VAR_EXPORT defines */
  285. #else /* FINSH_USING_DESCRIPTION */
  286. #if defined(__TI_COMPILER_VERSION__)
  287. #define FINSH_FUNCTION_EXPORT(name, desc) \
  288. __TI_FINSH_EXPORT_FUNCTION(__fsym_##name); \
  289. const char __fsym_##name##_name[] = #name; \
  290. const char __fsym_##name##_desc[] = #desc; \
  291. const struct finsh_syscall __fsym_##name = \
  292. { \
  293. __fsym_##name##_name, \
  294. __fsym_##name##_desc, \
  295. (syscall_func)&name \
  296. };
  297. #define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc) \
  298. const char __fsym_##alias##_name[] = #alias; \
  299. __TI_FINSH_EXPORT_FUNCTION(__fsym_##alias); \
  300. const struct finsh_syscall __fsym_##alias = \
  301. { \
  302. __fsym_##alias##_name, \
  303. (syscall_func)&name \
  304. };
  305. #define FINSH_VAR_EXPORT(name, type, desc) \
  306. __TI_FINSH_EXPORT_VAR(__vsym_##name); \
  307. const char __vsym_##name##_name[] = #name; \
  308. const struct finsh_sysvar __vsym_##name = \
  309. { \
  310. __vsym_##name##_name, \
  311. type, \
  312. (void*)&name \
  313. };
  314. #else
  315. #define FINSH_FUNCTION_EXPORT(name, desc) \
  316. const char __fsym_##name##_name[] = #name; \
  317. const struct finsh_syscall __fsym_##name SECTION("FSymTab")= \
  318. { \
  319. __fsym_##name##_name, \
  320. (syscall_func)&name \
  321. };
  322. #define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc) \
  323. const char __fsym_##alias##_name[] = #alias; \
  324. const struct finsh_syscall __fsym_##alias SECTION("FSymTab")= \
  325. { \
  326. __fsym_##alias##_name, \
  327. (syscall_func)&name \
  328. };
  329. #define FINSH_VAR_EXPORT(name, type, desc) \
  330. const char __vsym_##name##_name[] = #name; \
  331. const struct finsh_sysvar __vsym_##name SECTION("VSymTab")= \
  332. { \
  333. __vsym_##name##_name, \
  334. type, \
  335. (void*)&name \
  336. };
  337. #endif /* __TI_COMPILER_VERSION__ */
  338. #endif /* FINSH_USING_DESCRIPTION */
  339. #else
  340. #define FINSH_FUNCTION_EXPORT(name, desc)
  341. #define FINSH_FUNCTION_EXPORT_ALIAS(name, alias, desc)
  342. #define FINSH_VAR_EXPORT(name, type, desc)
  343. #endif
  344. struct finsh_token
  345. {
  346. char eof;
  347. char replay;
  348. int position;
  349. u_char current_token;
  350. union {
  351. char char_value;
  352. int int_value;
  353. long long_value;
  354. } value;
  355. u_char string[128];
  356. u_char* line;
  357. };
  358. #define FINSH_IDTYPE_VAR 0x01
  359. #define FINSH_IDTYPE_SYSVAR 0x02
  360. #define FINSH_IDTYPE_SYSCALL 0x04
  361. #define FINSH_IDTYPE_ADDRESS 0x08
  362. struct finsh_node
  363. {
  364. u_char node_type; /* node node_type */
  365. u_char data_type; /* node data node_type */
  366. u_char idtype; /* id node information */
  367. union { /* value node */
  368. char char_value;
  369. short short_value;
  370. int int_value;
  371. long long_value;
  372. void* ptr;
  373. } value;
  374. union
  375. {
  376. /* point to variable identifier or function identifier */
  377. struct finsh_var *var;
  378. struct finsh_sysvar *sysvar;
  379. struct finsh_syscall*syscall;
  380. }id;
  381. /* sibling and child node */
  382. struct finsh_node *sibling, *child;
  383. };
  384. struct finsh_parser
  385. {
  386. u_char* parser_string;
  387. struct finsh_token token;
  388. struct finsh_node* root;
  389. };
  390. /**
  391. * @ingroup finsh
  392. *
  393. * The basic data type in finsh shell
  394. */
  395. enum finsh_type {
  396. finsh_type_unknown = 0, /**< unknown data type */
  397. finsh_type_void, /**< void */
  398. finsh_type_voidp, /**< void pointer */
  399. finsh_type_char, /**< char */
  400. finsh_type_uchar, /**< unsigned char */
  401. finsh_type_charp, /**< char pointer */
  402. finsh_type_short, /**< short */
  403. finsh_type_ushort, /**< unsigned short */
  404. finsh_type_shortp, /**< short pointer */
  405. finsh_type_int, /**< int */
  406. finsh_type_uint, /**< unsigned int */
  407. finsh_type_intp, /**< int pointer */
  408. finsh_type_long, /**< long */
  409. finsh_type_ulong, /**< unsigned long */
  410. finsh_type_longp /**< long pointer */
  411. };
  412. /* init finsh environment */
  413. int finsh_init(struct finsh_parser* parser);
  414. /* flush finsh node, text segment */
  415. int finsh_flush(struct finsh_parser* parser);
  416. /* reset all of finsh */
  417. int finsh_reset(struct finsh_parser* parser);
  418. #ifdef RT_USING_DEVICE
  419. void finsh_set_device(const char* device_name);
  420. #endif
  421. /* run finsh parser to generate abstract synatx tree */
  422. void finsh_parser_run (struct finsh_parser* parser, const unsigned char* string);
  423. /* run compiler to compile abstract syntax tree */
  424. int finsh_compiler_run(struct finsh_node* node);
  425. /* run finsh virtual machine */
  426. void finsh_vm_run(void);
  427. /* get variable value */
  428. struct finsh_var* finsh_var_lookup(const char* name);
  429. /* get bottom value of stack */
  430. long finsh_stack_bottom(void);
  431. /* get error number of finsh */
  432. u_char finsh_errno(void);
  433. /* get error string */
  434. const char* finsh_error_string(u_char type);
  435. #ifdef RT_USING_HEAP
  436. /**
  437. * @ingroup finsh
  438. *
  439. * This function appends a system call to finsh runtime environment
  440. * @param name the name of system call
  441. * @param func the function pointer of system call
  442. */
  443. void finsh_syscall_append(const char* name, syscall_func func);
  444. /**
  445. * @ingroup finsh
  446. *
  447. * This function appends a system variable to finsh runtime environment
  448. * @param name the name of system variable
  449. * @param type the data type of system variable
  450. * @param addr the address of system variable
  451. */
  452. void finsh_sysvar_append(const char* name, u_char type, void* addr);
  453. #endif
  454. #endif