Exemplo n.º 1
0
HempBool
hemp_module_load(
    HempModule     module
) {
    hemp_debug_call("loading module: %s\n", module->name);

    /* just in case we've been here before */
    if (module->handle) {
//      hemp_debug_msg("module is already loaded: %s\n", module->name);
        return HEMP_TRUE;
    }
    else if (module->error) {
//      hemp_debug_msg("module has already failed: %s (%s)\n", module->name, module->error);
        return HEMP_FALSE;
    }

    module->handle = dlopen(module->name, RTLD_NOW|RTLD_GLOBAL);

    if (! module->handle) {
//      hemp_debug_msg("module failed: %s\n", module->name);
        return hemp_module_failed(
            module,
            "Failed to load %s module: %s", 
            module->name, dlerror()
        );
    }

//  hemp_debug_msg("loaded module: %s\n", module->name);

    module->loader = (HempLoader) dlsym(module->handle, HEMP_MODULE_LOADER);
    module->binder = (HempBinder) dlsym(module->handle, HEMP_MODULE_BINDER);

    /* customer loader can augment module and/or perform initialisation */    
    if (module->loader) {
        hemp_debug_call("calling module loader: %s", HEMP_MODULE_LOADER);
        if (! module->loader(module)) {
            return HEMP_FALSE;
        }
    }
    
    if (! module->binder) {
        return hemp_module_failed(
            module,
            "Missing %s() function in %s module",
            HEMP_MODULE_BINDER, module->name
        );
    }

//  hemp_debug_msg("found plugin init: %p\n", module->plugin);

    return HEMP_TRUE;
}
Exemplo n.º 2
0
Arquivo: parser.c Projeto: abw/hemp
HempList
hemp_parse_pairs(
    HEMP_PREFIX_ARGS
) {
    hemp_debug_call("hemp_parse_pairs()\n");

    HempFragment   expr;
    HempList       exprs = hemp_list_new();

    while (1) {
        /* skip whitespace and delimiters (commas) */
        hemp_skip_delimiter(fragptr);

//      hemp_debug_msg("%s parse_prefix (prec: %d): %p\n", save->type->name, precedence, save->type->parse_pair);
        expr = hemp_parse_pair(fragptr, scope, precedence, HEMP_FALSE);

        /* if it's not a pairable expression then we're done */
        if (! expr) {
//          hemp_debug_msg("expression does not yield pairs: %s (%p vs %p)\n", save->type->name, save, *fragptr);
            break;
        }
            
//      hemp_debug_msg("expression yields pairs: %s\n", expr->type->name);
        hemp_list_push(exprs, hemp_frag_val(expr));
    }

    if (! exprs->length && ! force) {
        hemp_list_free(exprs);
        exprs = NULL;
    }

    return exprs;
}
Exemplo n.º 3
0
Arquivo: document.c Projeto: abw/hemp
HempBool
hemp_document_scan(
    HempDocument document
) {
    hemp_debug_call("hemp_document_scan(%p)\n", document);

    if (! document->dialect->scanner)
        hemp_fatal("No scanner defined for %s document\n", document->dialect->name);

    if (! document->source->text)
        hemp_source_read(document->source);

    document->scanptr = 
    document->scantok = document->source->text;
    document->scanpos = 0;

    if (! document->scantags)
        document->scantags = hemp_stack_new(HEMP_SCANTAGS_SIZE);

    return document->dialect->scanner(document)
        ? HEMP_TRUE
        : HEMP_FALSE;

//    return hemp_action_run(document->scanner, document)
//        ? HEMP_TRUE
//        : HEMP_FALSE;
}
Exemplo n.º 4
0
Arquivo: document.c Projeto: abw/hemp
HempValue
hemp_document_data(
    HempDocument document,
    HempContext  context
) {
    hemp_debug_call("hemp_document_data(%p)\n", document);
    HempBool       my_context  = HEMP_FALSE;
    HempFragment   root        = hemp_document_tree(document);
    HempValue      values;
    HempList       results;

    if (! root)
        hemp_fatal("document does not have a root element");
    
    if (! context) {
        my_context  = HEMP_TRUE;
        context     = hemp_context_new(document->hemp);
    }

    values  = root->type->values(hemp_frag_val(root), context, HempNothing);
    results = hemp_val_list(values);
    
    if (my_context)
        hemp_context_free(context);

    if (results->length > 1) {
        return values;
    }
    else if (results->length == 1) {
        return hemp_list_item(results, 0);
    }
    else {
        return HempEmpty;
    }
}
Exemplo n.º 5
0
Arquivo: document.c Projeto: abw/hemp
HempText
hemp_document_process(
    HempDocument document,
    HempContext  context,
    HempText     output
) {
    hemp_debug_call("hemp_document_process(%p)\n", document);
    HempBool       my_context  = HEMP_FALSE;
    HempFragment   root        = hemp_document_tree(document);

    if (! context) {
        my_context = HEMP_TRUE;
        context = hemp_context_new(document->hemp);
    }

    if (! root)
        hemp_fatal("document does not have a root element");

    if (! output)
        output = hemp_text_new();

    root->type->text(hemp_frag_val(root), context, hemp_text_val(output));

//    HEMP_CATCH_ALL;
//       hemp_fatal("Error processing document: %s", hemp->error->message);
//    HEMP_END;

    if (my_context)
        hemp_context_free(context);

    return output;
}
Exemplo n.º 6
0
Arquivo: document.c Projeto: abw/hemp
HempText
hemp_document_render(
    HempDocument document,
    HempContext  context
) {
    hemp_debug_call("hemp_document_render(%p)\n", document);
    return hemp_document_process(document, context, NULL);
}
Exemplo n.º 7
0
Arquivo: file.c Projeto: abw/hemp
void
hemp_scheme_file_cleaner(
    HempSource source 
) {
    if (source->text) {
        hemp_debug_call("cleaning file source: %s\n%s\n", source->name, source->text);
        hemp_mem_free(source->text);
    }
}
Exemplo n.º 8
0
Arquivo: document.c Projeto: abw/hemp
HempFragment
hemp_document_tokens(
    HempDocument document
) {
    hemp_debug_call("hemp_document_tokens(%p)\n", document);

    if (! document->fragments->head)
        hemp_document_scan(document);

    return document->fragments->head;
}
Exemplo n.º 9
0
Arquivo: document.c Projeto: abw/hemp
HempFragment
hemp_document_tree(
    HempDocument document
) {
    hemp_debug_call("hemp_document_tree(%p)\n", document);

    if (! document->tree)
        hemp_document_compile(document);
        
    return document->tree;
}
Exemplo n.º 10
0
Arquivo: list.c Projeto: abw/hemp
HempList
hemp_list_init(
    HempList list
) {
    HEMP_INSTANCE(list);
    hemp_debug_call("hemp_list_init(%p)\n", list);
    list->items    = NULL;
    list->length   = 0;
    list->capacity = 0;
    list->cleaner  = NULL;
    return list;
}
Exemplo n.º 11
0
Arquivo: list.c Projeto: abw/hemp
void
hemp_list_release(
    HempList list
) {
    hemp_debug_call("hemp_list_release(%p)\n", list);
    if (list->items) {
        if (list->cleaner) {
            hemp_list_each(list, list->cleaner);
        }
        hemp_mem_free(list->items);
        list->items = NULL;
    }
}
Exemplo n.º 12
0
Arquivo: document.c Projeto: abw/hemp
HempBool
hemp_document_compile(
    HempDocument document
) {
    hemp_debug_call("hemp_document_compile(%p)\n", document);
    
    document->tree = hemp_fragment_parse(
        hemp_document_tokens(document),
        document->scope
    );

    // TODO: proper error handling
    return HEMP_TRUE;
}
Exemplo n.º 13
0
Arquivo: list.c Projeto: abw/hemp
HempBool
hemp_list_index(
    HempContext  context,
    HempValue    key,
    HempInt     *index
) {
    hemp_debug_call("hemp_list_index()\n");
    HempBool found = HEMP_FALSE;

    if (hemp_is_integer(key)) {
//      hemp_debug("got integer key\n");
        *index = hemp_val_int(key);
        found = HEMP_TRUE;
    }
    else {
        HempText ktext;
        HempBool kmine  = HEMP_FALSE;

        if (hemp_is_text(key)) {
//          hemp_debug("got text key\n");
            ktext = hemp_val_text(key);
        }
        else {
            /* otherwise we have to convert the key to text */
            /* TODO: must be a better way to check for numeric conversion without throwing an error? */
//          hemp_debug("creating text key\n");
            ktext = hemp_text_new_size(16);
            kmine = HEMP_TRUE;
            hemp_onto_text(key, context, hemp_text_val(ktext));
        }
//      hemp_debug("list text key: %s\n", ktext->string);

        if (hemp_string_intlike(ktext->string)) {
//          hemp_debug("got numlike string\n");
            *index = hemp_val_int(
                hemp_type_string_integer( hemp_str_val(ktext->string), context)
            );
            found = HEMP_TRUE;
        }
        else {
//          hemp_debug("text index is not numlike: %s\n", ktext->string);
        }

        if (kmine)
            hemp_text_free(ktext);
    }

    return found;
}
Exemplo n.º 14
0
Arquivo: parser.c Projeto: abw/hemp
HempList
hemp_parse_exprs(
    HEMP_PREFIX_ARGS
) {
    hemp_debug_call("hemp_parse_exprs( precedence => %d )\n", precedence);

    HempFragment   expr;
    HempList       exprs = hemp_list_new();
//  hemp_debug_msg("hemp_parse_exprs() LIST: %p\n", exprs);

    while (1) {
        /* skip whitespace, delimiters (commas) and separators (semi-colons) */
        hemp_skip_separator(fragptr);

        /* ask the next token to return an expression */
        hemp_debug_parse("%s parse_prefix: %p\n", (*fragptr)->type->name, (*fragptr)->type->parse_prefix);
        expr = hemp_parse_prefix(fragptr, scope, precedence, HEMP_FALSE);

        /* if it's not an expression (e.g. a terminator) then we're done */
        if (! expr)
            break;

        hemp_debug_parse("expr: %s\n", expr->type->name);
        hemp_list_push(exprs, hemp_frag_val(expr));
    }

    /* element should be EOF or we hit a duff token */
    if (hemp_at_eof(fragptr)) {
        hemp_debug_parse("%sReached EOF\n%s\n", HEMP_ANSI_GREEN, HEMP_ANSI_RESET);
    }
    else {
        hemp_debug_parse("%sNot an expression: %s:%s\n", HEMP_ANSI_RED, (*fragptr)->type->name, HEMP_ANSI_RESET);
    }

    // hemp_debug("n expressions: %d\n", exprs->length);
    
    if (! exprs->length && ! force) {
        hemp_list_free(exprs);
        exprs = NULL;
    }

#if HEMP_DEBUG & HEMP_DEBUG_PARSE
    hemp_fragment_dump_exprs(exprs);
#endif
    
    return exprs;
}
Exemplo n.º 15
0
Arquivo: viewer.c Projeto: abw/hemp
HempBool
hemp_viewer_add_view(
    HempViewer viewer,
    HempString name,
    hemp_view_f view
) {
    hemp_debug_call("hemp_viewer_add_view(%s:%s => %p)\n", viewer->name, name, view);
    HempU16 id = hemp_namespace_id(name);
    hemp_debug("%s ID: %d\n", name, id);
    
    if (id >= viewer->size)
        hemp_viewer_resize(viewer, id);

    if (viewer->view[id]) {
        hemp_debug("already got viewer for %s\n", name);
    }
    else {
        hemp_debug("installed view #%d\n", id);
        viewer->view[id] = view;
    }

    return HEMP_TRUE;
}
Exemplo n.º 16
0
Arquivo: viewer.c Projeto: abw/hemp
void
hemp_viewer_resize(
    HempViewer viewer,
    HempU16    min_size
) {
    hemp_debug_call("hemp_viewer_resize(%s, %d)\n", viewer->name, min_size);
    HempU16    old_size = viewer->size;
    HempU16    new_size = old_size;
    HempMemory buffer;
    HempU16    size;

    if (! new_size)
        new_size = HEMP_VIEW_SIZE;

    while (min_size >= new_size) {
        new_size = new_size << 1;
    }

    size   = new_size * sizeof(hemp_view_f);
    buffer = hemp_mem_alloc(size);

    if (! buffer)
        hemp_mem_fail("viewer view buffer");

    memset(buffer, 0, size);
    hemp_debug_mem("allocated and cleared %d bytes for %d views\n", size, new_size);
        
    if (old_size) {
        size = old_size * sizeof(hemp_view_f);
        hemp_mem_copy(viewer->view, buffer, size);
        hemp_debug_mem("copied %d bytes from previous %d views\n", size, old_size);
        hemp_mem_free(viewer->view);
    }
    
    viewer->view = buffer;
    viewer->size = new_size;
}
Exemplo n.º 17
0
HempModule
hemp_use_module(
    Hemp       hemp,
    HempString     type,
    HempString     name
) {
    hemp_debug_call("hemp_use_module(%s => %s)\n", type, name);

    HempValue  path = hemp_config_get(hemp, HEMP_CONFIG_MODPATH);
    HempString string;

    if (hemp_is_defined(path)) {
        string = hemp_to_string(path, hemp->context);
//      hemp_debug_msg("already got %s: %s\n", HEMP_CONFIG_MODPATH, string);
    }
    else {
        HempValue  dir  = hemp_config_get(hemp, HEMP_CONFIG_DIR);
        HempValue  mod  = hemp_config_get(hemp, HEMP_CONFIG_MODDIR);
        HempString dstr = hemp_to_string(dir, hemp->context);
        HempString mstr = hemp_to_string(mod, hemp->context);

        string = hemp_uri_path_join(dstr, mstr, 1);
//      hemp_debug_msg("constructed %s: %s\n", HEMP_CONFIG_MODPATH, string);

        /* ugly work-around so we can get the context to manage memory */
        HempText text = hemp_context_tmp_text_size(hemp->context, strlen(string) + 1);
        hemp_text_append_string(text, string);
        hemp_mem_free(string);
        string = text->string;
//        hemp_config_set(hemp, HEMP_CONFIG_MODPATH, hemp_text_val(text));
    }

    // TODO: need a way to save dotted path (hemp.module_path) back into config

    /* quick hack to get something working */
    HempString modpath = getenv("HEMP_MODULE_PATH");

    if (! modpath || ! *modpath) {
        modpath = string;
//        hemp_debug_msg("No HEMP_MODULE_PATH environment variable set\n");
//        return HEMP_FALSE;
    }

    /* TODO: sort this mess out */
    HempString tpath = hemp_uri_path_join(modpath, type, 1);
    HempString mpath = hemp_uri_path_join(tpath, name, 1);
    HempText   mtext = hemp_text_from_string(mpath);
    hemp_text_append_string(mtext, HEMP_MODULE_EXT);
    hemp_mem_free(mpath);
    hemp_mem_free(tpath);
//  hemp_debug_msg("constructed module path: %s\n", mtext->string);

    HempModule module = hemp_global_module(hemp->global, mtext->string);

    if (module->binder) {
        module->binder(module, hemp);
    }
    else if (module->error) {
        hemp_fatal(module->error);
    }
    else {
        /* should never happen - famous last word */
        hemp_fatal("No binder function for %s module", name);
    }

    hemp_text_free(mtext);
    return module;
}