cmd.c 23.8 KB
Newer Older
1
/*
2
 * Copyright (c) 2006-2018, RT-Thread Development Team
3
 *
4
 * SPDX-License-Identifier: Apache-2.0
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 *
 * Change Logs:
 * Date           Author       Notes
 * 2006-04-30     Bernard      first implementation
 * 2006-05-04     Bernard      add list_thread,
 *                                 list_sem,
 *                                 list_timer
 * 2006-05-20     Bernard      add list_mutex,
 *                                 list_mailbox,
 *                                 list_msgqueue,
 *                                 list_event,
 *                                 list_fevent,
 *                                 list_mempool
 * 2006-06-03     Bernard      display stack information in list_thread
 * 2006-08-10     Bernard      change version to invoke rt_show_version
 * 2008-09-10     Bernard      update the list function for finsh syscall
 *                                 list and sysvar list
 * 2009-05-30     Bernard      add list_device
23 24
 * 2010-04-21     yi.qiu       add list_module
 * 2012-04-29     goprife      improve the command line auto-complete feature.
25
 * 2012-06-02     lgnq         add list_memheap
26
 * 2012-10-22     Bernard      add MS VC++ patch.
27
 * 2016-06-02     armink       beautify the list_thread command
28 29 30
 */

#include <rtthread.h>
31 32
#include "finsh.h"

33
long hello(void)
34
{
35
    rt_kprintf("Hello RT-Thread!\n");
36

37
    return 0;
38
}
39
FINSH_FUNCTION_EXPORT(hello, say hello world);
40 41

extern void rt_show_version(void);
42
long version(void)
43
{
44
    rt_show_version();
45

46
    return 0;
47
}
48
FINSH_FUNCTION_EXPORT(version, show RT-Thread version information);
B
Bernard Xiong 已提交
49
MSH_CMD_EXPORT(version, show RT-Thread version information);
50

51
static int object_name_maxlen(const char *type_name, struct rt_list_node *list)
52
{
53
    struct rt_list_node *node;
54
    struct rt_object *object = NULL;
55
    int max_length = rt_strlen(type_name), length;
56

57 58 59 60
    rt_enter_critical();
    for (node = list->next; node != list; node = node->next)
    {
        object = rt_list_entry(node, struct rt_object, list);
61

62 63
        length = rt_strlen(object->name);
        if (length > max_length) max_length = length;
64
    }
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
    rt_exit_critical();

    if (max_length > RT_NAME_MAX || max_length == 0) max_length = RT_NAME_MAX;

    return max_length;
}

rt_inline void object_split(int len)
{
    while (len--) rt_kprintf("-");
}

static long _list_thread(struct rt_list_node *list)
{
    int maxlen;
    rt_uint8_t *ptr;
    struct rt_thread *thread;
    struct rt_list_node *node;
83
    const char *item_title = "thread";
84

85
    maxlen = object_name_maxlen(item_title, list);
86

87
    rt_kprintf("%-*.s pri  status      sp     stack size max used left tick  error\n", maxlen, item_title); object_split(maxlen);
88
    rt_kprintf(     " ---  ------- ---------- ----------  ------  ---------- ---\n");
89 90
    for (node = list->next; node != list; node = node->next)
    {
91
        rt_uint8_t stat;
92
        thread = rt_list_entry(node, struct rt_thread, list);
93
        rt_kprintf("%-*.*s %3d ", maxlen, RT_NAME_MAX, thread->name, thread->current_priority);
94

95
        stat = (thread->stat & RT_THREAD_STAT_MASK);
96 97 98 99
        if (stat == RT_THREAD_READY)        rt_kprintf(" ready  ");
        else if (stat == RT_THREAD_SUSPEND) rt_kprintf(" suspend");
        else if (stat == RT_THREAD_INIT)    rt_kprintf(" init   ");
        else if (stat == RT_THREAD_CLOSE)   rt_kprintf(" close  ");
100

101
        ptr = (rt_uint8_t *)thread->stack_addr;
102 103
        while (*ptr == '#')ptr ++;

104
        rt_kprintf(" 0x%08x 0x%08x    %02d%%   0x%08x %03d\n",
105 106
                   thread->stack_size + ((rt_uint32_t)thread->stack_addr - (rt_uint32_t)thread->sp),
                   thread->stack_size,
107 108
                   (thread->stack_size - ((rt_uint32_t) ptr - (rt_uint32_t) thread->stack_addr)) * 100
                        / thread->stack_size,
109 110
                   thread->remaining_tick,
                   thread->error);
111
    }
112

113
    return 0;
114
}
qiuyiuestc's avatar
qiuyiuestc 已提交
115 116 117

