Exemplo n.º 1
0
/* It's very fast if there are few close misses.            */
size_t CORD_str(CORD x, size_t start, CORD s)
{
    CORD_pos xpos;
    size_t xlen = CORD_len(x);
    size_t slen;
    register size_t start_len;
    const char * s_start;
    unsigned long s_buf = 0;    /* The first few characters of s    */
    unsigned long x_buf = 0;    /* Start of candidate substring.    */
                    /* Initialized only to make compilers   */
                    /* happy.               */
    unsigned long mask = 0;
    register size_t i;
    register size_t match_pos;

    if (s == CORD_EMPTY) return(start);
    if (CORD_IS_STRING(s)) {
        s_start = s;
        slen = strlen(s);
    } else {
        s_start = CORD_to_char_star(CORD_substr(s, 0, sizeof(unsigned long)));
        slen = CORD_len(s);
    }
    if (xlen < start || xlen - start < slen) return(CORD_NOT_FOUND);
    start_len = slen;
    if (start_len > sizeof(unsigned long)) start_len = sizeof(unsigned long);
    CORD_set_pos(xpos, x, start);
    for (i = 0; i < start_len; i++) {
        mask <<= 8;
        mask |= 0xff;
        s_buf <<= 8;
        s_buf |= (unsigned char)s_start[i];
        x_buf <<= 8;
        x_buf |= (unsigned char)CORD_pos_fetch(xpos);
        CORD_next(xpos);
    }
    for (match_pos = start; ; match_pos++) {
        if ((x_buf & mask) == s_buf) {
            if (slen == start_len ||
                CORD_ncmp(x, match_pos + start_len,
                      s, start_len, slen - start_len) == 0) {
                return(match_pos);
            }
        }
    if ( match_pos == xlen - slen ) {
        return(CORD_NOT_FOUND);
    }
        x_buf <<= 8;
        x_buf |= (unsigned char)CORD_pos_fetch(xpos);
        CORD_next(xpos);
    }
}
Exemplo n.º 2
0
int CORD_ncmp(CORD x, size_t x_start, CORD y, size_t y_start, size_t len)
{
    CORD_pos xpos;
    CORD_pos ypos;
    register size_t count;
    register long avail, yavail;

    CORD_set_pos(xpos, x, x_start);
    CORD_set_pos(ypos, y, y_start);
    for(count = 0; count < len;) {
        if (!CORD_pos_valid(xpos)) {
            if (CORD_pos_valid(ypos)) {
                return(-1);
            } else {
                return(0);
            }
        }
        if (!CORD_pos_valid(ypos)) {
            return(1);
        }
        if ((avail = CORD_pos_chars_left(xpos)) <= 0
            || (yavail = CORD_pos_chars_left(ypos)) <= 0) {
            register char xcurrent = CORD_pos_fetch(xpos);
            register char ycurrent = CORD_pos_fetch(ypos);
            if (xcurrent != ycurrent) return(xcurrent - ycurrent);
            CORD_next(xpos);
            CORD_next(ypos);
            count++;
        } else {
            /* process as many characters as we can */
            register int result;

            if (avail > yavail) avail = yavail;
            count += avail;
            if (count > len) avail -= (count - len);
            result = strncmp(CORD_pos_cur_char_addr(xpos),
                         CORD_pos_cur_char_addr(ypos), (size_t)avail);
            if (result != 0) return(result);
            CORD_pos_advance(xpos, (size_t)avail);
            CORD_pos_advance(ypos, (size_t)avail);
        }
    }
    return(0);
}
Exemplo n.º 3
0
int CORD_vsprintf(CORD * out, CORD format, va_list args)
{
    CORD_ec result;
    register int count;
    register char current;
    CORD_pos pos;
    char conv_spec[CONV_SPEC_LEN + 1];

    CORD_ec_init(result);
    for (CORD_set_pos(pos, format, 0); CORD_pos_valid(pos); CORD_next(pos)) {
        current = CORD_pos_fetch(pos);
        if (current == '%') {
            CORD_next(pos);
            if (!CORD_pos_valid(pos)) return(-1);
            current = CORD_pos_fetch(pos);
            if (current == '%') {
                CORD_ec_append(result, current);
            } else {
                int width, prec;
                int left_adj = 0;
                int long_arg = 0;
                CORD arg;
                size_t len;

                if (extract_conv_spec(pos, conv_spec,
                                      &width, &prec,
                                      &left_adj, &long_arg) < 0) {
                    return(-1);
                }
                current = CORD_pos_fetch(pos);
                switch(current) {
                case 'n':
                    /* Assign length to next arg */
                    if (long_arg == 0) {
                        int * pos_ptr;
                        pos_ptr = va_arg(args, int *);
                        *pos_ptr = ec_len(result);
                    } else if (long_arg > 0) {
                        long * pos_ptr;
                        pos_ptr = va_arg(args, long *);
                        *pos_ptr = ec_len(result);
                    } else {
Exemplo n.º 4
0
int CORD_cmp(CORD x, CORD y)
{
    CORD_pos xpos;
    CORD_pos ypos;
    register size_t avail, yavail;

    if (y == CORD_EMPTY) return(x != CORD_EMPTY);
    if (x == CORD_EMPTY) return(-1);
    if (CORD_IS_STRING(y) && CORD_IS_STRING(x)) return(strcmp(x,y));
    CORD_set_pos(xpos, x, 0);
    CORD_set_pos(ypos, y, 0);
    for(;;) {
        if (!CORD_pos_valid(xpos)) {
            if (CORD_pos_valid(ypos)) {
                return(-1);
            } else {
                return(0);
            }
        }
        if (!CORD_pos_valid(ypos)) {
            return(1);
        }
        if ((avail = CORD_pos_chars_left(xpos)) <= 0
            || (yavail = CORD_pos_chars_left(ypos)) <= 0) {
            register char xcurrent = CORD_pos_fetch(xpos);
            register char ycurrent = CORD_pos_fetch(ypos);
            if (xcurrent != ycurrent) return(xcurrent - ycurrent);
            CORD_next(xpos);
            CORD_next(ypos);
        } else {
            /* process as many characters as we can */
            register int result;

            if (avail > yavail) avail = yavail;
            result = strncmp(CORD_pos_cur_char_addr(xpos),
                         CORD_pos_cur_char_addr(ypos), avail);
            if (result != 0) return(result);
            CORD_pos_advance(xpos, avail);
            CORD_pos_advance(ypos, avail);
        }
    }
}
Exemplo n.º 5
0
/* -1 if 'h' is present.                                                */
static int extract_conv_spec(CORD_pos source, char *buf,
                             int * width, int *prec, int *left, int * long_arg)
{
    register int result = 0;
    register int current_number = 0;
    register int saw_period = 0;
    register int saw_number = 0;
    register int chars_so_far = 0;
    register char current;

    *width = NONE;
    buf[chars_so_far++] = '%';
    while(CORD_pos_valid(source)) {
        if (chars_so_far >= CONV_SPEC_LEN) return(-1);
        current = CORD_pos_fetch(source);
        buf[chars_so_far++] = current;
        switch(current) {
        case '*':
            saw_number = 1;
            current_number = VARIABLE;
            break;
        case '0':
            if (!saw_number) {
                /* Zero fill flag; ignore */
                break;
            } /* otherwise fall through: */
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            saw_number = 1;
            current_number *= 10;
            current_number += current - '0';
            break;
        case '.':
            saw_period = 1;
            if(saw_number) {
                *width = current_number;
                saw_number = 0;
            }
            current_number = 0;
            break;
        case 'l':
        case 'L':
            *long_arg = 1;
            current_number = 0;
            break;
        case 'h':
            *long_arg = -1;
            current_number = 0;
            break;
        case ' ':
        case '+':
        case '#':
            current_number = 0;
            break;
        case '-':
            *left = 1;
            current_number = 0;
            break;
        case 'd':
        case 'i':
        case 'o':
        case 'u':
        case 'x':
        case 'X':
        case 'f':
        case 'e':
        case 'E':
        case 'g':
        case 'G':
        case 'c':
        case 'C':
        case 's':
        case 'S':
        case 'p':
        case 'n':
        case 'r':
            goto done;
        default:
            return(-1);
        }
        CORD_next(source);
    }
    return(-1);
done:
    if (saw_number) {
        if (saw_period) {
            *prec = current_number;
        } else {
            *prec = NONE;
            *width = current_number;
        }
    } else {
        *prec = NONE;
    }
    buf[chars_so_far] = '\0';
    return(result);
}
Exemplo n.º 6
0
void test_basics(void)
{
    CORD x = CORD_from_char_star("ab");
    register int i;
    char c;
    CORD y;
    CORD_pos p;

    x = CORD_cat(x,x);
    if (x == CORD_EMPTY) ABORT("CORD_cat(x,x) returned empty cord");
    if (!CORD_IS_STRING(x)) ABORT("short cord should usually be a string");
    if (strcmp(x, "abab") != 0) ABORT("bad CORD_cat result");

    for (i = 1; i < 16; i++) {
        x = CORD_cat(x,x);
    }
    x = CORD_cat(x,"c");
    if (CORD_len(x) != 128*1024+1) ABORT("bad length");

    count = 0;
    if (CORD_iter5(x, 64*1024-1, test_fn, CORD_NO_FN, (void *)13) == 0) {
        ABORT("CORD_iter5 failed");
    }
    if (count != 64*1024 + 2) ABORT("CORD_iter5 failed");

    count = 0;
    CORD_set_pos(p, x, 64*1024-1);
    while(CORD_pos_valid(p)) {
        (void) test_fn(CORD_pos_fetch(p), (void *)13);
    CORD_next(p);
    }
    if (count != 64*1024 + 2) ABORT("Position based iteration failed");

    y = CORD_substr(x, 1023, 5);
    if (!y) ABORT("CORD_substr returned NULL");
    if (!CORD_IS_STRING(y)) ABORT("short cord should usually be a string");
    if (strcmp(y, "babab") != 0) ABORT("bad CORD_substr result");

    y = CORD_substr(x, 1024, 8);
    if (!y) ABORT("CORD_substr returned NULL");
    if (!CORD_IS_STRING(y)) ABORT("short cord should usually be a string");
    if (strcmp(y, "abababab") != 0) ABORT("bad CORD_substr result");

    y = CORD_substr(x, 128*1024-1, 8);
    if (!y) ABORT("CORD_substr returned NULL");
    if (!CORD_IS_STRING(y)) ABORT("short cord should usually be a string");
    if (strcmp(y, "bc") != 0) ABORT("bad CORD_substr result");

    x = CORD_balance(x);
    if (CORD_len(x) != 128*1024+1) ABORT("bad length");

    count = 0;
    if (CORD_iter5(x, 64*1024-1, test_fn, CORD_NO_FN, (void *)13) == 0) {
        ABORT("CORD_iter5 failed");
    }
    if (count != 64*1024 + 2) ABORT("CORD_iter5 failed");

    y = CORD_substr(x, 1023, 5);
    if (!y) ABORT("CORD_substr returned NULL");
    if (!CORD_IS_STRING(y)) ABORT("short cord should usually be a string");
    if (strcmp(y, "babab") != 0) ABORT("bad CORD_substr result");
    y = CORD_from_fn(id_cord_fn, 0, 13);
    i = 0;
    CORD_set_pos(p, y, i);
    while(CORD_pos_valid(p)) {
        c = CORD_pos_fetch(p);
        if(c != i) ABORT("Traversal of function node failed");
    CORD_next(p); i++;
    }
    if (i != 13) ABORT("Bad apparent length for function node");
}