Changeset 04a7435f in mainline for uspace/app/bithenge/script.c


Ignore:
Timestamp:
2012-06-26T19:56:26Z (12 years ago)
Author:
Sean Bartell <wingedtachikoma@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
978ccaf1
Parents:
f2da0bb
Message:

Bithenge: add the struct transform

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bithenge/script.c

    rf2da0bb r04a7435f  
    5353        TOKEN_EOF,
    5454        TOKEN_IDENTIFIER,
     55        TOKEN_LEFT_ARROW,
    5556
    5657        /* Keywords */
     58        TOKEN_STRUCT,
    5759        TOKEN_TRANSFORM,
    5860} token_type_t;
     
    181183                if (!value) {
    182184                        error_errno(state, ENOMEM);
     185                } else if (!str_cmp(value, "struct")) {
     186                        state->token = TOKEN_STRUCT;
     187                        free(value);
    183188                } else if (!str_cmp(value, "transform")) {
    184189                        state->token = TOKEN_TRANSFORM;
     
    188193                        state->token_string = value;
    189194                }
     195        } else if (ch == '<') {
     196                state->token = ch;
     197                state->buffer_pos++;
     198                if (state->buffer[state->buffer_pos] == '-') {
     199                        state->buffer_pos++;
     200                        state->token = TOKEN_LEFT_ARROW;
     201                }
    190202        } else {
    191203                state->token = ch;
     
    207219}
    208220
     221/** Reallocate memory and handle failure by setting the error in the state. If
     222 * an error occurs, the existing pointer will be returned. */
     223static void *state_realloc(state_t *state, void *ptr, size_t size)
     224{
     225        if (state->error != EOK)
     226                return ptr;
     227        void *result = realloc(ptr, size);
     228        if (result == NULL) {
     229                error_errno(state, ENOMEM);
     230                return ptr;
     231        }
     232        return result;
     233}
     234
    209235/** Expect and consume a certain token. If the next token is of the wrong type,
    210236 * an error is caused. */
     
    255281
    256282/** Add a named transform. This function takes ownership of the name and a
    257  * reference to the transform. */
     283 * reference to the transform. If an error has occurred, either may be null. */
    258284static void add_named_transform(state_t *state, bithenge_transform_t *xform, char *name)
    259285{
     
    269295        entry->next = state->transform_list;
    270296        state->transform_list = entry;
     297}
     298
     299static bithenge_transform_t *parse_transform(state_t *state);
     300
     301static bithenge_transform_t *parse_struct(state_t *state)
     302{
     303        size_t num = 0;
     304        bithenge_named_transform_t *subxforms;
     305        /* We keep an extra space for the {NULL, NULL} terminator. */
     306        subxforms = state_malloc(state, sizeof(*subxforms));
     307        expect(state, TOKEN_STRUCT);
     308        expect(state, '{');
     309        while (state->error == EOK && state->token != '}') {
     310                expect(state, '.');
     311                subxforms[num].name = expect_identifier(state);
     312                expect(state, TOKEN_LEFT_ARROW);
     313                subxforms[num].transform = parse_transform(state);
     314                expect(state, ';');
     315                num++;
     316                subxforms = state_realloc(state, subxforms,
     317                    (num + 1)*sizeof(*subxforms));
     318        }
     319        expect(state, '}');
     320
     321        if (state->error != EOK) {
     322                while (num--) {
     323                        free((void *)subxforms[num].name);
     324                        bithenge_transform_dec_ref(subxforms[num].transform);
     325                }
     326                free(subxforms);
     327                return NULL;
     328        }
     329
     330        subxforms[num].name = NULL;
     331        subxforms[num].transform = NULL;
     332        bithenge_transform_t *result;
     333        int rc = bithenge_new_struct(&result, subxforms);
     334        if (rc != EOK) {
     335                error_errno(state, rc);
     336                return NULL;
     337        }
     338        return result;
    271339}
    272340
     
    282350                next_token(state);
    283351                return result;
     352        } else if (state->token == TOKEN_STRUCT) {
     353                return parse_struct(state);
    284354        } else {
    285355                syntax_error(state, "unexpected (transform expected)");
Note: See TracChangeset for help on using the changeset viewer.