Changeset 5fb32c5 in mainline for uspace/app/bdsh/tok.c


Ignore:
Timestamp:
2011-08-20T09:05:14Z (13 years ago)
Author:
Petr Koupy <petr.koupy@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c916dfc
Parents:
921b84f (diff), a0fc4be (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge mainline changes.

File:
1 edited

Legend:

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

    r921b84f r5fb32c5  
    4242static bool tok_pending_chars(tokenizer_t *);
    4343static int tok_finish_string(tokenizer_t *);
     44static void tok_start_token(tokenizer_t *, token_type_t);
    4445
    4546/** Initialize the token parser
     
    5051 * @param max_tokens number of elements of the out_tokens array
    5152 */
    52 int tok_init(tokenizer_t *tok, char *input, char **out_tokens,
     53int tok_init(tokenizer_t *tok, char *input, token_t *out_tokens,
    5354    size_t max_tokens)
    5455{       
    5556        tok->in = input;
    5657        tok->in_offset = 0;
     58        tok->last_in_offset = 0;
     59        tok->in_char_offset = 0;
     60        tok->last_in_char_offset = 0;
    5761       
    5862        tok->outtok = out_tokens;
    5963        tok->outtok_offset = 0;
    60         /* Leave one slot for a null terminator */
    61         assert(max_tokens > 0);
    62         tok->outtok_size = max_tokens - 1;
     64        tok->outtok_size = max_tokens;
    6365       
    6466        /* Prepare a buffer where all the token strings will be stored */
     
    8789
    8890/** Tokenize the input string into the tokens */
    89 int tok_tokenize(tokenizer_t *tok)
     91int tok_tokenize(tokenizer_t *tok, size_t *tokens_length)
    9092{
    9193        int rc;
    92         wchar_t cur_char;
     94        wchar_t next_char;
    9395       
    9496        /* Read the input line char by char and append tokens */
    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.
     97        while ((next_char = tok_look_char(tok)) != 0) {
     98                if (next_char == ' ') {
     99                        /* Push the token if there is any.
    99100                         * There may not be any pending char for a token in case
    100101                         * there are several spaces in the input.
     
    106107                                }
    107108                        }
    108                 }
    109                 else if (cur_char == '|') {
    110                         /* Pipes are tokens that are delimiters and should be output
    111                          * as a separate token
     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
    112120                         */
    113121                        if (tok_pending_chars(tok)) {
     
    118126                        }
    119127                       
    120                         rc = tok_push_char(tok, '|');
     128                        tok_start_token(tok, TOKTYPE_PIPE);
     129                       
     130                        rc = tok_push_char(tok, tok_get_char(tok));
    121131                        if (rc != EOK) {
    122132                                return rc;
     
    128138                        }
    129139                }
    130                 else if (cur_char == '\'') {
     140                else if (next_char == '\'') {
    131141                        /* A string starts with a quote (') and ends again with a quote.
    132142                         * A literal quote is written as ''
    133143                         */
     144                        tok_start_token(tok, TOKTYPE_TEXT);
     145                        /* Eat the quote */
     146                        tok_get_char(tok);
    134147                        rc = tok_finish_string(tok);
    135148                        if (rc != EOK) {
     
    138151                }
    139152                else {
     153                        if (!tok_pending_chars(tok)) {
     154                                tok_start_token(tok, TOKTYPE_TEXT);
     155                        }
    140156                        /* If we are handling any other character, just append it to
    141157                         * the current token.
    142158                         */
    143                         rc = tok_push_char(tok, cur_char);
     159                        rc = tok_push_char(tok, tok_get_char(tok));
    144160                        if (rc != EOK) {
    145161                                return rc;
     
    156172        }
    157173       
    158         /* We always have a space for the terminator, as we
    159          * reserved it in tok_init */
    160         tok->outtok[tok->outtok_offset] = 0;
     174        *tokens_length = tok->outtok_offset;
    161175       
    162176        return EOK;
     
    167181{
    168182        int rc;
    169         wchar_t cur_char;
    170        
    171         while ((cur_char = tok_get_char(tok)) != 0) {
    172                 if (cur_char == '\'') {
     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);
    173189                        if (tok_look_char(tok) == '\'') {
    174190                                /* Encode a single literal quote */
     
    187203                }
    188204                else {
    189                         rc = tok_push_char(tok, cur_char);
     205                        rc = tok_push_char(tok, tok_get_char(tok));
    190206                        if (rc != EOK) {
    191207                                return rc;
     
    201217wchar_t tok_get_char(tokenizer_t *tok)
    202218{
     219        tok->in_char_offset++;
    203220        return str_decode(tok->in, &tok->in_offset, STR_NO_LIMIT);
    204221}
     
    207224wchar_t tok_look_char(tokenizer_t *tok)
    208225{
    209         size_t old_offset = tok->in_offset;
     226        unsigned int old_offset = tok->in_offset;
     227        unsigned int old_char_offset = tok->in_char_offset;
    210228        wchar_t ret = tok_get_char(tok);
    211229        tok->in_offset = old_offset;
     230        tok->in_char_offset = old_char_offset;
    212231        return ret;
    213232}
     
    219238}
    220239
     240void tok_start_token(tokenizer_t *tok, token_type_t type)
     241{
     242        tok->current_type = type;
     243}
     244
    221245/** Push the current token to the output array */
    222246int tok_push_token(tokenizer_t *tok)
     
    231255       
    232256        tok->outbuf[tok->outbuf_offset++] = 0;
    233         tok->outtok[tok->outtok_offset++] = tok->outbuf + tok->outbuf_last_start;
     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;
    234264        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;
    235269       
    236270        return EOK;
Note: See TracChangeset for help on using the changeset viewer.