示例#1
0
文件: ws.c 项目: markjeee/kannel
WsCompilerPtr ws_create(WsCompilerParams *params)
{
    WsCompilerPtr compiler = ws_calloc(1, sizeof(*compiler));

    if (compiler == NULL)
        return NULL;

    /* Store user params if specified. */
    if (params)
        compiler->params = *params;

    /* Basic initialization. */

    compiler->magic = COMPILER_MAGIC;

    if (compiler->params.stdout_cb == NULL) {
        compiler->params.stdout_cb = std_io;
        compiler->params.stdout_cb_context = stdout;
    }
    if (compiler->params.stderr_cb == NULL) {
        compiler->params.stderr_cb = std_io;
        compiler->params.stderr_cb_context = stderr;
    }

    return compiler;
}
示例#2
0
WsBc *ws_bc_alloc(WsBcStringEncoding string_encoding)
{
    WsBc *bc = ws_calloc(1, sizeof(WsBc));

    if (bc == NULL)
        return NULL;

    bc->string_encoding = string_encoding;

    return bc;
}
示例#3
0
WsHashPtr ws_hash_create(WsHashItemDestructor destructor, void *context)
{
    WsHashPtr hash = ws_calloc(1, sizeof(*hash));

    if (hash) {
        hash->destructor = destructor;
        hash->destructor_context = context;
    }

    return hash;
}
示例#4
0
WsFastMalloc *ws_f_create(size_t block_size)
{
    WsFastMalloc *pool = ws_calloc(1, sizeof(WsFastMalloc));

    if (pool == NULL)
        return NULL;

    pool->block_size = block_size;

    return pool;
}
示例#5
0
WsStream *ws_stream_new(void *context, WsStreamIOProc io,
                        WsStreamFlushProc flush, WsStreamCloseProc close)
{
    WsStream *stream = ws_calloc(1, sizeof(*stream));

    if (stream == NULL)
        return NULL;

    stream->io = io;
    stream->flush = flush;
    stream->close = close;
    stream->context = context;

    return stream;
}
示例#6
0
void ws_pragma_use(WsCompilerPtr compiler, WsUInt32 line, char *identifier,
                   WsUtf8String *url)
{
    WsPragmaUse *u = ws_calloc(1, sizeof(*u));
    WsPragmaUse *uold;

    /* Do we already know this pragma? */
    uold = ws_hash_get(compiler->pragma_use_hash, identifier);
    if (uold) {
        ws_src_error(compiler, line, "redefinition of pragma `%s'", identifier);
        ws_src_error(compiler, uold->line, "`%s' previously defined here",
                     identifier);
        goto error_cleanup;
    }

    if (u == NULL)
        goto error;

    u->line = line;

    /* Insert the URL to the byte-code module. */
    if (!ws_bc_add_const_utf8_string(compiler->bc, &u->urlindex, url->data,
                                     url->len))
        goto error;

    /* Add it to the use pragma hash. */
    if (!ws_hash_put(compiler->pragma_use_hash, identifier, u))
        goto error;

    /* Cleanup. */

    ws_lexer_free_block(compiler, identifier);
    ws_lexer_free_utf8(compiler, url);

    return;

    /* Error handling. */

error:

    ws_error_memory(compiler);

error_cleanup:

    ws_free(u);
    ws_lexer_free_block(compiler, identifier);
    ws_lexer_free_utf8(compiler, url);
}
示例#7
0
WsPragmaMetaBody *ws_pragma_meta_body(WsCompilerPtr compiler,
                                      WsUtf8String *property_name,
                                      WsUtf8String *content,
                                      WsUtf8String *scheme)
{
    WsPragmaMetaBody *mb = ws_calloc(1, sizeof(*mb));

    if (mb == NULL) {
        ws_error_memory(compiler);
        return NULL;
    }

    mb->property_name = property_name;
    mb->content = content;
    mb->scheme = scheme;

    return mb;
}
示例#8
0
WsStream *ws_stream_new_data_input(const unsigned char *data, size_t data_len)
{
    WsStreamDataInputCtx *ctx = ws_calloc(1, sizeof(*ctx));
    WsStream *stream;

    if (ctx == NULL)
        return NULL;

    ctx->data = data;
    ctx->data_len = data_len;

    stream = ws_stream_new(ctx, data_input, NULL, data_close);

    if (stream == NULL)
        /* The stream creation failed.  Close the stream context. */
        data_close(ctx);

    return stream;
}
示例#9
0
WsBool ws_hash_put(WsHashPtr hash, const char *name, void *data)
{
    WsHashItem *i;
    size_t h = count_hash(name);

    for (i = hash->items[h]; i; i = i->next) {
        if (strcmp(i->name, name) == 0) {
            /* Found it. */

            /* Destroy the old item */
            if (hash->destructor)
                (*hash->destructor)(i->data, hash->destructor_context);

            i->data = data;

            return WS_FALSE;
        }
    }

    /* Must create a new mapping. */
    i = ws_calloc(1, sizeof(*i));

    if (i == NULL)
        return WS_FALSE;

    i->name = ws_strdup(name);
    if (i->name == NULL) {
        ws_free(i);
        return WS_FALSE;
    }

    i->data = data;

    /* Link it to our hash. */
    i->next = hash->items[h];
    hash->items[h] = i;

    return WS_TRUE;
}
示例#10
0
WsStream *ws_stream_new_file(FILE *fp, WsBool output, WsBool close)
{
    WsStreamFileCtx *ctx = ws_calloc(1, sizeof(*ctx));
    WsStream *stream;

    if (ctx == NULL)
        return NULL;

    ctx->fp = fp;
    ctx->close_fp = close;

    if (output)
        stream = ws_stream_new(ctx, file_output, file_flush, file_close);
    else
        stream = ws_stream_new(ctx, file_input, file_flush, file_close);

    if (stream == NULL)
        /* The stream creation failed.  Close the stream context. */
        file_close(ctx);

    return stream;
}
示例#11
0
WsFunctionHash *ws_function_hash(WsCompilerPtr compiler, char *name)
{
    WsFunctionHash *i = ws_hash_get(compiler->functions_hash, name);

    if (i)
        return i;

    /* Must create a new mapping. */

    i = ws_calloc(1, sizeof(*i));
    if (i == NULL) {
        ws_error_memory(compiler);
        return NULL;
    }

    if (!ws_hash_put(compiler->functions_hash, name, i)) {
        ws_free(i);
        ws_error_memory(compiler);
        return NULL;
    }

    return i;
}
示例#12
0
WsNamespace *ws_variable_define(WsCompilerPtr compiler, WsUInt32 line,
                                WsBool variablep, char *name)
{
    WsNamespace *ns;

    /* Is the symbol already defined? */
    ns = ws_hash_get(compiler->variables_hash, name);
    if (ns) {
        ws_src_error(compiler, line, "redeclaration of `%s'", name);
        ws_src_error(compiler, ns->line, "`%s' previously declared here", name);
        return NULL;
    }

    /* Can we still define more variables? */
    if (compiler->next_vindex > 255) {
        /* No we can't. */
        ws_src_error(compiler, line, "too many local variables");
        return NULL;
    }

    ns = ws_calloc(1, sizeof(*ns));
    if (ns == NULL) {
        ws_error_memory(compiler);
        return NULL;
    }

    ns->line = line;
    ns->vindex = compiler->next_vindex++;

    if (!ws_hash_put(compiler->variables_hash, name, ns)) {
        ws_free(ns);
        ws_error_memory(compiler);
        return NULL;
    }

    return ns;
}
示例#13
0
WsBc *ws_bc_decode(const unsigned char *data, size_t data_len)
{
    WsBc *bc = ws_bc_alloc(WS_BC_STRING_ENC_ISO_8859_1);
    WsByte b;
    WsUInt32 ui32;
    WsUInt16 ui16, j;
    WsUInt16 ui16b;
    WsUInt8 ui8, num_functions, k, l;
    WsInt8 i8;
    WsInt16 i16;
    WsInt32 i32;
    WsIeee754Result ieee754;
    unsigned char *ucp;
    size_t decoded;

    /* Decode the byte-code header. */
    decoded = ws_decode_buffer(data, data_len,
                               WS_ENC_BYTE, &b,
                               WS_ENC_MB_UINT32, &ui32,
                               WS_ENC_END);

    if (!decoded
            || b != WS_BC_VERSION
            || ui32 != data_len - decoded)
        /* This is not a valid (or supported) byte-code header. */
        goto error;

    WS_UPDATE_DATA;

    /* Constant pool. */

    decoded = ws_decode_buffer(data, data_len,
                               WS_ENC_MB_UINT16, &ui16,
                               WS_ENC_MB_UINT16, &ui16b,
                               WS_ENC_END);
    if (!decoded)
        goto error;

    bc->string_encoding = ui16b;

    bc->constants = ws_calloc(ui16, sizeof(WsBcConstant));
    if (bc->constants == NULL)
        goto error;
    bc->num_constants = ui16;

    WS_UPDATE_DATA;

    for (j = 0; j < bc->num_constants; j++) {
        WsBcConstant *c = &bc->constants[j];

        decoded = ws_decode_buffer(data, data_len,
                                   WS_ENC_UINT8, &ui8,
                                   WS_ENC_END);
        if (decoded != 1)
            goto error;

        WS_UPDATE_DATA;

        switch (ui8) {
        case WS_BC_CONST_INT8:
            decoded = ws_decode_buffer(data, data_len,
                                       WS_ENC_INT8, &i8,
                                       WS_ENC_END);
            if (decoded != 1)
                goto error;

            WS_UPDATE_DATA;

            c->type = WS_BC_CONST_TYPE_INT;
            c->u.v_int = i8;
            break;

        case WS_BC_CONST_INT16:
            decoded = ws_decode_buffer(data, data_len,
                                       WS_ENC_INT16, &i16,
                                       WS_ENC_END);
            if (decoded != 2)
                goto error;

            WS_UPDATE_DATA;

            c->type = WS_BC_CONST_TYPE_INT;
            c->u.v_int = i16;
            break;

        case WS_BC_CONST_INT32:
            decoded = ws_decode_buffer(data, data_len,
                                       WS_ENC_INT32, &i32,
                                       WS_ENC_END);
            if (decoded != 4)
                goto error;

            WS_UPDATE_DATA;

            c->type = WS_BC_CONST_TYPE_INT;
            c->u.v_int = i32;
            break;

        case WS_BC_CONST_FLOAT32:
            decoded = ws_decode_buffer(data, data_len,
                                       WS_ENC_DATA, &ucp, (size_t) 4,
                                       WS_ENC_END);
            if (decoded != 4)
                goto error;

            WS_UPDATE_DATA;

            ieee754 = ws_ieee754_decode_single(ucp, &c->u.v_float);

            switch (ieee754) {
            case WS_IEEE754_OK:
                c->type = WS_BC_CONST_TYPE_FLOAT32;
                break;

            case WS_IEEE754_NAN:
                c->type = WS_BC_CONST_TYPE_FLOAT32_NAN;
                break;

            case WS_IEEE754_POSITIVE_INF:
                c->type = WS_BC_CONST_TYPE_FLOAT32_POSITIVE_INF;
                break;

            case WS_IEEE754_NEGATIVE_INF:
                c->type = WS_BC_CONST_TYPE_FLOAT32_NEGATIVE_INF;
                break;
            }

            break;

        case WS_BC_CONST_UTF8_STRING:
            decoded = ws_decode_buffer(data, data_len,
                                       WS_ENC_MB_UINT32, &ui32,
                                       WS_ENC_END);
            if (decoded == 0)
                goto error;

            WS_UPDATE_DATA;

            c->type = WS_BC_CONST_TYPE_UTF8_STRING;
            c->u.v_string.len = ui32;

            decoded = ws_decode_buffer(data, data_len,
                                       WS_ENC_DATA, &ucp, c->u.v_string.len,
                                       WS_ENC_END);
            if (decoded != ui32)
                goto error;

            WS_UPDATE_DATA;

            c->u.v_string.data = ws_memdup(ucp, ui32);
            if (c->u.v_string.data == NULL)
                goto error;

            /* Check the validity of the data. */
            if (!ws_utf8_verify(c->u.v_string.data, c->u.v_string.len,
                                &c->u.v_string.num_chars))
                goto error;
            break;

        case WS_BC_CONST_EMPTY_STRING:
            c->type = WS_BC_CONST_TYPE_EMPTY_STRING;
            break;

        case WS_BC_CONST_EXT_ENC_STRING:
            ws_fatal("external character encoding not implemented yet");
            break;

        default:
            /* Reserved. */
            goto error;
            break;
        }
    }

    /* Pragma pool. */

    decoded = ws_decode_buffer(data, data_len,
                               WS_ENC_MB_UINT16, &ui16,
                               WS_ENC_END);
    if (!decoded)
        goto error;

    bc->pragmas = ws_calloc(ui16, sizeof(WsBcPragma));
    if (bc->pragmas == NULL)
        goto error;
    bc->num_pragmas = ui16;

    WS_UPDATE_DATA;

    for (j = 0; j < bc->num_pragmas; j++) {
        WsBcPragma *p = &bc->pragmas[j];

        decoded = ws_decode_buffer(data, data_len,
                                   WS_ENC_UINT8, &ui8,
                                   WS_ENC_END);
        if (decoded != 1)
            goto error;

        WS_UPDATE_DATA;

        p->type = ui8;

        switch (ui8) {
        case WS_BC_PRAGMA_ACCESS_DOMAIN:
            decoded = ws_decode_buffer(data, data_len,
                                       WS_ENC_MB_UINT16, &p->index_1,
                                       WS_ENC_END);
            if (!decoded)
                goto error;

            WS_CHECK_STRING(p->index_1);
            break;

        case WS_BC_PRAGMA_ACCESS_PATH:
            decoded = ws_decode_buffer(data, data_len,
                                       WS_ENC_MB_UINT16, &p->index_1,
                                       WS_ENC_END);
            if (!decoded)
                goto error;

            WS_CHECK_STRING(p->index_1);
            break;

        case WS_BC_PRAGMA_USER_AGENT_PROPERTY:
            decoded = ws_decode_buffer(data, data_len,
                                       WS_ENC_MB_UINT16, &p->index_1,
                                       WS_ENC_MB_UINT16, &p->index_2,
                                       WS_ENC_END);
            if (!decoded)
                goto error;

            WS_CHECK_STRING(p->index_1);
            WS_CHECK_STRING(p->index_2);
            break;

        case WS_BC_PRAGMA_USER_AGENT_PROPERTY_AND_SCHEME:
            decoded = ws_decode_buffer(data, data_len,
                                       WS_ENC_MB_UINT16, &p->index_1,
                                       WS_ENC_MB_UINT16, &p->index_2,
                                       WS_ENC_MB_UINT16, &p->index_3,
                                       WS_ENC_END);
            if (!decoded)
                goto error;

            WS_CHECK_STRING(p->index_1);
            WS_CHECK_STRING(p->index_2);
            WS_CHECK_STRING(p->index_3);
            break;

        default:
            goto error;
            break;
        }

        WS_UPDATE_DATA;
    }

    /* Function pool. */

    decoded = ws_decode_buffer(data, data_len,
                               WS_ENC_UINT8, &num_functions,
                               WS_ENC_END);
    if (decoded != 1)
        goto error;

    WS_UPDATE_DATA;

    /* Function names. */

    decoded = ws_decode_buffer(data, data_len,
                               WS_ENC_UINT8, &ui8,
                               WS_ENC_END);
    if (decoded != 1)
        goto error;

    WS_UPDATE_DATA;

    if (ui8) {
        /* We have function names. */
        bc->function_names = ws_calloc(ui8, sizeof(WsBcFunctionName));
        if (bc->function_names == NULL)
            goto error;
        bc->num_function_names = ui8;

        for (k = 0; k < bc->num_function_names; k++) {
            WsBcFunctionName *n = &bc->function_names[k];

            decoded = ws_decode_buffer(data, data_len,
                                       WS_ENC_UINT8, &n->index,
                                       WS_ENC_UINT8, &ui8,
                                       WS_ENC_END);
            if (decoded != 2)
                goto error;

            WS_UPDATE_DATA;

            decoded = ws_decode_buffer(data, data_len,
                                       WS_ENC_DATA, &ucp, (size_t) ui8,
                                       WS_ENC_END);
            if (decoded != ui8)
                goto error;

            WS_UPDATE_DATA;

            n->name = ws_memdup(ucp, ui8);
            if (n->name == NULL)
                goto error;

            /* Check the validity of the name. */

            if (!ws_utf8_verify((unsigned char *) n->name, ui8, NULL))
                goto error;

            /* Just check that the data contains only valid characters. */
            for (l = 0; l < ui8; l++) {
                unsigned int ch = (unsigned char) n->name[l];

                if (('a' <= ch && ch <= 'z')
                        || ('A' <= ch && ch <= 'Z')
                        || ch == '_'
                        || (l > 0 && ('0' <= ch && ch <= '9')))
                    /* Ok. */
                    continue;

                /* Invalid character in the function name. */
                goto error;
            }

            /* Is the index valid? */
            if (n->index >= num_functions)
                goto error;
        }
    }

    /* Functions. */

    if (num_functions) {
        /* We have functions. */
        bc->functions = ws_calloc(num_functions, sizeof(WsBcFunction));
        if (bc->functions == NULL)
            goto error;
        bc->num_functions = num_functions;

        for (k = 0; k < bc->num_functions; k++) {
            WsBcFunction *f = &bc->functions[k];

            decoded = ws_decode_buffer(data, data_len,
                                       WS_ENC_UINT8, &f->num_arguments,
                                       WS_ENC_UINT8, &f->num_locals,
                                       WS_ENC_MB_UINT32, &f->code_size,
                                       WS_ENC_END);
            if (!decoded)
                goto error;

            WS_UPDATE_DATA;

            decoded = ws_decode_buffer(data, data_len,
                                       WS_ENC_DATA, &ucp, f->code_size,
                                       WS_ENC_END);
            if (decoded != f->code_size)
                goto error;

            WS_UPDATE_DATA;

            if (f->code_size) {
                /* It is not an empty function. */
                f->code = ws_memdup(ucp, f->code_size);
                if (f->code == NULL)
                    goto error;
            }
        }
    }

    /* Did we process it all? */
    if (data_len != 0)
        goto error;

    /* All done. */
    return bc;

    /*
     * Error handling.
     */

error:

    ws_bc_free(bc);

    return NULL;
}
示例#14
0
WsUtf8String *ws_utf8_alloc()
{
    return ws_calloc(1, sizeof(WsUtf8String));
}
示例#15
0
WsBuffer *ws_buffer_alloc()
{
    return ws_calloc(1, sizeof(WsBuffer));
}