Changes in / [a0fc4be:e3e4a2c] in mainline


Ignore:
Location:
uspace
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bdsh/compl.c

    ra0fc4be re3e4a2c  
    11/*
    22 * Copyright (c) 2011 Jiri Svoboda
    3  * Copyright (c) 2011 Martin Sucha
    43 * All rights reserved.
    54 *
     
    3837#include "compl.h"
    3938#include "exec.h"
    40 #include "tok.h"
    4139
    4240static int compl_init(wchar_t *text, size_t pos, size_t *cstart, void **state);
     
    9088{
    9189        compl_t *cs = NULL;
     90        size_t p;
    9291        size_t pref_size;
    9392        char *stext = NULL;
     
    9796        static const char *dirlist_arg[] = { ".", NULL };
    9897        int retval;
    99         tokenizer_t tok;
    100         token_t tokens[WORD_MAX];
    101         unsigned int current_token;
    102         size_t tokens_length;
    10398
    10499        cs = calloc(1, sizeof(compl_t));
     
    108103        }
    109104
     105        /*
     106         * Copy token pointed to by caret from start up to the caret.
     107         * XXX Ideally we would use the standard tokenizer.
     108         */
     109        p = pos;
     110        while (p > 0 && text[p - 1] != (wchar_t) ' ')
     111                --p;
     112        *cstart = p;
     113
    110114        /* Convert text buffer to string */
    111         stext = wstr_to_astr(text);
     115        stext = wstr_to_astr(text + *cstart);
    112116        if (stext == NULL) {
    113117                retval = ENOMEM;
    114118                goto error;
    115119        }
    116        
    117         /* Tokenize the input string */
    118         retval = tok_init(&tok, stext, tokens, WORD_MAX);
    119         if (retval != EOK) {
    120                 goto error;
    121         }
    122        
    123         retval = tok_tokenize(&tok, &tokens_length);
    124         if (retval != EOK) {
    125                 goto error;
    126         }
    127        
    128         /* Find the current token */
    129         for (current_token = 0; current_token < tokens_length; current_token++) {
    130                 token_t *t = &tokens[current_token];
    131                 size_t end = t->char_start + t->char_length;
    132                 /* Check if the caret lies inside the token or immediately
    133                  * after it
    134                  */
    135                 if (t->char_start <= pos && pos <= end) {
    136                         break;
    137                 }
    138         }
    139        
    140         if (tokens[current_token].type != TOKTYPE_SPACE) {
    141                 *cstart = tokens[current_token].char_start;
    142         }
    143         else {
    144                 *cstart = pos;
    145         }
    146        
    147         /* Extract the prefix being completed
    148          * XXX: handle strings, etc.
    149          */
     120
     121        /* Extract the prefix being completed */
    150122        pref_size = str_lsize(stext, pos - *cstart);
    151123        prefix = malloc(pref_size + 1);
     
    155127        }
    156128
    157         str_ncpy(prefix, pref_size + 1, stext +
    158             tokens[current_token].byte_start, pref_size);
     129        str_ncpy(prefix, pref_size + 1, stext, pref_size);
    159130
    160131        /*
     
    162133         * We look at the previous token. If there is none or it is a pipe
    163134         * ('|'), it is a command, otherwise it is an argument.
     135         * XXX Again we should use the standard tokenizer/parser.
    164136         */
    165137
    166138        /* Skip any whitespace before current token */
    167         int prev_token = current_token - 1;
    168         if (prev_token != -1 && tokens[prev_token].type == TOKTYPE_SPACE) {
    169                 prev_token--;
    170         }
     139        while (p > 0 && text[p - 1] == (wchar_t) ' ')
     140                --p;
    171141
    172142        /*
     
    174144         * follows a pipe token.
    175145         */
    176         if (prev_token == -1 || tokens[prev_token].type == TOKTYPE_SPACE)
     146        if (p == 0 || text[p - 1] == '|')
    177147                cs->is_command = true;
    178148        else
     
    219189
    220190        cs->prefix_len = str_length(cs->prefix);
    221        
    222         tok_fini(&tok);
    223191
    224192        *state = cs;
     
    227195error:
    228196        /* Error cleanup */
    229        
    230         tok_fini(&tok);
    231197
    232198        if (cs != NULL && cs->path_list != NULL) {
  • uspace/app/bdsh/input.c

    ra0fc4be re3e4a2c  
    22 * Copyright (c) 2008 Tim Post
    33 * Copyright (c) 2011 Jiri Svoboda
    4  * Copyright (c) 2011 Martin Sucha
    54 * All rights reserved.
    65 *
     
    6867{
    6968        char *cmd[WORD_MAX];
    70         token_t tokens_space[WORD_MAX];
    71         token_t *tokens = tokens_space;
    7269        int rc = 0;
    7370        tokenizer_t tok;
    74         unsigned int i, pipe_count, processed_pipes;
    75         unsigned int pipe_pos[2];
     71        int i, pipe_count, processed_pipes;
     72        int pipe_pos[2];
     73        char **actual_cmd;
    7674        char *redir_from = NULL;
    7775        char *redir_to = NULL;
     
    8078                return CL_EFAIL;
    8179
    82         rc = tok_init(&tok, usr->line, tokens, WORD_MAX);
     80        rc = tok_init(&tok, usr->line, cmd, WORD_MAX);
    8381        if (rc != EOK) {
    8482                goto finit;
    8583        }
    8684       
    87         size_t tokens_length;
    88         rc = tok_tokenize(&tok, &tokens_length);
     85        rc = tok_tokenize(&tok);
    8986        if (rc != EOK) {
    9087                goto finit;
    91         }
    92        
    93         if (tokens_length > 0 && tokens[0].type == TOKTYPE_SPACE) {
    94                 tokens++;
    95                 tokens_length--;
    96         }
    97        
    98         if (tokens_length > 0 && tokens[tokens_length-1].type == TOKTYPE_SPACE) {
    99                 tokens_length--;
    10088        }
    10189       
     
    10593         * First find the pipes and check that there are no more
    10694         */
    107         for (i = 0, pipe_count = 0; i < tokens_length; i++) {
    108                 if (tokens[i].type == TOKTYPE_PIPE) {
     95        int cmd_length = 0;
     96        for (i = 0, pipe_count = 0; cmd[i] != NULL; i++, cmd_length++) {
     97                if (cmd[i][0] == '|') {
    10998                        if (pipe_count >= 2) {
    11099                                print_pipe_usage();
     
    117106        }
    118107       
    119         unsigned int cmd_token_start = 0;
    120         unsigned int cmd_token_end = tokens_length;
    121        
     108        actual_cmd = cmd;
    122109        processed_pipes = 0;
    123110       
    124111        /* Check if the first part (from <file> |) is present */
    125         if (pipe_count > 0 && (pipe_pos[0] == 3 || pipe_pos[0] == 4) && str_cmp(tokens[0].text, "from") == 0) {
     112        if (pipe_count > 0 && pipe_pos[0] == 2 && str_cmp(cmd[0], "from") == 0) {
    126113                /* Ignore the first three tokens (from, file, pipe) and set from */
    127                 redir_from = tokens[2].text;
    128                 cmd_token_start = pipe_pos[0]+1;
     114                redir_from = cmd[1];
     115                actual_cmd = cmd + 3;
    129116                processed_pipes++;
    130117        }
     
    132119        /* Check if the second part (| to <file>) is present */
    133120        if ((pipe_count - processed_pipes) > 0 &&
    134             (pipe_pos[processed_pipes] == tokens_length - 4 ||
    135             (pipe_pos[processed_pipes] == tokens_length - 5 &&
    136             tokens[tokens_length-4].type == TOKTYPE_SPACE )) &&
    137             str_cmp(tokens[tokens_length-3].text, "to") == 0) {
     121            pipe_pos[processed_pipes] == cmd_length - 3 &&
     122            str_cmp(cmd[cmd_length-2], "to") == 0) {
    138123                /* Ignore the last three tokens (pipe, to, file) and set to */
    139                 redir_to = tokens[tokens_length-1].text;
    140                 cmd_token_end = pipe_pos[processed_pipes];
     124                redir_to = cmd[cmd_length-1];
     125                cmd[cmd_length-3] = NULL;
     126                cmd_length -= 3;
    141127                processed_pipes++;
    142128        }
     
    148134        }
    149135       
    150         /* Convert tokens of the command to string array */
    151         unsigned int cmd_pos = 0;
    152         for (i = cmd_token_start; i < cmd_token_end; i++) {
    153                 if (tokens[i].type != TOKTYPE_SPACE) {
    154                         cmd[cmd_pos++] = tokens[i].text;
    155                 }
    156         }
    157         cmd[cmd_pos++] = NULL;
    158        
    159         if (cmd[0] == NULL) {
     136        if (actual_cmd[0] == NULL) {
    160137                print_pipe_usage();
    161138                rc = ENOTSUP;
     
    193170        }
    194171       
    195         rc = run_command(cmd, usr, &new_iostate);
     172        rc = run_command(actual_cmd, usr, &new_iostate);
    196173       
    197174finit_with_files:
  • uspace/app/bdsh/tok.c

    ra0fc4be re3e4a2c  
    4242static bool tok_pending_chars(tokenizer_t *);
    4343static int tok_finish_string(tokenizer_t *);
    44 static void tok_start_token(tokenizer_t *, token_type_t);
    4544
    4645/** Initialize the token parser
     
    5150 * @param max_tokens number of elements of the out_tokens array
    5251 */
    53 int tok_init(tokenizer_t *tok, char *input, token_t *out_tokens,
     52int tok_init(tokenizer_t *tok, char *input, char **out_tokens,
    5453    size_t max_tokens)
    5554{       
    5655        tok->in = input;
    5756        tok->in_offset = 0;
    58         tok->last_in_offset = 0;
    59         tok->in_char_offset = 0;
    60         tok->last_in_char_offset = 0;
    6157       
    6258        tok->outtok = out_tokens;
    6359        tok->outtok_offset = 0;
    64         tok->outtok_size = max_tokens;
     60        /* Leave one slot for a null terminator */
     61        assert(max_tokens > 0);
     62        tok->outtok_size = max_tokens - 1;
    6563       
    6664        /* Prepare a buffer where all the token strings will be stored */
     
    8987
    9088/** Tokenize the input string into the tokens */
    91 int tok_tokenize(tokenizer_t *tok, size_t *tokens_length)
     89int tok_tokenize(tokenizer_t *tok)
    9290{
    9391        int rc;
    94         wchar_t next_char;
     92        wchar_t cur_char;
    9593       
    9694        /* Read the input line char by char and append tokens */
    97         while ((next_char = tok_look_char(tok)) != 0) {
    98                 if (next_char == ' ') {
    99                         /* Push the token if there is any.
     95        while ((cur_char = tok_get_char(tok)) != 0) {
     96                if (cur_char == ' ') {
     97                        /* Spaces delimit tokens, but are not processed in any way
     98                         * Push the token if there is any.
    10099                         * There may not be any pending char for a token in case
    101100                         * there are several spaces in the input.
     
    107106                                }
    108107                        }
    109                         tok_start_token(tok, TOKTYPE_SPACE);
    110                         /* Eat all the spaces */
    111                         while (tok_look_char(tok) == ' ') {
    112                                 tok_push_char(tok, tok_get_char(tok));
    113                         }
    114                         tok_push_token(tok);
    115                        
    116                 }
    117                 else if (next_char == '|') {
    118                         /* Pipes are tokens that are delimiters and should be
    119                          * output as a separate token
     108                }
     109                else if (cur_char == '|') {
     110                        /* Pipes are tokens that are delimiters and should be output
     111                         * as a separate token
    120112                         */
    121113                        if (tok_pending_chars(tok)) {
     
    126118                        }
    127119                       
    128                         tok_start_token(tok, TOKTYPE_PIPE);
    129                        
    130                         rc = tok_push_char(tok, tok_get_char(tok));
     120                        rc = tok_push_char(tok, '|');
    131121                        if (rc != EOK) {
    132122                                return rc;
     
    138128                        }
    139129                }
    140                 else if (next_char == '\'') {
     130                else if (cur_char == '\'') {
    141131                        /* A string starts with a quote (') and ends again with a quote.
    142132                         * A literal quote is written as ''
    143133                         */
    144                         tok_start_token(tok, TOKTYPE_TEXT);
    145                         /* Eat the quote */
    146                         tok_get_char(tok);
    147134                        rc = tok_finish_string(tok);
    148135                        if (rc != EOK) {
     
    151138                }
    152139                else {
    153                         if (!tok_pending_chars(tok)) {
    154                                 tok_start_token(tok, TOKTYPE_TEXT);
    155                         }
    156140                        /* If we are handling any other character, just append it to
    157141                         * the current token.
    158142                         */
    159                         rc = tok_push_char(tok, tok_get_char(tok));
     143                        rc = tok_push_char(tok, cur_char);
    160144                        if (rc != EOK) {
    161145                                return rc;
     
    172156        }
    173157       
    174         *tokens_length = tok->outtok_offset;
     158        /* We always have a space for the terminator, as we
     159         * reserved it in tok_init */
     160        tok->outtok[tok->outtok_offset] = 0;
    175161       
    176162        return EOK;
     
    181167{
    182168        int rc;
    183         wchar_t next_char;
    184        
    185         while ((next_char = tok_look_char(tok)) != 0) {
    186                 if (next_char == '\'') {
    187                         /* Eat the quote */
    188                         tok_get_char(tok);
     169        wchar_t cur_char;
     170       
     171        while ((cur_char = tok_get_char(tok)) != 0) {
     172                if (cur_char == '\'') {
    189173                        if (tok_look_char(tok) == '\'') {
    190174                                /* Encode a single literal quote */
     
    203187                }
    204188                else {
    205                         rc = tok_push_char(tok, tok_get_char(tok));
     189                        rc = tok_push_char(tok, cur_char);
    206190                        if (rc != EOK) {
    207191                                return rc;
     
    217201wchar_t tok_get_char(tokenizer_t *tok)
    218202{
    219         tok->in_char_offset++;
    220203        return str_decode(tok->in, &tok->in_offset, STR_NO_LIMIT);
    221204}
     
    224207wchar_t tok_look_char(tokenizer_t *tok)
    225208{
    226         unsigned int old_offset = tok->in_offset;
    227         unsigned int old_char_offset = tok->in_char_offset;
     209        size_t old_offset = tok->in_offset;
    228210        wchar_t ret = tok_get_char(tok);
    229211        tok->in_offset = old_offset;
    230         tok->in_char_offset = old_char_offset;
    231212        return ret;
    232213}
     
    238219}
    239220
    240 void tok_start_token(tokenizer_t *tok, token_type_t type)
    241 {
    242         tok->current_type = type;
    243 }
    244 
    245221/** Push the current token to the output array */
    246222int tok_push_token(tokenizer_t *tok)
     
    255231       
    256232        tok->outbuf[tok->outbuf_offset++] = 0;
    257         token_t *tokinfo = &tok->outtok[tok->outtok_offset++];
    258         tokinfo->type = tok->current_type;
    259         tokinfo->text = tok->outbuf + tok->outbuf_last_start;
    260         tokinfo->byte_start = tok->last_in_offset;
    261         tokinfo->byte_length = tok->in_offset - tok->last_in_offset;
    262         tokinfo->char_start = tok->last_in_char_offset;
    263         tokinfo->char_length = tok->in_char_offset - tok->last_in_char_offset;
     233        tok->outtok[tok->outtok_offset++] = tok->outbuf + tok->outbuf_last_start;
    264234        tok->outbuf_last_start = tok->outbuf_offset;
    265        
    266         /* We have consumed the first char of the next token already */
    267         tok->last_in_offset = tok->in_offset;
    268         tok->last_in_char_offset = tok->in_char_offset;
    269235       
    270236        return EOK;
  • uspace/app/bdsh/tok.h

    ra0fc4be re3e4a2c  
    3030#define TOK_H
    3131
    32 typedef enum {
    33         TOKTYPE_TEXT,
    34         TOKTYPE_PIPE,
    35         TOKTYPE_SPACE
    36 } token_type_t;
    37 
    38 typedef struct {
    39         char *text;
    40         unsigned int byte_start;
    41         unsigned int char_start;
    42         size_t byte_length;
    43         size_t char_length;
    44         token_type_t type;
    45 } token_t;
    46 
    4732typedef struct {
    4833        char *in;
    49         unsigned int in_offset;
    50         unsigned int last_in_offset;
    51         unsigned int in_char_offset;
    52         unsigned int last_in_char_offset;
     34        size_t in_offset;
    5335       
    5436        char *outbuf;
     
    5739        size_t outbuf_last_start;
    5840       
    59         token_t *outtok;
    60         token_type_t current_type;
     41        char **outtok;
    6142        size_t outtok_offset;
    6243        size_t outtok_size;
    6344} tokenizer_t;
    6445
    65 extern int tok_init(tokenizer_t *, char *, token_t *, size_t);
     46extern int tok_init(tokenizer_t *, char *, char **, size_t);
    6647extern void tok_fini(tokenizer_t *);
    67 extern int tok_tokenize(tokenizer_t *, size_t *);
     48extern int tok_tokenize(tokenizer_t *);
    6849
    6950#endif
  • uspace/lib/clui/tinput.c

    ra0fc4be re3e4a2c  
    591591}
    592592
    593 /* Print a list of completions */
    594 static void tinput_show_completions(tinput_t *ti, char **compl, size_t cnum)
    595 {
    596         unsigned int i;
    597         /* Determine the maximum length of the completion in chars */
    598         size_t max_length = 0;
    599         for (i = 0; i < cnum; i++)
    600                 max_length = max(max_length, str_length(compl[i]));
    601        
    602         unsigned int cols = max(1, (ti->con_cols + 1) / (max_length + 1));
    603         unsigned int col_width = ti->con_cols / cols;
    604         unsigned int rows = cnum / cols + ((cnum % cols) != 0);
    605        
    606         unsigned int row, col;
    607        
    608         for (row = 0; row < rows; row++) {
    609                 bool wlc = false;
    610                 for (col = 0; col < cols; col++) {
    611                         size_t compl_idx = col * rows + row;
    612                         if (compl_idx >= cnum)
    613                                 break;
    614                         if (col)
    615                                 printf(" ");
    616                         printf("%s", compl[compl_idx]);
    617                         size_t compl_len = str_length(compl[compl_idx]);
    618                         if (col == cols -1) {
    619                                 wlc = (compl_len == max_length);
    620                         }
    621                         else {
    622                                 for (i = compl_len; i < col_width; i++) {
    623                                         printf(" ");
    624                                 }
    625                         }
    626                 }
    627                 if (!wlc) printf("\n");
    628         }
    629 }
    630 
    631 
    632593static void tinput_text_complete(tinput_t *ti)
    633594{
     
    715676
    716677                        tinput_jump_after(ti);
    717                         tinput_show_completions(ti, compl, cnum);
     678                        for (i = 0; i < cnum; i++)
     679                                printf("%s\n", compl[i]);
    718680                        tinput_display(ti);
    719681                }
Note: See TracChangeset for help on using the changeset viewer.