Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
bt_shell/shell/tinyshell/tinysh.c@4:05484073a641, 2015-03-22 (annotated)
- 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?
| User | Revision | Line number | New 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 |