cmdline.c

Go to the documentation of this file.
00001 
00007 #include <string.h>
00008 #include <stdio.h>
00009 //#include <conio.h>
00010 #include "cmdline.h"
00011 
00012 #define PROMPT "UFFS>"
00013 
00014 
00015 static char buf[1024+16]; /* 1k x-modem need at least 1024+6 bytes */
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         //printf("cmdFind: Check cmd: %s with %s\n", cmd, cmdset[icmd].cmd);
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             //if ((icmd & 7) == 7 || cmdset[icmd+1].cmd == NULL) printf("\n");
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         //printf("Command idx: %d\n", icmd);
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             //printf("\r\n");
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                 //printf("%c", ch);
00209             }
00210         }
00211     }
00212 }

Generated on Sat Mar 17 15:45:44 2007 for uffs-doc by  doxygen 1.5.0