Changeset a35b458 in mainline for kernel/generic/src/console/kconsole.c
- Timestamp:
- 2018-03-02T20:10:49Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f1380b7
- Parents:
- 3061bc1
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/console/kconsole.c
r3061bc1 ra35b458 98 98 { 99 99 unsigned int i; 100 100 101 101 cmd_init(); 102 102 for (i = 0; i < KCONSOLE_HISTORY; i++) … … 114 114 { 115 115 spinlock_lock(&cmd_lock); 116 116 117 117 /* 118 118 * Make sure the command is not already listed. … … 124 124 return false; 125 125 } 126 126 127 127 /* Avoid deadlock. */ 128 128 if (hlp < cmd) { … … 133 133 spinlock_lock(&hlp->lock); 134 134 } 135 135 136 136 if (str_cmp(hlp->name, cmd->name) == 0) { 137 137 /* The command is already there. */ … … 141 141 return false; 142 142 } 143 143 144 144 spinlock_unlock(&hlp->lock); 145 145 spinlock_unlock(&cmd->lock); 146 146 } 147 147 148 148 /* 149 149 * Now the command can be added. 150 150 */ 151 151 list_append(&cmd->link, &cmd_list); 152 152 153 153 spinlock_unlock(&cmd_lock); 154 154 return true; … … 168 168 link_t **startpos = (link_t**) ctx; 169 169 size_t namelen = str_length(name); 170 170 171 171 spinlock_lock(&cmd_lock); 172 172 173 173 if (*startpos == NULL) 174 174 *startpos = cmd_list.head.next; 175 175 176 176 for (; *startpos != &cmd_list.head; *startpos = (*startpos)->next) { 177 177 cmd_info_t *hlp = list_get_instance(*startpos, cmd_info_t, link); 178 178 179 179 const char *curname = hlp->name; 180 180 if (str_length(curname) < namelen) 181 181 continue; 182 182 183 183 if (str_lcmp(curname, name, namelen) == 0) { 184 184 *startpos = (*startpos)->next; 185 185 if (h) 186 186 *h = hlp->description; 187 187 188 188 spinlock_unlock(&cmd_lock); 189 189 return (curname + str_lsize(curname, namelen)); 190 190 } 191 191 } 192 192 193 193 spinlock_unlock(&cmd_lock); 194 194 return NULL; … … 207 207 { 208 208 const char *name = input; 209 209 210 210 size_t found = 0; 211 211 212 212 /* 213 213 * Maximum Match Length: Length of longest matching common … … 223 223 size_t total_hints_shown = 0; 224 224 bool continue_showing_hints = true; 225 225 226 226 output[0] = 0; 227 227 228 228 while ((hint = hints_enum(name, NULL, &pos))) { 229 229 if ((found == 0) || (str_length(hint) > str_length(output))) 230 230 str_cpy(output, MAX_CMDLINE, hint); 231 231 232 232 found++; 233 233 } 234 234 235 235 /* 236 236 * If the number of possible completions is more than MAX_TAB_HINTS, … … 242 242 console_prompt_display_all_hints(indev, found); 243 243 } 244 244 245 245 if ((found > 1) && (str_length(output) != 0)) { 246 246 printf("\n"); 247 247 pos = NULL; 248 248 while ((hint = hints_enum(name, &help, &pos))) { 249 249 250 250 if (continue_showing_hints) { 251 251 if (help) … … 253 253 else 254 254 printf("%s%s\n", name, hint); 255 255 256 256 --hints_to_show; 257 257 ++total_hints_shown; 258 258 259 259 if ((hints_to_show == 0) && (total_hints_shown != found)) { 260 260 /* Ask user to continue */ … … 263 263 } 264 264 } 265 265 266 266 for (max_match_len_tmp = 0; 267 267 (output[max_match_len_tmp] == 268 268 hint[max_match_len_tmp]) && 269 269 (max_match_len_tmp < max_match_len); ++max_match_len_tmp); 270 270 271 271 max_match_len = max_match_len_tmp; 272 272 } 273 273 274 274 /* Keep only the characters common in all completions */ 275 275 output[max_match_len] = 0; 276 276 } 277 277 278 278 if (found > 0) 279 279 str_cpy(input, size, output); 280 280 281 281 free(output); 282 282 return found; … … 288 288 size_t end; 289 289 char *tmp; 290 290 291 291 while (isspace(cmdline[start])) 292 292 start++; 293 293 294 294 end = start + 1; 295 295 296 296 while (!isspace(cmdline[end])) 297 297 end++; 298 298 299 299 tmp = malloc(STR_BOUNDS(end - start + 1), 0); 300 300 301 301 wstr_to_str(tmp, end - start + 1, &cmdline[start]); 302 302 303 303 spinlock_lock(&cmd_lock); 304 304 305 305 list_foreach(cmd_list, link, cmd_info_t, hlp) { 306 306 spinlock_lock(&hlp->lock); 307 307 308 308 if (str_cmp(hlp->name, tmp) == 0) { 309 309 spinlock_unlock(&hlp->lock); … … 312 312 return hlp; 313 313 } 314 314 315 315 spinlock_unlock(&hlp->lock); 316 316 } 317 317 318 318 free(tmp); 319 319 spinlock_unlock(&cmd_lock); 320 320 321 321 return NULL; 322 322 } … … 325 325 { 326 326 printf("%s> ", prompt); 327 327 328 328 size_t position = 0; 329 329 wchar_t *current = history[history_pos]; 330 330 current[0] = 0; 331 331 char *tmp = malloc(STR_BOUNDS(MAX_CMDLINE), 0); 332 332 333 333 while (true) { 334 334 wchar_t ch = indev_pop_character(indev); 335 335 336 336 if (ch == '\n') { 337 337 /* Enter */ … … 339 339 break; 340 340 } 341 341 342 342 if (ch == '\b') { 343 343 /* Backspace */ 344 344 if (position == 0) 345 345 continue; 346 346 347 347 if (wstr_remove(current, position - 1)) { 348 348 position--; … … 353 353 } 354 354 } 355 355 356 356 if (ch == '\t') { 357 357 /* Tab completion */ 358 358 359 359 /* Move to the end of the word */ 360 360 for (; (current[position] != 0) && (!isspace(current[position])); 361 361 position++) 362 362 putchar(current[position]); 363 364 363 364 365 365 /* 366 366 * Find the beginning of the word … … 376 376 (beg > 0) && (!isspace(current[beg])); 377 377 beg--); 378 378 379 379 if (isspace(current[beg])) 380 380 beg++; 381 381 382 382 wstr_to_str(tmp, position - beg + 1, current + beg); 383 383 } 384 384 385 385 /* Count which argument number are we tabbing (narg=0 is cmd) */ 386 386 bool sp = false; … … 394 394 sp = false; 395 395 } 396 396 397 397 if (narg && isspace(current[0])) 398 398 narg--; 399 399 400 400 int found; 401 401 if (narg == 0) { … … 411 411 cmd->hints_enum); 412 412 } 413 413 414 414 if (found == 0) 415 415 continue; … … 424 424 if (!wstr_linsert(current, ch, position + i, MAX_CMDLINE)) 425 425 break; 426 426 427 427 i++; 428 428 } 429 429 430 430 if (found > 1) { 431 431 /* No unique hint, list was printed */ … … 436 436 continue; 437 437 } 438 438 439 439 /* We have a hint */ 440 440 441 441 printf("%ls", current + position); 442 442 position += str_length(tmp); 443 443 print_cc('\b', wstr_length(current) - position); 444 444 445 445 if (position == wstr_length(current)) { 446 446 /* Insert a space after the last completed argument */ … … 452 452 continue; 453 453 } 454 454 455 455 if (ch == U_LEFT_ARROW) { 456 456 /* Left */ … … 461 461 continue; 462 462 } 463 463 464 464 if (ch == U_RIGHT_ARROW) { 465 465 /* Right */ … … 470 470 continue; 471 471 } 472 472 473 473 if ((ch == U_UP_ARROW) || (ch == U_DOWN_ARROW)) { 474 474 /* Up, down */ … … 476 476 print_cc(' ', wstr_length(current)); 477 477 print_cc('\b', wstr_length(current)); 478 478 479 479 if (ch == U_UP_ARROW) { 480 480 /* Up */ … … 493 493 continue; 494 494 } 495 495 496 496 if (ch == U_HOME_ARROW) { 497 497 /* Home */ … … 500 500 continue; 501 501 } 502 502 503 503 if (ch == U_END_ARROW) { 504 504 /* End */ … … 507 507 continue; 508 508 } 509 509 510 510 if (ch == U_DELETE) { 511 511 /* Delete */ 512 512 if (position == wstr_length(current)) 513 513 continue; 514 514 515 515 if (wstr_remove(current, position)) { 516 516 printf("%ls ", current + position); … … 519 519 continue; 520 520 } 521 521 522 522 if (wstr_linsert(current, ch, position, MAX_CMDLINE)) { 523 523 printf("%ls", current + position); … … 526 526 } 527 527 } 528 528 529 529 if (wstr_length(current) > 0) { 530 530 history_pos++; 531 531 history_pos = history_pos % KCONSOLE_HISTORY; 532 532 } 533 533 534 534 free(tmp); 535 535 return current; … … 546 546 bool isaddr = false; 547 547 bool isptr = false; 548 548 549 549 /* If we get a name, try to find it in symbol table */ 550 550 if (text[0] == '&') { … … 557 557 len--; 558 558 } 559 559 560 560 if ((text[0] < '0') || (text[0] > '9')) { 561 561 char symname[MAX_SYMBOL_NAME]; 562 562 str_ncpy(symname, MAX_SYMBOL_NAME, text, len + 1); 563 563 564 564 uintptr_t symaddr; 565 565 errno_t rc = symtab_addr_lookup(symname, &symaddr); … … 611 611 } 612 612 } 613 613 614 614 return true; 615 615 } … … 635 635 assert(start != NULL); 636 636 assert(end != NULL); 637 637 638 638 bool found_start = false; 639 639 size_t offset = *start; 640 640 size_t prev = *start; 641 641 wchar_t ch; 642 642 643 643 while ((ch = str_decode(cmdline, &offset, size)) != 0) { 644 644 if (!found_start) { … … 651 651 break; 652 652 } 653 653 654 654 prev = offset; 655 655 } 656 656 *end = prev; 657 657 658 658 return found_start; 659 659 } … … 676 676 } 677 677 spinlock_lock(&cmd_lock); 678 678 679 679 cmd_info_t *cmd = NULL; 680 680 681 681 list_foreach(cmd_list, link, cmd_info_t, hlp) { 682 682 spinlock_lock(&hlp->lock); 683 683 684 684 if (str_lcmp(hlp->name, cmdline + start, 685 685 max(str_length(hlp->name), … … 688 688 break; 689 689 } 690 690 691 691 spinlock_unlock(&hlp->lock); 692 692 } 693 693 694 694 spinlock_unlock(&cmd_lock); 695 695 696 696 if (!cmd) { 697 697 /* Unknown command. */ … … 699 699 return NULL; 700 700 } 701 701 702 702 /* cmd == hlp is locked */ 703 703 704 704 /* 705 705 * The command line must be further analyzed and … … 708 708 * structure. 709 709 */ 710 710 711 711 bool error = false; 712 712 size_t i; 713 713 for (i = 0; i < cmd->argc; i++) { 714 714 char *buf; 715 715 716 716 start = end; 717 717 if (!parse_argument(cmdline, size, &start, &end)) { … … 721 721 continue; 722 722 } 723 723 724 724 printf("Too few arguments.\n"); 725 725 spinlock_unlock(&cmd->lock); 726 726 return NULL; 727 727 } 728 728 729 729 switch (cmd->argv[i].type) { 730 730 case ARG_TYPE_STRING: … … 767 767 } 768 768 } 769 769 770 770 if (error) { 771 771 spinlock_unlock(&cmd->lock); 772 772 return NULL; 773 773 } 774 774 775 775 start = end; 776 776 if (parse_argument(cmdline, size, &start, &end)) { … … 779 779 return NULL; 780 780 } 781 781 782 782 spinlock_unlock(&cmd->lock); 783 783 return cmd; … … 798 798 return; 799 799 } 800 800 801 801 if (msg) 802 802 printf("%s", msg); 803 803 804 804 if (kcon) 805 805 indev_pop_character(stdin); 806 806 else 807 807 printf("Type \"exit\" to leave the console.\n"); 808 808 809 809 char *cmdline = malloc(STR_BOUNDS(MAX_CMDLINE), 0); 810 810 while (true) { … … 813 813 if (!len) 814 814 continue; 815 815 816 816 wstr_to_str(cmdline, STR_BOUNDS(MAX_CMDLINE), tmp); 817 817 818 818 if ((!kcon) && (len == 4) && (str_lcmp(cmdline, "exit", 4) == 0)) 819 819 break; 820 820 821 821 cmd_info_t *cmd_info = parse_cmdline(cmdline, STR_BOUNDS(MAX_CMDLINE)); 822 822 if (!cmd_info) 823 823 continue; 824 824 825 825 (void) cmd_info->func(cmd_info->argv); 826 826 }
Note:
See TracChangeset
for help on using the changeset viewer.