Phrase * phrase_from_string (const gchar *str) { Tokenizer *tok; gchar *term; Phrase *phrase; g_return_val_if_fail(str != NULL, NULL); if (index(str, '/') != NULL) { gchar **strs; guint idx; strs = g_strsplit(str, "/", 0); phrase = phrase_new(); for (idx = 0; strs[idx] != NULL; idx++) { phrase_append(phrase, strs[idx]); } g_strfreev(strs); } else { tok = tokenizer_new(str); phrase = phrase_new(); while(term = tokenizer_next(tok)){ phrase_append_nocopy(phrase, term); } tokenizer_free(tok); } return phrase; }
Object * get_exp_list(FILE *fp) { Object *exp; tokenize(fp); scanner(); exp = s_exp_list(); tokenizer_free(); return exp; }
/** * Unloads plugin * @param plugin Plugin that should be unloaded. */ void plugins_unloadplugin(Plugin plugin) { if (plugin->beforeDepsUnload != NULL) { plugin->beforeDepsUnload(plugin->info); } // Unload all plugin's dependencies. if (plugin->deps != NULL) { TOKENS tok = tokenizer_tokenize(plugin->deps, ','); for (size_t i = 0; i < tok->count; i++) { if (plugins_isloaded(tokenizer_gettok(tok, i))) { plugins_unload(tokenizer_gettok(tok, i)); } } tokenizer_free(tok); } if (plugin->done != NULL) { plugin->done(plugin->info); } // Free plugin handle. if (dlclose(plugin->handle) != 0) { printError("plugins", "Unable to unload library: %s", dlerror()); } free(plugin->info); free(plugin->name); free(plugin->path); // Remove plugin from chain if (plugin->prev != NULL) { plugin->prev->next = plugin->next; } else { loadedPlugins->first = plugin->next; } if (plugin->next != NULL) { plugin->next->prev = plugin->prev; } else { loadedPlugins->last = plugin->prev; } free(plugin); } // plugins_unloadplugin
/** * Load plugin in exactly given filename. It checks plugin's dependencies, * and tries to load them too. * @param path Path to plugin * @return Plugin load status */ PluginLoadStatus plugins_loadplugin(char *path) { PluginLoadStatus result = PLUG_OK; char *pathdup = path; if (file_exists(pathdup)) { char *basename = dirs_basename(pathdup); if (plugins_isloaded(basename)) { free(basename); printError("plugins", "Plugin %s is already loaded.", pathdup); return PLUG_ALREADY_LOADED; } printError("plugins", "Loading plugin %s", pathdup); Plugin plugin = malloc(sizeof(struct sPlugin)); // Add plugin to linked list, for circular dependency check plugin->prev = loadedPlugins->last; plugin->next = NULL; if (loadedPlugins->last != NULL) { loadedPlugins->last->next = plugin; } else { loadedPlugins->first = plugin; } loadedPlugins->last = plugin; plugin->handle = dlopen(pathdup, RTLD_LAZY | RTLD_GLOBAL); if (plugin->handle != NULL) { plugin->name = basename; plugin->path = strdup(path); plugin->info = malloc(sizeof(PluginInfo)); plugin->info->name = NULL; plugin->info->author = NULL; plugin->info->version = NULL; plugin->info->customData = NULL; plugin->info->irc = loadedPlugins->irc; plugin->info->config = loadedPlugins->config; plugin->info->events = loadedPlugins->events; plugin->info->socketpool = loadedPlugins->socketpool; plugin->deps = NULL; plugin->init = (PluginInitPrototype *)dlsym( plugin->handle, "PluginInit"); plugin->done = (PluginDonePrototype *)dlsym( plugin->handle, "PluginDone"); plugin->beforeDepsUnload = (PluginDonePrototype *)dlsym( plugin->handle, "PluginBeforeUnload"); if (plugin->init != NULL && plugin->done != NULL) { // Scan plugin dependencies. PluginLoadStatus depsLoad = PLUG_OK; // PluginDeps function is optional. PluginDepsPrototype *plugindeps = (PluginDepsPrototype *)dlsym(plugin->handle, "PluginDeps"); if (plugindeps != NULL) { plugindeps(&plugin->deps); if (plugin->deps != NULL) { TOKENS tok = tokenizer_tokenize(plugin->deps, ','); for (size_t i = 0; i < tok->count; i++) { if (!plugins_isloaded(tokenizer_gettok(tok, i))) { depsLoad = plugins_load( tokenizer_gettok(tok, i)); if (depsLoad != PLUG_OK) { break; } } } tokenizer_free(tok); } } if (depsLoad == PLUG_OK) { // And finally, when everything is OK, call init function. plugin->init(plugin->info); result = PLUG_OK; } else { printError("plugins", "Plugin %s will not be loaded, " "because of dependency error.", path); result = PLUG_DEPENDENCY; } } else { // If no init and done functions were found. plugins_unloadplugin(plugin); printError("plugins", "%s is not valid plugin.", pathdup); result = PLUG_INVALID; } // Unload plugin if it's loading failed. if (result != PLUG_OK) { plugin->done = NULL; plugins_unloadplugin(plugin); } // End of plug->handle != NULL } else { // Remove plugin from linked list loadedPlugins->last = loadedPlugins->last->prev; loadedPlugins->last->next = NULL; printError("plugins", "Plugin loading error: %s", dlerror()); result = PLUG_DL_ERROR; } } else { printError("plugins", "Plugin file not found."); result = PLUG_FILE_NOT_FOUND; } return result; } // plugins_loadplugin
void parser_push(const context_t *ctx, const line_t *line) { position_t *pos = line->position; // is the first block already set? if (p->blk == NULL) { p->blk = block_init(NULL, pos); } statement_t *stmt = new_statement(ctx); const operation_t *op = NULL; const char *name = NULL; label_t *label = NULL; // allow the tokenizer to fold comma into ",x" etc addressing mode tokens int allow_index = 0; // tokenize the line pstate_t state = P_INIT; tokenizer_t *tok = tokenizer_init(line->line); while (tokenizer_next(tok, allow_index)) { switch(state) { case P_OP: if (tok->type == T_TOKEN && tok->vals.op == OP_COLON) { // accept after label // continue to next stmt->type = S_LABEQPC; statement_push(stmt); stmt = new_statement(ctx); state = P_INIT; break; } if (tok->type == T_TOKEN && tok->vals.op == OP_ASSIGN) { // after label, that's a label value definition stmt->type = S_LABDEF; // next define the label from param state = P_PARAM; break; } // fall-through! case P_INIT: switch(tok->type) { case T_NAME: name = mem_alloc_strn(tok->line + tok->ptr, tok->len); op = operation_find(name); if (op != NULL) { // check if the operation is compatible with the current CPU if (0 == (ctx->cpu->isa & op->isa)) { // TODO: config for either no message or error warn_operation_not_for_cpu(pos, name, ctx->cpu->name); op = NULL; } } if (op == NULL) { // label // TODO: redefinition? label = label_init(ctx, name, pos); if (state == P_OP) { // we already had a label stmt->type = S_LABEQPC; statement_push(stmt); stmt = new_statement(ctx); } stmt->label = label; // expect operation next (but accept labels too) state = P_OP; } else { // operation stmt->op = op; state = P_PARAM; } break; default: // syntax error error_syntax(pos); goto end; break; } break; case P_PARAM: // parse parameters arith_parse(tok, allow_index, &stmt->param); break; default: error_syntax(pos); goto end; break; }; } statement_push(stmt); end: tokenizer_free(tok); }