Have you tried to develop a key input feature on your small embedded platform with a serial input? It is not so easy to implement correctly because the input methodology is using a complicated protocol known as VT100. In my recent project "Natural Tiny Shell (NT-Shell)" provides VT100 compatible terminal control features for small embedded systems. However, the middleware is still large for small embedded processors such as 8-bit MCUs, 16-bit MCUs and also for small 32-bit MCUs like Cortex-M0. This "MicroShell" middleware provides a minimal terminal control for the platforms.

Dependents:   MicroShellExample

Files at this revision

API Documentation at this revision

Comitter:
shintamainjp
Date:
Sun Feb 05 03:55:01 2017 +0000
Commit message:
first commitment.

Changed in this revision

core/microshell.c Show annotated file Show diff for this revision Revisions of this file
core/microshell.h Show annotated file Show diff for this revision Revisions of this file
core/msconf.h Show annotated file Show diff for this revision Revisions of this file
core/mscore.c Show annotated file Show diff for this revision Revisions of this file
core/mscore.h Show annotated file Show diff for this revision Revisions of this file
util/mscmd.c Show annotated file Show diff for this revision Revisions of this file
util/mscmd.h Show annotated file Show diff for this revision Revisions of this file
util/msopt.c Show annotated file Show diff for this revision Revisions of this file
util/msopt.h Show annotated file Show diff for this revision Revisions of this file
util/ntlibc.c Show annotated file Show diff for this revision Revisions of this file
util/ntlibc.h Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/microshell.c	Sun Feb 05 03:55:01 2017 +0000
@@ -0,0 +1,322 @@
+/**
+ * @file      microshell.c
+ * @author    Shinichiro Nakamura (CuBeatSystems)
+ * ===============================================================
+ * MicroShell (Version 0.0.1)
+ * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
+ * ===============================================================
+ * The MIT License : https://opensource.org/licenses/MIT
+ *
+ * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "microshell.h"
+
+#define PRINT_ACTION_ENABLED    (0)
+#define PRINT_CODE_ENABLED      (0)
+
+#if PRINT_ACTION_ENABLED
+
+static void uart_puts(MICROSHELL *handle, char *str)
+{
+    while (*str) {
+        handle->uart_putc(*str++);
+    }
+}
+
+static void print_action(MICROSHELL *handle, MSCORE_ACTION action)
+{
+    switch (action) {
+        case MSCORE_ACTION_IGNORE:      uart_puts(handle, "[IGNORE]");      break;
+        case MSCORE_ACTION_DISPLAYABLE: uart_puts(handle, "[DISPLAYABLE]"); break;
+        case MSCORE_ACTION_INSERT:      uart_puts(handle, "[INSERT]");      break;
+        case MSCORE_ACTION_ENTER:       uart_puts(handle, "[ENTER]");       break;
+        case MSCORE_ACTION_TAB:         uart_puts(handle, "[TAB]");         break;
+        case MSCORE_ACTION_BS:          uart_puts(handle, "[BS]");          break;
+        case MSCORE_ACTION_DEL:         uart_puts(handle, "[DEL]");         break;
+        case MSCORE_ACTION_CTRL_A:      uart_puts(handle, "[Ctrl+A]");      break;
+        case MSCORE_ACTION_CTRL_B:      uart_puts(handle, "[Ctrl+B]");      break;
+        case MSCORE_ACTION_CTRL_C:      uart_puts(handle, "[Ctrl+C]");      break;
+        case MSCORE_ACTION_CTRL_D:      uart_puts(handle, "[Ctrl+D]");      break;
+        case MSCORE_ACTION_CTRL_E:      uart_puts(handle, "[Ctrl+E]");      break;
+        case MSCORE_ACTION_CTRL_F:      uart_puts(handle, "[Ctrl+F]");      break;
+        case MSCORE_ACTION_CTRL_G:      uart_puts(handle, "[Ctrl+G]");      break;
+        case MSCORE_ACTION_CTRL_H:      uart_puts(handle, "[Ctrl+H]");      break;
+        case MSCORE_ACTION_CTRL_I:      uart_puts(handle, "[Ctrl+I]");      break;
+        case MSCORE_ACTION_CTRL_J:      uart_puts(handle, "[Ctrl+J]");      break;
+        case MSCORE_ACTION_CTRL_K:      uart_puts(handle, "[Ctrl+K]");      break;
+        case MSCORE_ACTION_CTRL_L:      uart_puts(handle, "[Ctrl+L]");      break;
+        case MSCORE_ACTION_CTRL_M:      uart_puts(handle, "[Ctrl+M]");      break;
+        case MSCORE_ACTION_CTRL_N:      uart_puts(handle, "[Ctrl+N]");      break;
+        case MSCORE_ACTION_CTRL_O:      uart_puts(handle, "[Ctrl+O]");      break;
+        case MSCORE_ACTION_CTRL_P:      uart_puts(handle, "[Ctrl+P]");      break;
+        case MSCORE_ACTION_CTRL_Q:      uart_puts(handle, "[Ctrl+Q]");      break;
+        case MSCORE_ACTION_CTRL_R:      uart_puts(handle, "[Ctrl+R]");      break;
+        case MSCORE_ACTION_CTRL_S:      uart_puts(handle, "[Ctrl+S]");      break;
+        case MSCORE_ACTION_CTRL_T:      uart_puts(handle, "[Ctrl+T]");      break;
+        case MSCORE_ACTION_CTRL_U:      uart_puts(handle, "[Ctrl+U]");      break;
+        case MSCORE_ACTION_CTRL_V:      uart_puts(handle, "[Ctrl+V]");      break;
+        case MSCORE_ACTION_CTRL_W:      uart_puts(handle, "[Ctrl+W]");      break;
+        case MSCORE_ACTION_CTRL_X:      uart_puts(handle, "[Ctrl+X]");      break;
+        case MSCORE_ACTION_CTRL_Y:      uart_puts(handle, "[Ctrl+Y]");      break;
+        case MSCORE_ACTION_CTRL_Z:      uart_puts(handle, "[Ctrl+Z]");      break;
+        case MSCORE_ACTION_F1:          uart_puts(handle, "[F1]");          break;
+        case MSCORE_ACTION_F2:          uart_puts(handle, "[F2]");          break;
+        case MSCORE_ACTION_F3:          uart_puts(handle, "[F3]");          break;
+        case MSCORE_ACTION_F4:          uart_puts(handle, "[F4]");          break;
+        case MSCORE_ACTION_F5:          uart_puts(handle, "[F5]");          break;
+        case MSCORE_ACTION_F6:          uart_puts(handle, "[F6]");          break;
+        case MSCORE_ACTION_F7:          uart_puts(handle, "[F7]");          break;
+        case MSCORE_ACTION_F8:          uart_puts(handle, "[F8]");          break;
+        case MSCORE_ACTION_F9:          uart_puts(handle, "[F9]");          break;
+        case MSCORE_ACTION_F10:         uart_puts(handle, "[F10]");         break;
+        case MSCORE_ACTION_F11:         uart_puts(handle, "[F11]");         break;
+        case MSCORE_ACTION_F12:         uart_puts(handle, "[F12]");         break;
+        case MSCORE_ACTION_ARROW_LEFT:  uart_puts(handle, "[<]");           break;
+        case MSCORE_ACTION_ARROW_RIGHT: uart_puts(handle, "[>]");           break;
+        case MSCORE_ACTION_ARROW_UP:    uart_puts(handle, "[UP]");          break;
+        case MSCORE_ACTION_ARROW_DOWN:  uart_puts(handle, "[DOWN]");        break;
+        case MSCORE_ACTION_HOME:        uart_puts(handle, "[HOME]");        break;
+        case MSCORE_ACTION_END:         uart_puts(handle, "[END]");         break;
+        case MSCORE_ACTION_PAGE_UP:     uart_puts(handle, "[PAGE UP]");     break;
+        case MSCORE_ACTION_PAGE_DOWN:   uart_puts(handle, "[PAGE DOWN]");   break;
+    }
+}
+
+#endif
+
+#if PRINT_CODE_ENABLED
+
+static void print_code(MICROSHELL *handle, char c)
+{
+    static const char *txt = "0123456789ABCDEF";
+    handle->uart_putc('[');
+    handle->uart_putc('0');
+    handle->uart_putc('x');
+    handle->uart_putc(txt[(((unsigned char)c) >> 4) & 0x0F]);
+    handle->uart_putc(txt[(((unsigned char)c) >> 0) & 0x0F]);
+    handle->uart_putc(']');
+}
+
+#endif
+
+static char *copy_forward(char *buf, int ofs_src, int ofs_des, int siz)
+{
+    int i;
+    char *p_src = buf + ofs_src;
+    char *p_des = buf + ofs_des;
+    for (i = 0; i < siz; i++) {
+        *p_des++ = *p_src++;
+    }
+    return buf;
+}
+
+static char *copy_backward(char *buf, int ofs_src, int ofs_des, int siz)
+{
+    int i;
+    char *p_src = buf + ofs_src + siz;
+    char *p_des = buf + ofs_des + siz;
+    for (i = 0; i < siz; i++) {
+        *p_des-- = *p_src--;
+    }
+    return buf;
+}
+
+static char *clean_buffer(char *buf, int siz)
+{
+    int i;
+    char *p = buf;
+    for (i = 0; i < siz; i++) {
+        *p++ = 0;
+    }
+    return buf;
+}
+
+static int print_buffer(MICROSHELL *handle, char *buf, int ofs)
+{
+    int cnt = 0;
+    char *p = buf + ofs;
+    while (*p) {
+        handle->uart_putc(*p++);
+        cnt++;
+    }
+    return cnt;
+}
+
+static int print_char(MICROSHELL *handle, char c)
+{
+    handle->uart_putc(c);
+    return 1;
+}
+
+static void print_return(MICROSHELL *handle)
+{
+    handle->uart_putc('\r');
+    handle->uart_putc('\n');
+}
+
+static void cursor_left(MICROSHELL *handle, int n)
+{
+    int i;
+    for (i = 0; i < n; i++) {
+        handle->uart_putc('\x1B');
+        handle->uart_putc('[');
+        handle->uart_putc('D');
+    }
+}
+
+static void cursor_right(MICROSHELL *handle, int n)
+{
+    int i;
+    for (i = 0; i < n; i++) {
+        handle->uart_putc('\x1B');
+        handle->uart_putc('[');
+        handle->uart_putc('C');
+    }
+}
+
+void microshell_init(MICROSHELL *handle, MICROSHELL_UART_PUTC uart_putc, MICROSHELL_UART_GETC uart_getc, MICROSHELL_ACTION_HOOK action_hook)
+{
+    mscore_init(&(handle->mscore));
+    handle->uart_putc = uart_putc;
+    handle->uart_getc = uart_getc;
+    handle->action_hook = action_hook;
+}
+
+char *microshell_getline(MICROSHELL *handle, char *buf, int siz)
+{
+    char *ptr = buf;
+    int pos = 0;
+    int len = 0;
+    clean_buffer(buf, siz);
+    while (1) {
+        char c = handle->uart_getc();
+        MSCORE_ACTION action = mscore_push(&(handle->mscore), c);
+        if (handle->action_hook) {
+            handle->action_hook(action);
+        }
+#if PRINT_ACTION_ENABLED
+        print_action(handle, action);
+#endif
+#if PRINT_CODE_ENABLED
+        print_code(handle, c);
+#endif
+        switch (action) {
+            case MSCORE_ACTION_DISPLAYABLE:
+                {
+                    int n = 0;
+                    copy_backward(buf, pos - 1, pos - 0, len - pos + 1);
+                    handle->uart_putc(c);
+                    *ptr++ = c;
+                    pos++;
+                    len++;
+                    n += print_buffer(handle, buf, pos);
+                    cursor_left(handle, n);
+                    if (len >= siz - 1) {
+                        print_return(handle);
+                        goto end;
+                    }
+                }
+                break;
+            case MSCORE_ACTION_ENTER:
+            case MSCORE_ACTION_CTRL_J:
+                print_return(handle);
+                goto end;
+                break;
+            case MSCORE_ACTION_CTRL_C:
+                clean_buffer(buf, siz);
+                print_char(handle, '^');
+                print_char(handle, 'C');
+                print_return(handle);
+                goto end;
+                break;
+            case MSCORE_ACTION_BS:
+            case MSCORE_ACTION_CTRL_H:
+                if (pos > 0) {
+                    int n = 0;
+                    copy_forward(buf, pos, pos - 1, len - pos + 1);
+                    ptr--;
+                    pos--;
+                    len--;
+                    cursor_left(handle, 1);
+                    n += print_buffer(handle, buf, pos);
+                    n += print_char(handle, ' ');
+                    cursor_left(handle, n);
+                }
+                break;
+            case MSCORE_ACTION_DEL:
+            case MSCORE_ACTION_CTRL_D:
+                if (len > 0) {
+                    int n = 0;
+                    copy_forward(buf, pos + 1, pos + 0, len - pos + 1);
+                    len--;
+                    n += print_buffer(handle, buf, pos);
+                    n += print_char(handle, ' ');
+                    cursor_left(handle, n);
+                }
+                break;
+            case MSCORE_ACTION_ARROW_LEFT:
+            case MSCORE_ACTION_CTRL_B:
+                if (pos > 0) {
+                    ptr--;
+                    pos--;
+                    cursor_left(handle, 1);
+                }
+                break;
+            case MSCORE_ACTION_ARROW_RIGHT:
+            case MSCORE_ACTION_CTRL_F:
+                if (pos < len) {
+                    ptr++;
+                    pos++;
+                    cursor_right(handle, 1);
+                }
+                break;
+            case MSCORE_ACTION_HOME:
+            case MSCORE_ACTION_CTRL_A:
+                if (pos > 0) {
+                    int n = pos;
+                    ptr -= n;
+                    pos = 0;
+                    cursor_left(handle, n);
+                }
+                break;
+            case MSCORE_ACTION_END:
+            case MSCORE_ACTION_CTRL_E:
+                if (pos < len) {
+                    int n = len - pos;
+                    ptr += n;
+                    pos = len;
+                    cursor_right(handle, n);
+                }
+                break;
+            default:
+                break;
+        }
+    }
+
+end:
+    return buf;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/microshell.h	Sun Feb 05 03:55:01 2017 +0000
@@ -0,0 +1,63 @@
+/**
+ * @file      microshell.h
+ * @author    Shinichiro Nakamura (CuBeatSystems)
+ * ===============================================================
+ * MicroShell (Version 0.0.1)
+ * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
+ * ===============================================================
+ * The MIT License : https://opensource.org/licenses/MIT
+ *
+ * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef MICROSHELL_H
+#define MICROSHELL_H
+
+#include "mscore.h"
+
+typedef void (*MICROSHELL_UART_PUTC)(char c);
+typedef char (*MICROSHELL_UART_GETC)(void);
+typedef void (*MICROSHELL_ACTION_HOOK)(MSCORE_ACTION action);
+
+typedef struct {
+    MSCORE mscore;
+    MICROSHELL_UART_PUTC uart_putc;
+    MICROSHELL_UART_GETC uart_getc;
+    MICROSHELL_ACTION_HOOK action_hook;
+} MICROSHELL;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void microshell_init(MICROSHELL *handle, MICROSHELL_UART_PUTC uart_putc, MICROSHELL_UART_GETC uart_getc, MICROSHELL_ACTION_HOOK action_hook);
+char *microshell_getline(MICROSHELL *handle, char *buf, int siz);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/msconf.h	Sun Feb 05 03:55:01 2017 +0000
@@ -0,0 +1,52 @@
+/**
+ * @file      msconf.h
+ * @author    Shinichiro Nakamura (CuBeatSystems)
+ * ===============================================================
+ * MicroShell (Version 0.0.1)
+ * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
+ * ===============================================================
+ * The MIT License : https://opensource.org/licenses/MIT
+ *
+ * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef MSCONF_H
+#define MSCONF_H
+
+#define MSCONF_MAX_INPUT_LENGTH     (32)
+#define MSCONF_MAX_INPUT_ARGS       ((MSCONF_MAX_INPUT_LENGTH / 2) + 1)
+
+#if !defined(MSCONF_KEYMAP_SWAP_BS_DEL)
+#define MSCONF_KEYMAP_SWAP_BS_DEL   (0)
+#endif
+
+#define MSCONF_KEYMAP_USE_CTRL      (1)
+#define MSCONF_KEYMAP_USE_FUNCTION  (1)
+#define MSCONF_KEYMAP_USE_ARROW     (1)
+#define MSCONF_KEYMAP_USE_HOME_END  (1)
+#define MSCONF_KEYMAP_USE_PAGE      (1)
+
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/mscore.c	Sun Feb 05 03:55:01 2017 +0000
@@ -0,0 +1,194 @@
+/**
+ * @file      mscore.c
+ * @author    Shinichiro Nakamura (CuBeatSystems)
+ * ===============================================================
+ * MicroShell (Version 0.0.1)
+ * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
+ * ===============================================================
+ * The MIT License : https://opensource.org/licenses/MIT
+ *
+ * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "mscore.h"
+#include "msconf.h"
+
+typedef char * MSCORE_STREAM;
+
+typedef struct {
+    MSCORE_STREAM stream;
+    MSCORE_ACTION action;
+} MSCORE_KEYMAP;
+
+static const MSCORE_KEYMAP kmlist[] = {
+#if MSCONF_KEYMAP_SWAP_BS_DEL
+    {   "\x7f",                 MSCORE_ACTION_BS            },
+    {   "\x1b\x5b\x33\x7e",     MSCORE_ACTION_DEL           },
+#else
+    {   "\x08",                 MSCORE_ACTION_BS            },
+    {   "\x7f",                 MSCORE_ACTION_DEL           },
+#endif
+    {   "\x09",                 MSCORE_ACTION_TAB           },
+    {   "\x1b\x5b\x32\x7e",     MSCORE_ACTION_INSERT        },
+    {   "\x0d",                 MSCORE_ACTION_ENTER         },
+#if MSCONF_KEYMAP_USE_CTRL
+    {   "\x01",                 MSCORE_ACTION_CTRL_A        },
+    {   "\x02",                 MSCORE_ACTION_CTRL_B        },
+    {   "\x03",                 MSCORE_ACTION_CTRL_C        },
+    {   "\x04",                 MSCORE_ACTION_CTRL_D        },
+    {   "\x05",                 MSCORE_ACTION_CTRL_E        },
+    {   "\x06",                 MSCORE_ACTION_CTRL_F        },
+    {   "\x07",                 MSCORE_ACTION_CTRL_G        },
+    {   "\x08",                 MSCORE_ACTION_CTRL_H        },
+    {   "\x09",                 MSCORE_ACTION_CTRL_I        },
+    {   "\x0a",                 MSCORE_ACTION_CTRL_J        },
+    {   "\x0b",                 MSCORE_ACTION_CTRL_K        },
+    {   "\x0c",                 MSCORE_ACTION_CTRL_L        },
+    {   "\x0d",                 MSCORE_ACTION_CTRL_M        },
+    {   "\x0e",                 MSCORE_ACTION_CTRL_N        },
+    {   "\x0f",                 MSCORE_ACTION_CTRL_O        },
+    {   "\x10",                 MSCORE_ACTION_CTRL_P        },
+    {   "\x11",                 MSCORE_ACTION_CTRL_Q        },
+    {   "\x12",                 MSCORE_ACTION_CTRL_R        },
+    {   "\x13",                 MSCORE_ACTION_CTRL_S        },
+    {   "\x14",                 MSCORE_ACTION_CTRL_T        },
+    {   "\x15",                 MSCORE_ACTION_CTRL_U        },
+    {   "\x16",                 MSCORE_ACTION_CTRL_V        },
+    {   "\x17",                 MSCORE_ACTION_CTRL_W        },
+    {   "\x18",                 MSCORE_ACTION_CTRL_X        },
+    {   "\x19",                 MSCORE_ACTION_CTRL_Y        },
+    {   "\x1a",                 MSCORE_ACTION_CTRL_Z        },
+#endif
+#if MSCONF_KEYMAP_USE_FUNCTION
+    {   "\x1b\x5b\x31\x31\x7e", MSCORE_ACTION_F1            },
+    {   "\x1b\x5b\x31\x32\x7e", MSCORE_ACTION_F2            },
+    {   "\x1b\x5b\x31\x33\x7e", MSCORE_ACTION_F3            },
+    {   "\x1b\x5b\x31\x34\x7e", MSCORE_ACTION_F4            },
+    {   "\x1b\x5b\x31\x35\x7e", MSCORE_ACTION_F5            },
+    {   "\x1b\x5b\x31\x37\x7e", MSCORE_ACTION_F6            },
+    {   "\x1b\x5b\x31\x38\x7e", MSCORE_ACTION_F7            },
+    {   "\x1b\x5b\x31\x39\x7e", MSCORE_ACTION_F8            },
+    {   "\x1b\x5b\x32\x30\x7e", MSCORE_ACTION_F9            },
+    {   "\x1b\x5b\x32\x31\x7e", MSCORE_ACTION_F10           },
+    {   "\x1b\x5b\x32\x32\x7e", MSCORE_ACTION_F11           },
+    {   "\x1b\x5b\x32\x33\x7e", MSCORE_ACTION_F12           },
+    {   "\x1b\x4f\x50",         MSCORE_ACTION_F1            },
+    {   "\x1b\x4f\x51",         MSCORE_ACTION_F2            },
+    {   "\x1b\x4f\x52",         MSCORE_ACTION_F3            },
+    {   "\x1b\x4f\x53",         MSCORE_ACTION_F4            },
+    {   "\x1b\x5b\x31\x35\x7e", MSCORE_ACTION_F5            },
+    {   "\x1b\x5b\x31\x37\x7e", MSCORE_ACTION_F6            },
+    {   "\x1b\x5b\x31\x38\x7e", MSCORE_ACTION_F7            },
+    {   "\x1b\x5b\x31\x39\x7e", MSCORE_ACTION_F8            },
+    {   "\x1b\x5b\x32\x31\x7e", MSCORE_ACTION_F9            },
+    {   "\x1b\x5b\x32\x32\x7e", MSCORE_ACTION_F10           },
+    {   "\x1b\x5b\x32\x33\x7e", MSCORE_ACTION_F11           },
+    {   "\x1b\x5b\x32\x34\x7e", MSCORE_ACTION_F12           },
+#endif
+#if MSCONF_KEYMAP_USE_ARROW
+    {   "\x1b\x5b\x41",         MSCORE_ACTION_ARROW_UP      },
+    {   "\x1b\x5b\x42",         MSCORE_ACTION_ARROW_DOWN    },
+    {   "\x1b\x5b\x43",         MSCORE_ACTION_ARROW_RIGHT   },
+    {   "\x1b\x5b\x44",         MSCORE_ACTION_ARROW_LEFT    },
+#endif
+#if MSCONF_KEYMAP_USE_HOME_END
+    {   "\x1b\x4f\x48",         MSCORE_ACTION_HOME          },
+    {   "\x1b\x4f\x46",         MSCORE_ACTION_END           },
+    {   "\x1b[1~",              MSCORE_ACTION_HOME          },
+    {   "\x1b[4~",              MSCORE_ACTION_END           },
+#endif
+#if MSCONF_KEYMAP_USE_PAGE
+    {   "\x1b\x5b\x35\x7e",     MSCORE_ACTION_PAGE_UP       },
+    {   "\x1b\x5b\x36\x7e",     MSCORE_ACTION_PAGE_DOWN     },
+#endif
+};
+
+static int buf_length(char *buf)
+{
+    int n = 0;
+    while (*buf++) {
+        n++;
+    }
+    return n;
+}
+
+static int buf_match(char *a, char *b, int n)
+{
+    int i;
+    for (i = 0; i < n; i++) {
+        if (*a++ != *b++) {
+            return 0;
+        }
+    }
+    return 1;
+}
+
+static int buf_clear(char *buf, int n)
+{
+    int i;
+    for (i = 0; i < n; i++) {
+        buf[i] = 0;
+    }
+    return 1;
+}
+
+void mscore_init(MSCORE *handle)
+{
+    buf_clear(handle->keybuf, MSCORE_BUFFER_SIZE);
+    handle->keycnt = 0;
+}
+
+MSCORE_ACTION mscore_push(MSCORE *handle, char c)
+{
+    int match = 0;
+    handle->keybuf[handle->keycnt++] = c;
+    const MSCORE_KEYMAP *p = &kmlist[0];
+    const int N = sizeof(kmlist) / sizeof(kmlist[0]);
+    int i;
+    for (i = 0; i < N; i++) {
+        if (handle->keycnt == buf_length(p->stream))  {
+            if (buf_match(p->stream, handle->keybuf, handle->keycnt)) {
+                handle->keycnt = 0;
+                buf_clear(handle->keybuf, MSCORE_BUFFER_SIZE);
+                return p->action;
+            }
+        } else {
+            if (buf_match(p->stream, handle->keybuf, handle->keycnt)) {
+                match = 1;
+                break;
+            }
+        }
+        p++;
+    }
+    if (!match) {
+        handle->keycnt = 0;
+        buf_clear(handle->keybuf, MSCORE_BUFFER_SIZE);
+        if ((' ' <= c) && (c <= '~')) {
+            return MSCORE_ACTION_DISPLAYABLE;
+        }
+    }
+    return MSCORE_ACTION_IGNORE;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/mscore.h	Sun Feb 05 03:55:01 2017 +0000
@@ -0,0 +1,114 @@
+/**
+ * @file      mscore.h
+ * @author    Shinichiro Nakamura (CuBeatSystems)
+ * ===============================================================
+ * MicroShell (Version 0.0.1)
+ * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
+ * ===============================================================
+ * The MIT License : https://opensource.org/licenses/MIT
+ *
+ * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef MSCORE_H
+#define MSCORE_H
+
+#define MSCORE_BUFFER_SIZE     (8)
+#define MSCORE_INITIALIZER()   { .keycnt = 0, .keybuf = {0} }
+
+typedef enum {
+    MSCORE_ACTION_IGNORE,
+    MSCORE_ACTION_DISPLAYABLE,
+    MSCORE_ACTION_BS,
+    MSCORE_ACTION_DEL,
+    MSCORE_ACTION_TAB,
+    MSCORE_ACTION_INSERT,
+    MSCORE_ACTION_ENTER,
+    MSCORE_ACTION_CTRL_A,
+    MSCORE_ACTION_CTRL_B,
+    MSCORE_ACTION_CTRL_C,
+    MSCORE_ACTION_CTRL_D,
+    MSCORE_ACTION_CTRL_E,
+    MSCORE_ACTION_CTRL_F,
+    MSCORE_ACTION_CTRL_G,
+    MSCORE_ACTION_CTRL_H,
+    MSCORE_ACTION_CTRL_I,
+    MSCORE_ACTION_CTRL_J,
+    MSCORE_ACTION_CTRL_K,
+    MSCORE_ACTION_CTRL_L,
+    MSCORE_ACTION_CTRL_M,
+    MSCORE_ACTION_CTRL_N,
+    MSCORE_ACTION_CTRL_O,
+    MSCORE_ACTION_CTRL_P,
+    MSCORE_ACTION_CTRL_Q,
+    MSCORE_ACTION_CTRL_R,
+    MSCORE_ACTION_CTRL_S,
+    MSCORE_ACTION_CTRL_T,
+    MSCORE_ACTION_CTRL_U,
+    MSCORE_ACTION_CTRL_V,
+    MSCORE_ACTION_CTRL_W,
+    MSCORE_ACTION_CTRL_X,
+    MSCORE_ACTION_CTRL_Y,
+    MSCORE_ACTION_CTRL_Z,
+    MSCORE_ACTION_F1,
+    MSCORE_ACTION_F2,
+    MSCORE_ACTION_F3,
+    MSCORE_ACTION_F4,
+    MSCORE_ACTION_F5,
+    MSCORE_ACTION_F6,
+    MSCORE_ACTION_F7,
+    MSCORE_ACTION_F8,
+    MSCORE_ACTION_F9,
+    MSCORE_ACTION_F10,
+    MSCORE_ACTION_F11,
+    MSCORE_ACTION_F12,
+    MSCORE_ACTION_ARROW_UP,
+    MSCORE_ACTION_ARROW_DOWN,
+    MSCORE_ACTION_ARROW_LEFT,
+    MSCORE_ACTION_ARROW_RIGHT,
+    MSCORE_ACTION_HOME,
+    MSCORE_ACTION_END,
+    MSCORE_ACTION_PAGE_UP,
+    MSCORE_ACTION_PAGE_DOWN,
+} MSCORE_ACTION;
+
+typedef struct {
+    int keycnt;
+    char keybuf[MSCORE_BUFFER_SIZE];
+} MSCORE;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void mscore_init(MSCORE *handle);
+MSCORE_ACTION mscore_push(MSCORE *handle, char c);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/mscmd.c	Sun Feb 05 03:55:01 2017 +0000
@@ -0,0 +1,70 @@
+/**
+ * @file      mscmd.c
+ * @author    Shinichiro Nakamura (CuBeatSystems)
+ * ===============================================================
+ * MicroShell (Version 0.0.1)
+ * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
+ * ===============================================================
+ * The MIT License : https://opensource.org/licenses/MIT
+ *
+ * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "msopt.h"
+#include "mscmd.h"
+#include "ntlibc.h"
+
+int mscmd_init(MSCMD *handle, MSCMD_COMMAND_TABLE *command_table, int command_count, MSCMD_USER_OBJECT usrobj)
+{
+    handle->command_table = command_table;
+    handle->command_count = command_count;
+    handle->usrobj = usrobj;
+    return 0;
+}
+
+int mscmd_execute(MSCMD *handle, char *text, MSCMD_USER_RESULT *result)
+{
+    MSOPT msopt;
+    int argc = 0;
+    char argv0[MSCONF_MAX_INPUT_LENGTH];
+
+    msopt_init(&msopt, text);
+    msopt_get_argc(&msopt, &argc);
+    if (argc == 0) {
+        return -1;
+    }
+    MSCMD_COMMAND_TABLE *p = handle->command_table;
+    int i;
+    for (i = 0; i < handle->command_count; i++) {
+        msopt_get_argv(&msopt, 0, argv0, sizeof(argv0));
+        if (ntlibc_strcmp(argv0, p->argv0) == 0) {
+            *result = p->func(&msopt, handle->usrobj);
+            return 0;
+        }
+        p++;
+    }
+    return -2;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/mscmd.h	Sun Feb 05 03:55:01 2017 +0000
@@ -0,0 +1,68 @@
+/**
+ * @file      mscmd.h
+ * @author    Shinichiro Nakamura (CuBeatSystems)
+ * ===============================================================
+ * MicroShell (Version 0.0.1)
+ * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
+ * ===============================================================
+ * The MIT License : https://opensource.org/licenses/MIT
+ *
+ * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef MSCMD_H
+#define MSCMD_H
+
+#include "msopt.h"
+
+typedef int MSCMD_USER_RESULT;
+typedef void * MSCMD_USER_OBJECT;
+
+typedef MSCMD_USER_RESULT (*MSCMD_FUNC)(MSOPT *msopt, MSCMD_USER_OBJECT usrobj);
+
+typedef struct {
+    char *argv0;
+    MSCMD_FUNC func;
+} MSCMD_COMMAND_TABLE;
+
+typedef struct {
+    MSCMD_COMMAND_TABLE *command_table;
+    int command_count;
+    MSCMD_USER_OBJECT usrobj;
+} MSCMD;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int mscmd_init(MSCMD *handle, MSCMD_COMMAND_TABLE *command_table, int command_count, MSCMD_USER_OBJECT usrobj);
+int mscmd_execute(MSCMD *handle, char *text, MSCMD_USER_RESULT *result);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/msopt.c	Sun Feb 05 03:55:01 2017 +0000
@@ -0,0 +1,122 @@
+/**
+ * @file      msopt.c
+ * @author    Shinichiro Nakamura (CuBeatSystems)
+ * ===============================================================
+ * MicroShell (Version 0.0.1)
+ * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
+ * ===============================================================
+ * The MIT License : https://opensource.org/licenses/MIT
+ *
+ * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "msopt.h"
+
+#define INITCODE            (0x248e97c0)
+#define IS_WHITE_SPACE(C)   (((C) == ' ') || ((C) == '\t') || ((C) == '\r') || ((C) == '\n'))
+
+static char *skip_white_space(char *text)
+{
+    char *p = text;
+    while (IS_WHITE_SPACE(*p)) {
+        if (*p == 0) {
+            break;
+        }
+        p++;
+    }
+    return p;
+}
+
+static char *skip_text_string(char *text, int *length)
+{
+    char *p = text;
+    int count = 0;
+    while (!IS_WHITE_SPACE(*p)) {
+        if (*p == 0) {
+            break;
+        }
+        p++;
+        count++;
+    }
+    *length = count;
+    return p;
+}
+
+MSOPT_RESULT msopt_init(MSOPT *handle, char *text)
+{
+    char *src = text;
+    char *des = handle->argv;
+    while (*src) {
+        *des++ = *src++;
+    }
+    *des = 0;
+    handle->argc = 0;
+    char *p = handle->argv;
+    while (1) {
+        if (handle->argc >= MSCONF_MAX_INPUT_ARGS) {
+            return MSOPT_RESULT_ERROR_TOO_MUCH_ARGUMENTS;
+        }
+        p = skip_white_space(p);
+        if (*p == 0) {
+            break;
+        }
+        handle->info[handle->argc].head = p;
+        p = skip_text_string(p, &(handle->info[handle->argc].length));
+        handle->argc++;
+    }
+    handle->initcode = INITCODE;
+    return MSOPT_RESULT_OK;
+}
+
+MSOPT_RESULT msopt_get_argc(MSOPT *handle, int *argc)
+{
+    if (handle->initcode != INITCODE) {
+        *argc = 0;
+        return MSOPT_RESULT_ERROR_ILLEGAL_OBJECT;
+    }
+    *argc = handle->argc;
+    return MSOPT_RESULT_OK;
+}
+
+MSOPT_RESULT msopt_get_argv(MSOPT *handle, int index, char *bufptr, int bufsiz)
+{
+    *bufptr = 0;
+    if (handle->argc <= index) {
+        return MSOPT_RESULT_ERROR_ILLEGAL_INDEX_NUMBER;
+    }
+    char *src = handle->info[index].head;
+    char *des = bufptr;
+    int i;
+    for (i = 0; i < handle->info[index].length; i++) {
+        if (i >= bufsiz - 1) {
+            *des = 0;
+            return MSOPT_RESULT_ERROR_BUFFER_SIZE;
+        }
+        *des++ = *src++;
+    }
+    *des = 0;
+    return MSOPT_RESULT_OK;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/msopt.h	Sun Feb 05 03:55:01 2017 +0000
@@ -0,0 +1,73 @@
+/**
+ * @file      msopt.h
+ * @author    Shinichiro Nakamura (CuBeatSystems)
+ * ===============================================================
+ * MicroShell (Version 0.0.1)
+ * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
+ * ===============================================================
+ * The MIT License : https://opensource.org/licenses/MIT
+ *
+ * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef MSOPT_H
+#define MSOPT_H
+
+#include "msconf.h"
+
+typedef struct {
+    char *head;
+    int length;
+} MSOPT_ARGINFO;
+
+typedef struct {
+    unsigned int initcode;
+    int argc;
+    char argv[MSCONF_MAX_INPUT_LENGTH];
+    MSOPT_ARGINFO info[MSCONF_MAX_INPUT_ARGS];
+} MSOPT;
+
+typedef enum {
+    MSOPT_RESULT_OK = 0,
+    MSOPT_RESULT_ERROR_ILLEGAL_OBJECT,
+    MSOPT_RESULT_ERROR_ILLEGAL_INDEX_NUMBER,
+    MSOPT_RESULT_ERROR_TOO_MUCH_ARGUMENTS,
+    MSOPT_RESULT_ERROR_BUFFER_SIZE,
+} MSOPT_RESULT;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+MSOPT_RESULT msopt_init(MSOPT *handle, char *text);
+MSOPT_RESULT msopt_get_argc(MSOPT *handle, int *argc);
+MSOPT_RESULT msopt_get_argv(MSOPT *handle, int index, char *bufptr, int bufsiz);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/ntlibc.c	Sun Feb 05 03:55:01 2017 +0000
@@ -0,0 +1,283 @@
+/**
+ * @file      ntlibc.c
+ * @author    Shinichiro Nakamura (CuBeatSystems)
+ * ===============================================================
+ * MicroShell (Version 0.0.1)
+ * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
+ * ===============================================================
+ * The MIT License : https://opensource.org/licenses/MIT
+ *
+ * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#include "ntlibc.h"
+
+int ntlibc_strlen(const char *s)
+{
+    const char *p = s;
+    int cnt = 0;
+    while (*p) {
+        cnt++;
+        p++;
+    }
+    return cnt;
+}
+
+char *ntlibc_strcpy(char *des, const char *src)
+{
+    char *d = des;
+    const char *s = src;
+    while (*s) {
+        *d = *s;
+        d++;
+        s++;
+    }
+    *d = '\0';
+    return des;
+}
+
+char *ntlibc_strcat(char *des, const char *src)
+{
+    char *d = des;
+    const char *s = src;
+    while (*d) {
+        d++;
+    }
+    while (*s) {
+        *d = *s;
+        d++;
+        s++;
+    }
+    *d = '\0';
+    return des;
+}
+
+int ntlibc_strcmp(const char *s1, const char *s2)
+{
+    char *p1 = (char *)s1;
+    char *p2 = (char *)s2;
+    while (*p1 || *p2) {
+        if (*p1 != *p2) {
+            return (*p1 < *p2) ? -1 : 1;
+        }
+        p1++;
+        p2++;
+    }
+    if (*p1 == *p2) {
+        return 0;
+    } else {
+        return (*p1 < *p2) ? -1 : 1;
+    }
+}
+
+int ntlibc_stricmp(const char *s1, const char *s2)
+{
+    char *p1 = (char *)s1;
+    char *p2 = (char *)s2;
+    while (*p1 || *p2) {
+        if (ntlibc_toupper(*p1) != ntlibc_toupper(*p2)) {
+            return (*p1 < *p2) ? -1 : 1;
+        }
+        p1++;
+        p2++;
+    }
+    if (*p1 == *p2) {
+        return 0;
+    } else {
+        return (*p1 < *p2) ? -1 : 1;
+    }
+}
+
+int ntlibc_strncmp(const char *s1, const char *s2, int n)
+{
+    char *p1 = (char *)s1;
+    char *p2 = (char *)s2;
+    int len = 0;
+    while (*p1 || *p2) {
+        if (n <= len) {
+            break;
+        }
+        if (*p1 != *p2) {
+            return (*p1 < *p2) ? -1 : 1;
+        }
+        p1++;
+        p2++;
+        len++;
+    }
+    return 0;
+}
+
+int ntlibc_isdigit(int c)
+{
+  if (('0' <= c) && (c <= '9')) {
+    return 1;
+  }
+  return 0;
+}
+
+int ntlibc_isalpha(int c)
+{
+  if (('A' <= c) && (c <= 'Z')) {
+    return 1;
+  }
+  if (('a' <= c) && (c <= 'z')) {
+    return 1;
+  }
+  return 0;
+}
+
+int ntlibc_iscntrl(int c)
+{
+  if (c == 0x07) { return 0; }
+  if (c == 0x08) { return 0; }
+  if (c == 0x09) { return 0; }
+  if (c == 0x0a) { return 0; }
+  if (c == 0x0b) { return 0; }
+  if (c == 0x0c) { return 0; }
+  if (c == 0x0d) { return 0; }
+  if ((0x00 <= c) && (c <= 0x1f)) {
+    return 1;
+  }
+  return 0;
+}
+
+int ntlibc_toupper(int c)
+{
+  if (('a' <= c) && (c <= 'z')) {
+    int diff = 'a' - 'A';
+    return c - diff;
+  }
+  return c;
+}
+
+int ntlibc_tolower(int c)
+{
+  if (('A' <= c) && (c <= 'Z')) {
+    int diff = 'a' - 'A';
+    return c + diff;
+  }
+  return c;
+}
+
+int ntlibc_atoi(const char *nptr)
+{
+  int cnt;
+  int num = 0;
+  int ofs = 0;
+  int sign = 0;
+  int scnt = 0;
+  char *p = (char *)nptr;
+  while (*p != '\0') {
+    if (!ntlibc_isdigit(*p)) {
+      if (*p == ' ') {
+        ofs++;
+      }
+      if (*p == '+') {
+        sign = 0;
+        ofs++;
+        if (scnt++ > 0) {
+          return 0;
+        }
+      }
+      if (*p == '-') {
+        sign = 1;
+        ofs++;
+        if (scnt++ > 0) {
+          return 0;
+        }
+      }
+    }
+    p++;
+  }
+  for (cnt = ofs; (nptr[cnt] >= '0') && (nptr[cnt] <= '9'); cnt++) {
+    num = 10 * num + (nptr[cnt] - '0');
+  }
+  if (sign) {
+    return -num;
+  } else {
+    return num;
+  }
+}
+
+char *ntlibc_strchr(const char *s, int c)
+{
+  char *p = (char *)s;
+  while (*p) {
+    if (*p == c) {
+      return p;
+    }
+    p++;
+  }
+  return 0;
+}
+
+char *ntlibc_utoa(unsigned int value, char *s, int radix)
+{
+  char *s1 = s;
+  char *s2 = s;
+
+  do {
+    *s2++ = "0123456789abcdefghijklmnopqrstuvwxyz"[value % radix];
+    value /= radix;
+  } while (value > 0);
+
+  *s2-- = '\0';
+
+  while (s1 < s2) {
+    char c = *s1;
+    *s1++ = *s2;
+    *s2-- = c;
+  }
+
+  return s;
+}
+
+char *ntlibc_itoa(int value, char *s, int radix)
+{
+    char *ptr = s, *ptr1 = s, tmp_char;
+    int tmp_value;
+
+    if ((radix < 2) || (radix > 36)) {
+        *s = '\0';
+        return s;
+    }
+    do {
+        tmp_value = value;
+        value /= radix;
+        *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * radix)];
+    } while (value);
+
+    if (tmp_value < 0) {
+        *ptr++ = '-';
+    }
+    *ptr-- = '\0';
+    while (ptr1 < ptr) {
+        tmp_char = *ptr;
+        *ptr--= *ptr1;
+        *ptr1++ = tmp_char;
+    }
+    return s;
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/util/ntlibc.h	Sun Feb 05 03:55:01 2017 +0000
@@ -0,0 +1,63 @@
+/**
+ * @file      ntlibc.h
+ * @author    Shinichiro Nakamura (CuBeatSystems)
+ * ===============================================================
+ * MicroShell (Version 0.0.1)
+ * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
+ * ===============================================================
+ * The MIT License : https://opensource.org/licenses/MIT
+ *
+ * Copyright (c) 2016, 2017 Shinichiro Nakamura (CuBeatSystems)
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation
+ * files (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use,
+ * copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following
+ * conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+ * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+ * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef NTLIBC_H
+#define NTLIBC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int ntlibc_strlen(const char *s);
+char *ntlibc_strcpy(char *des, const char *src);
+char *ntlibc_strcat(char *des, const char *src);
+int ntlibc_strcmp(const char *s1, const char *s2);
+int ntlibc_stricmp(const char *s1, const char *s2);
+int ntlibc_strncmp(const char *s1, const char *s2, int n);
+int ntlibc_isdigit(int c);
+int ntlibc_isalpha(int c);
+int ntlibc_iscntrl(int c);
+int ntlibc_toupper(int c);
+int ntlibc_tolower(int c);
+int ntlibc_atoi(const char *nptr);
+char *ntlibc_strchr(const char *s, int c);
+char *ntlibc_utoa(unsigned int value, char *s, int radix);
+char *ntlibc_itoa(int value, char *s, int radix);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+