cmd.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. /*
  2. * File : cmd.c
  3. * This file is part of RT-Thread RTOS
  4. * COPYRIGHT (C) 2006, 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. * 2006-04-30 Bernard first implementation
  13. * 2006-05-04 Bernard add list_thread,
  14. * list_sem,
  15. * list_timer
  16. * 2006-05-20 Bernard add list_mutex,
  17. * list_mailbox,
  18. * list_msgqueue,
  19. * list_event,
  20. * list_fevent,
  21. * list_mempool
  22. * 2006-06-03 Bernard display stack information in list_thread
  23. * 2006-08-10 Bernard change version to invoke rt_show_version
  24. * 2008-09-10 Bernard update the list function for finsh syscall
  25. * list and sysvar list
  26. * 2009-05-30 Bernard add list_device
  27. * 2010-04-21 yi.qiu add list_module
  28. */
  29. #include <rtthread.h>
  30. #include "finsh.h"
  31. // Copy from kservice.h because we can not use it out of the kernel.
  32. // Ugly. Should let kservice.h avaliable for applications?
  33. rt_inline int rt_list_isempty(const rt_list_t *l)
  34. {
  35. return l->next == l;
  36. }
  37. rt_inline unsigned int rt_list_len(const rt_list_t *l)
  38. {
  39. unsigned int len = 0;
  40. const rt_list_t *p = l;
  41. while( p->next != l )
  42. {
  43. p = p->next;
  44. len++;
  45. }
  46. return len;
  47. }
  48. long hello(void)
  49. {
  50. rt_kprintf("Hello RT-Thread!\n");
  51. return 0;
  52. }
  53. FINSH_FUNCTION_EXPORT(hello, say hello world);
  54. extern void rt_show_version(void);
  55. long version(void)
  56. {
  57. rt_show_version();
  58. return 0;
  59. }
  60. FINSH_FUNCTION_EXPORT(version, show RT-Thread version information);
  61. #define rt_list_entry(node, type, member) \
  62. ((type *)((char *)(node) - (unsigned long)(&((type *)0)->member)))
  63. extern struct rt_object_information rt_object_container[];
  64. static long _list_thread(struct rt_list_node* list)
  65. {
  66. struct rt_thread *thread;
  67. struct rt_list_node *node;
  68. rt_uint8_t* ptr;
  69. rt_kprintf(" thread pri status sp stack size max used left tick error\n");
  70. rt_kprintf("-------- ---- ------- ---------- ---------- ---------- ---------- ---\n");
  71. for (node = list->next; node != list; node = node->next)
  72. {
  73. thread = rt_list_entry(node, struct rt_thread, list);
  74. rt_kprintf("%-8s 0x%02x", thread->name, thread->current_priority);
  75. if (thread->stat == RT_THREAD_READY) rt_kprintf(" ready ");
  76. else if (thread->stat == RT_THREAD_SUSPEND) rt_kprintf(" suspend");
  77. else if (thread->stat == RT_THREAD_INIT) rt_kprintf(" init ");
  78. ptr = (rt_uint8_t*)thread->stack_addr;
  79. while (*ptr == '#')ptr ++;
  80. rt_kprintf(" 0x%08x 0x%08x 0x%08x 0x%08x %03d\n",
  81. thread->stack_size + ((rt_uint32_t)thread->stack_addr - (rt_uint32_t)thread->sp),
  82. thread->stack_size,
  83. thread->stack_size - ((rt_uint32_t) ptr - (rt_uint32_t)thread->stack_addr),
  84. thread->remaining_tick,
  85. thread->error);
  86. }
  87. return 0;
  88. }
  89. long list_thread(void)
  90. {
  91. return _list_thread(&rt_object_container[RT_Object_Class_Thread].object_list);
  92. }
  93. FINSH_FUNCTION_EXPORT(list_thread, list thread);
  94. static void show_wait_queue(struct rt_list_node* list)
  95. {
  96. struct rt_thread *thread;
  97. struct rt_list_node *node;
  98. for (node = list->next; node != list; node = node->next)
  99. {
  100. thread = rt_list_entry(node, struct rt_thread, tlist);
  101. rt_kprintf("%s", thread->name);
  102. if (node->next != list) rt_kprintf("/");
  103. }
  104. }
  105. #ifdef RT_USING_SEMAPHORE
  106. static long _list_sem(struct rt_list_node *list)
  107. {
  108. struct rt_semaphore *sem;
  109. struct rt_list_node *node;
  110. rt_kprintf("semaphore v suspend thread\n");
  111. rt_kprintf("-------- --- --------------\n");
  112. for (node = list->next; node != list; node = node->next)
  113. {
  114. sem = (struct rt_semaphore*)(rt_list_entry(node, struct rt_object, list));
  115. if( !rt_list_isempty(&sem->parent.suspend_thread) )
  116. {
  117. rt_kprintf("%-8s %03d %d:", sem->parent.parent.name, sem->value, rt_list_len(&sem->parent.suspend_thread) );
  118. show_wait_queue(&(sem->parent.suspend_thread));
  119. rt_kprintf("\n");
  120. }
  121. else
  122. {
  123. rt_kprintf("%-8s %03d %d\n", sem->parent.parent.name, sem->value, rt_list_len(&sem->parent.suspend_thread));
  124. }
  125. }
  126. return 0;
  127. }
  128. long list_sem(void)
  129. {
  130. return _list_sem(&rt_object_container[RT_Object_Class_Semaphore].object_list);
  131. }
  132. FINSH_FUNCTION_EXPORT(list_sem, list semaphone in system)
  133. #endif
  134. #ifdef RT_USING_EVENT
  135. static long _list_event(struct rt_list_node *list)
  136. {
  137. struct rt_event *e;
  138. struct rt_list_node *node;
  139. rt_kprintf("event set suspend thread\n");
  140. rt_kprintf("-------- ---------- --------------\n");
  141. for (node = list->next; node != list; node = node->next)
  142. {
  143. e = (struct rt_event*)(rt_list_entry(node, struct rt_object, list));
  144. rt_kprintf("%-8s 0x%08x %03d\n", e->parent.parent.name, e->set, rt_list_len(&e->parent.suspend_thread));
  145. }
  146. return 0;
  147. }
  148. long list_event(void)
  149. {
  150. return _list_event(&rt_object_container[RT_Object_Class_Event].object_list);
  151. }
  152. FINSH_FUNCTION_EXPORT(list_event, list event in system)
  153. #endif
  154. #ifdef RT_USING_MUTEX
  155. static long _list_mutex(struct rt_list_node *list)
  156. {
  157. struct rt_mutex *m;
  158. struct rt_list_node *node;
  159. rt_kprintf("mutex owner hold suspend thread\n");
  160. rt_kprintf("-------- -------- ---- --------------\n");
  161. for (node = list->next; node != list; node = node->next)
  162. {
  163. m = (struct rt_mutex*)(rt_list_entry(node, struct rt_object, list));
  164. rt_kprintf("%-8s %-8s %04d %d\n", m->parent.parent.name, m->owner->name, m->hold, rt_list_len(&m->parent.suspend_thread));
  165. }
  166. return 0;
  167. }
  168. long list_mutex(void)
  169. {
  170. return _list_mutex(&rt_object_container[RT_Object_Class_Mutex].object_list);
  171. }
  172. FINSH_FUNCTION_EXPORT(list_mutex, list mutex in system)
  173. #endif
  174. #ifdef RT_USING_MAILBOX
  175. static long _list_mailbox(struct rt_list_node *list)
  176. {
  177. struct rt_mailbox *m;
  178. struct rt_list_node *node;
  179. rt_kprintf("mailbox entry size suspend thread\n");
  180. rt_kprintf("-------- ---- ---- --------------\n");
  181. for (node = list->next; node != list; node = node->next)
  182. {
  183. m = (struct rt_mailbox*)(rt_list_entry(node, struct rt_object, list));
  184. if( !rt_list_isempty(&m->parent.suspend_thread) )
  185. {
  186. rt_kprintf("%-8s %04d %04d %d:", m->parent.parent.name, m->entry, m->size, rt_list_len(&m->parent.suspend_thread));
  187. show_wait_queue(&(m->parent.suspend_thread));
  188. rt_kprintf("\n");
  189. }
  190. else
  191. {
  192. rt_kprintf("%-8s %04d %04d %d\n", m->parent.parent.name, m->entry, m->size, rt_list_len(&m->parent.suspend_thread));
  193. }
  194. }
  195. return 0;
  196. }
  197. long list_mailbox(void)
  198. {
  199. return _list_mailbox(&rt_object_container[RT_Object_Class_MailBox].object_list);
  200. }
  201. FINSH_FUNCTION_EXPORT(list_mailbox, list mail box in system)
  202. #endif
  203. #ifdef RT_USING_MESSAGEQUEUE
  204. static long _list_msgqueue(struct rt_list_node *list)
  205. {
  206. struct rt_messagequeue *m;
  207. struct rt_list_node *node;
  208. rt_kprintf("msgqueue entry suspend thread\n");
  209. rt_kprintf("-------- ---- --------------\n");
  210. for (node = list->next; node != list; node = node->next)
  211. {
  212. m = (struct rt_messagequeue*)(rt_list_entry(node, struct rt_object, list));
  213. if( !rt_list_isempty(&m->parent.suspend_thread) )
  214. {
  215. rt_kprintf("%-8s %04d %d:", m->parent.parent.name, m->entry, rt_list_len(&m->parent.suspend_thread));
  216. show_wait_queue(&(m->parent.suspend_thread));
  217. rt_kprintf("\n");
  218. }
  219. else
  220. {
  221. rt_kprintf("%-8s %04d %d\n", m->parent.parent.name, m->entry, rt_list_len(&m->parent.suspend_thread));
  222. }
  223. }
  224. return 0;
  225. }
  226. long list_msgqueue(void)
  227. {
  228. return _list_msgqueue(&rt_object_container[RT_Object_Class_MessageQueue].object_list);
  229. }
  230. FINSH_FUNCTION_EXPORT(list_msgqueue, list message queue in system)
  231. #endif
  232. #ifdef RT_USING_MEMPOOL
  233. static long _list_mempool(struct rt_list_node *list)
  234. {
  235. struct rt_mempool *mp;
  236. struct rt_list_node *node;
  237. rt_kprintf("mempool block total free suspend thread\n");
  238. rt_kprintf("-------- ---- ---- ---- --------------\n");
  239. for (node = list->next; node != list; node = node->next)
  240. {
  241. mp = (struct rt_mempool*)rt_list_entry(node, struct rt_object, list);
  242. if (mp->suspend_thread_count > 0)
  243. {
  244. rt_kprintf("%-8s %04d %04d %04d %d:", mp->parent.name,
  245. mp->block_size, mp->block_total_count, mp->block_free_count,
  246. mp->suspend_thread_count);
  247. show_wait_queue(&(mp->suspend_thread));
  248. rt_kprintf("\n");
  249. }
  250. else
  251. {
  252. rt_kprintf("%-8s %04d %04d %04d %d\n", mp->parent.name,
  253. mp->block_size, mp->block_total_count, mp->block_free_count,
  254. mp->suspend_thread_count);
  255. }
  256. }
  257. return 0;
  258. }
  259. long list_mempool(void)
  260. {
  261. return _list_mempool(&rt_object_container[RT_Object_Class_MemPool].object_list);
  262. }
  263. FINSH_FUNCTION_EXPORT(list_mempool, list memory pool in system)
  264. #endif
  265. static long _list_timer(struct rt_list_node *list)
  266. {
  267. struct rt_timer *timer;
  268. struct rt_list_node *node;
  269. rt_kprintf("timer periodic timeout flag\n");
  270. rt_kprintf("-------- ---------- ---------- -----------\n");
  271. for (node = list->next; node != list; node = node->next)
  272. {
  273. timer = (struct rt_timer*)(rt_list_entry(node, struct rt_object, list));
  274. rt_kprintf("%-8s 0x%08x 0x%08x ", timer->parent.name, timer->init_tick, timer->timeout_tick);
  275. if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED) rt_kprintf("activated\n");
  276. else rt_kprintf("deactivated\n");
  277. }
  278. rt_kprintf("current tick:0x%08x\n", rt_tick_get());
  279. return 0;
  280. }
  281. long list_timer(void)
  282. {
  283. return _list_timer(&rt_object_container[RT_Object_Class_Timer].object_list);
  284. }
  285. FINSH_FUNCTION_EXPORT(list_timer, list timer in system)
  286. #ifdef RT_USING_DEVICE
  287. static long _list_device(struct rt_list_node *list)
  288. {
  289. struct rt_device *device;
  290. struct rt_list_node *node;
  291. const char *device_type_str[] =
  292. {
  293. "Character Device",
  294. "Block Device",
  295. "Network Interface",
  296. "MTD Device",
  297. "CAN",
  298. "RTC",
  299. "Unknown"
  300. };
  301. rt_kprintf("device type \n");
  302. rt_kprintf("-------- ---------- \n");
  303. for (node = list->next; node != list; node = node->next)
  304. {
  305. device = (struct rt_device*)(rt_list_entry(node, struct rt_object, list));
  306. rt_kprintf("%-8s %-8s \n", device->parent.name, device_type_str[device->type]);
  307. }
  308. return 0;
  309. }
  310. long list_device(void)
  311. {
  312. return _list_device(&rt_object_container[RT_Object_Class_Device].object_list);
  313. }
  314. FINSH_FUNCTION_EXPORT(list_device, list device in system)
  315. #endif
  316. #ifdef RT_USING_MODULE
  317. #include <rtm.h>
  318. int list_module(void)
  319. {
  320. struct rt_module *module;
  321. struct rt_list_node *list, *node;
  322. list = &rt_object_container[RT_Object_Class_Module].object_list;
  323. rt_kprintf("module name ref\n");
  324. rt_kprintf("------------ --------\n");
  325. for (node = list->next; node != list; node = node->next)
  326. {
  327. module = (struct rt_module*)(rt_list_entry(node, struct rt_object, list));
  328. rt_kprintf("%-16s ", module->parent.name);
  329. rt_kprintf("%-04d \n", module->nref);
  330. }
  331. }
  332. FINSH_FUNCTION_EXPORT(list_module, list module in system)
  333. int list_mod_detail(const char* name)
  334. {
  335. int i;
  336. struct rt_module *module;
  337. struct rt_list_node *list, *node;
  338. /* find module */
  339. if((module = rt_module_find(name)) != RT_NULL)
  340. {
  341. /* module has entry point */
  342. if(!(module->parent.flag & RT_MODULE_FLAG_WITHOUTENTRY))
  343. {
  344. struct rt_thread *thread;
  345. struct rt_list_node *tlist;
  346. rt_uint8_t* ptr;
  347. /* list main thread in module */
  348. if(module->module_thread != RT_NULL)
  349. {
  350. rt_kprintf("main thread pri status sp stack size max used left tick error\n");
  351. rt_kprintf("------------- ---- ------- ---------- ---------- ---------- ---------- ---\n");
  352. thread = module->module_thread;
  353. rt_kprintf("%-8s 0x%02x", thread->name, thread->current_priority);
  354. if (thread->stat == RT_THREAD_READY) rt_kprintf(" ready ");
  355. else if (thread->stat == RT_THREAD_SUSPEND) rt_kprintf(" suspend");
  356. else if (thread->stat == RT_THREAD_INIT) rt_kprintf(" init ");
  357. ptr = (rt_uint8_t*)thread->stack_addr;
  358. while (*ptr == '#')ptr ++;
  359. rt_kprintf(" 0x%08x 0x%08x 0x%08x 0x%08x %03d\n",
  360. thread->stack_size + ((rt_uint32_t)thread->stack_addr - (rt_uint32_t)thread->sp),
  361. thread->stack_size,
  362. thread->stack_size - ((rt_uint32_t) ptr - (rt_uint32_t)thread->stack_addr),
  363. thread->remaining_tick,
  364. thread->error);
  365. }
  366. /* list sub thread in module */
  367. tlist = &module->module_object[RT_Object_Class_Thread].object_list;
  368. if(!rt_list_isempty(tlist)) _list_thread(tlist);
  369. #ifdef RT_USING_SEMAPHORE
  370. /* list semaphored in module */
  371. tlist = &module->module_object[RT_Object_Class_Semaphore].object_list;
  372. if(!rt_list_isempty(tlist)) _list_sem(tlist);
  373. #endif
  374. #ifdef RT_USING_MUTEX
  375. /* list mutex in module */
  376. tlist = &module->module_object[RT_Object_Class_Mutex].object_list;
  377. if(!rt_list_isempty(tlist)) _list_mutex(tlist);
  378. #endif
  379. #ifdef RT_USING_EVENT
  380. /* list event in module */
  381. tlist = &module->module_object[RT_Object_Class_Event].object_list;
  382. if(!rt_list_isempty(tlist)) _list_event(tlist);
  383. #endif
  384. #ifdef RT_USING_MAILBOX
  385. /* list mailbox in module */
  386. tlist = &module->module_object[RT_Object_Class_MailBox].object_list;
  387. if(!rt_list_isempty(tlist)) _list_mailbox(tlist);
  388. #endif
  389. #ifdef RT_USING_MESSAGEQUEUE
  390. /* list message queue in module */
  391. tlist = &module->module_object[RT_Object_Class_MessageQueue].object_list;
  392. if(!rt_list_isempty(tlist)) _list_msgqueue(tlist);
  393. #endif
  394. #ifdef RT_USING_MEMPOOL
  395. /* list memory pool in module */
  396. tlist = &module->module_object[RT_Object_Class_MemPool].object_list;
  397. if(!rt_list_isempty(tlist)) _list_mempool(tlist);
  398. #endif
  399. #ifdef RT_USING_DEVICE
  400. /* list device in module */
  401. tlist = &module->module_object[RT_Object_Class_Device].object_list;
  402. if(!rt_list_isempty(tlist)) _list_device(tlist);
  403. #endif
  404. /* list timer in module */
  405. tlist = &module->module_object[RT_Object_Class_Timer].object_list;
  406. if(!rt_list_isempty(tlist)) _list_timer(tlist);
  407. }
  408. rt_kprintf("symbol address \n");
  409. rt_kprintf("-------- ----------\n");
  410. /* list module export symbols */
  411. for(i=0; i<module->nsym; i++)
  412. {
  413. rt_kprintf("%s 0x%x\n", module->symtab[i].name, module->symtab[i].addr);
  414. }
  415. }
  416. return 0;
  417. }
  418. FINSH_FUNCTION_EXPORT(list_mod_detail, list module objects in system)
  419. #endif
  420. int list()
  421. {
  422. struct finsh_syscall_item* syscall_item;
  423. struct finsh_sysvar_item* sysvar_item;
  424. rt_kprintf("--Function List:\n");
  425. {
  426. struct finsh_syscall* index;
  427. for (index = _syscall_table_begin; index < _syscall_table_end; index ++)
  428. {
  429. #ifdef FINSH_USING_DESCRIPTION
  430. rt_kprintf("%-16s -- %s\n", index->name, index->desc);
  431. #else
  432. rt_kprintf("%s\n", index->name);
  433. #endif
  434. }
  435. }
  436. /* list syscall list */
  437. syscall_item = global_syscall_list;
  438. while (syscall_item != NULL)
  439. {
  440. rt_kprintf("[l] %s\n", syscall_item->syscall.name);
  441. syscall_item = syscall_item->next;
  442. }
  443. rt_kprintf("--Variable List:\n");
  444. {
  445. struct finsh_sysvar* index;
  446. for (index = _sysvar_table_begin; index < _sysvar_table_end; index ++)
  447. {
  448. #ifdef FINSH_USING_DESCRIPTION
  449. rt_kprintf("%-16s -- %s\n", index->name, index->desc);
  450. #else
  451. rt_kprintf("%s\n", index->name);
  452. #endif
  453. }
  454. }
  455. sysvar_item = global_sysvar_list;
  456. while (sysvar_item != NULL)
  457. {
  458. rt_kprintf("[l] %s\n", sysvar_item->sysvar.name);
  459. sysvar_item = sysvar_item->next;
  460. }
  461. return 0;
  462. }
  463. FINSH_FUNCTION_EXPORT(list, list all symbol in system)
  464. static int str_is_prefix(const char* prefix, const char* str)
  465. {
  466. while ((*prefix) && (*prefix == *str))
  467. {
  468. prefix ++;
  469. str ++;
  470. }
  471. if (*prefix == 0) return 0;
  472. return -1;
  473. }
  474. void list_prefix(char* prefix)
  475. {
  476. struct finsh_syscall_item* syscall_item;
  477. struct finsh_sysvar_item* sysvar_item;
  478. rt_uint16_t func_cnt, var_cnt;
  479. const char* name_ptr;
  480. func_cnt = 0;
  481. var_cnt = 0;
  482. name_ptr = RT_NULL;
  483. {
  484. struct finsh_syscall* index;
  485. for (index = _syscall_table_begin; index < _syscall_table_end; index ++)
  486. {
  487. if (str_is_prefix(prefix, index->name) == 0)
  488. {
  489. if (func_cnt == 0)
  490. rt_kprintf("--function:\n");
  491. func_cnt ++;
  492. /* set name_ptr */
  493. name_ptr = index->name;
  494. #ifdef FINSH_USING_DESCRIPTION
  495. rt_kprintf("%-16s -- %s\n", index->name, index->desc);
  496. #else
  497. rt_kprintf("%s\n", index->name);
  498. #endif
  499. }
  500. }
  501. }
  502. /* list syscall list */
  503. syscall_item = global_syscall_list;
  504. while (syscall_item != NULL)
  505. {
  506. if (str_is_prefix(prefix, syscall_item->syscall.name) == 0)
  507. {
  508. if (func_cnt == 0)
  509. rt_kprintf("--function:\n");
  510. func_cnt ++;
  511. /* set name_ptr */
  512. name_ptr = syscall_item->syscall.name;
  513. rt_kprintf("[l] %s\n", syscall_item->syscall.name);
  514. }
  515. syscall_item = syscall_item->next;
  516. }
  517. {
  518. struct finsh_sysvar* index;
  519. for (index = _sysvar_table_begin; index < _sysvar_table_end; index ++)
  520. {
  521. if (str_is_prefix(prefix, index->name) == 0)
  522. {
  523. if (var_cnt == 0)
  524. rt_kprintf("--variable:\n");
  525. var_cnt ++;
  526. /* set name ptr */
  527. name_ptr = index->name;
  528. #ifdef FINSH_USING_DESCRIPTION
  529. rt_kprintf("%-16s -- %s\n", index->name, index->desc);
  530. #else
  531. rt_kprintf("%s\n", index->name);
  532. #endif
  533. }
  534. }
  535. }
  536. sysvar_item = global_sysvar_list;
  537. while (sysvar_item != NULL)
  538. {
  539. if (str_is_prefix(prefix, sysvar_item->sysvar.name) == 0)
  540. {
  541. if (var_cnt == 0)
  542. rt_kprintf("--variable:\n");
  543. var_cnt ++;
  544. /* set name ptr */
  545. name_ptr = sysvar_item->sysvar.name;
  546. rt_kprintf("[l] %s\n", sysvar_item->sysvar.name);
  547. }
  548. sysvar_item = sysvar_item->next;
  549. }
  550. /* only one matched */
  551. if ((func_cnt + var_cnt) == 1)
  552. {
  553. rt_strncpy(prefix, name_ptr, strlen(name_ptr));
  554. }
  555. }
  556. #ifdef FINSH_USING_SYMTAB
  557. static int dummy = 0;
  558. FINSH_VAR_EXPORT(dummy, finsh_type_int, dummy variable for finsh)
  559. #endif