Mark Vandermeulen / FYDP_Final2

Dependencies:   Servo mbed

Committer:
majik
Date:
Sun Mar 22 06:34:30 2015 +0000
Revision:
4:05484073a641
Parent:
0:21019d94ad33
BOTH IMUs WORK NOW. Put them in separate threads. Servo is included.

Who changed what in which revision?

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