long list_thread(void)
{
118 119 120 121
    struct rt_object_information *info;

    info = rt_object_get_information(RT_Object_Class_Thread);
    return _list_thread(&info->object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
122
}
123
FINSH_FUNCTION_EXPORT(list_thread, list thread);
B
Bernard Xiong 已提交
124
MSH_CMD_EXPORT(list_thread, list thread);
125

126
static void show_wait_queue(struct rt_list_node *list)
127
{
128 129 130 131 132 133 134
    struct rt_thread *thread;
    struct rt_list_node *node;

    for (node = list->next; node != list; node = node->next)
    {
        thread = rt_list_entry(node, struct rt_thread, tlist);
        rt_kprintf("%s", thread->name);
D
dzzxzz@gmail.com 已提交
135

136
        if (node->next != list)
D
dzzxzz@gmail.com 已提交
137
            rt_kprintf("/");
138
    }
139 140 141
}

#ifdef RT_USING_SEMAPHORE
qiuyiuestc's avatar
qiuyiuestc 已提交
142
static long _list_sem(struct rt_list_node *list)
143
{
144
    int maxlen;
145 146
    struct rt_semaphore *sem;
    struct rt_list_node *node;
147
    const char *item_title = "semaphore";
148

149
    maxlen = object_name_maxlen(item_title, list);
150

151
    rt_kprintf("%-*.s v   suspend thread\n", maxlen, item_title); object_split(maxlen);
152
    rt_kprintf(     " --- --------------\n");
153 154
    for (node = list->next; node != list; node = node->next)
    {
155
        sem = (struct rt_semaphore *)(rt_list_entry(node, struct rt_object, list));
D
dzzxzz@gmail.com 已提交
156
        if (!rt_list_isempty(&sem->parent.suspend_thread))
157
        {
158 159
            rt_kprintf("%-*.*s %03d %d:",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
160 161 162
                       sem->parent.parent.name,
                       sem->value,
                       rt_list_len(&sem->parent.suspend_thread));
163 164 165 166 167
            show_wait_queue(&(sem->parent.suspend_thread));
            rt_kprintf("\n");
        }
        else
        {
168 169
            rt_kprintf("%-*.*s %03d %d\n",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
170 171 172
                       sem->parent.parent.name,
                       sem->value,
                       rt_list_len(&sem->parent.suspend_thread));
173 174 175 176
        }
    }

    return 0;
177
}
qiuyiuestc's avatar
qiuyiuestc 已提交
178 179 180

long list_sem(void)
{
181 182 183 184 185
    struct rt_object_information *info;

    info = rt_object_get_information(RT_Object_Class_Semaphore);

    return _list_sem(&info->object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
186
}
B
Bernard Xiong 已提交
187 188
FINSH_FUNCTION_EXPORT(list_sem, list semaphone in system);
MSH_CMD_EXPORT(list_sem, list semaphore in system);
189 190 191
#endif

#ifdef RT_USING_EVENT
qiuyiuestc's avatar
qiuyiuestc 已提交
192
static long _list_event(struct rt_list_node *list)
193
{
194
    int maxlen;
195 196
    struct rt_event *e;
    struct rt_list_node *node;
197
    const char *item_title = "event";
198

199
    maxlen = object_name_maxlen(item_title, list);
200

201
    rt_kprintf("%-*.s      set    suspend thread\n", maxlen, item_title); object_split(maxlen);
202
    rt_kprintf(     "  ---------- --------------\n");
203 204
    for (node = list->next; node != list; node = node->next)
    {
205 206
        e = (struct rt_event *)(rt_list_entry(node, struct rt_object, list));
        if (!rt_list_isempty(&e->parent.suspend_thread))
207
        {
208 209
            rt_kprintf("%-*.*s  0x%08x %03d:",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
210 211 212
                       e->parent.parent.name,
                       e->set,
                       rt_list_len(&e->parent.suspend_thread));
213 214 215 216 217
            show_wait_queue(&(e->parent.suspend_thread));
            rt_kprintf("\n");
        }
        else
        {
218 219
            rt_kprintf("%-*.*s  0x%08x 0\n",
                       maxlen, RT_NAME_MAX, e->parent.parent.name, e->set);
220 221 222 223
        }
    }

    return 0;
224
}
qiuyiuestc's avatar
qiuyiuestc 已提交
225 226 227

long list_event(void)
{
228 229 230 231
    struct rt_object_information *info;

    info = rt_object_get_information(RT_Object_Class_Event);
    return _list_event(&info->object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
232
}
B
Bernard Xiong 已提交
233 234
FINSH_FUNCTION_EXPORT(list_event, list event in system);
MSH_CMD_EXPORT(list_event, list event in system);
235 236 237
#endif

#ifdef RT_USING_MUTEX
qiuyiuestc's avatar
qiuyiuestc 已提交
238
static long _list_mutex(struct rt_list_node *list)
239
{
240
    int maxlen;
241 242
    struct rt_mutex *m;
    struct rt_list_node *node;
243
    const char *item_title = "mutex";
244

245 246 247
    maxlen = object_name_maxlen(item_title, list);

    rt_kprintf("%-*.s   owner  hold suspend thread\n", maxlen, item_title); object_split(maxlen);
248
    rt_kprintf(     " -------- ---- --------------\n");
249 250
    for (node = list->next; node != list; node = node->next)
    {
251
        m = (struct rt_mutex *)(rt_list_entry(node, struct rt_object, list));
252 253
        rt_kprintf("%-*.*s %-8.*s %04d %d\n",
                   maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
254 255 256 257 258
                   m->parent.parent.name,
                   RT_NAME_MAX,
                   m->owner->name,
                   m->hold,
                   rt_list_len(&m->parent.suspend_thread));
259 260 261
    }

    return 0;
262
}
qiuyiuestc's avatar
qiuyiuestc 已提交
263 264 265

long list_mutex(void)
{
266 267 268 269 270
    struct rt_object_information *info;

    info = rt_object_get_information(RT_Object_Class_Mutex);

    return _list_mutex(&info->object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
271
}
B
Bernard Xiong 已提交
272 273
FINSH_FUNCTION_EXPORT(list_mutex, list mutex in system);
MSH_CMD_EXPORT(list_mutex, list mutex in system);
274 275 276
#endif

#ifdef RT_USING_MAILBOX
qiuyiuestc's avatar
qiuyiuestc 已提交
277
static long _list_mailbox(struct rt_list_node *list)
278
{
279
    int maxlen;
280 281
    struct rt_mailbox *m;
    struct rt_list_node *node;
G
gbcwbz 已提交
282
    const char *item_title = "mailbox";
283

284
    maxlen = object_name_maxlen(item_title, list);
285

286 287
    rt_kprintf("%-*.s entry size suspend thread\n", maxlen, item_title); object_split(maxlen);
    rt_kprintf(     " ----  ---- --------------\n");
288 289
    for (node = list->next; node != list; node = node->next)
    {
290 291
        m = (struct rt_mailbox *)(rt_list_entry(node, struct rt_object, list));
        if (!rt_list_isempty(&m->parent.suspend_thread))
292
        {
293 294
            rt_kprintf("%-*.*s %04d  %04d %d:",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
295 296 297 298
                       m->parent.parent.name,
                       m->entry,
                       m->size,
                       rt_list_len(&m->parent.suspend_thread));
299 300 301 302 303
            show_wait_queue(&(m->parent.suspend_thread));
            rt_kprintf("\n");
        }
        else
        {
304 305
            rt_kprintf("%-*.*s %04d  %04d %d\n",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
306 307 308 309
                       m->parent.parent.name,
                       m->entry,
                       m->size,
                       rt_list_len(&m->parent.suspend_thread));
310 311 312 313
        }
    }

    return 0;
314
}
qiuyiuestc's avatar
qiuyiuestc 已提交
315 316 317

long list_mailbox(void)
{
318 319 320 321
    struct rt_object_information *info;

    info = rt_object_get_information(RT_Object_Class_MailBox);
    return _list_mailbox(&info->object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
322
}
B
Bernard Xiong 已提交
323 324
FINSH_FUNCTION_EXPORT(list_mailbox, list mail box in system);
MSH_CMD_EXPORT(list_mailbox, list mail box in system);
325 326 327
#endif

#ifdef RT_USING_MESSAGEQUEUE
qiuyiuestc's avatar
qiuyiuestc 已提交
328
static long _list_msgqueue(struct rt_list_node *list)
329
{
330
    int maxlen;
331 332
    struct rt_messagequeue *m;
    struct rt_list_node *node;
G
gbcwbz 已提交
333
    const char *item_title = "msgqueue";
334

335
    maxlen = object_name_maxlen(item_title, list);
336

337
    rt_kprintf("%-*.s entry suspend thread\n", maxlen, item_title); object_split(maxlen);
338
    rt_kprintf(     " ----  --------------\n");
339 340
    for (node = list->next; node != list; node = node->next)
    {
341 342
        m = (struct rt_messagequeue *)(rt_list_entry(node, struct rt_object, list));
        if (!rt_list_isempty(&m->parent.suspend_thread))
343
        {
344 345
            rt_kprintf("%-*.*s %04d  %d:",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
346 347 348
                       m->parent.parent.name,
                       m->entry,
                       rt_list_len(&m->parent.suspend_thread));
349 350 351 352 353
            show_wait_queue(&(m->parent.suspend_thread));
            rt_kprintf("\n");
        }
        else
        {
354 355
            rt_kprintf("%-*.*s %04d  %d\n",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
356 357 358
                       m->parent.parent.name,
                       m->entry,
                       rt_list_len(&m->parent.suspend_thread));
359 360 361 362
        }
    }

    return 0;
363
}
qiuyiuestc's avatar
qiuyiuestc 已提交
364 365 366

long list_msgqueue(void)
{
367 368 369 370
    struct rt_object_information *info;

    info = rt_object_get_information(RT_Object_Class_MessageQueue);
    return _list_msgqueue(&info->object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
371
}
B
Bernard Xiong 已提交
372 373
FINSH_FUNCTION_EXPORT(list_msgqueue, list message queue in system);
MSH_CMD_EXPORT(list_msgqueue, list message queue in system);
374 375
#endif

376 377 378
#ifdef RT_USING_MEMHEAP
static long _list_memheap(struct rt_list_node *list)
{
379
    int maxlen;
380 381
    struct rt_memheap *mh;
    struct rt_list_node *node;
382
    const char *item_title = "memheap";
383

384
    maxlen = object_name_maxlen(item_title, list);
385

386
    rt_kprintf("%-*.s  pool size  max used size available size\n", maxlen, item_title); object_split(maxlen);
387
    rt_kprintf(      " ---------- ------------- --------------\n");
388 389 390 391
    for (node = list->next; node != list; node = node->next)
    {
        mh = (struct rt_memheap *)rt_list_entry(node, struct rt_object, list);

392 393
        rt_kprintf("%-*.*s %-010d %-013d %-05d\n",
                   maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
394 395 396 397
                   mh->parent.name,
                   mh->pool_size,
                   mh->max_used_size,
                   mh->available_size);
398 399 400 401 402 403 404
    }

    return 0;
}

long list_memheap(void)
{
405 406 407 408
    struct rt_object_information *info;

    info = rt_object_get_information(RT_Object_Class_MemHeap);
    return _list_memheap(&info->object_list);
409
}
B
Bernard Xiong 已提交
410 411
FINSH_FUNCTION_EXPORT(list_memheap, list memory heap in system);
MSH_CMD_EXPORT(list_memheap, list memory heap in system);
412 413
#endif

414
#ifdef RT_USING_MEMPOOL
qiuyiuestc's avatar
qiuyiuestc 已提交
415
static long _list_mempool(struct rt_list_node *list)
416
{
417
    int maxlen;
418 419
    struct rt_mempool *mp;
    struct rt_list_node *node;
420
    const char *item_title = "mempool";
421

422
    maxlen = object_name_maxlen(item_title, list);
423

424
    rt_kprintf("%-*.s block total free suspend thread\n", maxlen, item_title); object_split(maxlen);
425
    rt_kprintf(     " ----  ----  ---- --------------\n");
426 427
    for (node = list->next; node != list; node = node->next)
    {
428
        mp = (struct rt_mempool *)rt_list_entry(node, struct rt_object, list);
429 430
        if (mp->suspend_thread_count > 0)
        {
431 432
            rt_kprintf("%-*.*s %04d  %04d  %04d %d:",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
433 434 435 436 437
                       mp->parent.name,
                       mp->block_size,
                       mp->block_total_count,
                       mp->block_free_count,
                       mp->suspend_thread_count);
438
            show_wait_queue(&(mp->suspend_thread));
D
dzzxzz@gmail.com 已提交
439
            rt_kprintf("\n");
440 441 442
        }
        else
        {
443 444
            rt_kprintf("%-*.*s %04d  %04d  %04d %d\n",
                       maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
445 446 447 448 449
                       mp->parent.name,
                       mp->block_size,
                       mp->block_total_count,
                       mp->block_free_count,
                       mp->suspend_thread_count);
450 451 452 453
        }
    }

    return 0;
454
}
qiuyiuestc's avatar
qiuyiuestc 已提交
455 456 457

long list_mempool(void)
{
458 459 460 461
    struct rt_object_information *info;

    info = rt_object_get_information(RT_Object_Class_MemPool);
    return _list_mempool(&info->object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
462
}
463
FINSH_FUNCTION_EXPORT(list_mempool, list memory pool in system)
B
Bernard Xiong 已提交
464
MSH_CMD_EXPORT(list_mempool, list memory pool in system);
465 466
#endif

qiuyiuestc's avatar
qiuyiuestc 已提交
467
static long _list_timer(struct rt_list_node *list)
468
{
469
    int maxlen;
470 471
    struct rt_timer *timer;
    struct rt_list_node *node;
472
    const char *item_title = "timer";
473

474
    maxlen = object_name_maxlen(item_title, list);
475

476
    rt_kprintf("%-*.s  periodic   timeout       flag\n", maxlen, item_title); object_split(maxlen);
477
    rt_kprintf(     " ---------- ---------- -----------\n");
478 479
    for (node = list->next; node != list; node = node->next)
    {
480
        timer = (struct rt_timer *)(rt_list_entry(node, struct rt_object, list));
481 482
        rt_kprintf("%-*.*s 0x%08x 0x%08x ",
                   maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
483 484 485
                   timer->parent.name,
                   timer->init_tick,
                   timer->timeout_tick);
486
        if (timer->parent.flag & RT_TIMER_FLAG_ACTIVATED)
D
dzzxzz@gmail.com 已提交
487
            rt_kprintf("activated\n");
488
        else
D
dzzxzz@gmail.com 已提交
489
            rt_kprintf("deactivated\n");
490 491 492 493 494
    }

    rt_kprintf("current tick:0x%08x\n", rt_tick_get());

    return 0;
495
}
qiuyiuestc's avatar
qiuyiuestc 已提交
496 497 498

long list_timer(void)
{
499 500 501 502
    struct rt_object_information *info;

    info = rt_object_get_information(RT_Object_Class_Timer);
    return _list_timer(&info->object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
503
}
B
Bernard Xiong 已提交
504 505
FINSH_FUNCTION_EXPORT(list_timer, list timer in system);
MSH_CMD_EXPORT(list_timer, list timer in system);
506 507

#ifdef RT_USING_DEVICE
qiuyiuestc's avatar
qiuyiuestc 已提交
508
static long _list_device(struct rt_list_node *list)
509
{
510
    int maxlen;
511 512
    struct rt_device *device;
    struct rt_list_node *node;
513
    char *const device_type_str[] =
514 515 516 517 518 519 520 521
    {
        "Character Device",
        "Block Device",
        "Network Interface",
        "MTD Device",
        "CAN Device",
        "RTC",
        "Sound Device",
522
        "Graphic Device",
523
        "I2C Bus",
524 525 526 527 528
        "USB Slave Device",
        "USB Host Bus",
        "SPI Bus",
        "SPI Device",
        "SDIO Bus",
529
        "PM Pseudo Device",
530 531
        "Pipe",
        "Portal Device",
532 533
        "Timer Device",
        "Miscellaneous Device",
534 535
        "Unknown"
    };
G
gbcwbz 已提交
536 537
    const char *item_title = "device";

538
    maxlen = object_name_maxlen(item_title, list);
539

540 541
    rt_kprintf("%-*.s         type         ref count\n", maxlen, item_title); object_split(maxlen);
    rt_kprintf(     " -------------------- ----------\n");
542 543
    for (node = list->next; node != list; node = node->next)
    {
544
        device = (struct rt_device *)(rt_list_entry(node, struct rt_object, list));
545 546
        rt_kprintf("%-*.*s %-20s %-8d\n",
                   maxlen, RT_NAME_MAX,
D
dzzxzz@gmail.com 已提交
547 548 549
                   device->parent.name,
                   (device->type <= RT_Device_Class_Unknown) ?
                   device_type_str[device->type] :
550 551
                   device_type_str[RT_Device_Class_Unknown],
                   device->ref_count);
552 553 554
    }

    return 0;
555
}
qiuyiuestc's avatar
qiuyiuestc 已提交
556 557 558

long list_device(void)
{
559 560 561 562
    struct rt_object_information *info;

    info = rt_object_get_information(RT_Object_Class_Device);
    return _list_device(&info->object_list);
qiuyiuestc's avatar
qiuyiuestc 已提交
563
}
B
Bernard Xiong 已提交
564 565
FINSH_FUNCTION_EXPORT(list_device, list device in system);
MSH_CMD_EXPORT(list_device, list device in system);
566 567
#endif

D
dzzxzz 已提交
568
long list(void)
569
{
B
bernard 已提交
570
#ifndef FINSH_USING_MSH_ONLY
571 572
    struct finsh_syscall_item *syscall_item;
    struct finsh_sysvar_item *sysvar_item;
B
bernard 已提交
573
#endif
574

575 576
    rt_kprintf("--Function List:\n");
    {
577
        struct finsh_syscall *index;
D
dzzxzz@gmail.com 已提交
578
        for (index = _syscall_table_begin;
579 580
                index < _syscall_table_end;
                FINSH_NEXT_SYSCALL(index))
581
        {
582 583
            /* skip the internal command */
            if (strncmp((char *)index->name, "__", 2) == 0) continue;
B
Bernard Xiong 已提交
584

585
#ifdef FINSH_USING_DESCRIPTION
586
            rt_kprintf("%-16s -- %s\n", index->name, index->desc);
587
#else
588
            rt_kprintf("%s\n", index->name);
589
#endif
590 591 592
        }
    }

B
bernard 已提交
593
#ifndef FINSH_USING_MSH_ONLY
594 595 596 597 598 599 600 601 602 603
    /* list syscall list */
    syscall_item = global_syscall_list;
    while (syscall_item != NULL)
    {
        rt_kprintf("[l] %s\n", syscall_item->syscall.name);
        syscall_item = syscall_item->next;
    }

    rt_kprintf("--Variable List:\n");
    {
604
        struct finsh_sysvar *index;
605
        for (index = _sysvar_table_begin;
606 607
                index < _sysvar_table_end;
                FINSH_NEXT_SYSVAR(index))
608
        {
609
#ifdef FINSH_USING_DESCRIPTION
610
            rt_kprintf("%-16s -- %s\n", index->name, index->desc);
611
#else
612
            rt_kprintf("%s\n", index->name);
613
#endif
614 615
        }
    }
616

617 618 619 620 621 622
    sysvar_item = global_sysvar_list;
    while (sysvar_item != NULL)
    {
        rt_kprintf("[l] %s\n", sysvar_item->sysvar.name);
        sysvar_item = sysvar_item->next;
    }
B
bernard 已提交
623
#endif
624

625
    return 0;
626 627 628
}
FINSH_FUNCTION_EXPORT(list, list all symbol in system)

B
bernard 已提交
629
#ifndef FINSH_USING_MSH_ONLY
630
static int str_is_prefix(const char *prefix, const char *str)
631
{
632 633 634 635 636 637
    while ((*prefix) && (*prefix == *str))
    {
        prefix ++;
        str ++;
    }

638
    if (*prefix == 0)
D
dzzxzz@gmail.com 已提交
639 640
        return 0;

641 642 643
    return -1;
}

644
static int str_common(const char *str1, const char *str2)
645
{
646
    const char *str = str1;
647

648
    while ((*str != 0) && (*str2 != 0) && (*str == *str2))
649 650 651 652 653 654
    {
        str ++;
        str2 ++;
    }

    return (str - str1);
655 656
}

657
void list_prefix(char *prefix)
658
{
659 660
    struct finsh_syscall_item *syscall_item;
    struct finsh_sysvar_item *sysvar_item;
661 662
    rt_uint16_t func_cnt, var_cnt;
    int length, min_length;
663
    const char *name_ptr;
664 665 666

    func_cnt = 0;
    var_cnt  = 0;
D
dzzxzz@gmail.com 已提交
667
    min_length = 0;
668 669 670 671
    name_ptr = RT_NULL;

    /* checks in system function call */
    {
D
dzzxzz@gmail.com 已提交
672 673
        struct finsh_syscall *index;
        for (index = _syscall_table_begin;
674 675
                index < _syscall_table_end;
                FINSH_NEXT_SYSCALL(index))
676
        {
677 678 679
            /* skip internal command */
            if (str_is_prefix("__", index->name) == 0) continue;

680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703
            if (str_is_prefix(prefix, index->name) == 0)
            {
                if (func_cnt == 0)
                {
                    rt_kprintf("--function:\n");

                    if (*prefix != 0)
                    {
                        /* set name_ptr */
                        name_ptr = index->name;

                        /* set initial length */
                        min_length = strlen(name_ptr);
                    }
                }

                func_cnt ++;

                if (*prefix != 0)
                {
                    length = str_common(name_ptr, index->name);
                    if (length < min_length)
                        min_length = length;
                }
704 705

#ifdef FINSH_USING_DESCRIPTION
706
                rt_kprintf("%-16s -- %s\n", index->name, index->desc);
707
#else
708
                rt_kprintf("%s\n", index->name);
709
#endif
710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748
            }
        }
    }

    /* checks in dynamic system function call */
    syscall_item = global_syscall_list;
    while (syscall_item != NULL)
    {
        if (str_is_prefix(prefix, syscall_item->syscall.name) == 0)
        {
            if (func_cnt == 0)
            {
                rt_kprintf("--function:\n");
                if (*prefix != 0 && name_ptr == NULL)
                {
                    /* set name_ptr */
                    name_ptr = syscall_item->syscall.name;

                    /* set initial length */
                    min_length = strlen(name_ptr);
                }
            }

            func_cnt ++;

            if (*prefix != 0)
            {
                length = str_common(name_ptr, syscall_item->syscall.name);
                if (length < min_length)
                    min_length = length;
            }

            rt_kprintf("[l] %s\n", syscall_item->syscall.name);
        }
        syscall_item = syscall_item->next;
    }

    /* checks in system variable */
    {
749
        struct finsh_sysvar *index;
750
        for (index = _sysvar_table_begin;
751 752
                index < _sysvar_table_end;
                FINSH_NEXT_SYSVAR(index))
753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778
        {
            if (str_is_prefix(prefix, index->name) == 0)
            {
                if (var_cnt == 0)
                {
                    rt_kprintf("--variable:\n");

                    if (*prefix != 0 && name_ptr == NULL)
                    {
                        /* set name_ptr */
                        name_ptr = index->name;

                        /* set initial length */
                        min_length = strlen(name_ptr);

                    }
                }

                var_cnt ++;

                if (*prefix != 0)
                {
                    length = str_common(name_ptr, index->name);
                    if (length < min_length)
                        min_length = length;
                }
B
bernard.xiong 已提交
779

780
#ifdef FINSH_USING_DESCRIPTION
781
                rt_kprintf("%-16s -- %s\n", index->name, index->desc);
782
#else
783
                rt_kprintf("%s\n", index->name);
784
#endif
785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826
            }
        }
    }

    /* checks in dynamic system variable */
    sysvar_item = global_sysvar_list;
    while (sysvar_item != NULL)
    {
        if (str_is_prefix(prefix, sysvar_item->sysvar.name) == 0)
        {
            if (var_cnt == 0)
            {
                rt_kprintf("--variable:\n");
                if (*prefix != 0 && name_ptr == NULL)
                {
                    /* set name_ptr */
                    name_ptr = sysvar_item->sysvar.name;

                    /* set initial length */
                    min_length = strlen(name_ptr);
                }
            }

            var_cnt ++;

            if (*prefix != 0)
            {
                length = str_common(name_ptr, sysvar_item->sysvar.name);
                if (length < min_length)
                    min_length = length;
            }

            rt_kprintf("[v] %s\n", sysvar_item->sysvar.name);
        }
        sysvar_item = sysvar_item->next;
    }

    /* only one matched */
    if (name_ptr != NULL)
    {
        rt_strncpy(prefix, name_ptr, min_length);
    }
827
}
B
bernard 已提交
828
#endif
829

B
bernard 已提交
830
#if defined(FINSH_USING_SYMTAB) && !defined(FINSH_USING_MSH_ONLY)
831 832 833
static int dummy = 0;
FINSH_VAR_EXPORT(dummy, finsh_type_int, dummy variable for finsh)
#endif