Changeset d6c8ff6 in mainline
- Timestamp:
- 2009-04-03T07:58:42Z (16 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c583970
- Parents:
- 20cc877
- Location:
- kernel/generic
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/include/console/kconsole.h
r20cc877 rd6c8ff6 40 40 #include <ipc/irq.h> 41 41 42 #define MAX_CMDLINE 25643 #define KCONSOLE_HISTORY 1042 #define MAX_CMDLINE 256 43 #define KCONSOLE_HISTORY 10 44 44 45 45 typedef enum { … … 48 48 ARG_TYPE_STRING, 49 49 /** Variable type - either symbol or string. */ 50 ARG_TYPE_VAR 50 ARG_TYPE_VAR 51 51 } cmd_arg_type_t; 52 52 … … 97 97 extern void kconsole_thread(void *data); 98 98 99 extern intcmd_register(cmd_info_t *cmd);99 extern bool cmd_register(cmd_info_t *cmd); 100 100 101 101 #endif -
kernel/generic/src/console/kconsole.c
r20cc877 rd6c8ff6 32 32 33 33 /** 34 * @file 35 * @brief 34 * @file kconsole.c 35 * @brief Kernel console. 36 36 * 37 37 * This file contains kernel thread managing the kernel console. 38 * 38 39 */ 39 40 … … 57 58 #include <errno.h> 58 59 #include <putchar.h> 60 #include <string.h> 59 61 60 62 /** Simple kernel console. … … 65 67 * register their own commands. 66 68 */ 67 69 68 70 /** Locking. 69 71 * … … 80 82 * lower address must be locked first. 81 83 */ 82 83 SPINLOCK_INITIALIZE(cmd_lock); /**< Lock protecting command list. */ 84 LIST_INITIALIZE(cmd_head); /**< Command list. */ 85 86 static cmd_info_t *parse_cmdline(char *cmdline, size_t len); 87 static bool parse_argument(char *cmdline, size_t len, index_t *start, 88 index_t *end); 89 static char history[KCONSOLE_HISTORY][MAX_CMDLINE] = {}; 84 85 SPINLOCK_INITIALIZE(cmd_lock); /**< Lock protecting command list. */ 86 LIST_INITIALIZE(cmd_head); /**< Command list. */ 87 88 static wchar_t history[KCONSOLE_HISTORY][MAX_CMDLINE] = {}; 89 static count_t history_pos = 0; 90 90 91 91 /** Initialize kconsole data structures … … 98 98 { 99 99 unsigned int i; 100 100 101 101 cmd_init(); 102 102 for (i = 0; i < KCONSOLE_HISTORY; i++) 103 history[i][0] = '\0';103 history[i][0] = 0; 104 104 } 105 105 … … 108 108 * @param cmd Structure describing the command. 109 109 * 110 * @return 0 on failure, 1 on success. 111 */ 112 int cmd_register(cmd_info_t *cmd) 110 * @return False on failure, true on success. 111 * 112 */ 113 bool cmd_register(cmd_info_t *cmd) 113 114 { 114 115 link_t *cur; … … 120 121 */ 121 122 for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) { 122 cmd_info_t *hlp; 123 124 hlp = list_get_instance(cur, cmd_info_t, link); 125 123 cmd_info_t *hlp = list_get_instance(cur, cmd_info_t, link); 124 126 125 if (hlp == cmd) { 127 126 /* The command is already there. */ 128 127 spinlock_unlock(&cmd_lock); 129 return 0;130 } 131 128 return false; 129 } 130 132 131 /* Avoid deadlock. */ 133 132 if (hlp < cmd) { … … 138 137 spinlock_lock(&hlp->lock); 139 138 } 140 if ((strncmp(hlp->name, cmd->name, max(str_size(cmd->name),141 str_size(hlp->name))) == 0)) {139 140 if (str_cmp(hlp->name, cmd->name) == 0) { 142 141 /* The command is already there. */ 143 142 spinlock_unlock(&hlp->lock); 144 143 spinlock_unlock(&cmd->lock); 145 144 spinlock_unlock(&cmd_lock); 146 return 0;145 return false; 147 146 } 148 147 … … 157 156 158 157 spinlock_unlock(&cmd_lock); 159 return 1;158 return true; 160 159 } 161 160 162 161 /** Print count times a character */ 163 static void rdln_print_c(wchar_t ch, count_t count)162 static void print_cc(wchar_t ch, count_t count) 164 163 { 165 164 count_t i; … … 168 167 } 169 168 170 /** Insert character to string */171 static void insert_char(char *str, char ch, int pos)172 {173 int i;174 175 for (i = str_size(str); i > pos; i--)176 str[i] = str[i - 1];177 str[pos] = ch;178 }179 180 169 /** Try to find a command beginning with prefix */ 181 static const char *cmdtab_search_one(const char *name,link_t **startpos) 182 { 183 size_t namelen = str_size(name); 184 const char *curname; 185 170 static const char *cmdtab_search_one(const char *name, link_t **startpos) 171 { 172 count_t namelen = str_length(name); 173 186 174 spinlock_lock(&cmd_lock); 187 188 if ( !*startpos)175 176 if (*startpos == NULL) 189 177 *startpos = cmd_head.next; 190 178 191 179 for (; *startpos != &cmd_head; *startpos = (*startpos)->next) { 192 cmd_info_t *hlp; 193 hlp = list_get_instance(*startpos, cmd_info_t, link); 194 195 curname = hlp->name; 196 if (str_size(curname) < namelen) 180 cmd_info_t *hlp = list_get_instance(*startpos, cmd_info_t, link); 181 182 const char *curname = hlp->name; 183 if (str_length(curname) < namelen) 197 184 continue; 198 if (strncmp(curname, name, namelen) == 0) { 199 spinlock_unlock(&cmd_lock); 200 return curname+namelen; 201 } 202 } 203 spinlock_unlock(&cmd_lock); 185 186 if (str_lcmp(curname, name, namelen) == 0) { 187 spinlock_unlock(&cmd_lock); 188 return (curname + str_lsize(curname, namelen)); 189 } 190 } 191 192 spinlock_unlock(&cmd_lock); 204 193 return NULL; 205 194 } 206 195 207 208 /** Command completion of the commands 209 * 210 * @param name - string to match, changed to hint on exit 211 * @return number of found matches 212 */ 213 static int cmdtab_compl(char *name) 214 { 215 static char output[/*MAX_SYMBOL_NAME*/128 + 1]; 216 link_t *startpos = NULL; 217 const char *foundtxt; 218 int found = 0; 219 int i; 220 221 output[0] = '\0'; 222 while ((foundtxt = cmdtab_search_one(name, &startpos))) { 223 startpos = startpos->next; 224 if (!found) 225 strncpy(output, foundtxt, str_size(foundtxt) + 1); 226 else { 227 for (i = 0; output[i] && foundtxt[i] && 228 output[i] == foundtxt[i]; i++) 229 ; 230 output[i] = '\0'; 231 } 196 /** Command completion of the commands 197 * 198 * @param name String to match, changed to hint on exit 199 * @param size Input buffer size 200 * 201 * @return Number of found matches 202 * 203 */ 204 static int cmdtab_compl(char *input, size_t size) 205 { 206 const char *name = input; 207 208 count_t found = 0; 209 link_t *pos = NULL; 210 const char *hint; 211 char output[MAX_CMDLINE]; 212 213 output[0] = 0; 214 215 while ((hint = cmdtab_search_one(name, &pos))) { 216 if ((found == 0) || (str_length(output) > str_length(hint))) 217 str_ncpy(output, hint, MAX_CMDLINE); 218 219 pos = pos->next; 232 220 found++; 233 221 } 234 if (!found) 235 return 0; 236 237 if (found > 1 && !str_size(output)) { 222 223 if ((found > 1) && (str_length(output) != 0)) { 238 224 printf("\n"); 239 startpos = NULL; 240 while ((foundtxt = cmdtab_search_one(name, &startpos))) { 241 cmd_info_t *hlp; 242 hlp = list_get_instance(startpos, cmd_info_t, link); 243 printf("%s - %s\n", hlp->name, hlp->description); 244 startpos = startpos->next; 245 } 246 } 247 strncpy(name, output, 128/*MAX_SYMBOL_NAME*/); 225 pos = NULL; 226 while ((hint = cmdtab_search_one(name, &pos))) { 227 cmd_info_t *hlp = list_get_instance(pos, cmd_info_t, link); 228 printf("%s (%s)\n", hlp->name, hlp->description); 229 pos = pos->next; 230 } 231 } 232 233 if (found > 0) 234 str_ncpy(input, output, size); 235 248 236 return found; 249 237 } 250 238 251 static char *clever_readline(const char *prompt, indev_t *input) 252 { 253 static int histposition = 0; 254 255 static char tmp[MAX_CMDLINE + 1]; 256 int curlen = 0, position = 0; 257 char *current = history[histposition]; 258 int i; 259 char mod; /* Command Modifier */ 260 char c; 261 239 static wchar_t *clever_readline(const char *prompt, indev_t *indev) 240 { 262 241 printf("%s> ", prompt); 263 while (1) { 264 c = _getc(input); 265 if (c == '\n') { 266 putchar(c); 242 243 count_t position = 0; 244 wchar_t *current = history[history_pos]; 245 current[0] = 0; 246 247 while (true) { 248 wchar_t ch = _getc(indev); 249 250 if (ch == '\n') { 251 /* Enter */ 252 putchar(ch); 267 253 break; 268 254 } 269 if (c == '\b') { /* Backspace */ 255 256 if (ch == '\b') { 257 /* Backspace */ 270 258 if (position == 0) 271 259 continue; 272 for (i = position; i < curlen; i++) 273 current[i - 1] = current[i]; 274 curlen--; 275 position--; 276 putchar('\b'); 277 for (i = position; i < curlen; i++) 278 putchar(current[i]); 279 putchar(' '); 280 rdln_print_c('\b', curlen - position + 1); 281 continue; 282 } 283 if (c == '\t') { /* Tabulator */ 284 int found; 285 260 261 if (wstr_remove(current, position - 1)) { 262 putchar('\b'); 263 printf("%ls", current + position); 264 position--; 265 print_cc('\b', wstr_length(current) - position); 266 continue; 267 } 268 } 269 270 if (ch == '\t') { 271 /* Tab completion */ 272 286 273 /* Move to the end of the word */ 287 for (; position < curlen && current[position] != ' ';274 for (; (current[position] != 0) && (!isspace(current[position])); 288 275 position++) 289 276 putchar(current[position]); 290 /* Copy to tmp last word */ 291 for (i = position - 1; i >= 0 && current[i] != ' '; i--) 292 ; 293 /* If word begins with * or &, skip it */ 294 if (tmp[0] == '*' || tmp[0] == '&') 295 for (i = 1; tmp[i]; i++) 296 tmp[i - 1] = tmp[i]; 297 i++; /* I is at the start of the word */ 298 strncpy(tmp, current + i, position - i + 1); 299 300 if (i == 0) { /* Command completion */ 301 found = cmdtab_compl(tmp); 302 } else { /* Symtab completion */ 303 found = symtab_compl(tmp); 277 278 if (position == 0) 279 continue; 280 281 /* Find the beginning of the word 282 and copy it to tmp */ 283 count_t beg; 284 for (beg = position - 1; (beg > 0) && (!isspace(current[beg])); 285 beg--); 286 287 if (isspace(current[beg])) 288 beg++; 289 290 char tmp[STR_BOUNDS(MAX_CMDLINE)]; 291 wstr_nstr(tmp, current + beg, position - beg + 1); 292 293 int found; 294 if (beg == 0) { 295 /* Command completion */ 296 found = cmdtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE)); 297 } else { 298 /* Symbol completion */ 299 found = symtab_compl(tmp, STR_BOUNDS(MAX_CMDLINE)); 304 300 } 305 306 if (found == 0) 301 302 if (found == 0) 307 303 continue; 308 for (i = 0; tmp[i] && curlen < MAX_CMDLINE; 309 i++, curlen++) 310 insert_char(current, tmp[i], i + position); 311 312 if (str_size(tmp) || found == 1) { /* If we have a hint */ 313 for (i = position; i < curlen; i++) 314 putchar(current[i]); 315 position += str_size(tmp); 316 /* Add space to end */ 317 if (found == 1 && position == curlen && 318 curlen < MAX_CMDLINE) { 319 current[position] = ' '; 320 curlen++; 321 position++; 322 putchar(' '); 304 305 size_t off = 0; 306 count_t i = 0; 307 while ((ch = str_decode(tmp, &off, STR_NO_LIMIT)) != 0) { 308 if (!wstr_linsert(current, ch, position + i, MAX_CMDLINE)) 309 break; 310 i++; 311 } 312 313 if ((str_length(tmp) > 0) || (found == 1)) { 314 /* We have a hint */ 315 printf("%ls", current + position); 316 print_cc('\b', wstr_length(current) - position); 317 position += str_length(tmp); 318 319 if ((found == 1) && (position == wstr_length(current))) { 320 if (wstr_linsert(current, ' ', position, MAX_CMDLINE)) { 321 printf("%ls", current + position); 322 position++; 323 } 323 324 } 324 } else { /* No hint, table was printed */ 325 } else { 326 /* No unique hint, list was printed */ 325 327 printf("%s> ", prompt); 326 for (i = 0; i < curlen; i++) 327 putchar(current[i]); 328 position += str_size(tmp); 328 printf("%ls", current); 329 position += str_length(tmp); 329 330 } 330 rdln_print_c('\b', curlen - position); 331 332 print_cc('\b', wstr_length(current) - position); 331 333 continue; 332 334 } 333 if (c == 0x1b) { /* Special command */ 334 mod = _getc(input); 335 c = _getc(input); 336 337 if (mod != 0x5b && mod != 0x4f) 335 336 if (ch == 0x1b) { 337 /* Special command */ 338 wchar_t mod = _getc(indev); 339 wchar_t ch = _getc(indev); 340 341 if ((mod != 0x5b) && (mod != 0x4f)) 338 342 continue; 339 340 if ( c == 0x33 && _getc(input) == 0x7e) {343 344 if ((ch == 0x33) && (_getc(indev) == 0x7e)) { 341 345 /* Delete */ 342 if (position == curlen)346 if (position == wstr_length(current)) 343 347 continue; 344 for (i = position + 1; i < curlen; i++) { 345 putchar(current[i]); 346 current[i - 1] = current[i]; 348 349 if (wstr_remove(current, position)) { 350 putchar('\b'); 351 printf("%ls", current + position); 352 position--; 353 print_cc('\b', wstr_length(current) - position); 347 354 } 348 putchar(' '); 349 rdln_print_c('\b', curlen - position); 350 curlen--; 351 } else if (c == 0x48) { /* Home */ 352 rdln_print_c('\b', position); 355 } else if (ch == 0x48) { 356 /* Home */ 357 print_cc('\b', position); 353 358 position = 0; 354 } else if (c == 0x46) { /* End */ 355 for (i = position; i < curlen; i++) 356 putchar(current[i]); 357 position = curlen; 358 } else if (c == 0x44) { /* Left */ 359 } else if (ch == 0x46) { 360 /* End */ 361 printf("%ls", current + position); 362 position = wstr_length(current); 363 } else if (ch == 0x44) { 364 /* Left */ 359 365 if (position > 0) { 360 366 putchar('\b'); 361 367 position--; 362 368 } 363 continue;364 } else if (c == 0x43) {/* Right */365 if (position < curlen) {369 } else if (ch == 0x43) { 370 /* Right */ 371 if (position < wstr_length(current)) { 366 372 putchar(current[position]); 367 373 position++; 368 374 } 369 continue;370 } else if (c == 0x41 || c == 0x42) {371 /* Up, down */ 372 rdln_print_c('\b', position);373 rdln_print_c(' ', curlen);374 rdln_print_c('\b', curlen);375 if (c == 0x41) /* Up */376 histposition--;377 else378 histposition++;379 if (histposition < 0) {380 histposition = KCONSOLE_HISTORY - 1;375 } else if ((ch == 0x41) || (ch == 0x42)) { 376 /* Up, down */ 377 print_cc('\b', position); 378 print_cc(' ', wstr_length(current)); 379 print_cc('\b', wstr_length(current)); 380 381 if (ch == 0x41) { 382 /* Up */ 383 if (history_pos == 0) 384 history_pos = KCONSOLE_HISTORY - 1; 385 else 386 history_pos--; 381 387 } else { 382 histposition = 383 histposition % KCONSOLE_HISTORY; 388 /* Down */ 389 history_pos++; 390 history_pos = history_pos % KCONSOLE_HISTORY; 384 391 } 385 current = history[histposition]; 386 printf("%s", current); 387 curlen = str_size(current); 388 position = curlen; 389 continue; 392 current = history[history_pos]; 393 printf("%ls", current); 394 position = wstr_length(current); 390 395 } 391 396 continue; 392 397 } 393 if (curlen >= MAX_CMDLINE) 394 continue; 395 396 insert_char(current, c, position); 397 398 curlen++; 399 for (i = position; i < curlen; i++) 400 putchar(current[i]); 401 position++; 402 rdln_print_c('\b',curlen - position); 403 } 404 if (curlen) { 405 histposition++; 406 histposition = histposition % KCONSOLE_HISTORY; 407 } 408 current[curlen] = '\0'; 398 399 if (wstr_linsert(current, ch, position, MAX_CMDLINE)) { 400 printf("%ls", current + position); 401 position++; 402 print_cc('\b', wstr_length(current) - position); 403 } 404 } 405 406 if (wstr_length(current) > 0) { 407 history_pos++; 408 history_pos = history_pos % KCONSOLE_HISTORY; 409 } 410 409 411 return current; 410 412 } … … 415 417 } 416 418 417 /** Kernel console prompt. 418 * 419 * @param prompt Kernel console prompt (e.g kconsole/panic). 420 * @param msg Message to display in the beginning. 421 * @param kcon Wait for keypress to show the prompt 422 * and never exit. 423 * 424 */ 425 void kconsole(char *prompt, char *msg, bool kcon) 426 { 427 cmd_info_t *cmd_info; 428 count_t len; 429 char *cmdline; 430 431 if (!stdin) { 432 LOG("No stdin for kernel console"); 433 return; 434 } 435 436 if (msg) 437 printf("%s", msg); 438 439 if (kcon) 440 _getc(stdin); 441 else 442 printf("Type \"exit\" to leave the console.\n"); 443 444 while (true) { 445 cmdline = clever_readline((char *) prompt, stdin); 446 len = str_size(cmdline); 447 if (!len) 448 continue; 449 450 if ((!kcon) && (len == 4) && (strncmp(cmdline, "exit", 4) == 0)) 451 break; 452 453 cmd_info = parse_cmdline(cmdline, len); 454 if (!cmd_info) 455 continue; 456 457 (void) cmd_info->func(cmd_info->argv); 458 } 459 } 460 461 /** Kernel console managing thread. 462 * 463 */ 464 void kconsole_thread(void *data) 465 { 466 kconsole("kconsole", "Kernel console ready (press any key to activate)\n", true); 467 } 468 469 static int parse_int_arg(char *text, size_t len, unative_t *result) 470 { 471 uintptr_t symaddr; 419 static bool parse_int_arg(const char *text, size_t len, unative_t *result) 420 { 472 421 bool isaddr = false; 473 422 bool isptr = false; 474 int rc;475 476 static char symname[MAX_SYMBOL_NAME];477 423 478 424 /* If we get a name, try to find it in symbol table */ … … 486 432 len--; 487 433 } 488 if (text[0] < '0' || text[0] > '9') { 489 strncpy(symname, text, min(len + 1, MAX_SYMBOL_NAME)); 490 rc = symtab_addr_lookup(symname, &symaddr); 434 435 if ((text[0] < '0') || (text[0] > '9')) { 436 char symname[MAX_SYMBOL_NAME]; 437 str_ncpy(symname, text, min(len + 1, MAX_SYMBOL_NAME)); 438 439 uintptr_t symaddr; 440 int rc = symtab_addr_lookup(symname, &symaddr); 491 441 switch (rc) { 492 442 case ENOENT: 493 443 printf("Symbol %s not found.\n", symname); 494 return -1;444 return false; 495 445 case EOVERFLOW: 496 446 printf("Duplicate symbol %s.\n", symname); 497 447 symtab_print_search(symname); 498 return -1;499 default:448 return false; 449 case ENOTSUP: 500 450 printf("No symbol information available.\n"); 501 return -1;502 } 503 451 return false; 452 } 453 504 454 if (isaddr) 505 *result = (unative_t) symaddr;455 *result = (unative_t) symaddr; 506 456 else if (isptr) 507 *result = **((unative_t **) symaddr);457 *result = **((unative_t **) symaddr); 508 458 else 509 *result = *((unative_t *)symaddr); 510 } else { /* It's a number - convert it */ 459 *result = *((unative_t *) symaddr); 460 } else { 461 /* It's a number - convert it */ 511 462 *result = atoi(text); 512 463 if (isptr) 513 *result = *((unative_t *)*result); 514 } 515 516 return 0; 464 *result = *((unative_t *) *result); 465 } 466 467 return true; 468 } 469 470 /** Parse argument. 471 * 472 * Find start and end positions of command line argument. 473 * 474 * @param cmdline Command line as read from the input device. 475 * @param size Size (in bytes) of the string. 476 * @param start On entry, 'start' contains pointer to the offset 477 * of the first unprocessed character of cmdline. 478 * On successful exit, it marks beginning of the next argument. 479 * @param end Undefined on entry. On exit, 'end' is the offset of the first 480 * character behind the next argument. 481 * 482 * @return False on failure, true on success. 483 * 484 */ 485 static bool parse_argument(const char *cmdline, size_t size, size_t *start, size_t *end) 486 { 487 ASSERT(start != NULL); 488 ASSERT(end != NULL); 489 490 bool found_start = false; 491 size_t offset = *start; 492 size_t prev = *start; 493 wchar_t ch; 494 495 while ((ch = str_decode(cmdline, &offset, size)) != 0) { 496 if (!found_start) { 497 if (!isspace(ch)) { 498 *start = prev; 499 found_start = true; 500 } 501 } else { 502 if (isspace(ch)) 503 break; 504 } 505 506 prev = offset; 507 } 508 *end = offset; 509 510 return found_start; 517 511 } 518 512 519 513 /** Parse command line. 520 514 * 521 * @param cmdline Command line as read from input device. 522 * @param len Command line length.515 * @param cmdline Command line as read from input device. 516 * @param size Size (in bytes) of the string. 523 517 * 524 518 * @return Structure describing the command. 525 */ 526 cmd_info_t *parse_cmdline(char *cmdline, size_t len) 527 { 528 index_t start = 0, end = 0; 519 * 520 */ 521 static cmd_info_t *parse_cmdline(const char *cmdline, size_t size) 522 { 523 size_t start = 0; 524 size_t end = 0; 525 if (!parse_argument(cmdline, size, &start, &end)) { 526 /* Command line did not contain alphanumeric word. */ 527 return NULL; 528 } 529 spinlock_lock(&cmd_lock); 530 529 531 cmd_info_t *cmd = NULL; 530 532 link_t *cur; 531 count_t i;532 int error = 0;533 534 if (!parse_argument(cmdline, len, &start, &end)) {535 /* Command line did not contain alphanumeric word. */536 return NULL;537 }538 539 spinlock_lock(&cmd_lock);540 533 541 534 for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) { 542 cmd_info_t *hlp; 543 544 hlp = list_get_instance(cur, cmd_info_t, link); 535 cmd_info_t *hlp = list_get_instance(cur, cmd_info_t, link); 545 536 spinlock_lock(&hlp->lock); 546 537 547 if (strncmp(hlp->name, &cmdline[start], max(str_size(hlp->name), 548 end - start + 1)) == 0) { 538 if (str_lcmp(hlp->name, cmdline + start, 539 max(str_length(hlp->name), 540 str_nlength(cmdline + start, (count_t) (end - start) - 1))) == 0) { 549 541 cmd = hlp; 550 542 break; … … 554 546 } 555 547 556 spinlock_unlock(&cmd_lock); 548 spinlock_unlock(&cmd_lock); 557 549 558 550 if (!cmd) { … … 561 553 return NULL; 562 554 } 563 555 564 556 /* cmd == hlp is locked */ 565 557 … … 570 562 * structure. 571 563 */ 572 564 565 bool error = false; 566 count_t i; 573 567 for (i = 0; i < cmd->argc; i++) { 574 char *buf; 575 start = end + 1; 576 if (!parse_argument(cmdline, len, &start, &end)) { 568 start = end; 569 if (!parse_argument(cmdline, size, &start, &end)) { 577 570 printf("Too few arguments.\n"); 578 571 spinlock_unlock(&cmd->lock); … … 580 573 } 581 574 582 error = 0;575 char *buf; 583 576 switch (cmd->argv[i].type) { 584 577 case ARG_TYPE_STRING: 585 578 buf = (char *) cmd->argv[i].buffer; 586 strncpy(buf, (const char *) &cmdline[start], 587 min((end - start) + 2, cmd->argv[i].len)); 588 buf[min((end - start) + 1, cmd->argv[i].len - 1)] = 589 '\0'; 579 str_ncpy(buf, cmdline + start, 580 min((end - start) + 1, cmd->argv[i].len)); 590 581 break; 591 case ARG_TYPE_INT: 592 if ( parse_int_arg(cmdline + start, end - start + 1,582 case ARG_TYPE_INT: 583 if (!parse_int_arg(cmdline + start, end - start, 593 584 &cmd->argv[i].intval)) 594 error = 1;585 error = true; 595 586 break; 596 587 case ARG_TYPE_VAR: 597 if (start != end && cmdline[start] == '"' && 598 cmdline[end] == '"') { 599 buf = (char *) cmd->argv[i].buffer; 600 strncpy(buf, (const char *) &cmdline[start + 1], 601 min((end-start), cmd->argv[i].len)); 602 buf[min((end - start), cmd->argv[i].len - 1)] = 603 '\0'; 604 cmd->argv[i].intval = (unative_t) buf; 605 cmd->argv[i].vartype = ARG_TYPE_STRING; 606 } else if (!parse_int_arg(cmdline + start, 607 end - start + 1, &cmd->argv[i].intval)) { 588 if ((start < end - 1) && (cmdline[start] == '"')) { 589 if (cmdline[end - 1] == '"') { 590 buf = (char *) cmd->argv[i].buffer; 591 str_ncpy(buf, cmdline + start + 1, 592 min((end - start) - 1, cmd->argv[i].len)); 593 cmd->argv[i].intval = (unative_t) buf; 594 cmd->argv[i].vartype = ARG_TYPE_STRING; 595 } else { 596 printf("Wrong synxtax.\n"); 597 error = true; 598 } 599 } else if (parse_int_arg(cmdline + start, 600 end - start, &cmd->argv[i].intval)) { 608 601 cmd->argv[i].vartype = ARG_TYPE_INT; 609 602 } else { 610 603 printf("Unrecognized variable argument.\n"); 611 error = 1;604 error = true; 612 605 } 613 606 break; 614 607 case ARG_TYPE_INVALID: 615 608 default: 616 printf(" invalid argument type\n");617 error = 1;609 printf("Invalid argument type\n"); 610 error = true; 618 611 break; 619 612 } … … 625 618 } 626 619 627 start = end + 1;628 if (parse_argument(cmdline, len, &start, &end)) {620 start = end; 621 if (parse_argument(cmdline, size, &start, &end)) { 629 622 printf("Too many arguments.\n"); 630 623 spinlock_unlock(&cmd->lock); … … 636 629 } 637 630 638 /** Parse argument. 639 * 640 * Find start and end positions of command line argument. 641 * 642 * @param cmdline Command line as read from the input device. 643 * @param len Number of characters in cmdline. 644 * @param start On entry, 'start' contains pointer to the index 645 * of first unprocessed character of cmdline. 646 * On successful exit, it marks beginning of the next argument. 647 * @param end Undefined on entry. On exit, 'end' points to the last character 648 * of the next argument. 649 * 650 * @return false on failure, true on success. 651 */ 652 bool parse_argument(char *cmdline, size_t len, index_t *start, index_t *end) 653 { 654 index_t i; 655 bool found_start = false; 656 657 ASSERT(start != NULL); 658 ASSERT(end != NULL); 659 660 for (i = *start; i < len; i++) { 661 if (!found_start) { 662 if (isspace(cmdline[i])) 663 (*start)++; 664 else 665 found_start = true; 666 } else { 667 if (isspace(cmdline[i])) 668 break; 669 } 670 } 671 *end = i - 1; 672 673 return found_start; 631 /** Kernel console prompt. 632 * 633 * @param prompt Kernel console prompt (e.g kconsole/panic). 634 * @param msg Message to display in the beginning. 635 * @param kcon Wait for keypress to show the prompt 636 * and never exit. 637 * 638 */ 639 void kconsole(char *prompt, char *msg, bool kcon) 640 { 641 if (!stdin) { 642 LOG("No stdin for kernel console"); 643 return; 644 } 645 646 if (msg) 647 printf("%s", msg); 648 649 if (kcon) 650 _getc(stdin); 651 else 652 printf("Type \"exit\" to leave the console.\n"); 653 654 while (true) { 655 wchar_t *tmp = clever_readline((char *) prompt, stdin); 656 count_t len = wstr_length(tmp); 657 if (!len) 658 continue; 659 660 char cmdline[STR_BOUNDS(MAX_CMDLINE)]; 661 wstr_nstr(cmdline, tmp, STR_BOUNDS(MAX_CMDLINE)); 662 663 if ((!kcon) && (len == 4) && (str_lcmp(cmdline, "exit", 4) == 0)) 664 break; 665 666 cmd_info_t *cmd_info = parse_cmdline(cmdline, STR_BOUNDS(MAX_CMDLINE)); 667 if (!cmd_info) 668 continue; 669 670 (void) cmd_info->func(cmd_info->argv); 671 } 672 } 673 674 /** Kernel console managing thread. 675 * 676 */ 677 void kconsole_thread(void *data) 678 { 679 kconsole("kconsole", "Kernel console ready (press any key to activate)\n", true); 674 680 } 675 681
Note:
See TracChangeset
for help on using the changeset viewer.