Пример #1
0
static ParserElem*
S_consume_text(StringIterator *iter) {
    StringIterator *temp = StrIter_Clone(iter);

    while (1) {
        int32_t code_point = StrIter_Next(temp);
        if (code_point == '\\') {
            code_point = StrIter_Next(temp);
            if (code_point == STR_OOB) {
                break;
            }
        }
        else if (code_point == STR_OOB) {
            break;
        }
        else if (StrHelp_is_whitespace(code_point)
            || code_point == '"'
            || code_point == '('
            || code_point == ')'
           ) {
            StrIter_Recede(temp, 1);
            break;
        }
    }

    String *text = StrIter_crop(iter, temp);
    StrIter_Assign(iter, temp);
    DECREF(temp);
    return ParserElem_new(TOKEN_STRING, (Obj*)text);
}
Пример #2
0
String*
IxFileNames_local_part(String *path) {
    StringIterator *top = Str_Tail(path);
    int32_t code_point = StrIter_Prev(top);

    // Trim trailing slash.
    while (code_point == '/') {
        code_point = StrIter_Prev(top);
    }

    StringIterator *tail = StrIter_Clone(top);
    StrIter_Advance(tail, 1);

    // Substring should start after last slash.
    while (code_point != STR_OOB) {
        if (code_point == '/') {
            StrIter_Advance(top, 1);
            break;
        }
        code_point = StrIter_Prev(top);
    }

    String *retval = StrIter_crop(top, tail);

    DECREF(tail);
    DECREF(top);
    return retval;
}
Пример #3
0
static ParserElem*
S_consume_field(StringIterator *iter) {
    StringIterator *temp = StrIter_Clone(iter);

    // Field names constructs must start with a letter or underscore.
    int32_t code_point = StrIter_Next(temp);
    if (code_point == STR_OOB) {
        DECREF(temp);
        return NULL;
    }
    if (!(isalpha(code_point) || code_point == '_')) {
        DECREF(temp);
        return NULL;
    }

    // Only alphanumerics and underscores are allowed in field names.
    while (':' != (code_point = StrIter_Next(temp))) {
        if (code_point == STR_OOB) {
            DECREF(temp);
            return NULL;
        }
        if (!(isalnum(code_point) || code_point == '_')) {
            DECREF(temp);
            return NULL;
        }
    }

    // Field name constructs must be followed by something sensible.
    int32_t lookahead = StrIter_Next(temp);
    if (lookahead == STR_OOB) {
        DECREF(temp);
        return NULL;
    }
    if (!(isalnum(lookahead)
          || lookahead == '_'
          || lookahead > 127
          || lookahead == '"'
          || lookahead == '('
         )
       ) {
        DECREF(temp);
        return NULL;
    }

    // Consume string data.
    StrIter_Recede(temp, 2); // Back up over lookahead and colon.
    String *field = StrIter_crop(iter, temp);
    StrIter_Advance(temp, 1); // Skip colon.
    StrIter_Assign(iter, temp);
    DECREF(temp);
    return ParserElem_new(TOKEN_FIELD, (Obj*)field);
}
Пример #4
0
String*
Str_Trim_IMP(String *self) {
    StringIterator *top = STACK_ITER(self, 0);
    StrIter_Skip_Whitespace(top);

    StringIterator *tail = NULL;
    if (top->byte_offset < self->size) {
        tail = STACK_ITER(self, self->size);
        StrIter_Skip_Whitespace_Back(tail);
    }

    return StrIter_crop((StringIterator*)top, (StringIterator*)tail);
}
Пример #5
0
uint64_t
IxFileNames_extract_gen(String *name) {
    StringIterator *iter = Str_Top(name);

    // Advance past first underscore.  Bail if we run out of string or if we
    // encounter a NULL.
    while (1) {
        int32_t code_point = StrIter_Next(iter);
        if (code_point == STR_OOB) { return 0; }
        else if (code_point == '_') { break; }
    }

    String *num_string = StrIter_crop(iter, NULL);
    uint64_t retval = (uint64_t)Str_BaseX_To_I64(num_string, 36);

    DECREF(num_string);
    DECREF(iter);
    return retval;
}
Пример #6
0
static ParserElem*
S_consume_quoted_string(StringIterator *iter) {
    StringIterator *temp = StrIter_Clone(iter);

    if (StrIter_Next(temp) != '"') {
        THROW(ERR, "Internal error: expected a quote");
    }

    while (1) {
        int32_t code_point = StrIter_Next(temp);
        if (code_point == STR_OOB || code_point == '"') {
            break;
        }
        else if (code_point == '\\') {
            StrIter_Next(temp);
        }
    }

    String *text = StrIter_crop(iter, temp);
    StrIter_Assign(iter, temp);
    DECREF(temp);
    return ParserElem_new(TOKEN_STRING, (Obj*)text);
}
Пример #7
0
String*
Str_Trim_Tail_IMP(String *self) {
    StringIterator *tail = STACK_ITER(self, self->size);
    StrIter_Skip_Whitespace_Back(tail);
    return StrIter_crop(NULL, (StringIterator*)tail);
}
Пример #8
0
String*
Str_Trim_Top_IMP(String *self) {
    StringIterator *top = STACK_ITER(self, 0);
    StrIter_Skip_Whitespace(top);
    return StrIter_crop((StringIterator*)top, NULL);
}
Пример #9
0
static void
test_iterator_substring(TestBatchRunner *runner) {
    String *string = Str_newf("a%sb%sc%sd", smiley, smiley, smiley);

    StringIterator *start = Str_Top(string);
    StringIterator *end = Str_Tail(string);

    {
        String *substring = StrIter_crop(start, end);
        TEST_TRUE(runner, Str_Equals(substring, (Obj*)string),
                  "StrIter_crop whole string");
        DECREF(substring);
    }

    StrIter_Advance(start, 2);
    StrIter_Recede(end, 2);

    {
        String *substring = StrIter_crop(start, end);
        String *wanted = Str_newf("b%sc", smiley);
        TEST_TRUE(runner, Str_Equals(substring, (Obj*)wanted),
                  "StrIter_crop");

        TEST_TRUE(runner, StrIter_Starts_With(start, wanted),
                  "Starts_With returns true");
        TEST_TRUE(runner, StrIter_Ends_With(end, wanted),
                  "Ends_With returns true");

        DECREF(wanted);
        DECREF(substring);
    }

    {
        String *short_str = Str_newf("b%sx", smiley);
        TEST_FALSE(runner, StrIter_Starts_With(start, short_str),
                   "Starts_With returns false");
        TEST_FALSE(runner, StrIter_Ends_With(start, short_str),
                   "Ends_With returns false");

        String *long_str = Str_newf("b%sxxxxxxxxxxxx%sc", smiley, smiley);
        TEST_FALSE(runner, StrIter_Starts_With(start, long_str),
                   "Starts_With long string returns false");
        TEST_FALSE(runner, StrIter_Ends_With(end, long_str),
                   "Ends_With long string returns false");

        DECREF(short_str);
        DECREF(long_str);
    }

    {
        String *substring = StrIter_crop(end, NULL);
        String *wanted = Str_newf("%sd", smiley);
        TEST_TRUE(runner, Str_Equals(substring, (Obj*)wanted),
                  "StrIter_crop with NULL tail");
        DECREF(wanted);
        DECREF(substring);
    }

    {
        String *substring = StrIter_crop(NULL, start);
        String *wanted = Str_newf("a%s", smiley);
        TEST_TRUE(runner, Str_Equals(substring, (Obj*)wanted),
                  "StrIter_crop with NULL top");
        DECREF(wanted);
        DECREF(substring);
    }

    DECREF(start);
    DECREF(end);
    DECREF(string);
}