port http://sourceforge.net/projects/tinysh to mbed enviroment
Dependents: kl25z-tinyshell-demo HelloWorld_IHM02A1
This library is a port of tiny shell library to mbed enviroment.
Features
- Autocomplete
- Command history
- Linux like
Tiny Shell minimal example
#include "mbed.h" #include "tinysh.h" //serial port to use Serial pc(USBTX, USBRX); //custom function void foo_fnt(int argc, char **argv) { printf("foo command called\r\n"); for(int i=0; i<argc; i++) { printf("argv[%d]=\"%s\"\r\n",i,argv[i]); } } //custom command tinysh_cmd_t myfoocmd= {0,"foo","foo command","[args]",foo_fnt,0,0,0}; //mandatory tiny shell output function void tinysh_char_out(unsigned char c) { pc.putc(c); } void main(void){ //configure serial baudrate pc.baud(115200); //print build date pc.printf("tiny shell build %s %s\r\n",__DATE__,__TIME__); //set prompt tinysh_set_prompt("$ "); //add custom commands here tinysh_add_command(&myfoocmd); //run command parser loop foverer while(true) { tinysh_char_in( pc.getc() ); } }
tinysh.c@1:71580bf962fe, 2014-03-11 (annotated)
- Committer:
- murilopontes
- Date:
- Tue Mar 11 05:19:36 2014 +0000
- Revision:
- 1:71580bf962fe
- Parent:
- 0:78b46c0d5246
update \r e \n
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
murilopontes | 0:78b46c0d5246 | 1 | /* |
murilopontes | 0:78b46c0d5246 | 2 | * tinysh.c |
murilopontes | 0:78b46c0d5246 | 3 | * |
murilopontes | 0:78b46c0d5246 | 4 | * Minimal portable shell |
murilopontes | 0:78b46c0d5246 | 5 | * |
murilopontes | 0:78b46c0d5246 | 6 | * Copyright (C) 2001 Michel Gutierrez <mig@nerim.net> |
murilopontes | 0:78b46c0d5246 | 7 | * |
murilopontes | 0:78b46c0d5246 | 8 | * This library is free software; you can redistribute it and/or |
murilopontes | 0:78b46c0d5246 | 9 | * modify it under the terms of the GNU Lesser General Public |
murilopontes | 0:78b46c0d5246 | 10 | * License as published by the Free Software Foundation; either |
murilopontes | 0:78b46c0d5246 | 11 | * version 2.1 of the License, or (at your option) any later version. |
murilopontes | 0:78b46c0d5246 | 12 | * |
murilopontes | 0:78b46c0d5246 | 13 | * This library is distributed in the hope that it will be useful, |
murilopontes | 0:78b46c0d5246 | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
murilopontes | 0:78b46c0d5246 | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
murilopontes | 0:78b46c0d5246 | 16 | * Lesser General Public License for more details. |
murilopontes | 0:78b46c0d5246 | 17 | * |
murilopontes | 0:78b46c0d5246 | 18 | * You should have received a copy of the GNU Lesser General Public |
murilopontes | 0:78b46c0d5246 | 19 | * License along with this library; if not, write to the Free |
murilopontes | 0:78b46c0d5246 | 20 | * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
murilopontes | 0:78b46c0d5246 | 21 | */ |
murilopontes | 0:78b46c0d5246 | 22 | |
murilopontes | 0:78b46c0d5246 | 23 | #include "tinysh.h" |
murilopontes | 0:78b46c0d5246 | 24 | |
murilopontes | 0:78b46c0d5246 | 25 | #ifndef BUFFER_SIZE |
murilopontes | 0:78b46c0d5246 | 26 | #define BUFFER_SIZE 64 |
murilopontes | 0:78b46c0d5246 | 27 | #endif |
murilopontes | 0:78b46c0d5246 | 28 | #ifndef HISTORY_DEPTH |
murilopontes | 0:78b46c0d5246 | 29 | #define HISTORY_DEPTH 3 |
murilopontes | 0:78b46c0d5246 | 30 | #endif |
murilopontes | 0:78b46c0d5246 | 31 | #ifndef MAX_ARGS |
murilopontes | 0:78b46c0d5246 | 32 | #define MAX_ARGS 4 |
murilopontes | 0:78b46c0d5246 | 33 | #endif |
murilopontes | 0:78b46c0d5246 | 34 | #ifndef PROMPT_SIZE |
murilopontes | 0:78b46c0d5246 | 35 | #define PROMPT_SIZE 4 |
murilopontes | 0:78b46c0d5246 | 36 | #endif |
murilopontes | 0:78b46c0d5246 | 37 | #ifndef TOPCHAR |
murilopontes | 0:78b46c0d5246 | 38 | #define TOPCHAR '/' |
murilopontes | 0:78b46c0d5246 | 39 | #endif |
murilopontes | 0:78b46c0d5246 | 40 | |
murilopontes | 0:78b46c0d5246 | 41 | |
murilopontes | 0:78b46c0d5246 | 42 | typedef unsigned char uchar; |
murilopontes | 0:78b46c0d5246 | 43 | /* redefine some useful and maybe missing utilities to avoid conflicts */ |
murilopontes | 0:78b46c0d5246 | 44 | #define strlen tinysh_strlen |
murilopontes | 0:78b46c0d5246 | 45 | #define puts tinysh_puts |
murilopontes | 0:78b46c0d5246 | 46 | #define putchar tinysh_char_out |
murilopontes | 0:78b46c0d5246 | 47 | |
murilopontes | 0:78b46c0d5246 | 48 | static void help_fnt(int argc, char **argv); |
murilopontes | 0:78b46c0d5246 | 49 | |
murilopontes | 0:78b46c0d5246 | 50 | static tinysh_cmd_t help_cmd={ |
murilopontes | 0:78b46c0d5246 | 51 | 0,"help","display help","<cr>",help_fnt,0,0,0 }; |
murilopontes | 0:78b46c0d5246 | 52 | |
murilopontes | 0:78b46c0d5246 | 53 | static uchar input_buffers[HISTORY_DEPTH][BUFFER_SIZE+1]={0}; |
murilopontes | 0:78b46c0d5246 | 54 | static uchar trash_buffer[BUFFER_SIZE+1]={0}; |
murilopontes | 0:78b46c0d5246 | 55 | static int cur_buf_index=0; |
murilopontes | 0:78b46c0d5246 | 56 | static uchar context_buffer[BUFFER_SIZE+1]={0}; |
murilopontes | 0:78b46c0d5246 | 57 | static int cur_context=0; |
murilopontes | 0:78b46c0d5246 | 58 | static int cur_index=0; |
murilopontes | 0:78b46c0d5246 | 59 | static int echo=1; |
murilopontes | 0:78b46c0d5246 | 60 | static char prompt[PROMPT_SIZE+1]="$ "; |
murilopontes | 0:78b46c0d5246 | 61 | static tinysh_cmd_t *root_cmd=&help_cmd; |
murilopontes | 0:78b46c0d5246 | 62 | static tinysh_cmd_t *cur_cmd_ctx=0; |
murilopontes | 0:78b46c0d5246 | 63 | static void *tinysh_arg=0; |
murilopontes | 0:78b46c0d5246 | 64 | |
murilopontes | 0:78b46c0d5246 | 65 | /* few useful utilities that may be missing */ |
murilopontes | 0:78b46c0d5246 | 66 | |
murilopontes | 0:78b46c0d5246 | 67 | static int strlen(uchar *s) |
murilopontes | 0:78b46c0d5246 | 68 | { |
murilopontes | 0:78b46c0d5246 | 69 | int i; |
murilopontes | 0:78b46c0d5246 | 70 | for(i=0;*s;s++,i++); |
murilopontes | 0:78b46c0d5246 | 71 | return i; |
murilopontes | 0:78b46c0d5246 | 72 | } |
murilopontes | 0:78b46c0d5246 | 73 | |
murilopontes | 0:78b46c0d5246 | 74 | static void puts(char *s) |
murilopontes | 0:78b46c0d5246 | 75 | { |
murilopontes | 0:78b46c0d5246 | 76 | while(*s) |
murilopontes | 0:78b46c0d5246 | 77 | putchar(*s++); |
murilopontes | 0:78b46c0d5246 | 78 | } |
murilopontes | 0:78b46c0d5246 | 79 | |
murilopontes | 0:78b46c0d5246 | 80 | /* callback for help function |
murilopontes | 0:78b46c0d5246 | 81 | */ |
murilopontes | 0:78b46c0d5246 | 82 | static void help_fnt(int argc, char **argv) |
murilopontes | 0:78b46c0d5246 | 83 | { |
murilopontes | 0:78b46c0d5246 | 84 | puts("? display help on given or available commands\r\n"); |
murilopontes | 0:78b46c0d5246 | 85 | puts("<TAB> auto-completion\r\n"); |
murilopontes | 0:78b46c0d5246 | 86 | puts("<cr> execute command line\r\n"); |
murilopontes | 0:78b46c0d5246 | 87 | puts("CTRL-P recall previous input line\r\n"); |
murilopontes | 0:78b46c0d5246 | 88 | puts("CTRL-N recall next input line\r\n"); |
murilopontes | 0:78b46c0d5246 | 89 | puts("<any> treat as input character\r\n"); |
murilopontes | 0:78b46c0d5246 | 90 | } |
murilopontes | 0:78b46c0d5246 | 91 | |
murilopontes | 0:78b46c0d5246 | 92 | /* |
murilopontes | 0:78b46c0d5246 | 93 | */ |
murilopontes | 0:78b46c0d5246 | 94 | |
murilopontes | 0:78b46c0d5246 | 95 | enum { NULLMATCH,FULLMATCH,PARTMATCH,UNMATCH,MATCH,AMBIG }; |
murilopontes | 0:78b46c0d5246 | 96 | |
murilopontes | 0:78b46c0d5246 | 97 | /* verify if the non-spaced part of s2 is included at the begining |
murilopontes | 0:78b46c0d5246 | 98 | * of s1. |
murilopontes | 0:78b46c0d5246 | 99 | * return FULLMATCH if s2 equal to s1, PARTMATCH if s1 starts with s2 |
murilopontes | 0:78b46c0d5246 | 100 | * but there are remaining chars in s1, UNMATCH if s1 does not start with |
murilopontes | 0:78b46c0d5246 | 101 | * s2 |
murilopontes | 0:78b46c0d5246 | 102 | */ |
murilopontes | 0:78b46c0d5246 | 103 | int strstart(uchar *s1, uchar *s2) |
murilopontes | 0:78b46c0d5246 | 104 | { |
murilopontes | 0:78b46c0d5246 | 105 | while(*s1 && *s1==*s2) { s1++; s2++; } |
murilopontes | 0:78b46c0d5246 | 106 | |
murilopontes | 0:78b46c0d5246 | 107 | if(*s2==' ' || *s2==0) |
murilopontes | 0:78b46c0d5246 | 108 | { |
murilopontes | 0:78b46c0d5246 | 109 | if(*s1==0) |
murilopontes | 0:78b46c0d5246 | 110 | return FULLMATCH; /* full match */ |
murilopontes | 0:78b46c0d5246 | 111 | else |
murilopontes | 0:78b46c0d5246 | 112 | return PARTMATCH; /* partial match */ |
murilopontes | 0:78b46c0d5246 | 113 | } |
murilopontes | 0:78b46c0d5246 | 114 | else |
murilopontes | 0:78b46c0d5246 | 115 | return UNMATCH; /* no match */ |
murilopontes | 0:78b46c0d5246 | 116 | } |
murilopontes | 0:78b46c0d5246 | 117 | |
murilopontes | 0:78b46c0d5246 | 118 | /* |
murilopontes | 0:78b46c0d5246 | 119 | * check commands at given level with input string. |
murilopontes | 0:78b46c0d5246 | 120 | * _cmd: point to first command at this level, return matched cmd |
murilopontes | 0:78b46c0d5246 | 121 | * _str: point to current unprocessed input, return next unprocessed |
murilopontes | 0:78b46c0d5246 | 122 | */ |
murilopontes | 0:78b46c0d5246 | 123 | static int parse_command(tinysh_cmd_t **_cmd, uchar **_str) |
murilopontes | 0:78b46c0d5246 | 124 | { |
murilopontes | 0:78b46c0d5246 | 125 | uchar *str=*_str; |
murilopontes | 0:78b46c0d5246 | 126 | tinysh_cmd_t *cmd; |
murilopontes | 0:78b46c0d5246 | 127 | int matched_len=0; |
murilopontes | 0:78b46c0d5246 | 128 | tinysh_cmd_t *matched_cmd=0; |
murilopontes | 0:78b46c0d5246 | 129 | |
murilopontes | 0:78b46c0d5246 | 130 | /* first eliminate first blanks */ |
murilopontes | 0:78b46c0d5246 | 131 | while(*str==' ') str++; |
murilopontes | 0:78b46c0d5246 | 132 | if(!*str) |
murilopontes | 0:78b46c0d5246 | 133 | { |
murilopontes | 0:78b46c0d5246 | 134 | *_str=str; |
murilopontes | 0:78b46c0d5246 | 135 | return NULLMATCH; /* end of input */ |
murilopontes | 0:78b46c0d5246 | 136 | } |
murilopontes | 0:78b46c0d5246 | 137 | |
murilopontes | 0:78b46c0d5246 | 138 | /* first pass: count matches */ |
murilopontes | 0:78b46c0d5246 | 139 | for(cmd=*_cmd;cmd;cmd=cmd->next) |
murilopontes | 0:78b46c0d5246 | 140 | { |
murilopontes | 0:78b46c0d5246 | 141 | int ret=strstart(cmd->name,str); |
murilopontes | 0:78b46c0d5246 | 142 | |
murilopontes | 0:78b46c0d5246 | 143 | if(ret==FULLMATCH) |
murilopontes | 0:78b46c0d5246 | 144 | { |
murilopontes | 0:78b46c0d5246 | 145 | /* found full match */ |
murilopontes | 0:78b46c0d5246 | 146 | while(*str && *str!=' ') str++; |
murilopontes | 0:78b46c0d5246 | 147 | while(*str==' ') str++; |
murilopontes | 0:78b46c0d5246 | 148 | *_str=str; |
murilopontes | 0:78b46c0d5246 | 149 | *_cmd=cmd; |
murilopontes | 0:78b46c0d5246 | 150 | return MATCH; |
murilopontes | 0:78b46c0d5246 | 151 | } |
murilopontes | 0:78b46c0d5246 | 152 | else if (ret==PARTMATCH) |
murilopontes | 0:78b46c0d5246 | 153 | { |
murilopontes | 0:78b46c0d5246 | 154 | if(matched_cmd) |
murilopontes | 0:78b46c0d5246 | 155 | { |
murilopontes | 0:78b46c0d5246 | 156 | *_cmd=matched_cmd; |
murilopontes | 0:78b46c0d5246 | 157 | return AMBIG; |
murilopontes | 0:78b46c0d5246 | 158 | } |
murilopontes | 0:78b46c0d5246 | 159 | else |
murilopontes | 0:78b46c0d5246 | 160 | { |
murilopontes | 0:78b46c0d5246 | 161 | matched_cmd=cmd; |
murilopontes | 0:78b46c0d5246 | 162 | } |
murilopontes | 0:78b46c0d5246 | 163 | } |
murilopontes | 0:78b46c0d5246 | 164 | else /* UNMATCH */ |
murilopontes | 0:78b46c0d5246 | 165 | { |
murilopontes | 0:78b46c0d5246 | 166 | } |
murilopontes | 0:78b46c0d5246 | 167 | } |
murilopontes | 0:78b46c0d5246 | 168 | if(matched_cmd) |
murilopontes | 0:78b46c0d5246 | 169 | { |
murilopontes | 0:78b46c0d5246 | 170 | while(*str && *str!=' ') str++; |
murilopontes | 0:78b46c0d5246 | 171 | while(*str==' ') str++; |
murilopontes | 0:78b46c0d5246 | 172 | *_cmd=matched_cmd; |
murilopontes | 0:78b46c0d5246 | 173 | *_str=str; |
murilopontes | 0:78b46c0d5246 | 174 | return MATCH; |
murilopontes | 0:78b46c0d5246 | 175 | } |
murilopontes | 0:78b46c0d5246 | 176 | else |
murilopontes | 0:78b46c0d5246 | 177 | return UNMATCH; |
murilopontes | 0:78b46c0d5246 | 178 | } |
murilopontes | 0:78b46c0d5246 | 179 | |
murilopontes | 0:78b46c0d5246 | 180 | /* create a context from current input line |
murilopontes | 0:78b46c0d5246 | 181 | */ |
murilopontes | 0:78b46c0d5246 | 182 | static void do_context(tinysh_cmd_t *cmd, uchar *str) |
murilopontes | 0:78b46c0d5246 | 183 | { |
murilopontes | 0:78b46c0d5246 | 184 | while(*str) |
murilopontes | 0:78b46c0d5246 | 185 | context_buffer[cur_context++]=*str++; |
murilopontes | 0:78b46c0d5246 | 186 | context_buffer[cur_context]=0; |
murilopontes | 0:78b46c0d5246 | 187 | cur_cmd_ctx=cmd; |
murilopontes | 0:78b46c0d5246 | 188 | } |
murilopontes | 0:78b46c0d5246 | 189 | |
murilopontes | 0:78b46c0d5246 | 190 | /* execute the given command by calling callback with appropriate |
murilopontes | 0:78b46c0d5246 | 191 | * arguments |
murilopontes | 0:78b46c0d5246 | 192 | */ |
murilopontes | 0:78b46c0d5246 | 193 | static void exec_command(tinysh_cmd_t *cmd, uchar *str) |
murilopontes | 0:78b46c0d5246 | 194 | { |
murilopontes | 0:78b46c0d5246 | 195 | char *argv[MAX_ARGS]; |
murilopontes | 0:78b46c0d5246 | 196 | int argc=0; |
murilopontes | 0:78b46c0d5246 | 197 | int i; |
murilopontes | 0:78b46c0d5246 | 198 | |
murilopontes | 0:78b46c0d5246 | 199 | /* copy command line to preserve it for history */ |
murilopontes | 0:78b46c0d5246 | 200 | for(i=0;i<BUFFER_SIZE;i++) |
murilopontes | 0:78b46c0d5246 | 201 | trash_buffer[i]=str[i]; |
murilopontes | 0:78b46c0d5246 | 202 | str=trash_buffer; |
murilopontes | 0:78b46c0d5246 | 203 | |
murilopontes | 0:78b46c0d5246 | 204 | /* cut into arguments */ |
murilopontes | 0:78b46c0d5246 | 205 | argv[argc++]=cmd->name; |
murilopontes | 0:78b46c0d5246 | 206 | while(*str && argc<MAX_ARGS) |
murilopontes | 0:78b46c0d5246 | 207 | { |
murilopontes | 0:78b46c0d5246 | 208 | while(*str==' ') str++; |
murilopontes | 0:78b46c0d5246 | 209 | if(*str==0) |
murilopontes | 0:78b46c0d5246 | 210 | break; |
murilopontes | 0:78b46c0d5246 | 211 | argv[argc++]=str; |
murilopontes | 0:78b46c0d5246 | 212 | while(*str!=' ' && *str) str++; |
murilopontes | 0:78b46c0d5246 | 213 | if(!*str) break; |
murilopontes | 0:78b46c0d5246 | 214 | *str++=0; |
murilopontes | 0:78b46c0d5246 | 215 | } |
murilopontes | 0:78b46c0d5246 | 216 | /* call command function if present */ |
murilopontes | 0:78b46c0d5246 | 217 | if(cmd->function) |
murilopontes | 0:78b46c0d5246 | 218 | { |
murilopontes | 0:78b46c0d5246 | 219 | tinysh_arg=cmd->arg; |
murilopontes | 0:78b46c0d5246 | 220 | cmd->function(argc,&argv[0]); |
murilopontes | 0:78b46c0d5246 | 221 | } |
murilopontes | 0:78b46c0d5246 | 222 | } |
murilopontes | 0:78b46c0d5246 | 223 | |
murilopontes | 0:78b46c0d5246 | 224 | /* try to execute the current command line |
murilopontes | 0:78b46c0d5246 | 225 | */ |
murilopontes | 0:78b46c0d5246 | 226 | static int exec_command_line(tinysh_cmd_t *cmd, uchar *_str) |
murilopontes | 0:78b46c0d5246 | 227 | { |
murilopontes | 0:78b46c0d5246 | 228 | uchar *str=_str; |
murilopontes | 0:78b46c0d5246 | 229 | |
murilopontes | 0:78b46c0d5246 | 230 | while(1) |
murilopontes | 0:78b46c0d5246 | 231 | { |
murilopontes | 0:78b46c0d5246 | 232 | int ret; |
murilopontes | 0:78b46c0d5246 | 233 | ret=parse_command(&cmd,&str); |
murilopontes | 0:78b46c0d5246 | 234 | if(ret==MATCH) /* found unique match */ |
murilopontes | 0:78b46c0d5246 | 235 | { |
murilopontes | 0:78b46c0d5246 | 236 | if(cmd) |
murilopontes | 0:78b46c0d5246 | 237 | { |
murilopontes | 0:78b46c0d5246 | 238 | if(!cmd->child) /* no sub-command, execute */ |
murilopontes | 0:78b46c0d5246 | 239 | { |
murilopontes | 0:78b46c0d5246 | 240 | exec_command(cmd,str); |
murilopontes | 0:78b46c0d5246 | 241 | return 0; |
murilopontes | 0:78b46c0d5246 | 242 | } |
murilopontes | 0:78b46c0d5246 | 243 | else |
murilopontes | 0:78b46c0d5246 | 244 | { |
murilopontes | 0:78b46c0d5246 | 245 | if(*str==0) /* no more input, this is a context */ |
murilopontes | 0:78b46c0d5246 | 246 | { |
murilopontes | 0:78b46c0d5246 | 247 | do_context(cmd,_str); |
murilopontes | 0:78b46c0d5246 | 248 | return 0; |
murilopontes | 0:78b46c0d5246 | 249 | } |
murilopontes | 0:78b46c0d5246 | 250 | else /* process next command word */ |
murilopontes | 0:78b46c0d5246 | 251 | { |
murilopontes | 0:78b46c0d5246 | 252 | cmd=cmd->child; |
murilopontes | 0:78b46c0d5246 | 253 | } |
murilopontes | 0:78b46c0d5246 | 254 | } |
murilopontes | 0:78b46c0d5246 | 255 | } |
murilopontes | 0:78b46c0d5246 | 256 | else /* cmd == 0 */ |
murilopontes | 0:78b46c0d5246 | 257 | { |
murilopontes | 0:78b46c0d5246 | 258 | return 0; |
murilopontes | 0:78b46c0d5246 | 259 | } |
murilopontes | 0:78b46c0d5246 | 260 | } |
murilopontes | 0:78b46c0d5246 | 261 | else if(ret==AMBIG) |
murilopontes | 0:78b46c0d5246 | 262 | { |
murilopontes | 0:78b46c0d5246 | 263 | puts("ambiguity: "); |
murilopontes | 0:78b46c0d5246 | 264 | puts(str); |
murilopontes | 0:78b46c0d5246 | 265 | puts("\r\n"); |
murilopontes | 0:78b46c0d5246 | 266 | return 0; |
murilopontes | 0:78b46c0d5246 | 267 | } |
murilopontes | 0:78b46c0d5246 | 268 | else if(ret==UNMATCH) /* UNMATCH */ |
murilopontes | 0:78b46c0d5246 | 269 | { |
murilopontes | 0:78b46c0d5246 | 270 | puts("no match: "); |
murilopontes | 0:78b46c0d5246 | 271 | puts(str); |
murilopontes | 0:78b46c0d5246 | 272 | puts("\r\n"); |
murilopontes | 0:78b46c0d5246 | 273 | return 0; |
murilopontes | 0:78b46c0d5246 | 274 | } |
murilopontes | 0:78b46c0d5246 | 275 | else /* NULLMATCH */ |
murilopontes | 0:78b46c0d5246 | 276 | return 0; |
murilopontes | 0:78b46c0d5246 | 277 | } |
murilopontes | 0:78b46c0d5246 | 278 | } |
murilopontes | 0:78b46c0d5246 | 279 | |
murilopontes | 0:78b46c0d5246 | 280 | /* display help for list of commands |
murilopontes | 0:78b46c0d5246 | 281 | */ |
murilopontes | 0:78b46c0d5246 | 282 | static void display_child_help(tinysh_cmd_t *cmd) |
murilopontes | 0:78b46c0d5246 | 283 | { |
murilopontes | 0:78b46c0d5246 | 284 | tinysh_cmd_t *cm; |
murilopontes | 0:78b46c0d5246 | 285 | int len=0; |
murilopontes | 0:78b46c0d5246 | 286 | |
murilopontes | 0:78b46c0d5246 | 287 | puts("\r\n"); |
murilopontes | 0:78b46c0d5246 | 288 | for(cm=cmd;cm;cm=cm->next) |
murilopontes | 0:78b46c0d5246 | 289 | if(len<strlen(cm->name)) |
murilopontes | 0:78b46c0d5246 | 290 | len=strlen(cm->name); |
murilopontes | 0:78b46c0d5246 | 291 | for(cm=cmd;cm;cm=cm->next) |
murilopontes | 0:78b46c0d5246 | 292 | if(cm->help) |
murilopontes | 0:78b46c0d5246 | 293 | { |
murilopontes | 0:78b46c0d5246 | 294 | int i; |
murilopontes | 0:78b46c0d5246 | 295 | puts(cm->name); |
murilopontes | 0:78b46c0d5246 | 296 | for(i=strlen(cm->name);i<len+2;i++) |
murilopontes | 0:78b46c0d5246 | 297 | putchar(' '); |
murilopontes | 0:78b46c0d5246 | 298 | puts(cm->help); |
murilopontes | 0:78b46c0d5246 | 299 | puts("\r\n"); |
murilopontes | 0:78b46c0d5246 | 300 | } |
murilopontes | 0:78b46c0d5246 | 301 | } |
murilopontes | 0:78b46c0d5246 | 302 | |
murilopontes | 0:78b46c0d5246 | 303 | /* try to display help for current comand line |
murilopontes | 0:78b46c0d5246 | 304 | */ |
murilopontes | 0:78b46c0d5246 | 305 | static int help_command_line(tinysh_cmd_t *cmd, uchar *_str) |
murilopontes | 0:78b46c0d5246 | 306 | { |
murilopontes | 0:78b46c0d5246 | 307 | uchar *str=_str; |
murilopontes | 0:78b46c0d5246 | 308 | |
murilopontes | 0:78b46c0d5246 | 309 | while(1) |
murilopontes | 0:78b46c0d5246 | 310 | { |
murilopontes | 0:78b46c0d5246 | 311 | int ret; |
murilopontes | 0:78b46c0d5246 | 312 | ret=parse_command(&cmd,&str); |
murilopontes | 0:78b46c0d5246 | 313 | if(ret==MATCH && *str==0) /* found unique match or empty line */ |
murilopontes | 0:78b46c0d5246 | 314 | { |
murilopontes | 0:78b46c0d5246 | 315 | tinysh_cmd_t *cm; |
murilopontes | 0:78b46c0d5246 | 316 | int len=0; |
murilopontes | 0:78b46c0d5246 | 317 | |
murilopontes | 0:78b46c0d5246 | 318 | if(cmd->child) /* display sub-commands help */ |
murilopontes | 0:78b46c0d5246 | 319 | { |
murilopontes | 0:78b46c0d5246 | 320 | display_child_help(cmd->child); |
murilopontes | 0:78b46c0d5246 | 321 | return 0; |
murilopontes | 0:78b46c0d5246 | 322 | } |
murilopontes | 0:78b46c0d5246 | 323 | else /* no sub-command, show single help */ |
murilopontes | 0:78b46c0d5246 | 324 | { |
murilopontes | 0:78b46c0d5246 | 325 | if(*(str-1)!=' ') |
murilopontes | 0:78b46c0d5246 | 326 | putchar(' '); |
murilopontes | 0:78b46c0d5246 | 327 | if(cmd->usage) |
murilopontes | 0:78b46c0d5246 | 328 | puts(cmd->usage); |
murilopontes | 0:78b46c0d5246 | 329 | puts(": "); |
murilopontes | 0:78b46c0d5246 | 330 | if(cmd->help) |
murilopontes | 0:78b46c0d5246 | 331 | puts(cmd->help); |
murilopontes | 0:78b46c0d5246 | 332 | else |
murilopontes | 0:78b46c0d5246 | 333 | puts("no help available"); |
murilopontes | 0:78b46c0d5246 | 334 | puts("\r\n"); |
murilopontes | 0:78b46c0d5246 | 335 | } |
murilopontes | 0:78b46c0d5246 | 336 | return 0; |
murilopontes | 0:78b46c0d5246 | 337 | } |
murilopontes | 0:78b46c0d5246 | 338 | else if(ret==MATCH && *str) |
murilopontes | 0:78b46c0d5246 | 339 | { /* continue processing the line */ |
murilopontes | 0:78b46c0d5246 | 340 | cmd=cmd->child; |
murilopontes | 0:78b46c0d5246 | 341 | } |
murilopontes | 0:78b46c0d5246 | 342 | else if(ret==AMBIG) |
murilopontes | 0:78b46c0d5246 | 343 | { |
murilopontes | 0:78b46c0d5246 | 344 | puts("\r\nambiguity: "); |
murilopontes | 0:78b46c0d5246 | 345 | puts(str); |
murilopontes | 0:78b46c0d5246 | 346 | puts("\r\n"); |
murilopontes | 0:78b46c0d5246 | 347 | return 0; |
murilopontes | 0:78b46c0d5246 | 348 | } |
murilopontes | 0:78b46c0d5246 | 349 | else if(ret==UNMATCH) |
murilopontes | 0:78b46c0d5246 | 350 | { |
murilopontes | 0:78b46c0d5246 | 351 | puts("\r\nno match: "); |
murilopontes | 0:78b46c0d5246 | 352 | puts(str); |
murilopontes | 0:78b46c0d5246 | 353 | puts("\r\n"); |
murilopontes | 0:78b46c0d5246 | 354 | return 0; |
murilopontes | 0:78b46c0d5246 | 355 | } |
murilopontes | 0:78b46c0d5246 | 356 | else /* NULLMATCH */ |
murilopontes | 0:78b46c0d5246 | 357 | { |
murilopontes | 0:78b46c0d5246 | 358 | if(cur_cmd_ctx) |
murilopontes | 0:78b46c0d5246 | 359 | display_child_help(cur_cmd_ctx->child); |
murilopontes | 0:78b46c0d5246 | 360 | else |
murilopontes | 0:78b46c0d5246 | 361 | display_child_help(root_cmd); |
murilopontes | 0:78b46c0d5246 | 362 | return 0; |
murilopontes | 0:78b46c0d5246 | 363 | } |
murilopontes | 0:78b46c0d5246 | 364 | } |
murilopontes | 0:78b46c0d5246 | 365 | } |
murilopontes | 0:78b46c0d5246 | 366 | |
murilopontes | 0:78b46c0d5246 | 367 | /* try to complete current command line |
murilopontes | 0:78b46c0d5246 | 368 | */ |
murilopontes | 0:78b46c0d5246 | 369 | static int complete_command_line(tinysh_cmd_t *cmd, uchar *_str) |
murilopontes | 0:78b46c0d5246 | 370 | { |
murilopontes | 0:78b46c0d5246 | 371 | uchar *str=_str; |
murilopontes | 0:78b46c0d5246 | 372 | |
murilopontes | 0:78b46c0d5246 | 373 | while(1) |
murilopontes | 0:78b46c0d5246 | 374 | { |
murilopontes | 0:78b46c0d5246 | 375 | int ret; |
murilopontes | 0:78b46c0d5246 | 376 | int common_len=BUFFER_SIZE; |
murilopontes | 0:78b46c0d5246 | 377 | int _str_len; |
murilopontes | 0:78b46c0d5246 | 378 | int i; |
murilopontes | 0:78b46c0d5246 | 379 | uchar *__str=str; |
murilopontes | 0:78b46c0d5246 | 380 | |
murilopontes | 0:78b46c0d5246 | 381 | tinysh_cmd_t *_cmd=cmd; |
murilopontes | 0:78b46c0d5246 | 382 | ret=parse_command(&cmd,&str); |
murilopontes | 0:78b46c0d5246 | 383 | for(_str_len=0;__str[_str_len]&&__str[_str_len]!=' ';_str_len++); |
murilopontes | 0:78b46c0d5246 | 384 | if(ret==MATCH && *str) |
murilopontes | 0:78b46c0d5246 | 385 | { |
murilopontes | 0:78b46c0d5246 | 386 | cmd=cmd->child; |
murilopontes | 0:78b46c0d5246 | 387 | } |
murilopontes | 0:78b46c0d5246 | 388 | else if(ret==AMBIG || ret==MATCH || ret==NULLMATCH) |
murilopontes | 0:78b46c0d5246 | 389 | { |
murilopontes | 0:78b46c0d5246 | 390 | tinysh_cmd_t *cm; |
murilopontes | 0:78b46c0d5246 | 391 | tinysh_cmd_t *matched_cmd=0; |
murilopontes | 0:78b46c0d5246 | 392 | int nb_match=0; |
murilopontes | 0:78b46c0d5246 | 393 | |
murilopontes | 0:78b46c0d5246 | 394 | for(cm=cmd;cm;cm=cm->next) |
murilopontes | 0:78b46c0d5246 | 395 | { |
murilopontes | 0:78b46c0d5246 | 396 | int r=strstart(cm->name,__str); |
murilopontes | 0:78b46c0d5246 | 397 | if(r==FULLMATCH) |
murilopontes | 0:78b46c0d5246 | 398 | { |
murilopontes | 0:78b46c0d5246 | 399 | for(i=_str_len;cmd->name[i];i++) |
murilopontes | 0:78b46c0d5246 | 400 | tinysh_char_in(cmd->name[i]); |
murilopontes | 0:78b46c0d5246 | 401 | if(*(str-1)!=' ') |
murilopontes | 0:78b46c0d5246 | 402 | tinysh_char_in(' '); |
murilopontes | 0:78b46c0d5246 | 403 | if(!cmd->child) |
murilopontes | 0:78b46c0d5246 | 404 | { |
murilopontes | 0:78b46c0d5246 | 405 | if(cmd->usage) |
murilopontes | 0:78b46c0d5246 | 406 | { |
murilopontes | 0:78b46c0d5246 | 407 | puts(cmd->usage); |
murilopontes | 0:78b46c0d5246 | 408 | putchar('\n'); |
murilopontes | 0:78b46c0d5246 | 409 | return 1; |
murilopontes | 0:78b46c0d5246 | 410 | } |
murilopontes | 0:78b46c0d5246 | 411 | else |
murilopontes | 0:78b46c0d5246 | 412 | return 0; |
murilopontes | 0:78b46c0d5246 | 413 | } |
murilopontes | 0:78b46c0d5246 | 414 | else |
murilopontes | 0:78b46c0d5246 | 415 | { |
murilopontes | 0:78b46c0d5246 | 416 | cmd=cmd->child; |
murilopontes | 0:78b46c0d5246 | 417 | break; |
murilopontes | 0:78b46c0d5246 | 418 | } |
murilopontes | 0:78b46c0d5246 | 419 | } |
murilopontes | 0:78b46c0d5246 | 420 | else if(r==PARTMATCH) |
murilopontes | 0:78b46c0d5246 | 421 | { |
murilopontes | 0:78b46c0d5246 | 422 | nb_match++; |
murilopontes | 0:78b46c0d5246 | 423 | if(!matched_cmd) |
murilopontes | 0:78b46c0d5246 | 424 | { |
murilopontes | 0:78b46c0d5246 | 425 | matched_cmd=cm; |
murilopontes | 0:78b46c0d5246 | 426 | common_len=strlen(cm->name); |
murilopontes | 0:78b46c0d5246 | 427 | } |
murilopontes | 0:78b46c0d5246 | 428 | else |
murilopontes | 0:78b46c0d5246 | 429 | { |
murilopontes | 0:78b46c0d5246 | 430 | for(i=_str_len;cm->name[i] && i<common_len && |
murilopontes | 0:78b46c0d5246 | 431 | cm->name[i]==matched_cmd->name[i];i++); |
murilopontes | 0:78b46c0d5246 | 432 | if(i<common_len) |
murilopontes | 0:78b46c0d5246 | 433 | common_len=i; |
murilopontes | 0:78b46c0d5246 | 434 | } |
murilopontes | 0:78b46c0d5246 | 435 | } |
murilopontes | 0:78b46c0d5246 | 436 | } |
murilopontes | 0:78b46c0d5246 | 437 | if(cm) |
murilopontes | 0:78b46c0d5246 | 438 | continue; |
murilopontes | 0:78b46c0d5246 | 439 | if(matched_cmd) |
murilopontes | 0:78b46c0d5246 | 440 | { |
murilopontes | 0:78b46c0d5246 | 441 | if(_str_len==common_len) |
murilopontes | 0:78b46c0d5246 | 442 | { |
murilopontes | 1:71580bf962fe | 443 | puts("\r\n"); |
murilopontes | 0:78b46c0d5246 | 444 | for(cm=cmd;cm;cm=cm->next) |
murilopontes | 0:78b46c0d5246 | 445 | { |
murilopontes | 0:78b46c0d5246 | 446 | int r=strstart(cm->name,__str); |
murilopontes | 0:78b46c0d5246 | 447 | if(r==FULLMATCH || r==PARTMATCH) |
murilopontes | 0:78b46c0d5246 | 448 | { |
murilopontes | 0:78b46c0d5246 | 449 | puts(cm->name); |
murilopontes | 1:71580bf962fe | 450 | puts("\r\n"); |
murilopontes | 0:78b46c0d5246 | 451 | } |
murilopontes | 0:78b46c0d5246 | 452 | } |
murilopontes | 0:78b46c0d5246 | 453 | return 1; |
murilopontes | 0:78b46c0d5246 | 454 | } |
murilopontes | 0:78b46c0d5246 | 455 | else |
murilopontes | 0:78b46c0d5246 | 456 | { |
murilopontes | 0:78b46c0d5246 | 457 | for(i=_str_len;i<common_len;i++) |
murilopontes | 0:78b46c0d5246 | 458 | tinysh_char_in(matched_cmd->name[i]); |
murilopontes | 0:78b46c0d5246 | 459 | if(nb_match==1) |
murilopontes | 0:78b46c0d5246 | 460 | tinysh_char_in(' '); |
murilopontes | 0:78b46c0d5246 | 461 | } |
murilopontes | 0:78b46c0d5246 | 462 | } |
murilopontes | 0:78b46c0d5246 | 463 | return 0; |
murilopontes | 0:78b46c0d5246 | 464 | } |
murilopontes | 0:78b46c0d5246 | 465 | else /* UNMATCH */ |
murilopontes | 0:78b46c0d5246 | 466 | { |
murilopontes | 0:78b46c0d5246 | 467 | return 0; |
murilopontes | 0:78b46c0d5246 | 468 | } |
murilopontes | 0:78b46c0d5246 | 469 | } |
murilopontes | 0:78b46c0d5246 | 470 | } |
murilopontes | 0:78b46c0d5246 | 471 | |
murilopontes | 0:78b46c0d5246 | 472 | /* start a new line |
murilopontes | 0:78b46c0d5246 | 473 | */ |
murilopontes | 0:78b46c0d5246 | 474 | static void start_of_line() |
murilopontes | 0:78b46c0d5246 | 475 | { |
murilopontes | 0:78b46c0d5246 | 476 | /* display start of new line */ |
murilopontes | 0:78b46c0d5246 | 477 | puts(prompt); |
murilopontes | 0:78b46c0d5246 | 478 | if(cur_context) |
murilopontes | 0:78b46c0d5246 | 479 | { |
murilopontes | 0:78b46c0d5246 | 480 | puts(context_buffer); |
murilopontes | 0:78b46c0d5246 | 481 | puts("> "); |
murilopontes | 0:78b46c0d5246 | 482 | } |
murilopontes | 0:78b46c0d5246 | 483 | cur_index=0; |
murilopontes | 0:78b46c0d5246 | 484 | } |
murilopontes | 0:78b46c0d5246 | 485 | |
murilopontes | 0:78b46c0d5246 | 486 | /* character input |
murilopontes | 0:78b46c0d5246 | 487 | */ |
murilopontes | 0:78b46c0d5246 | 488 | static void _tinysh_char_in(uchar c) |
murilopontes | 0:78b46c0d5246 | 489 | { |
murilopontes | 0:78b46c0d5246 | 490 | uchar *line=input_buffers[cur_buf_index]; |
murilopontes | 0:78b46c0d5246 | 491 | |
murilopontes | 0:78b46c0d5246 | 492 | if(c=='\n' || c=='\r') /* validate command */ |
murilopontes | 0:78b46c0d5246 | 493 | { |
murilopontes | 0:78b46c0d5246 | 494 | tinysh_cmd_t *cmd; |
murilopontes | 0:78b46c0d5246 | 495 | int context=0; |
murilopontes | 0:78b46c0d5246 | 496 | |
murilopontes | 0:78b46c0d5246 | 497 | /* first, echo the newline */ |
murilopontes | 0:78b46c0d5246 | 498 | if(echo) |
murilopontes | 0:78b46c0d5246 | 499 | putchar(c); |
murilopontes | 0:78b46c0d5246 | 500 | |
murilopontes | 0:78b46c0d5246 | 501 | while(*line && *line==' ') line++; |
murilopontes | 0:78b46c0d5246 | 502 | if(*line) /* not empty line */ |
murilopontes | 0:78b46c0d5246 | 503 | { |
murilopontes | 0:78b46c0d5246 | 504 | cmd=cur_cmd_ctx?cur_cmd_ctx->child:root_cmd; |
murilopontes | 0:78b46c0d5246 | 505 | exec_command_line(cmd,line); |
murilopontes | 0:78b46c0d5246 | 506 | cur_buf_index=(cur_buf_index+1)%HISTORY_DEPTH; |
murilopontes | 0:78b46c0d5246 | 507 | cur_index=0; |
murilopontes | 0:78b46c0d5246 | 508 | input_buffers[cur_buf_index][0]=0; |
murilopontes | 0:78b46c0d5246 | 509 | } |
murilopontes | 0:78b46c0d5246 | 510 | start_of_line(); |
murilopontes | 0:78b46c0d5246 | 511 | } |
murilopontes | 0:78b46c0d5246 | 512 | else if(c==TOPCHAR) /* return to top level */ |
murilopontes | 0:78b46c0d5246 | 513 | { |
murilopontes | 0:78b46c0d5246 | 514 | if(echo) |
murilopontes | 0:78b46c0d5246 | 515 | putchar(c); |
murilopontes | 0:78b46c0d5246 | 516 | |
murilopontes | 0:78b46c0d5246 | 517 | cur_context=0; |
murilopontes | 0:78b46c0d5246 | 518 | cur_cmd_ctx=0; |
murilopontes | 0:78b46c0d5246 | 519 | } |
murilopontes | 0:78b46c0d5246 | 520 | else if(c==8 || c==127) /* backspace */ |
murilopontes | 0:78b46c0d5246 | 521 | { |
murilopontes | 0:78b46c0d5246 | 522 | if(cur_index>0) |
murilopontes | 0:78b46c0d5246 | 523 | { |
murilopontes | 0:78b46c0d5246 | 524 | puts("\b \b"); |
murilopontes | 0:78b46c0d5246 | 525 | cur_index--; |
murilopontes | 0:78b46c0d5246 | 526 | line[cur_index]=0; |
murilopontes | 0:78b46c0d5246 | 527 | } |
murilopontes | 0:78b46c0d5246 | 528 | } |
murilopontes | 0:78b46c0d5246 | 529 | else if(c==16) /* CTRL-P: back in history */ |
murilopontes | 0:78b46c0d5246 | 530 | { |
murilopontes | 0:78b46c0d5246 | 531 | int prevline=(cur_buf_index+HISTORY_DEPTH-1)%HISTORY_DEPTH; |
murilopontes | 0:78b46c0d5246 | 532 | |
murilopontes | 0:78b46c0d5246 | 533 | if(input_buffers[prevline][0]) |
murilopontes | 0:78b46c0d5246 | 534 | { |
murilopontes | 0:78b46c0d5246 | 535 | line=input_buffers[prevline]; |
murilopontes | 0:78b46c0d5246 | 536 | /* fill the rest of the line with spaces */ |
murilopontes | 0:78b46c0d5246 | 537 | while(cur_index-->strlen(line)) |
murilopontes | 0:78b46c0d5246 | 538 | puts("\b \b"); |
murilopontes | 0:78b46c0d5246 | 539 | putchar('\r'); |
murilopontes | 0:78b46c0d5246 | 540 | start_of_line(); |
murilopontes | 0:78b46c0d5246 | 541 | puts(line); |
murilopontes | 0:78b46c0d5246 | 542 | cur_index=strlen(line); |
murilopontes | 0:78b46c0d5246 | 543 | cur_buf_index=prevline; |
murilopontes | 0:78b46c0d5246 | 544 | } |
murilopontes | 0:78b46c0d5246 | 545 | } |
murilopontes | 0:78b46c0d5246 | 546 | else if(c==14) /* CTRL-N: next in history */ |
murilopontes | 0:78b46c0d5246 | 547 | { |
murilopontes | 0:78b46c0d5246 | 548 | int nextline=(cur_buf_index+1)%HISTORY_DEPTH; |
murilopontes | 0:78b46c0d5246 | 549 | |
murilopontes | 0:78b46c0d5246 | 550 | if(input_buffers[nextline][0]) |
murilopontes | 0:78b46c0d5246 | 551 | { |
murilopontes | 0:78b46c0d5246 | 552 | line=input_buffers[nextline]; |
murilopontes | 0:78b46c0d5246 | 553 | /* fill the rest of the line with spaces */ |
murilopontes | 0:78b46c0d5246 | 554 | while(cur_index-->strlen(line)) |
murilopontes | 0:78b46c0d5246 | 555 | puts("\b \b"); |
murilopontes | 0:78b46c0d5246 | 556 | putchar('\r'); |
murilopontes | 0:78b46c0d5246 | 557 | start_of_line(); |
murilopontes | 0:78b46c0d5246 | 558 | puts(line); |
murilopontes | 0:78b46c0d5246 | 559 | cur_index=strlen(line); |
murilopontes | 0:78b46c0d5246 | 560 | cur_buf_index=nextline; |
murilopontes | 0:78b46c0d5246 | 561 | } |
murilopontes | 0:78b46c0d5246 | 562 | } |
murilopontes | 0:78b46c0d5246 | 563 | else if(c=='?') /* display help */ |
murilopontes | 0:78b46c0d5246 | 564 | { |
murilopontes | 0:78b46c0d5246 | 565 | tinysh_cmd_t *cmd; |
murilopontes | 0:78b46c0d5246 | 566 | cmd=cur_cmd_ctx?cur_cmd_ctx->child:root_cmd; |
murilopontes | 0:78b46c0d5246 | 567 | help_command_line(cmd,line); |
murilopontes | 0:78b46c0d5246 | 568 | start_of_line(); |
murilopontes | 0:78b46c0d5246 | 569 | puts(line); |
murilopontes | 0:78b46c0d5246 | 570 | cur_index=strlen(line); |
murilopontes | 0:78b46c0d5246 | 571 | } |
murilopontes | 0:78b46c0d5246 | 572 | else if(c==9 || c=='!') /* TAB: autocompletion */ |
murilopontes | 0:78b46c0d5246 | 573 | { |
murilopontes | 0:78b46c0d5246 | 574 | tinysh_cmd_t *cmd; |
murilopontes | 0:78b46c0d5246 | 575 | cmd=cur_cmd_ctx?cur_cmd_ctx->child:root_cmd; |
murilopontes | 0:78b46c0d5246 | 576 | if(complete_command_line(cmd,line)) |
murilopontes | 0:78b46c0d5246 | 577 | { |
murilopontes | 0:78b46c0d5246 | 578 | start_of_line(); |
murilopontes | 0:78b46c0d5246 | 579 | puts(line); |
murilopontes | 0:78b46c0d5246 | 580 | } |
murilopontes | 0:78b46c0d5246 | 581 | cur_index=strlen(line); |
murilopontes | 0:78b46c0d5246 | 582 | } |
murilopontes | 0:78b46c0d5246 | 583 | else /* any input character */ |
murilopontes | 0:78b46c0d5246 | 584 | { |
murilopontes | 0:78b46c0d5246 | 585 | if(cur_index<BUFFER_SIZE) |
murilopontes | 0:78b46c0d5246 | 586 | { |
murilopontes | 0:78b46c0d5246 | 587 | if(echo) |
murilopontes | 0:78b46c0d5246 | 588 | putchar(c); |
murilopontes | 0:78b46c0d5246 | 589 | line[cur_index++]=c; |
murilopontes | 0:78b46c0d5246 | 590 | line[cur_index]=0; |
murilopontes | 0:78b46c0d5246 | 591 | } |
murilopontes | 0:78b46c0d5246 | 592 | } |
murilopontes | 0:78b46c0d5246 | 593 | } |
murilopontes | 0:78b46c0d5246 | 594 | |
murilopontes | 0:78b46c0d5246 | 595 | /* new character input */ |
murilopontes | 0:78b46c0d5246 | 596 | void tinysh_char_in(uchar c) |
murilopontes | 0:78b46c0d5246 | 597 | { |
murilopontes | 0:78b46c0d5246 | 598 | /* |
murilopontes | 0:78b46c0d5246 | 599 | * filter characters here |
murilopontes | 0:78b46c0d5246 | 600 | */ |
murilopontes | 0:78b46c0d5246 | 601 | _tinysh_char_in(c); |
murilopontes | 0:78b46c0d5246 | 602 | } |
murilopontes | 0:78b46c0d5246 | 603 | |
murilopontes | 0:78b46c0d5246 | 604 | /* add a new command */ |
murilopontes | 0:78b46c0d5246 | 605 | void tinysh_add_command(tinysh_cmd_t *cmd) |
murilopontes | 0:78b46c0d5246 | 606 | { |
murilopontes | 0:78b46c0d5246 | 607 | tinysh_cmd_t *cm; |
murilopontes | 0:78b46c0d5246 | 608 | |
murilopontes | 0:78b46c0d5246 | 609 | if(cmd->parent) |
murilopontes | 0:78b46c0d5246 | 610 | { |
murilopontes | 0:78b46c0d5246 | 611 | cm=cmd->parent->child; |
murilopontes | 0:78b46c0d5246 | 612 | if(!cm) |
murilopontes | 0:78b46c0d5246 | 613 | { |
murilopontes | 0:78b46c0d5246 | 614 | cmd->parent->child=cmd; |
murilopontes | 0:78b46c0d5246 | 615 | } |
murilopontes | 0:78b46c0d5246 | 616 | else |
murilopontes | 0:78b46c0d5246 | 617 | { |
murilopontes | 0:78b46c0d5246 | 618 | while(cm->next) cm=cm->next; |
murilopontes | 0:78b46c0d5246 | 619 | cm->next=cmd; |
murilopontes | 0:78b46c0d5246 | 620 | } |
murilopontes | 0:78b46c0d5246 | 621 | } |
murilopontes | 0:78b46c0d5246 | 622 | else if(!root_cmd) |
murilopontes | 0:78b46c0d5246 | 623 | { |
murilopontes | 0:78b46c0d5246 | 624 | root_cmd=cmd; |
murilopontes | 0:78b46c0d5246 | 625 | } |
murilopontes | 0:78b46c0d5246 | 626 | else |
murilopontes | 0:78b46c0d5246 | 627 | { |
murilopontes | 0:78b46c0d5246 | 628 | cm=root_cmd; |
murilopontes | 0:78b46c0d5246 | 629 | while(cm->next) cm=cm->next; |
murilopontes | 0:78b46c0d5246 | 630 | cm->next=cmd; |
murilopontes | 0:78b46c0d5246 | 631 | } |
murilopontes | 0:78b46c0d5246 | 632 | } |
murilopontes | 0:78b46c0d5246 | 633 | |
murilopontes | 0:78b46c0d5246 | 634 | /* modify shell prompt |
murilopontes | 0:78b46c0d5246 | 635 | */ |
murilopontes | 0:78b46c0d5246 | 636 | void tinysh_set_prompt(char *str) |
murilopontes | 0:78b46c0d5246 | 637 | { |
murilopontes | 0:78b46c0d5246 | 638 | int i; |
murilopontes | 0:78b46c0d5246 | 639 | for(i=0;str[i] && i<PROMPT_SIZE;i++) |
murilopontes | 0:78b46c0d5246 | 640 | prompt[i]=str[i]; |
murilopontes | 0:78b46c0d5246 | 641 | prompt[i]=0; |
murilopontes | 0:78b46c0d5246 | 642 | /* force prompt display by generating empty command */ |
murilopontes | 0:78b46c0d5246 | 643 | tinysh_char_in('\r'); |
murilopontes | 0:78b46c0d5246 | 644 | } |
murilopontes | 0:78b46c0d5246 | 645 | |
murilopontes | 0:78b46c0d5246 | 646 | /* return current command argument |
murilopontes | 0:78b46c0d5246 | 647 | */ |
murilopontes | 0:78b46c0d5246 | 648 | void *tinysh_get_arg() |
murilopontes | 0:78b46c0d5246 | 649 | { |
murilopontes | 0:78b46c0d5246 | 650 | return tinysh_arg; |
murilopontes | 0:78b46c0d5246 | 651 | } |
murilopontes | 0:78b46c0d5246 | 652 | |
murilopontes | 0:78b46c0d5246 | 653 | /* string to decimal/hexadecimal conversion |
murilopontes | 0:78b46c0d5246 | 654 | */ |
murilopontes | 0:78b46c0d5246 | 655 | unsigned long tinysh_atoxi(char *s) |
murilopontes | 0:78b46c0d5246 | 656 | { |
murilopontes | 0:78b46c0d5246 | 657 | int ishex=0; |
murilopontes | 0:78b46c0d5246 | 658 | unsigned long res=0; |
murilopontes | 0:78b46c0d5246 | 659 | |
murilopontes | 0:78b46c0d5246 | 660 | if(*s==0) return 0; |
murilopontes | 0:78b46c0d5246 | 661 | |
murilopontes | 0:78b46c0d5246 | 662 | if(*s=='0' && *(s+1)=='x') |
murilopontes | 0:78b46c0d5246 | 663 | { |
murilopontes | 0:78b46c0d5246 | 664 | ishex=1; |
murilopontes | 0:78b46c0d5246 | 665 | s+=2; |
murilopontes | 0:78b46c0d5246 | 666 | } |
murilopontes | 0:78b46c0d5246 | 667 | |
murilopontes | 0:78b46c0d5246 | 668 | while(*s) |
murilopontes | 0:78b46c0d5246 | 669 | { |
murilopontes | 0:78b46c0d5246 | 670 | if(ishex) |
murilopontes | 0:78b46c0d5246 | 671 | res*=16; |
murilopontes | 0:78b46c0d5246 | 672 | else |
murilopontes | 0:78b46c0d5246 | 673 | res*=10; |
murilopontes | 0:78b46c0d5246 | 674 | |
murilopontes | 0:78b46c0d5246 | 675 | if(*s>='0' && *s<='9') |
murilopontes | 0:78b46c0d5246 | 676 | res+=*s-'0'; |
murilopontes | 0:78b46c0d5246 | 677 | else if(ishex && *s>='a' && *s<='f') |
murilopontes | 0:78b46c0d5246 | 678 | res+=*s+10-'a'; |
murilopontes | 0:78b46c0d5246 | 679 | else if(ishex && *s>='A' && *s<='F') |
murilopontes | 0:78b46c0d5246 | 680 | res+=*s+10-'A'; |
murilopontes | 0:78b46c0d5246 | 681 | else |
murilopontes | 0:78b46c0d5246 | 682 | break; |
murilopontes | 0:78b46c0d5246 | 683 | |
murilopontes | 0:78b46c0d5246 | 684 | s++; |
murilopontes | 0:78b46c0d5246 | 685 | } |
murilopontes | 0:78b46c0d5246 | 686 | |
murilopontes | 0:78b46c0d5246 | 687 | return res; |
murilopontes | 0:78b46c0d5246 | 688 | } |
murilopontes | 0:78b46c0d5246 | 689 |