00001
00007 #include <string.h>
00008 #include <stdio.h>
00009
00010 #include "cmdline.h"
00011
00012 #define PROMPT "UFFS>"
00013
00014
00015 static char buf[1024+16];
00016 static BOOL m_exit = FALSE;
00017 static struct cli_commandset cmdset[200] = {0};
00018 static int m_cmdCount = 0;
00019 static char str_buf[128];
00020
00021 const char * cli_getparam(const char *tail, char **next)
00022 {
00023 char *p;
00024 if (tail == NULL) return NULL;
00025 strcpy(str_buf, tail);
00026 p = str_buf;
00027 while(*tail != ' ' && *tail != 0) { tail++; p++; }
00028 if (*tail == ' ') {
00029 *p = 0;
00030 while(*tail == ' ') tail++;
00031 }
00032 if(next) *next = (char *)(*tail ? tail : NULL);
00033
00034 return str_buf;
00035 }
00036
00037
00038 static BOOL cmdExit(const char *tail)
00039 {
00040 m_exit = TRUE;
00041 return TRUE;
00042 }
00043
00044 static BOOL cmdHelp(const char *tail);
00045
00046
00047 static struct cli_commandset default_cmdset[] =
00048 {
00049 { cmdHelp, "help|?", "[<command>]", "Show commands or help on one command" },
00050 { cmdExit, "exit", NULL, "exit command line" },
00051 { NULL, NULL, NULL, NULL }
00052 };
00053
00054 static BOOL match_cmd(const char *src, int start, int end, const char *des)
00055 {
00056 while (src[start] == ' ' && start < end) start++;
00057 while (src[end] == ' ' && start < end) end--;
00058
00059 if ((int)strlen(des) == (end - start + 1)) {
00060 if (memcmp(src + start, des, end - start + 1) == 0) {
00061 return TRUE;
00062 }
00063 }
00064
00065 return FALSE;
00066 }
00067
00068 static BOOL check_cmd(const char *cmds, const char *cmd)
00069 {
00070 int start, end;
00071
00072 for (start = end = 0; cmds[end] != 0 && cmds[end] != '|'; end++);
00073 while (end > start) {
00074 if (match_cmd(cmds, start, end - 1, cmd) == TRUE) return TRUE;
00075 if (cmds[end] == 0) break;
00076 if (cmds[end] == '|') {
00077 end++;
00078 for (start = end; cmds[end] != 0 && cmds[end] != '|'; end++);
00079 }
00080 }
00081
00082 return FALSE;
00083 }
00084
00085 static int cmdFind(const char *cmd)
00086 {
00087 int icmd;
00088
00089 for (icmd = 0; cmdset[icmd].cmd != NULL; icmd++) {
00090
00091 if (check_cmd(cmdset[icmd].cmd, cmd) == TRUE) return icmd;
00092 }
00093 return -1;
00094 }
00095
00096
00097 static BOOL cmdHelp(const char *tail)
00098 {
00099 int icmd;
00100
00101 if (tail == NULL) {
00102 printf("Available commands:\n");
00103 for (icmd = 0; cmdset[icmd].cmd != NULL; icmd++) {
00104 int i;
00105
00106 printf("%s", cmdset[icmd].cmd);
00107 for (i = strlen(cmdset[icmd].cmd); i%10; i++,printf(" "));
00108
00109 }
00110 printf("\n");
00111 }
00112 else {
00113 icmd = cmdFind(tail);
00114 if (icmd < 0) {
00115 printf("No such command\n");
00116 }
00117 else {
00118 printf("%s: %s\n", cmdset[icmd].cmd, cmdset[icmd].descr);
00119 printf("Usage: %s %s\n", cmdset[icmd].cmd, cmdset[icmd].args);
00120 }
00121 }
00122 return TRUE;
00123 }
00124
00125
00126 static void cliInterpret(const char *line)
00127 {
00128 char cmd[64];
00129 const char *tail;
00130 const char *psep;
00131 int icmd;
00132
00133 psep = strchr(line, ' ');
00134 cmd[0] = 0;
00135 if (psep == NULL) {
00136 strncat(cmd, line, sizeof(cmd) - 1);
00137 tail = NULL;
00138 }
00139 else {
00140 strncat(cmd, line, psep - line);
00141 for (tail = psep; *tail == ' '; ++tail);
00142 if (*tail == 0) tail = NULL;
00143 }
00144
00145 icmd = cmdFind(cmd);
00146 if (icmd < 0) {
00147 printf("Unknown command - try help\n");
00148 return;
00149 }
00150 else {
00151
00152 if (!cmdset[icmd].handler(tail)) {
00153 cmdHelp(cmd);
00154 }
00155 }
00156 }
00157
00158 void cli_add_commandset(struct cli_commandset *cmds)
00159 {
00160 int icmd;
00161
00162 for (icmd = 0; cmds[icmd].cmd != NULL; icmd++) {
00163 memcpy(&(cmdset[m_cmdCount++]), &(cmds[icmd]), sizeof(struct cli_commandset));
00164 }
00165 }
00166
00167 void cliMain()
00168 {
00169 char line[80];
00170 int linelen = 0;
00171
00172 printf(PROMPT);
00173 cli_add_commandset(default_cmdset);
00174
00175 while (!m_exit) {
00176 char ch;
00177 ch = getc(stdin);
00178 switch (ch) {
00179 case 8:
00180 case 127:
00181 if (linelen > 0) {
00182 --linelen;
00183 printf("\x08 \x08");
00184 }
00185 break;
00186
00187 case '\r':
00188 case '\n':
00189
00190 if (linelen > 0) {
00191 line[linelen] = 0;
00192 cliInterpret(line);
00193 }
00194 linelen = 0;
00195 printf(PROMPT);
00196 break;
00197
00198 case 21:
00199 while (linelen > 0) {
00200 --linelen;
00201 printf("\x08 \x08");
00202 }
00203 break;
00204
00205 default:
00206 if (ch >= ' ' && ch < 127 && linelen < sizeof(line) - 1) {
00207 line[linelen++] = ch;
00208
00209 }
00210 }
00211 }
00212 }