Changeset a35b458 in mainline for kernel/generic/src/console
- 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)
- Location:
- kernel/generic/src/console
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/generic/src/console/chardev.c
r3061bc1 ra35b458 68 68 { 69 69 assert(indev); 70 70 71 71 irq_spinlock_lock(&indev->lock, true); 72 72 if (indev->counter == INDEV_BUFLEN - 1) { … … 75 75 return; 76 76 } 77 77 78 78 indev->counter++; 79 79 indev->buffer[indev->index++] = ch; 80 80 81 81 /* Index modulo size of buffer */ 82 82 indev->index = indev->index % INDEV_BUFLEN; … … 102 102 if (check_poll(indev)) 103 103 return indev->op->poll(indev); 104 104 105 105 /* No other way of interacting with user */ 106 106 interrupts_disable(); 107 107 108 108 if (CPU) 109 109 printf("cpu%u: ", CPU->id); 110 110 else 111 111 printf("cpu: "); 112 112 113 113 printf("halted (no polling input)\n"); 114 114 cpu_halt(); 115 115 } 116 116 117 117 waitq_sleep(&indev->wq); 118 118 irq_spinlock_lock(&indev->lock, true); … … 121 121 indev->counter--; 122 122 irq_spinlock_unlock(&indev->lock, true); 123 123 124 124 return ch; 125 125 } … … 158 158 if (indev == NULL) 159 159 return false; 160 160 161 161 if (indev->op == NULL) 162 162 return false; 163 163 164 164 return (indev->op->poll != NULL); 165 165 } -
kernel/generic/src/console/cmd.c
r3061bc1 ra35b458 686 686 { 687 687 spinlock_lock(&cmd_lock); 688 688 689 689 size_t len = 0; 690 690 list_foreach(cmd_list, link, cmd_info_t, hlp) { … … 694 694 spinlock_unlock(&hlp->lock); 695 695 } 696 696 697 697 unsigned int _len = (unsigned int) len; 698 698 if ((_len != len) || (((int) _len) < 0)) { … … 700 700 return 1; 701 701 } 702 702 703 703 list_foreach(cmd_list, link, cmd_info_t, hlp) { 704 704 spinlock_lock(&hlp->lock); … … 706 706 spinlock_unlock(&hlp->lock); 707 707 } 708 708 709 709 spinlock_unlock(&cmd_lock); 710 710 711 711 return 1; 712 712 } … … 721 721 { 722 722 uint8_t *ptr = NULL; 723 723 724 724 #ifdef IO_SPACE_BOUNDARY 725 725 if ((void *) argv->intval < IO_SPACE_BOUNDARY) … … 729 729 ptr = (uint8_t *) km_map(argv[0].intval, sizeof(uint8_t), 730 730 PAGE_NOT_CACHEABLE); 731 731 732 732 const uint8_t val = pio_read_8(ptr); 733 733 printf("read %" PRIxn ": %" PRIx8 "\n", argv[0].intval, val); 734 734 735 735 #ifdef IO_SPACE_BOUNDARY 736 736 if ((void *) argv->intval < IO_SPACE_BOUNDARY) 737 737 return 1; 738 738 #endif 739 739 740 740 km_unmap((uintptr_t) ptr, sizeof(uint8_t)); 741 741 return 1; … … 751 751 { 752 752 uint16_t *ptr = NULL; 753 753 754 754 #ifdef IO_SPACE_BOUNDARY 755 755 if ((void *) argv->intval < IO_SPACE_BOUNDARY) … … 759 759 ptr = (uint16_t *) km_map(argv[0].intval, sizeof(uint16_t), 760 760 PAGE_NOT_CACHEABLE); 761 761 762 762 const uint16_t val = pio_read_16(ptr); 763 763 printf("read %" PRIxn ": %" PRIx16 "\n", argv[0].intval, val); 764 764 765 765 #ifdef IO_SPACE_BOUNDARY 766 766 if ((void *) argv->intval < IO_SPACE_BOUNDARY) 767 767 return 1; 768 768 #endif 769 769 770 770 km_unmap((uintptr_t) ptr, sizeof(uint16_t)); 771 771 return 1; … … 781 781 { 782 782 uint32_t *ptr = NULL; 783 783 784 784 #ifdef IO_SPACE_BOUNDARY 785 785 if ((void *) argv->intval < IO_SPACE_BOUNDARY) … … 789 789 ptr = (uint32_t *) km_map(argv[0].intval, sizeof(uint32_t), 790 790 PAGE_NOT_CACHEABLE); 791 791 792 792 const uint32_t val = pio_read_32(ptr); 793 793 printf("read %" PRIxn ": %" PRIx32 "\n", argv[0].intval, val); 794 794 795 795 #ifdef IO_SPACE_BOUNDARY 796 796 if ((void *) argv->intval < IO_SPACE_BOUNDARY) 797 797 return 1; 798 798 #endif 799 799 800 800 km_unmap((uintptr_t) ptr, sizeof(uint32_t)); 801 801 return 1; … … 811 811 { 812 812 uint8_t *ptr = NULL; 813 813 814 814 #ifdef IO_SPACE_BOUNDARY 815 815 if ((void *) argv->intval < IO_SPACE_BOUNDARY) … … 819 819 ptr = (uint8_t *) km_map(argv[0].intval, sizeof(uint8_t), 820 820 PAGE_NOT_CACHEABLE); 821 821 822 822 printf("write %" PRIxn ": %" PRIx8 "\n", argv[0].intval, 823 823 (uint8_t) argv[1].intval); 824 824 pio_write_8(ptr, (uint8_t) argv[1].intval); 825 825 826 826 #ifdef IO_SPACE_BOUNDARY 827 827 if ((void *) argv->intval < IO_SPACE_BOUNDARY) 828 828 return 1; 829 829 #endif 830 830 831 831 km_unmap((uintptr_t) ptr, sizeof(uint8_t)); 832 832 return 1; … … 842 842 { 843 843 uint16_t *ptr = NULL; 844 844 845 845 #ifdef IO_SPACE_BOUNDARY 846 846 if ((void *) argv->intval < IO_SPACE_BOUNDARY) … … 850 850 ptr = (uint16_t *) km_map(argv[0].intval, sizeof(uint16_t), 851 851 PAGE_NOT_CACHEABLE); 852 852 853 853 printf("write %" PRIxn ": %" PRIx16 "\n", argv[0].intval, 854 854 (uint16_t) argv[1].intval); 855 855 pio_write_16(ptr, (uint16_t) argv[1].intval); 856 856 857 857 #ifdef IO_SPACE_BOUNDARY 858 858 if ((void *) argv->intval < IO_SPACE_BOUNDARY) 859 859 return 1; 860 860 #endif 861 861 862 862 km_unmap((uintptr_t) ptr, sizeof(uint16_t)); 863 863 return 1; … … 873 873 { 874 874 uint32_t *ptr = NULL; 875 875 876 876 #ifdef IO_SPACE_BOUNDARY 877 877 if ((void *) argv->intval < IO_SPACE_BOUNDARY) … … 881 881 ptr = (uint32_t *) km_map(argv[0].intval, sizeof(uint32_t), 882 882 PAGE_NOT_CACHEABLE); 883 883 884 884 printf("write %" PRIxn ": %" PRIx32 "\n", argv[0].intval, 885 885 (uint32_t) argv[1].intval); 886 886 pio_write_32(ptr, (uint32_t) argv[1].intval); 887 887 888 888 #ifdef IO_SPACE_BOUNDARY 889 889 if ((void *) argv->intval < IO_SPACE_BOUNDARY) 890 890 return 1; 891 891 #endif 892 892 893 893 km_unmap((uintptr_t) ptr, sizeof(uint32_t)); 894 894 return 1; … … 904 904 { 905 905 reboot(); 906 906 907 907 /* Not reached */ 908 908 return 1; … … 918 918 { 919 919 assert(uptime); 920 920 921 921 /* This doesn't have to be very accurate */ 922 922 sysarg_t sec = uptime->seconds1; 923 923 924 924 printf("Up %" PRIun " days, %" PRIun " hours, %" PRIun " minutes, %" PRIun " seconds\n", 925 925 sec / 86400, (sec % 86400) / 3600, (sec % 3600) / 60, sec % 60); 926 926 927 927 return 1; 928 928 } … … 937 937 { 938 938 spinlock_lock(&cmd_lock); 939 939 940 940 list_foreach(cmd_list, link, cmd_info_t, hlp) { 941 941 spinlock_lock(&hlp->lock); 942 942 943 943 if (str_lcmp(hlp->name, (const char *) argv->buffer, str_length(hlp->name)) == 0) { 944 944 printf("%s - %s\n", hlp->name, hlp->description); … … 948 948 break; 949 949 } 950 950 951 951 spinlock_unlock(&hlp->lock); 952 952 } 953 953 954 954 spinlock_unlock(&cmd_lock); 955 955 956 956 return 1; 957 957 } … … 961 961 { 962 962 symtab_print_search((char *) argv->buffer); 963 963 964 964 return 1; 965 965 } … … 1004 1004 * call the function. 1005 1005 */ 1006 1006 1007 1007 unsigned int i; 1008 1008 for (i = 0; i < config.cpu_count; i++) { 1009 1009 if (!cpus[i].active) 1010 1010 continue; 1011 1011 1012 1012 thread_t *thread; 1013 1013 if ((thread = thread_create((void (*)(void *)) cmd_call0, … … 1021 1021 printf("Unable to create thread for cpu%u\n", i); 1022 1022 } 1023 1023 1024 1024 return 1; 1025 1025 } … … 1108 1108 fncptr_t fptr; 1109 1109 errno_t rc; 1110 1110 1111 1111 symbol = (char *) argv->buffer; 1112 1112 rc = symtab_addr_lookup(symbol, &symaddr); … … 1183 1183 bool pointer = false; 1184 1184 errno_t rc; 1185 1185 1186 1186 if (((char *) argv->buffer)[0] == '*') { 1187 1187 rc = symtab_addr_lookup((char *) argv->buffer + 1, &addr); … … 1195 1195 } else 1196 1196 rc = symtab_addr_lookup((char *) argv->buffer, &addr); 1197 1197 1198 1198 if (rc == ENOENT) 1199 1199 printf("Symbol %s not found.\n", (char *) argv->buffer); … … 1210 1210 } else 1211 1211 printf("No symbol information available.\n"); 1212 1212 1213 1213 return 1; 1214 1214 } … … 1252 1252 else 1253 1253 printf("Unknown argument \"%s\".\n", flag_buf); 1254 1254 1255 1255 return 1; 1256 1256 } … … 1270 1270 else 1271 1271 printf("Unknown argument \"%s\".\n", flag_buf); 1272 1272 1273 1273 return 1; 1274 1274 } … … 1412 1412 release_console(); 1413 1413 indev_pop_character(stdin); 1414 1414 1415 1415 return 1; 1416 1416 } … … 1420 1420 { 1421 1421 printf("%s (%s)\n", test->name, test->desc); 1422 1422 1423 1423 /* Update and read thread accounting 1424 1424 for benchmarking */ … … 1427 1427 task_get_accounting(TASK, &ucycles0, &kcycles0); 1428 1428 irq_spinlock_unlock(&TASK->lock, true); 1429 1429 1430 1430 /* Execute the test */ 1431 1431 test_quiet = false; 1432 1432 const char *ret = test->entry(); 1433 1433 1434 1434 /* Update and read thread accounting */ 1435 1435 uint64_t ucycles1, kcycles1; … … 1437 1437 task_get_accounting(TASK, &ucycles1, &kcycles1); 1438 1438 irq_spinlock_unlock(&TASK->lock, true); 1439 1439 1440 1440 uint64_t ucycles, kcycles; 1441 1441 char usuffix, ksuffix; 1442 1442 order_suffix(ucycles1 - ucycles0, &ucycles, &usuffix); 1443 1443 order_suffix(kcycles1 - kcycles0, &kcycles, &ksuffix); 1444 1444 1445 1445 printf("Time: %" PRIu64 "%c user cycles, %" PRIu64 "%c kernel cycles\n", 1446 1446 ucycles, usuffix, kcycles, ksuffix); 1447 1447 1448 1448 if (ret == NULL) { 1449 1449 printf("Test passed\n"); 1450 1450 return true; 1451 1451 } 1452 1452 1453 1453 printf("%s\n", ret); 1454 1454 return false; … … 1461 1461 uint64_t ucycles, kcycles; 1462 1462 char usuffix, ksuffix; 1463 1463 1464 1464 if (cnt < 1) 1465 1465 return true; 1466 1466 1467 1467 uint64_t *data = (uint64_t *) malloc(sizeof(uint64_t) * cnt, 0); 1468 1468 if (data == NULL) { … … 1470 1470 return false; 1471 1471 } 1472 1472 1473 1473 for (i = 0; i < cnt; i++) { 1474 1474 printf("%s (%u/%u) ... ", test->name, i + 1, cnt); 1475 1475 1476 1476 /* Update and read thread accounting 1477 1477 for benchmarking */ … … 1480 1480 task_get_accounting(TASK, &ucycles0, &kcycles0); 1481 1481 irq_spinlock_unlock(&TASK->lock, true); 1482 1482 1483 1483 /* Execute the test */ 1484 1484 test_quiet = true; 1485 1485 const char *test_ret = test->entry(); 1486 1486 1487 1487 /* Update and read thread accounting */ 1488 1488 irq_spinlock_lock(&TASK->lock, true); … … 1490 1490 task_get_accounting(TASK, &ucycles1, &kcycles1); 1491 1491 irq_spinlock_unlock(&TASK->lock, true); 1492 1492 1493 1493 if (test_ret != NULL) { 1494 1494 printf("%s\n", test_ret); … … 1496 1496 break; 1497 1497 } 1498 1498 1499 1499 data[i] = ucycles1 - ucycles0 + kcycles1 - kcycles0; 1500 1500 order_suffix(ucycles1 - ucycles0, &ucycles, &usuffix); … … 1503 1503 ucycles, usuffix, kcycles, ksuffix); 1504 1504 } 1505 1505 1506 1506 if (ret) { 1507 1507 printf("\n"); 1508 1508 1509 1509 uint64_t sum = 0; 1510 1510 1511 1511 for (i = 0; i < cnt; i++) { 1512 1512 sum += data[i]; 1513 1513 } 1514 1514 1515 1515 order_suffix(sum / (uint64_t) cnt, &ucycles, &usuffix); 1516 1516 printf("Average\t\t%" PRIu64 "%c\n", ucycles, usuffix); 1517 1517 } 1518 1518 1519 1519 free(data); 1520 1520 1521 1521 return ret; 1522 1522 } … … 1526 1526 size_t len = 0; 1527 1527 test_t *test; 1528 1528 1529 1529 for (test = tests; test->name != NULL; test++) { 1530 1530 if (str_length(test->name) > len) 1531 1531 len = str_length(test->name); 1532 1532 } 1533 1533 1534 1534 unsigned int _len = (unsigned int) len; 1535 1535 if ((_len != len) || (((int) _len) < 0)) { … … 1537 1537 return; 1538 1538 } 1539 1539 1540 1540 for (test = tests; test->name != NULL; test++) 1541 1541 printf("%-*s %s%s\n", _len, test->name, test->desc, 1542 1542 (test->safe ? "" : " (unsafe)")); 1543 1543 1544 1544 printf("%-*s Run all safe tests\n", _len, "*"); 1545 1545 } … … 1555 1555 { 1556 1556 test_t *test; 1557 1557 1558 1558 if (str_cmp((char *) argv->buffer, "*") == 0) { 1559 1559 for (test = tests; test->name != NULL; test++) { … … 1566 1566 } else if (str_cmp((char *) argv->buffer, "") != 0) { 1567 1567 bool fnd = false; 1568 1568 1569 1569 for (test = tests; test->name != NULL; test++) { 1570 1570 if (str_cmp(test->name, (char *) argv->buffer) == 0) { … … 1574 1574 } 1575 1575 } 1576 1576 1577 1577 if (!fnd) 1578 1578 printf("Unknown test\n"); 1579 1579 } else 1580 1580 list_tests(); 1581 1581 1582 1582 return 1; 1583 1583 } … … 1593 1593 test_t *test; 1594 1594 uint32_t cnt = argv[1].intval; 1595 1595 1596 1596 if (str_cmp((char *) argv->buffer, "*") == 0) { 1597 1597 for (test = tests; test->name != NULL; test++) { … … 1603 1603 } else { 1604 1604 bool fnd = false; 1605 1605 1606 1606 for (test = tests; test->name != NULL; test++) { 1607 1607 if (str_cmp(test->name, (char *) argv->buffer) == 0) { 1608 1608 fnd = true; 1609 1609 1610 1610 if (test->safe) 1611 1611 run_bench(test, cnt); 1612 1612 else 1613 1613 printf("Unsafe test\n"); 1614 1614 1615 1615 break; 1616 1616 } 1617 1617 } 1618 1618 1619 1619 if (!fnd) 1620 1620 printf("Unknown test\n"); 1621 1621 } 1622 1622 1623 1623 return 1; 1624 1624 } -
kernel/generic/src/console/console.c
r3061bc1 ra35b458 119 119 stdin = &stdin_sink; 120 120 } 121 121 122 122 return stdin; 123 123 } … … 143 143 stdout = &stdout_source; 144 144 } 145 145 146 146 list_append(&outdev->link, &stdout->list); 147 147 } … … 189 189 { 190 190 void *faddr = (void *) KA2PA(kio); 191 191 192 192 assert((uintptr_t) faddr % FRAME_SIZE == 0); 193 193 194 194 kio_parea.pbase = (uintptr_t) faddr; 195 195 kio_parea.frames = SIZE2FRAMES(sizeof(kio)); … … 197 197 kio_parea.mapped = false; 198 198 ddi_parea_register(&kio_parea); 199 199 200 200 sysinfo_set_item_val("kio.faddr", NULL, (sysarg_t) faddr); 201 201 sysinfo_set_item_val("kio.pages", NULL, KIO_PAGES); 202 202 203 203 event_set_unmask_callback(EVENT_KIO, kio_update); 204 204 atomic_set(&kio_inited, true); … … 209 209 event_notify_1(EVENT_KCONSOLE, false, true); 210 210 bool prev = console_override; 211 211 212 212 console_override = true; 213 213 if ((stdout) && (stdout->op->redraw)) 214 214 stdout->op->redraw(stdout); 215 215 216 216 if ((stdin) && (!prev)) { 217 217 /* … … 256 256 size_t count = 0; 257 257 buf[offset] = 0; 258 258 259 259 wchar_t ch; 260 260 while ((ch = indev_pop_character(indev)) != '\n') { … … 265 265 putchar(' '); 266 266 putchar('\b'); 267 267 268 268 count--; 269 269 offset = str_lsize(buf, count); … … 271 271 } 272 272 } 273 273 274 274 if (chr_encode(ch, buf, &offset, buflen - 1) == EOK) { 275 275 putchar(ch); … … 278 278 } 279 279 } 280 280 281 281 return count; 282 282 } … … 294 294 if (!atomic_get(&kio_inited)) 295 295 return; 296 296 297 297 spinlock_lock(&kio_lock); 298 298 299 299 if (kio_uspace > 0) { 300 300 if (event_notify_3(EVENT_KIO, true, kio_start, kio_len, … … 302 302 kio_uspace = 0; 303 303 } 304 304 305 305 spinlock_unlock(&kio_lock); 306 306 } … … 312 312 { 313 313 bool ordy = ((stdout) && (stdout->op->write)); 314 314 315 315 if (!ordy) 316 316 return; … … 347 347 else 348 348 kio_start = (kio_start + 1) % KIO_LENGTH; 349 349 350 350 if (kio_stored < kio_len) 351 351 kio_stored++; 352 352 353 353 /* The character is stored for uspace */ 354 354 if (kio_uspace < kio_len) … … 359 359 { 360 360 bool ordy = ((stdout) && (stdout->op->write)); 361 361 362 362 spinlock_lock(&kio_lock); 363 363 kio_push_char(ch); 364 364 spinlock_unlock(&kio_lock); 365 365 366 366 /* Output stored characters */ 367 367 kio_flush(); 368 368 369 369 if (!ordy) { 370 370 /* … … 380 380 early_putchar(ch); 381 381 } 382 382 383 383 /* Force notification on newline */ 384 384 if (ch == '\n') … … 409 409 if (size > PAGE_SIZE) 410 410 return (sys_errno_t) ELIMIT; 411 411 412 412 if (size > 0) { 413 413 data = (char *) malloc(size + 1, 0); 414 414 if (!data) 415 415 return (sys_errno_t) ENOMEM; 416 416 417 417 rc = copy_from_uspace(data, buf, size); 418 418 if (rc) { … … 421 421 } 422 422 data[size] = 0; 423 423 424 424 switch (cmd) { 425 425 case KIO_WRITE: -
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 } -
kernel/generic/src/console/prompt.c
r3061bc1 ra35b458 52 52 assert(indev); 53 53 assert(hints > 0); 54 54 55 55 printf("Display all %zu possibilities? (y or n) ", hints); 56 56 57 57 while (true) { 58 58 wchar_t answer = indev_pop_character(indev); 59 59 60 60 if ((answer == 'y') || (answer == 'Y')) { 61 61 printf("y"); 62 62 return true; 63 63 } 64 64 65 65 if ((answer == 'n') || (answer == 'N')) { 66 66 printf("n"); … … 84 84 assert(indev); 85 85 assert(display_hints != NULL); 86 86 87 87 printf("--More--"); 88 88 while (true) { … … 95 95 break; 96 96 } 97 97 98 98 /* Stop displaying hints? */ 99 99 if ((continue_showing_hints == 'n') || … … 104 104 break; 105 105 } 106 106 107 107 /* Show one more hint? */ 108 108 if (continue_showing_hints == '\n') { … … 111 111 } 112 112 } 113 113 114 114 /* Delete the --More-- option */ 115 115 printf("\r \r"); 116 116 117 117 return *display_hints > 0; 118 118 }
Note:
See TracChangeset
for help on using the changeset viewer.