Example #1
0
static void
parse_query_string(sl_vm_t* vm, SLVAL dict, size_t len, uint8_t* query_string)
{
    uint8_t *key = query_string, *value = NULL;
    size_t key_len = 0, value_len = 0;
    size_t i;
    SLVAL addee = dict, k, v;
    int bracket_mode = 0, in_bracket = 0;
    for(i = 0; i <= len; i++) {
        if(i == len || query_string[i] == '&') {
            if(key_len > 0) {
                k = sl_string_url_decode(vm, sl_make_string(vm, key, key_len));
                if(value) {
                    v = sl_string_url_decode(vm, sl_make_string(vm, value, value_len));
                }
                sl_dict_set(vm, addee, k, value ? v : vm->lib.nil);
            }
            key = query_string + i + 1;
            key_len = 0;
            value = NULL;
            value_len = 0;
            addee = dict;
            in_bracket = 0;
            bracket_mode = 0;
            continue;
        }
        if(query_string[i] == '=' && !value) {
            value = query_string + i + 1;
            continue;
        }
        if(value) {
            value_len++;
        } else {
            if(query_string[i] == '[') {
                k = sl_make_string(vm, key, key_len);
                key = query_string + i + 1;
                key_len = 0;
                if(!sl_is_a(vm, sl_dict_get(vm, addee, k), vm->lib.Dict)) {
                    sl_dict_set(vm, addee, k, sl_make_dict(vm, 0, NULL));
                }
                addee = sl_dict_get(vm, addee, k);
                in_bracket = 1;
                bracket_mode = 1;
                continue;
            }
            if(query_string[i] == ']' && in_bracket) {
                in_bracket = 0;
                continue;
            }
            if(bracket_mode && !in_bracket) {
                /* skip until \0, & or = */
                while(i + 1 < len && query_string[i + 1] != '&' && query_string[i + 1] != '=') {
                    i++;
                }
                continue;
            }
            key_len++;
        }
    }
}
Example #2
0
static void
parse_cookie_string(sl_vm_t* vm, SLVAL dict, size_t len, uint8_t* cookies)
{
    uint8_t *key = NULL, *value = NULL;
    size_t key_len = 0, value_len = 0;
    size_t i;
    for(i = 0; i <= len; i++) {
        if(i == len || cookies[i] == ';') {
            if(key_len) {
                sl_dict_set(vm, dict,
                    sl_string_url_decode(vm, sl_make_string(vm, key, key_len)),
                    sl_string_url_decode(vm, sl_make_string(vm, value, value_len)));
            }
            key_len = 0;
            value_len = 0;
            key = NULL;
            value = NULL;
        }
        if(cookies[i] != ' ' && !key) {
            key = cookies + i;
            key_len++;
            continue;
        }
        if(cookies[i] == '=' && !value) {
            value = cookies + i + 1;
            continue;
        }
        if(!value) {
            key_len++;
        } else {
            value_len++;
        }
    }
}
Example #3
0
File: json.c Project: Hmaal/slash
static int
on_map_key(void* ctx, const uint8_t* str, size_t len)
{
    json_parse_t* json = ctx;
    json->key = sl_make_string(json->vm, (uint8_t*)str, len);
    return 1;
}
Example #4
0
SLVAL
sl_string_html_escape(sl_vm_t* vm, SLVAL self)
{
    sl_string_t* str = sl_get_string(vm, self);
    size_t out_cap = 32;
    size_t out_len = 0;
    size_t str_i;
    uint8_t* out = sl_alloc_buffer(vm->arena, out_cap);
    for(str_i = 0; str_i < str->buff_len; str_i++) {
        if(out_len + 8 >= out_cap) {
            out_cap *= 2;
            out = sl_realloc(vm->arena, out, out_cap);
        }
        if(str->buff[str_i] == '<') {
            memcpy(out + out_len, "&lt;", 4);
            out_len += 4;
        } else if(str->buff[str_i] == '>') {
            memcpy(out + out_len, "&gt;", 4);
            out_len += 4;
        } else if(str->buff[str_i] == '"') {
            memcpy(out + out_len, "&quot;", 6);
            out_len += 6;
        } else if(str->buff[str_i] == '\'') {
            memcpy(out + out_len, "&#039;", 6);
            out_len += 6;
        } else if(str->buff[str_i] == '&') {
            memcpy(out + out_len, "&amp;", 5);
            out_len += 5;
        } else {
            out[out_len++] = str->buff[str_i];
        }
    }
    return sl_make_string(vm, out, out_len);
}
Example #5
0
File: string.c Project: richo/slash
SLVAL
sl_string_char_at_index(sl_vm_t* vm, SLVAL self, SLVAL index)
{
    sl_string_t* str = sl_get_string(vm, self);
    if(sl_is_a(vm, index, vm->lib.Range_Inclusive) || sl_is_a(vm, index, vm->lib.Range_Exclusive)) {
        return string_range_index(vm, self, index);
    }
    long idx = sl_get_int(sl_expect(vm, index, vm->lib.Int));
    if(idx < 0) {
        idx += str->char_len;
    }
    if(idx < 0 || idx >= (long)str->char_len) {
        return vm->lib.nil;
    }
    uint8_t* buff_ptr = str->buff;
    size_t len = str->buff_len;
    while(idx) {
        sl_utf8_each_char(vm, &buff_ptr, &len);
        idx--;
    }
    size_t slice_len = 1;
    while(slice_len < len && (buff_ptr[slice_len] & 0xc0) == 0x80) {
        slice_len++;
    }
    return sl_make_string(vm, buff_ptr, slice_len);
}
Example #6
0
SLVAL
sl_string_url_decode(sl_vm_t* vm, SLVAL self)
{
    sl_string_t* str = sl_get_string(vm, self);
    size_t out_cap = 32;
    size_t out_len = 0;
    uint8_t* out = sl_alloc_buffer(vm->arena, out_cap);
    size_t str_i;
    char tmp[3];
    for(str_i = 0; str_i < str->buff_len; str_i++) {
        if(out_len + 8 >= out_cap) {
            out_cap *= 2;
            out = sl_realloc(vm->arena, out, out_cap);
        }
        if(str->buff[str_i] == '%') {
            if(str_i + 2 < str->buff_len) {
                if(is_hex_char(str->buff[str_i + 1]) && is_hex_char(str->buff[str_i + 2])) {
                    tmp[0] = str->buff[str_i + 1];
                    tmp[1] = str->buff[str_i + 2];
                    tmp[2] = 0;
                    out[out_len++] = strtol(tmp, NULL, 16);
                    str_i += 2;
                    continue;
                }
            }
        }
        if(str->buff[str_i] == '+') {
            out[out_len++] = ' ';
            continue;
        }
        out[out_len++] = str->buff[str_i];
    }
    return sl_make_string(vm, out, out_len);
}
Example #7
0
File: json.c Project: Hmaal/slash
static int
on_string(void* ctx, const uint8_t* str, size_t len)
{
    json_parse_t* json = ctx;
    SLVAL s = sl_make_string(json->vm, (uint8_t*)str, len);
    JSON_ADD_VALUE(s);
    return 1;
}
Example #8
0
SLVAL
sl_regexp_match_after(sl_vm_t* vm, SLVAL self)
{
    sl_regexp_match_t* match = get_regexp_match(vm, self);
    int index = cap_index(vm, self, sl_make_int(vm, 0));
    sl_string_t* str = (sl_string_t*)sl_get_ptr(match->match_string);
    return sl_make_string(vm, str->buff + match->captures[index + 1], str->buff_len - match->captures[index + 1]);
}
Example #9
0
File: mysql.c Project: Hmaal/slash
static SLVAL
sl_mysql_escape(sl_vm_t* vm, SLVAL self, SLVAL str)
{
    mysql_t* mysql = get_mysql(vm, self);
    sl_string_t* s = sl_get_string(vm, str);
    char* esc = sl_alloc(vm->arena, s->buff_len * 2 + 1);
    size_t esc_len = mysql_real_escape_string(&mysql->mysql, esc, (char*)s->buff, s->buff_len);
    return sl_make_string(vm, (uint8_t*)esc, esc_len);
}
Example #10
0
File: string.c Project: richo/slash
SLVAL
sl_string_concat(sl_vm_t* vm, SLVAL self, SLVAL other)
{
    sl_string_t* a = sl_get_string(vm, self);
    sl_string_t* b = sl_get_string(vm, other);
    uint8_t* buff = (uint8_t*)sl_alloc_buffer(vm->arena, a->buff_len + b->buff_len);
    memcpy(buff, a->buff, a->buff_len);
    memcpy(buff + a->buff_len, b->buff, b->buff_len);
    return sl_make_string(vm, buff, a->buff_len + b->buff_len);
}
Example #11
0
static sl_node_base_t*
lambda_expression(sl_parse_state_t* ps)
{
    sl_node_base_t* body;
    sl_token_t* tok;
    size_t arg_count = 0, arg_cap = 2;
    sl_string_t** args = sl_alloc(ps->vm->arena, sizeof(sl_string_t*) * arg_cap);
    sl_parse_scope_t scope;
    expect_token(ps, SL_TOK_LAMBDA);
    if(peek_token(ps)->type == SL_TOK_IDENTIFIER) {
        tok = next_token(ps);
        args[arg_count++] = (sl_string_t*)sl_get_ptr(
            sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len));
    } else if(peek_token(ps)->type != SL_TOK_OPEN_BRACE && peek_token(ps)->type != SL_TOK_DOT) {
        expect_token(ps, SL_TOK_OPEN_PAREN);
        while(peek_token(ps)->type != SL_TOK_CLOSE_PAREN) {
            if(arg_count >= arg_cap) {
                arg_cap *= 2;
                args = sl_realloc(ps->vm->arena, args, sizeof(sl_string_t*) * arg_cap);
            }
            tok = expect_token(ps, SL_TOK_IDENTIFIER);
            args[arg_count++] = (sl_string_t*)sl_get_ptr(
                sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len));
            if(peek_token(ps)->type != SL_TOK_CLOSE_PAREN) {
                expect_token(ps, SL_TOK_COMMA);
            }
        }
        expect_token(ps, SL_TOK_CLOSE_PAREN);
    }
    scope.prev = ps->scope;
    scope.flags = SL_PF_CAN_RETURN;
    ps->scope = &scope;
    if(peek_token(ps)->type == SL_TOK_DOT) {
        next_token(ps);
        body = expression(ps);
    } else {
        body = body_expression(ps);
    }
    ps->scope = scope.prev;
    ps->scope->flags |= SL_PF_SCOPE_CLOSURE;
    return sl_make_lambda_node(ps, arg_count, args, body);
}
Example #12
0
SLVAL
sl_regexp_match_index(sl_vm_t* vm, SLVAL self, SLVAL i)
{
    sl_regexp_match_t* match = get_regexp_match(vm, self);
    int index = cap_index(vm, self, i);
    if(index < 0) {
        return vm->lib.nil;
    }
    sl_string_t* str = (sl_string_t*)sl_get_ptr(match->match_string);
    return sl_make_string(vm, str->buff + match->captures[index], match->captures[index + 1] - match->captures[index]);
}
Example #13
0
static sl_node_base_t*
class_expression(sl_parse_state_t* ps)
{
    sl_token_t* class_token = expect_token(ps, SL_TOK_CLASS);
    SLVAL doc = ps->vm->lib.nil;
    if(class_token->comment) {
        doc = sl_make_string(ps->vm, class_token->comment->buff, class_token->comment->len);
    }
    sl_token_t* tok = expect_token(ps, SL_TOK_CONSTANT);
    SLID name = sl_intern2(ps->vm, sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len));
    sl_node_base_t *extends, *body;
    if(peek_token(ps)->type == SL_TOK_EXTENDS) {
        next_token(ps);
        extends = expression(ps);
    } else {
        extends = NULL;
    }
    body = body_expression(ps);
    return sl_make_class_node(ps, name, doc, extends, body);
}
Example #14
0
static sl_node_base_t*
send_expression(sl_parse_state_t* ps, sl_node_base_t* recv)
{
    SLVAL id;
    sl_token_t* tok;
    tok = expect_token(ps, SL_TOK_IDENTIFIER);
    id = sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len);
    if(peek_token(ps)->type != SL_TOK_OPEN_PAREN) {
        return sl_make_send_node(ps, recv, sl_intern2(ps->vm, id), 0, NULL);
    }
    return send_with_args_expression(ps, recv, sl_intern2(ps->vm, id));
}
Example #15
0
static sl_node_base_t*
call_expression(sl_parse_state_t* ps)
{
    sl_node_base_t* left = primary_expression(ps);
    sl_node_base_t** nodes;
    size_t node_len;
    size_t node_cap;
    sl_token_t* tok;
    if(left->type == SL_NODE_VAR && peek_token(ps)->type == SL_TOK_OPEN_PAREN) {
        left = send_with_args_expression(ps, sl_make_self_node(ps),
            sl_intern2(ps->vm, sl_make_ptr((sl_object_t*)((sl_node_var_t*)left)->name)));
    }
    while(1) {
        tok = peek_token(ps);
        switch(tok->type) {
            case SL_TOK_DOT:
                next_token(ps);
                left = send_expression(ps, left);
                break;
            case SL_TOK_COLON:
                next_token(ps);
                left = sl_make_bind_method_node(ps, left, def_expression_method_name(ps));
                break;
            case SL_TOK_PAAMAYIM_NEKUDOTAYIM:
                next_token(ps);
                tok = expect_token(ps, SL_TOK_CONSTANT);
                left = sl_make_const_node(ps, left,
                    sl_intern2(ps->vm,
                        sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len)));
                break;
            case SL_TOK_OPEN_BRACKET:
                next_token(ps);
                node_cap = 1;
                node_len = 0;
                nodes = sl_alloc(ps->vm->arena, sizeof(SLVAL) * node_cap);
                while(peek_token(ps)->type != SL_TOK_CLOSE_BRACKET) {
                    if(node_len >= node_cap) {
                        node_cap *= 2;
                        nodes = sl_realloc(ps->vm->arena, nodes, sizeof(SLVAL) * node_cap);
                    }
                    nodes[node_len++] = expression(ps);
                    if(peek_token(ps)->type != SL_TOK_CLOSE_BRACKET) {
                        expect_token(ps, SL_TOK_COMMA);
                    }
                }
                expect_token(ps, SL_TOK_CLOSE_BRACKET);
                left = sl_make_send_node(ps, left, sl_intern(ps->vm, "[]"), node_len, nodes);
                break;
            default:
                return left;
        }
    }
}
Example #16
0
File: slash.c Project: Hmaal/slash
static void
output(sl_vm_t* sub_vm, char* buff, size_t len)
{
    slash_t* sl = sub_vm->data;
    sl_vm_t* vm = sl->host_vm;
    if(sl_responds_to2(vm, sl->output_handler, vm->id.call)) {
        SLVAL ex;
        sl_vm_frame_t catch_frame;
        SL_TRY(catch_frame, SL_UNWIND_ALL, {
            SLVAL string = sl_make_string(vm, (uint8_t*)buff, len);
            sl_send_id(vm, sl->output_handler, vm->id.call, 1, string);
        }, ex, {
Example #17
0
SLVAL
sl_string_concat(sl_vm_t* vm, SLVAL self, SLVAL other)
{
    sl_string_t* a = sl_get_string(vm, self);
    sl_string_t* b = sl_get_string(vm, other);
    if(strcmp(a->encoding, b->encoding) != 0) {
        return sl_string_concat(vm, self, sl_string_encode(vm, other, a->encoding));
    }
    uint8_t* buff = (uint8_t*)sl_alloc_buffer(vm->arena, a->buff_len + b->buff_len);
    memcpy(buff, a->buff, a->buff_len);
    memcpy(buff + a->buff_len, b->buff, b->buff_len);
    return sl_make_string(vm, buff, a->buff_len + b->buff_len);
}
Example #18
0
static SLVAL
sl_gcrypt_algorithm_hex_digest(sl_vm_t* vm, SLVAL self, SLVAL strv)
{
    size_t i;
    sl_string_t* str = sl_get_string(vm, strv);
    gcrypt_algorithm_t* algo = get_algo_check(vm, self);
    size_t digest_len = gcry_md_get_algo_dlen(algo->algo);
    char* digest = alloca(digest_len);
    char* hex_digest = alloca(digest_len * 2);
    gcry_md_hash_buffer(algo->algo, digest, str->buff, str->buff_len);
    for(i = 0; i < digest_len; i++) {
        sprintf(hex_digest + 2 * i, "%02x", (uint8_t)digest[i]);
    }
    return sl_make_string(vm, (uint8_t*)hex_digest, digest_len * 2);
}
Example #19
0
File: json.c Project: Hmaal/slash
static SLVAL
sl_json_dump(sl_vm_t* vm, SLVAL self, SLVAL object)
{
    json_dump_t dump;
    dump.vm = vm;
    dump.buffer_len = 0;
    dump.buffer_cap = 32;
    dump.buffer = sl_alloc_buffer(vm->arena, dump.buffer_cap);
    dump.seen_len = 0;
    dump.seen_cap = 32;
    dump.seen_ptrs = sl_alloc(vm->arena, sizeof(void*) * dump.seen_cap);
    json_dump(&dump, object);
    return sl_make_string(vm, dump.buffer, dump.buffer_len);
    (void)self;
}
Example #20
0
SLVAL
sl_string_url_encode(sl_vm_t* vm, SLVAL self)
{
    sl_string_t* str = sl_get_string(vm, self);
    size_t out_cap = 32;
    size_t out_len = 0;
    uint8_t* out = sl_alloc_buffer(vm->arena, out_cap);
    size_t clen = str->buff_len;
    uint8_t* cbuff = str->buff;
    uint32_t c;
    uint8_t utf8buff[8];
    uint32_t utf8len;
    while(clen) {
        if(out_len + 16 >= out_cap) {
            out_cap *= 2;
            out = sl_realloc(vm->arena, out, out_cap);
        }
        c = sl_utf8_each_char(vm, &cbuff, &clen);
        if(c >= 'A' && c <= 'Z') {
            out[out_len++] = c;
            continue;
        }
        if(c >= 'a' && c <= 'z') {
            out[out_len++] = c;
            continue;
        }
        if(c >= '0' && c <= '9') {
            out[out_len++] = c;
            continue;
        }
        if(c == '-' || c == '_' || c == '.' || c == '~') {
            out[out_len++] = c;
            continue;
        }
        if(c == ' ') {
            out[out_len++] = '+';
            continue;
        }
        utf8len = sl_utf32_char_to_utf8(vm, c, utf8buff);
        for(unsigned int i = 0; i < utf8len; i++) {
            sprintf((char*)out + out_len, "%%%2X", utf8buff[i]);
            out_len += 3;
        }
    }
    return sl_make_string(vm, out, out_len);
}
Example #21
0
SLVAL
sl_string_times(sl_vm_t* vm, SLVAL self, SLVAL other)
{
    sl_string_t* str = sl_get_string(vm, self);
    long mul = sl_get_int(sl_expect(vm, other, vm->lib.Int));
    if(mul && (size_t)LONG_MAX / mul < str->buff_len) {
        sl_throw_message2(vm, vm->lib.ArgumentError, "String multiplier is too big");
    }
    sl_string_t* new_str = sl_get_string(vm, sl_make_string(vm, NULL, 0));
    new_str->buff_len = str->buff_len * mul;
    new_str->buff = sl_alloc(vm->arena, new_str->buff_len);
    for(size_t i = 0; i < new_str->buff_len; i += str->buff_len) {
        memcpy(new_str->buff + i, str->buff, str->buff_len);
    }
    new_str->char_len = str->char_len * mul;
    return sl_make_ptr((sl_object_t*)new_str);
}
Example #22
0
SLVAL
sl_string_inspect(sl_vm_t* vm, SLVAL self)
{
    sl_string_t* str = sl_get_string(vm, self);
    size_t out_cap = 32;
    size_t out_len = 0;
    size_t str_i;
    uint8_t* out = sl_alloc_buffer(vm->arena, out_cap);
    out[out_len++] = '"';
    for(str_i = 0; str_i < str->buff_len; str_i++) {
        if(out_len + 8 >= out_cap) {
            out_cap *= 2;
            out = sl_realloc(vm->arena, out, out_cap);
        }
        if(str->buff[str_i] == '"') {
            memcpy(out + out_len, "\\\"", 2);
            out_len += 2;
        } else if(str->buff[str_i] == '\\') {
            memcpy(out + out_len, "\\\\", 2);
            out_len += 2;
        } else if(str->buff[str_i] == '\n') {
            memcpy(out + out_len, "\\n", 2);
            out_len += 2;
        } else if(str->buff[str_i] == '\r') {
            memcpy(out + out_len, "\\r", 2);
            out_len += 2;
        } else if(str->buff[str_i] == '\t') {
            memcpy(out + out_len, "\\t", 2);
            out_len += 2;
        } else if(str->buff[str_i] < 0x20) {
            out[out_len++] = '\\';
            out[out_len++] = 'x';
            out[out_len++] = '0' + str->buff[str_i] / 0x10;
            if(str->buff[str_i] % 0x10 < 10) {
                out[out_len++] = '0' + str->buff[str_i] % 0x10;
            } else {
                out[out_len++] = 'A' + (str->buff[str_i] % 0x10) - 10;
            }
        } else {
            out[out_len++] = str->buff[str_i];
        }
    }
    out[out_len++] = '"';
    return sl_make_string(vm, out, out_len);
}
Example #23
0
File: string.c Project: richo/slash
static SLVAL
string_range_index(sl_vm_t* vm, SLVAL self, SLVAL range)
{
    sl_string_t* str = sl_get_string(vm, self);
    SLVAL lowerv = sl_range_lower(vm, range);
    SLVAL upperv = sl_range_upper(vm, range);
    if(!sl_is_a(vm, lowerv, vm->lib.Int) || !sl_is_a(vm, upperv, vm->lib.Int)) {
        sl_throw_message2(vm, vm->lib.TypeError, "Expected range of integers");
    }
    long lower = sl_get_int(lowerv), upper = sl_get_int(upperv);
    if(lower < 0) {
        lower += str->char_len;
    }
    if(lower < 0 || (size_t)lower >= str->char_len) {
        return sl_make_cstring(vm, "");
    }
    if(upper < 0) {
        upper += str->char_len;
    }
    if(upper < 0) {
        return sl_make_cstring(vm, "");
    }
    if(sl_range_is_exclusive(vm, range)) {
        upper--;
    }
    if(upper < lower) {
        return sl_make_cstring(vm, "");
    }
    uint8_t* begin_ptr = str->buff;
    uint8_t* end_ptr;
    size_t len = str->buff_len;
    long idx = 0;
    while(idx < lower && len) {
        idx++;
        sl_utf8_each_char(vm, &begin_ptr, &len);
    }
    end_ptr = begin_ptr;
    while(lower <= upper) {
        lower++;
        sl_utf8_each_char(vm, &end_ptr, &len);
    }
    return sl_make_string(vm, begin_ptr, (size_t)end_ptr - (size_t)begin_ptr);
}
Example #24
0
void
sl_request_set_opts(sl_vm_t* vm, sl_request_opts_t* opts)
{
    size_t i;
    SLVAL n, v, cookies;
    sl_string_t* str;
    sl_request_internal_opts_t* req = sl_alloc(vm->arena, sizeof(sl_request_internal_opts_t));
    req->method       = sl_make_cstring(vm, opts->method);
    req->uri          = sl_make_cstring(vm, opts->uri);
    req->path_info    = sl_make_cstring(vm, opts->path_info ? opts->path_info : "");
    req->query_string = sl_make_cstring(vm, opts->query_string ? opts->query_string : "");
    req->remote_addr  = sl_make_cstring(vm, opts->remote_addr);
    req->headers      = sl_make_dict(vm, 0, NULL);
    req->env          = sl_make_dict(vm, 0, NULL);
    req->get          = sl_make_dict(vm, 0, NULL);
    req->post         = sl_make_dict(vm, 0, NULL);
    req->post_data    = sl_make_string(vm, (uint8_t*)opts->post_data, opts->post_length);
    req->cookies      = sl_make_dict(vm, 0, NULL);
    for(i = 0; i < opts->header_count; i++) {
        n = sl_make_cstring(vm, opts->headers[i].name);
        v = sl_make_cstring(vm, opts->headers[i].value);
        sl_dict_set(vm, req->headers, n, v);
    }
    for(i = 0; i < opts->env_count; i++) {
        n = sl_make_cstring(vm, opts->env[i].name);
        v = sl_make_cstring(vm, opts->env[i].value);
        sl_dict_set(vm, req->env, n, v);
    }
    if(opts->query_string) {
        parse_query_string(vm, req->get, strlen(opts->query_string), (uint8_t*)opts->query_string);
    }
    if(opts->content_type && strcmp(opts->content_type, "application/x-www-form-urlencoded") == 0) {
        parse_query_string(vm, req->post, opts->post_length, (uint8_t*)opts->post_data);
    }
    cookies = sl_dict_get(vm, req->headers, sl_make_cstring(vm, "Cookie"));
    if(sl_is_a(vm, cookies, vm->lib.String)) {
        str = (sl_string_t*)sl_get_ptr(cookies);
        parse_cookie_string(vm, req->cookies, str->buff_len, str->buff);
    }
    req->params = sl_dict_merge(vm, req->get, req->post);
    sl_vm_store_put(vm, &Request_opts, sl_make_ptr((sl_object_t*)req));
}
Example #25
0
File: mysql.c Project: Hmaal/slash
static SLVAL
sl_mysql_raw_query(sl_vm_t* vm, SLVAL self, SLVAL query)
{
    mysql_t* mysql = get_mysql(vm, self);
    sl_string_t* str = sl_get_string(vm, query);

    if(mysql_real_query(&mysql->mysql, (char*)str->buff, str->buff_len)) {
        sl_mysql_check_error(vm, &mysql->mysql);
    }

    MYSQL_RES* result;
    if((result = mysql_store_result(&mysql->mysql))) {
        /* do shit */
        int ncolumns = mysql_num_fields(result);
        int nrows = mysql_num_rows(result);
        SLVAL* rows = sl_alloc(vm->arena, sizeof(SLVAL) * nrows);
        MYSQL_FIELD* fields = mysql_fetch_fields(result);
        for(int i = 0; i < nrows; i++) {
            SLVAL* cells = sl_alloc(vm->arena, sizeof(SLVAL) * ncolumns * 2);
            MYSQL_ROW row = mysql_fetch_row(result);
            size_t* lengths = mysql_fetch_lengths(result);
            for(int j = 0; j < ncolumns; j++) {
                cells[j * 2] = sl_make_cstring(vm, fields[j].name);
                if(row[j]) {
                    cells[j * 2 + 1] = sl_make_string(vm, (uint8_t*)row[j], lengths[j]);
                } else {
                    cells[j * 2 + 1] = vm->lib.nil;
                }
            }
            rows[i] = sl_make_dict(vm, ncolumns, cells);
        }
        mysql_free_result(result);
        return sl_make_array(vm, nrows, rows);
    } else {
        if(mysql_field_count(&mysql->mysql) != 0) {
            sl_mysql_check_error(vm, &mysql->mysql);
        }
        return sl_make_int(vm, mysql_affected_rows(&mysql->mysql));
    }
}
Example #26
0
static void
sl_setup_regexp(sl_vm_t* vm, sl_regexp_t* re_ptr, uint8_t* re_buff, size_t re_len, uint8_t* opts_buff, size_t opts_len)
{
    char buff[256];
    const char* error;
    char* rez;
    int error_offset;
    int opts = DEFAULT_OPTIONS;
    pcre* re;
    size_t i;
    for(i = 0; i < opts_len; i++) {
        switch(opts_buff[i]) {
            case 'i':
                opts |= PCRE_CASELESS;
                break;
            case 'x':
                opts |= PCRE_EXTENDED;
                break;
            default:
                sprintf(buff, "Unknown regular expression option '%c'", opts_buff[i]);
                sl_throw_message2(vm, vm->lib.ArgumentError, buff);
        }
    }
    if(memchr(re_buff, 0, re_len)) {
        sl_throw_message2(vm, vm->lib.ArgumentError, "Regular expression contains null byte");
    }
    rez = sl_alloc_buffer(vm->arena, re_len + 1);
    memcpy(rez, re_buff, re_len);
    rez[re_len] = 0;
    re = pcre_compile(rez, opts, &error, &error_offset, NULL);
    if(!re) {
        sl_throw_message2(vm, vm->lib.SyntaxError, (char*)error);
    }
    re_ptr->source = sl_make_string(vm, re_buff, re_len);
    re_ptr->options = opts;
    re_ptr->re = re;
    re_ptr->study = NULL;
}
Example #27
0
File: mysql.c Project: Hmaal/slash
static SLVAL
sl_mysql_stmt_execute(sl_vm_t* vm, SLVAL self, size_t argc, SLVAL* argv)
{
    mysql_stmt_t* stmt = get_mysql_stmt(vm, self);
    size_t req = mysql_stmt_param_count(stmt->stmt);
    if(argc < req) {
        char buff[100];
        sprintf(buff, "Prepared statement has %lu parameter markers, but only %lu parameters were given", req, argc);
        sl_throw_message2(vm, vm->lib.ArgumentError, buff);
    }

    if(!stmt->bind) {
        stmt->bind = sl_alloc(vm->arena, sizeof(MYSQL_BIND) * req);
    }

    for(size_t i = 0; i < req; i++) {
        stmt->bind[i].buffer_type = MYSQL_TYPE_STRING;
        sl_string_t* str = sl_get_string(vm, sl_to_s(vm, argv[i]));
        stmt->bind[i].buffer = str->buff;
        stmt->bind[i].buffer_length = str->buff_len;
        stmt->bind[i].length = NULL;
        stmt->bind[i].is_null = NULL;
        stmt->bind[i].is_unsigned = 1;
        stmt->bind[i].error = NULL;
    }

    if(mysql_stmt_bind_param(stmt->stmt, stmt->bind)) {
        sl_mysql_stmt_check_error(vm, stmt->stmt);
    }

    if(mysql_stmt_execute(stmt->stmt)) {
        sl_mysql_stmt_check_error(vm, stmt->stmt);
    }

    MYSQL_RES* res = mysql_stmt_result_metadata(stmt->stmt);
    if(!res) {
        /* query did not produce a result set */
        return sl_make_int(vm, mysql_stmt_affected_rows(stmt->stmt));
    }

    int field_count = mysql_stmt_field_count(stmt->stmt);
    MYSQL_FIELD* field;
    SLVAL field_names[field_count];
    enum enum_field_types field_types[field_count];
    size_t field_i = 0;
    while((field = mysql_fetch_field(res))) {
        field_names[field_i] = sl_make_cstring(vm, field->name);
        if(field->type == MYSQL_TYPE_LONG || field->type == MYSQL_TYPE_SHORT || field->type == MYSQL_TYPE_TINY) {
            field_types[field_i] = MYSQL_TYPE_LONG;
        } else {
            field_types[field_i] = MYSQL_TYPE_STRING;
        }
        field_i++;
    }

    MYSQL_BIND output_binds[field_count];
    my_bool output_errors[field_count];
    my_bool output_is_nulls[field_count];
    unsigned long output_lengths[field_count];
    for(int i = 0; i < field_count; i++) {
        output_binds[i].buffer_type = MYSQL_TYPE_STRING;
        output_binds[i].buffer = NULL;
        output_binds[i].buffer_length = 0;
        output_binds[i].length = &output_lengths[i];
        output_binds[i].is_null = &output_is_nulls[i];
        output_binds[i].error = &output_errors[i];
    }
    if(mysql_stmt_bind_result(stmt->stmt, output_binds)) {
        sl_mysql_stmt_check_error(vm, stmt->stmt);
    }

    SLVAL result_rows = sl_make_array(vm, 0, NULL);
    while(1) {
        int code = mysql_stmt_fetch(stmt->stmt);
        if(code == MYSQL_NO_DATA) {
            break;
        }
        if(code == 1) {
            sl_mysql_stmt_check_error(vm, stmt->stmt);
        }
        SLVAL row = sl_make_dict(vm, 0, NULL);
        for(int i = 0; i < field_count; i++) {
            MYSQL_BIND cell;
            cell.length = &output_lengths[i];
            cell.is_null = &output_is_nulls[i];
            cell.error = &output_errors[i];
            cell.buffer_type = field_types[i];
            int buffer_long;
            switch(field_types[i]) {
                case MYSQL_TYPE_LONG:
                    cell.buffer = &buffer_long;
                    cell.buffer_length = sizeof(buffer_long);
                    break;
                default: /* MYSQL_TYPE_STRING */
                    cell.buffer = sl_alloc_buffer(vm->arena, output_lengths[i] + 1);
                    cell.buffer_length = output_lengths[i];
                    break;
            }
            if(mysql_stmt_fetch_column(stmt->stmt, &cell, i, 0)) {
                sl_mysql_stmt_check_error(vm, stmt->stmt);
            }
            switch(field_types[i]) {
                case MYSQL_TYPE_LONG:
                    sl_dict_set(vm, row, field_names[i], sl_make_int(vm, buffer_long));
                    break;
                default: /* MYSQL_TYPE_STRING */
                    sl_dict_set(vm, row, field_names[i], sl_make_string(vm, cell.buffer, output_lengths[i]));
                    break;
            }
        }
        sl_array_push(vm, result_rows, 1, &row);
    }

    return result_rows;
}
Example #28
0
static sl_node_base_t*
static_string_expression(sl_parse_state_t* ps)
{
    sl_token_t* tok = expect_token(ps, SL_TOK_STRING);
    return sl_make_immediate_node(ps, sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len));
}
Example #29
0
static sl_node_base_t*
primary_expression(sl_parse_state_t* ps)
{
    sl_token_t* tok;
    sl_node_base_t* node;
    switch(peek_token(ps)->type) {
        case SL_TOK_INTEGER:
            tok = next_token(ps);
            return sl_make_immediate_node(ps, sl_integer_parse(ps->vm, tok->as.str.buff, tok->as.str.len));
        case SL_TOK_FLOAT:
            return sl_make_immediate_node(ps, sl_make_float(ps->vm, next_token(ps)->as.dbl));
        case SL_TOK_STRING:
            tok = next_token(ps);
            return sl_make_immediate_node(ps, sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len));
        case SL_TOK_REGEXP:
            return regexp_expression(ps);
        case SL_TOK_CONSTANT:
            tok = next_token(ps);
            return sl_make_const_node(ps, NULL, sl_intern2(ps->vm, sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len)));
        case SL_TOK_IDENTIFIER:
            tok = next_token(ps);
            return sl_make_var_node(ps, SL_NODE_VAR,
                sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len));
        case SL_TOK_TRUE:
            next_token(ps);
            return sl_make_immediate_node(ps, ps->vm->lib._true);
        case SL_TOK_FALSE:
            next_token(ps);
            return sl_make_immediate_node(ps, ps->vm->lib._false);
        case SL_TOK_NIL:
            next_token(ps);
            return sl_make_immediate_node(ps, ps->vm->lib.nil);
        case SL_TOK_SELF:
            next_token(ps);
            return sl_make_self_node(ps);
        case SL_TOK_IVAR:
            tok = next_token(ps);
            node = sl_make_var_node(ps, SL_NODE_IVAR,
                sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len));
            return node;
        case SL_TOK_CVAR:
            tok = next_token(ps);
            node = sl_make_var_node(ps, SL_NODE_CVAR,
                sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len));
            return node;
        case SL_TOK_IF:
        case SL_TOK_UNLESS:
            return if_expression(ps);
        case SL_TOK_WHILE:
        case SL_TOK_UNTIL:
            return while_expression(ps);
        case SL_TOK_FOR:
            return for_expression(ps);
        case SL_TOK_CLASS:
            return class_expression(ps);
        case SL_TOK_DEF:
            return def_expression(ps);
        case SL_TOK_LAMBDA:
            return lambda_expression(ps);
        case SL_TOK_TRY:
            return try_expression(ps);
        case SL_TOK_OPEN_BRACKET:
            return array_expression(ps);
        case SL_TOK_OPEN_PAREN:
            return bracketed_expression(ps);
        case SL_TOK_OPEN_BRACE:
            return dict_expression(ps);
        case SL_TOK_NEXT:
            tok = next_token(ps);
            if(!(ps->scope->flags & SL_PF_CAN_NEXT_LAST)) {
                error(ps, sl_make_cstring(ps->vm, "next invalid outside loop"), tok);
            }
            return sl_make_singleton_node(ps, SL_NODE_NEXT);
        case SL_TOK_LAST:
            tok = next_token(ps);
            if(!(ps->scope->flags & SL_PF_CAN_NEXT_LAST)) {
                error(ps, sl_make_cstring(ps->vm, "last invalid outside loop"), tok);
            }
            return sl_make_singleton_node(ps, SL_NODE_LAST);
        case SL_TOK_RANGE_EX:
            next_token(ps);
            return sl_make_singleton_node(ps, SL_NODE_YADA_YADA);
        default:
            unexpected(ps, peek_token(ps));
            return NULL;
    }
}
Example #30
0
static sl_node_base_t*
def_expression(sl_parse_state_t* ps)
{
    SLID name;
    sl_node_base_t* on = NULL;
    sl_node_base_t* body;
    sl_token_t* tok;
    size_t req_arg_count = 0, req_arg_cap = 2;
    sl_string_t** req_args = sl_alloc(ps->vm->arena, sizeof(sl_string_t*) * req_arg_cap);
    size_t opt_arg_count = 0, opt_arg_cap = 2;
    sl_node_opt_arg_t* opt_args = sl_alloc(ps->vm->arena, sizeof(sl_node_opt_arg_t) * opt_arg_cap);
    sl_parse_scope_t scope;
    expect_token(ps, SL_TOK_DEF);
    switch(peek_token(ps)->type) {
        case SL_TOK_IDENTIFIER:
            if(peek_token_n(ps, 2)->type == SL_TOK_DOT) {
                on = sl_make_var_node(ps, SL_NODE_VAR, next_token(ps)->str);
                next_token(ps);
                name = def_expression_method_name(ps);
            } else {
                on = NULL;
                name = def_expression_method_name(ps);
            }
            break;
        case SL_TOK_SELF:
        case SL_TOK_IVAR:
        case SL_TOK_CVAR:
        case SL_TOK_CONSTANT:
            on = primary_expression(ps);
            expect_token(ps, SL_TOK_DOT);
            name = def_expression_method_name(ps);
            break;
        default:
            name = def_expression_method_name(ps);
    }
    if(peek_token(ps)->type == SL_TOK_EQUALS) {
        next_token(ps);
        name = sl_intern2(ps->vm,
            sl_string_concat(ps->vm, sl_id_to_string(ps->vm, name), sl_make_cstring(ps->vm, "=")));
    }
    int at_opt_args = 0;
    if(peek_token(ps)->type != SL_TOK_OPEN_BRACE) {
        expect_token(ps, SL_TOK_OPEN_PAREN);
        if(peek_token(ps)->type == SL_TOK_SELF) {
            error(ps, sl_make_cstring(ps->vm, "not a chance"), peek_token(ps));
        }
        while(peek_token(ps)->type != SL_TOK_CLOSE_PAREN) {
            tok = expect_token(ps, SL_TOK_IDENTIFIER);
            if(peek_token(ps)->type == SL_TOK_EQUALS) {
                at_opt_args = 1;
            }
            if(at_opt_args) {
                expect_token(ps, SL_TOK_EQUALS);
                if(opt_arg_count >= opt_arg_cap) {
                    opt_arg_cap *= 2;
                    opt_args = sl_realloc(ps->vm->arena, opt_args, sizeof(sl_node_opt_arg_t) * opt_arg_cap);
                }
                opt_args[opt_arg_count].name = (sl_string_t*)sl_get_ptr(
                    sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len));
                opt_args[opt_arg_count++].default_value = expression(ps);
            } else {
                if(req_arg_count >= req_arg_cap) {
                    req_arg_cap *= 2;
                    req_args = sl_realloc(ps->vm->arena, req_args, sizeof(sl_string_t*) * req_arg_cap);
                }
                req_args[req_arg_count++] = (sl_string_t*)sl_get_ptr(
                    sl_make_string(ps->vm, tok->as.str.buff, tok->as.str.len));
            }
            if(peek_token(ps)->type != SL_TOK_CLOSE_PAREN) {
                expect_token(ps, SL_TOK_COMMA);
            }
        }
        expect_token(ps, SL_TOK_CLOSE_PAREN);
    }
    scope.prev = ps->scope;
    scope.flags = SL_PF_CAN_RETURN;
    ps->scope = &scope;
    body = body_expression(ps);
    ps->scope = scope.prev;
    ps->scope->flags |= SL_PF_SCOPE_CLOSURE;
    return sl_make_def_node(ps, name, on, req_arg_count, req_args, opt_arg_count, opt_args, body);
}