Changeset 9be9c4d in mainline
- Timestamp:
- 2011-07-13T19:54:05Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 3e5c48c9
- Parents:
- 026793d
- Location:
- uspace
- Files:
-
- 2 added
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/bdsh/Makefile
r026793d r9be9c4d 54 54 cmds/mod_cmds.c \ 55 55 cmds/builtin_cmds.c \ 56 compl.c \ 56 57 errors.c \ 57 58 input.c \ -
uspace/app/bdsh/config.h
r026793d r9be9c4d 40 40 #endif 41 41 42 /* Work around for getenv() */43 #define PATH "/srv:/app"44 #define PATH_DELIM ":"45 46 42 /* Used in many places */ 47 43 #define SMALL_BUFLEN 256 -
uspace/app/bdsh/exec.c
r026793d r9be9c4d 52 52 static int try_access(const char *); 53 53 54 const char *search_dir[] = { "app", "srv", NULL }; 55 54 56 /* work-around for access() */ 55 57 static int try_access(const char *f) … … 69 71 static char *find_command(char *cmd) 70 72 { 71 char *path_tok; 72 char *path[PATH_MAX]; 73 int n = 0, i = 0; 74 size_t x = str_size(cmd) + 2; 73 size_t i; 75 74 76 75 found = (char *)malloc(PATH_MAX); … … 81 80 } 82 81 83 path_tok = str_dup(PATH);84 85 /* Extract the PATH env to a path[] array */86 path[n] = strtok(path_tok, PATH_DELIM);87 while (NULL != path[n]) {88 if ((str_size(path[n]) + x ) > PATH_MAX) {89 cli_error(CL_ENOTSUP,90 "Segment %d of path is too large, search ends at segment %d",91 n, n-1);92 break;93 }94 path[++n] = strtok(NULL, PATH_DELIM);95 }96 97 82 /* We now have n places to look for the command */ 98 for (i =0; path[i]; i++) {83 for (i = 0; search_dir[i] != NULL; i++) { 99 84 memset(found, 0, sizeof(found)); 100 snprintf(found, PATH_MAX, "%s/%s", path[i], cmd);85 snprintf(found, PATH_MAX, "%s/%s", search_dir[i], cmd); 101 86 if (-1 != try_access(found)) { 102 free(path_tok);103 87 return (char *) found; 104 88 } … … 106 90 107 91 /* We didn't find it, just give it back as-is. */ 108 free(path_tok);109 92 return (char *) cmd; 110 93 } -
uspace/app/bdsh/exec.h
r026793d r9be9c4d 33 33 #include "scli.h" 34 34 35 extern const char *search_dir[]; 36 35 37 extern unsigned int try_exec(char *, char **, iostate_t *); 36 38 -
uspace/app/bdsh/input.c
r026793d r9be9c4d 1 1 /* 2 2 * Copyright (c) 2008 Tim Post 3 * Copyright (c) 2011 Jiri Svoboda 3 4 * All rights reserved. 4 5 * … … 43 44 44 45 #include "config.h" 46 #include "compl.h" 45 47 #include "util.h" 46 48 #include "scli.h" … … 226 228 int rc; 227 229 228 console_flush(tinput->console); 229 console_set_style(tinput->console, STYLE_EMPHASIS); 230 printf("%s", usr->prompt); 231 console_flush(tinput->console); 232 console_set_style(tinput->console, STYLE_NORMAL); 230 tinput_set_prompt(tinput, usr->prompt); 233 231 234 232 rc = tinput_read(tinput, &str); … … 263 261 } 264 262 263 tinput_set_compl_ops(tinput, &compl_ops); 264 265 265 return 0; 266 266 } -
uspace/app/bdsh/scli.h
r026793d r9be9c4d 32 32 #include "config.h" 33 33 #include <stdint.h> 34 #include <stdio.h> 34 35 35 36 typedef struct { -
uspace/app/sbi/src/input.c
r026793d r9be9c4d 176 176 int input_get_line(input_t *input, char **line) 177 177 { 178 const char *prompt; 178 179 const char *sp; 179 180 char *dp; … … 212 213 /* Interactive mode */ 213 214 if (input->line_no == 0) 214 pr intf("sbi> ");215 prompt = "sbi> "; 215 216 else 216 pr intf("... ");217 prompt = "... "; 217 218 218 219 fflush(stdout); 219 if (os_input_line( &line_p) != EOK)220 if (os_input_line(prompt, &line_p) != EOK) 220 221 return EIO; 221 222 -
uspace/app/sbi/src/os/helenos.c
r026793d r9be9c4d 210 210 * @param ptr Place to store pointer to new string. 211 211 */ 212 int os_input_line(c har **ptr)212 int os_input_line(const char *prompt, char **ptr) 213 213 { 214 214 char *line; … … 219 219 if (tinput == NULL) 220 220 return EIO; 221 222 tinput_set_prompt(tinput, prompt); 221 223 } 222 224 -
uspace/app/sbi/src/os/os.h
r026793d r9be9c4d 38 38 char *os_chr_to_astr(wchar_t chr); 39 39 void os_input_disp_help(void); 40 int os_input_line(c har **ptr);40 int os_input_line(const char *prompt, char **ptr); 41 41 int os_exec(char * const cmd[]); 42 42 -
uspace/app/sbi/src/os/posix.c
r026793d r9be9c4d 193 193 * @param ptr Place to store pointer to new string. 194 194 */ 195 int os_input_line(char **ptr) 196 { 195 int os_input_line(const char *prompt, char **ptr) 196 { 197 printf("%s", prompt); 198 197 199 if (fgets(os_input_buffer, OS_INPUT_BUFFER_SIZE, stdin) == NULL) 198 200 os_input_buffer[0] = '\0'; -
uspace/lib/clui/tinput.c
r026793d r9be9c4d 1 1 /* 2 * Copyright (c) 201 0Jiri Svoboda2 * Copyright (c) 2011 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 27 27 */ 28 28 29 #include <sort.h> 29 30 #include <stdio.h> 30 31 #include <stdlib.h> … … 42 43 #include <tinput.h> 43 44 45 #define LIN_TO_COL(ti, lpos) ((lpos) % ((ti)->con_cols)) 46 #define LIN_TO_ROW(ti, lpos) ((lpos) / ((ti)->con_cols)) 47 44 48 /** Seek direction */ 45 49 typedef enum { … … 61 65 static void tinput_post_seek(tinput_t *, bool); 62 66 67 static void tinput_console_set_lpos(tinput_t *ti, unsigned lpos) 68 { 69 console_set_pos(ti->console, LIN_TO_COL(ti, lpos), 70 LIN_TO_ROW(ti, lpos)); 71 } 72 63 73 /** Create a new text input field. */ 64 74 tinput_t *tinput_new(void) … … 66 76 tinput_t *ti; 67 77 68 ti = malloc(sizeof(tinput_t));78 ti = calloc(1, sizeof(tinput_t)); 69 79 if (ti == NULL) 70 80 return NULL; … … 77 87 void tinput_destroy(tinput_t *ti) 78 88 { 89 if (ti->prompt != NULL) 90 free(ti->prompt); 79 91 free(ti); 92 } 93 94 static void tinput_display_prompt(tinput_t *ti) 95 { 96 tinput_console_set_lpos(ti, ti->prompt_coord); 97 98 console_set_style(ti->console, STYLE_EMPHASIS); 99 printf("%s", ti->prompt); 100 console_flush(ti->console); 101 console_set_style(ti->console, STYLE_NORMAL); 80 102 } 81 103 … … 88 110 tinput_sel_get_bounds(ti, &sa, &sb); 89 111 90 console_set_pos(ti->console, (ti->col0 + start) % ti->con_cols, 91 ti->row0 + (ti->col0 + start) / ti->con_cols); 112 tinput_console_set_lpos(ti, ti->text_coord + start); 92 113 console_set_style(ti->console, STYLE_NORMAL); 93 114 … … 134 155 static void tinput_position_caret(tinput_t *ti) 135 156 { 136 console_set_pos(ti->console, (ti->col0 + ti->pos) % ti->con_cols, 137 ti->row0 + (ti->col0 + ti->pos) / ti->con_cols); 138 } 139 140 /** Update row0 in case the screen could have scrolled. */ 157 tinput_console_set_lpos(ti, ti->text_coord + ti->pos); 158 } 159 160 /** Update text_coord, prompt_coord in case the screen could have scrolled. */ 141 161 static void tinput_update_origin(tinput_t *ti) 142 162 { 143 sysarg_t width = ti->col0 + ti->nc; 144 sysarg_t rows = (width / ti->con_cols) + 1; 145 146 /* Update row0 if the screen scrolled. */ 147 if (ti->row0 + rows > ti->con_rows) 148 ti->row0 = ti->con_rows - rows; 163 unsigned end_coord = ti->text_coord + ti->nc; 164 unsigned end_row = LIN_TO_ROW(ti, end_coord); 165 166 unsigned scroll_rows; 167 168 /* Update coords if the screen scrolled. */ 169 if (end_row >= ti->con_rows) { 170 scroll_rows = end_row - ti->con_rows + 1; 171 ti->text_coord -= ti->con_cols * scroll_rows; 172 ti->prompt_coord -= ti->con_cols * scroll_rows; 173 } 174 } 175 176 static void tinput_jump_after(tinput_t *ti) 177 { 178 tinput_console_set_lpos(ti, ti->text_coord + ti->nc); 179 console_flush(ti->console); 180 putchar('\n'); 181 } 182 183 static int tinput_display(tinput_t *ti) 184 { 185 sysarg_t col0, row0; 186 187 if (console_get_pos(ti->console, &col0, &row0) != EOK) 188 return EIO; 189 190 ti->prompt_coord = row0 * ti->con_cols + col0; 191 ti->text_coord = ti->prompt_coord + str_length(ti->prompt); 192 193 tinput_display_prompt(ti); 194 tinput_display_tail(ti, 0, 0); 195 tinput_position_caret(ti); 196 197 return EOK; 149 198 } 150 199 … … 154 203 return; 155 204 156 sysarg_t new_width = ti->col0+ ti->nc + 1;205 unsigned new_width = LIN_TO_COL(ti, ti->text_coord) + ti->nc + 1; 157 206 if (new_width % ti->con_cols == 0) { 158 207 /* Advancing to new line. */ … … 185 234 return; 186 235 187 sysarg_t new_width = ti->col0+ ti->nc + ilen;188 sysarg_tnew_height = (new_width / ti->con_cols) + 1;236 unsigned new_width = LIN_TO_COL(ti, ti->text_coord) + ti->nc + ilen; 237 unsigned new_height = (new_width / ti->con_cols) + 1; 189 238 if (new_height >= ti->con_rows) { 190 239 /* Disallow text longer than 1 page for now. */ … … 511 560 } 512 561 562 /** Compare two entries in array of completions. */ 563 static int compl_cmp(void *va, void *vb, void *arg) 564 { 565 const char *a = *(const char **) va; 566 const char *b = *(const char **) vb; 567 568 return str_cmp(a, b); 569 } 570 571 static size_t common_pref_len(const char *a, const char *b) 572 { 573 size_t i; 574 size_t a_off, b_off; 575 wchar_t ca, cb; 576 577 i = 0; 578 a_off = 0; 579 b_off = 0; 580 581 while (true) { 582 ca = str_decode(a, &a_off, STR_NO_LIMIT); 583 cb = str_decode(b, &b_off, STR_NO_LIMIT); 584 585 if (ca == '\0' || cb == '\0' || ca != cb) 586 break; 587 ++i; 588 } 589 590 return i; 591 } 592 593 static void tinput_text_complete(tinput_t *ti) 594 { 595 void *state; 596 size_t cstart; 597 char *ctmp; 598 char **compl; /* Array of completions */ 599 size_t compl_len; /* Current length of @c compl array */ 600 size_t cnum; 601 size_t i; 602 int rc; 603 604 if (ti->compl_ops == NULL) 605 return; 606 607 /* 608 * Obtain list of all possible completions (growing array). 609 */ 610 611 rc = (*ti->compl_ops->init)(ti->buffer, ti->pos, &cstart, &state); 612 if (rc != EOK) 613 return; 614 615 cnum = 0; 616 617 compl_len = 1; 618 compl = malloc(compl_len * sizeof(char *)); 619 if (compl == NULL) { 620 printf("Error: Out of memory.\n"); 621 return; 622 } 623 624 while (true) { 625 rc = (*ti->compl_ops->get_next)(state, &ctmp); 626 if (rc != EOK) 627 break; 628 629 if (cnum >= compl_len) { 630 /* Extend array */ 631 compl_len = 2 * compl_len; 632 compl = realloc(compl, compl_len * sizeof(char *)); 633 if (compl == NULL) { 634 printf("Error: Out of memory.\n"); 635 break; 636 } 637 } 638 639 compl[cnum] = str_dup(ctmp); 640 if (compl[cnum] == NULL) { 641 printf("Error: Out of memory.\n"); 642 break; 643 } 644 cnum++; 645 } 646 647 (*ti->compl_ops->fini)(state); 648 649 if (cnum > 1) { 650 /* 651 * More than one match. Determine maximum common prefix. 652 */ 653 size_t cplen; 654 655 cplen = str_length(compl[0]); 656 for (i = 1; i < cnum; i++) 657 cplen = min(cplen, common_pref_len(compl[0], compl[i])); 658 659 /* Compute how many bytes we should skip. */ 660 size_t istart = str_lsize(compl[0], ti->pos - cstart); 661 662 if (cplen > istart) { 663 /* Insert common prefix. */ 664 665 /* Copy remainder of common prefix. */ 666 char *cpref = str_ndup(compl[0] + istart, 667 str_lsize(compl[0], cplen - istart)); 668 669 /* Insert it. */ 670 tinput_insert_string(ti, cpref); 671 free(cpref); 672 } else { 673 /* No common prefix. Sort and display all entries. */ 674 675 qsort(compl, cnum, sizeof(char *), compl_cmp, NULL); 676 677 tinput_jump_after(ti); 678 for (i = 0; i < cnum; i++) 679 printf("%s\n", compl[i]); 680 tinput_display(ti); 681 } 682 } else if (cnum == 1) { 683 /* 684 * We have exactly one match. Insert it. 685 */ 686 687 /* Compute how many bytes of completion string we should skip. */ 688 size_t istart = str_lsize(compl[0], ti->pos - cstart); 689 690 /* Insert remainder of completion string at current position. */ 691 tinput_insert_string(ti, compl[0] + istart); 692 } 693 694 for (i = 0; i < cnum; i++) 695 free(compl[i]); 696 free(compl); 697 } 698 513 699 /** Initialize text input field. 514 700 * … … 521 707 ti->hpos = 0; 522 708 ti->history[0] = NULL; 709 } 710 711 /** Set prompt string. 712 * 713 * @param ti Text input 714 * @param prompt Prompt string 715 * 716 * @return EOK on success, ENOMEM if out of memory. 717 */ 718 int tinput_set_prompt(tinput_t *ti, const char *prompt) 719 { 720 if (ti->prompt != NULL) 721 free(ti->prompt); 722 723 ti->prompt = str_dup(prompt); 724 if (ti->prompt == NULL) 725 return ENOMEM; 726 727 return EOK; 728 } 729 730 /** Set completion ops. 731 * 732 * Set pointer to completion ops structure that will be used for text 733 * completion. 734 */ 735 void tinput_set_compl_ops(tinput_t *ti, tinput_compl_ops_t *compl_ops) 736 { 737 ti->compl_ops = compl_ops; 523 738 } 524 739 … … 539 754 return EIO; 540 755 541 if (console_get_pos(ti->console, &ti->col0, &ti->row0) != EOK)542 return EIO;543 544 756 ti->pos = 0; 545 757 ti->sel_start = 0; … … 549 761 ti->exit_clui = false; 550 762 763 if (tinput_display(ti) != EOK) 764 return EIO; 765 551 766 while (!ti->done) { 552 767 console_flush(ti->console); … … 714 929 tinput_history_seek(ti, -1); 715 930 break; 931 case KC_TAB: 932 tinput_text_complete(ti); 933 break; 716 934 default: 717 935 break; -
uspace/lib/clui/tinput.h
r026793d r9be9c4d 1 1 /* 2 * Copyright (c) 201 0Jiri Svoboda2 * Copyright (c) 2011 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 37 37 #define LIBCLUI_TINPUT_H_ 38 38 39 #include < stdio.h>39 #include <adt/list.h> 40 40 #include <async.h> 41 41 #include <inttypes.h> 42 42 #include <io/console.h> 43 #include <stdio.h> 43 44 44 45 #define HISTORY_LEN 10 45 46 #define INPUT_MAX_SIZE 1024 47 48 /** Begin enumeration of text completions. 49 * 50 * When user requests text completion, tinput will call this function to start 51 * text completion operation. @a *cstart should be set to the position 52 * (character index) of the first character of the 'word' that is being 53 * completed. The resulting text is obtained by replacing the range of text 54 * starting at @a *cstart and ending at @a pos with the completion text. 55 * 56 * The function can pass information to the get_next and fini functions 57 * via @a state. The init function allocates the state object and stores 58 * a pointer to it to @a *state. The fini function destroys the state object. 59 * 60 * @param text Current contents of edit buffer (null-terminated). 61 * @param pos Current caret position. 62 * @param cstart Output, position in text where completion begins from. 63 * @param state Output, pointer to a client state object. 64 * 65 * @return EOK on success, negative error code on failure. 66 */ 67 typedef int (*tinput_compl_init_fn)(wchar_t *text, size_t pos, size_t *cstart, 68 void **state); 69 70 /** Obtain one text completion alternative. 71 * 72 * Upon success the function sets @a *compl to point to a string, the 73 * completion text. The caller (Tinput) should not modify or free the text. 74 * The pointer is only valid until the next invocation of any completion 75 * function. 76 * 77 * @param state Pointer to state object created by the init funtion. 78 * @param compl Output, the completion text, ownership retained. 79 * 80 * @return EOK on success, negative error code on failure. 81 */ 82 typedef int (*tinput_compl_get_next_fn)(void *state, char **compl); 83 84 85 /** Finish enumeration of text completions. 86 * 87 * The function must deallocate any state information allocated by the init 88 * function or temporary data allocated by the get_next function. 89 * 90 * @param state Pointer to state object created by the init funtion. 91 */ 92 typedef void (*tinput_compl_fini_fn)(void *state); 93 94 /** Text completion ops. */ 95 typedef struct { 96 tinput_compl_init_fn init; 97 tinput_compl_get_next_fn get_next; 98 tinput_compl_fini_fn fini; 99 } tinput_compl_ops_t; 46 100 47 101 /** Text input field (command line). … … 53 107 console_ctrl_t *console; 54 108 109 /** Prompt string */ 110 char *prompt; 111 112 /** Completion ops. */ 113 tinput_compl_ops_t *compl_ops; 114 55 115 /** Buffer holding text currently being edited */ 56 116 wchar_t buffer[INPUT_MAX_SIZE + 1]; 57 117 58 /** Screen coordinates of the top-left corner of the text field */ 59 sysarg_t col0; 60 sysarg_t row0; 118 /** Linear position on screen where the prompt starts */ 119 unsigned prompt_coord; 120 /** Linear position on screen where the text field starts */ 121 unsigned text_coord; 61 122 62 123 /** Screen dimensions */ … … 90 151 91 152 extern tinput_t *tinput_new(void); 153 extern int tinput_set_prompt(tinput_t *, const char *); 154 extern void tinput_set_compl_ops(tinput_t *, tinput_compl_ops_t *); 92 155 extern void tinput_destroy(tinput_t *); 93 156 extern int tinput_read(tinput_t *, char **);
Note:
See TracChangeset
for help on using the changeset viewer.