⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 embedded.cc

📁 Unix下的MUD客户端程序
💻 CC
字号:
#include "mcl.h"#include "EmbeddedInterpreter.h"#include "NullEmbeddedInterpreter.h"#include "Plugin.h"#include <dlfcn.h>#include <unistd.h>// Default interpreter if we don't manage to load anythingstatic NullEmbeddedInterpreter nullEmbeddedInterpreter;EmbeddedInterpreter *embed_interp = &nullEmbeddedInterpreter;static StackedInterpreter *stacked_interp;static int interp_count = 0; // How many interpreters total do we havevoid EmbeddedInterpreter::runCallouts() {    static int last_callout_time;        if(last_callout_time != current_time) {        last_callout_time = current_time;        embed_interp->run_quietly("sys/idle", "", 0);    }}StackedInterpreter::StackedInterpreter(EmbeddedInterpreter *e1,EmbeddedInterpreter *e2) {    interpreters.insert(e1);    interpreters.insert(e2);}StackedInterpreter::~StackedInterpreter() {    FOREACH(EmbeddedInterpreter*, e, interpreters)        delete e;}// Slight code duplication here, but can't do much about it since the functions called are different,// unless I start messing around with some functors I guessbool StackedInterpreter::run(const char *function, const char *arg, char *out) {    char buf[interpreters.count()][MAX_MUD_BUF];    int i = 0;    bool res = false;        FOREACH(EmbeddedInterpreter*, e, interpreters) {        res = e->run(function, arg, buf[i]) || res;        arg = buf[i++];    }    if (out && res)        strcpy(out, buf[i-1]);    return res;}bool StackedInterpreter::load_file(const char* filename, bool suppress) {    bool res = false;    FOREACH(EmbeddedInterpreter*, e, interpreters)        res = e->load_file(filename, suppress) || res;    return res;}void StackedInterpreter::eval(const char* expr, char* out) {    interpreters[0]->eval(expr, out);}void *StackedInterpreter::match_prepare(const char* pattern, const char* replacement) {    return interpreters[0]->match_prepare(pattern,replacement);}void* StackedInterpreter::substitute_prepare(const char* pattern, const char* replacement)  {    return interpreters[0]->match_prepare(pattern,replacement);}bool StackedInterpreter::match(void *perlsub, const char *str, char *&out) {    return interpreters[0]->match(perlsub, str, out);}void StackedInterpreter::set(const char *var, int value) {    FOREACH(EmbeddedInterpreter*, e, interpreters)        e->set(var, value);}void StackedInterpreter::set(const char *var, const char* value) {    FOREACH(EmbeddedInterpreter*, e, interpreters)        e->set(var, value);}int StackedInterpreter::get_int(const char* name) {    return interpreters[0]->get_int(name);}char* StackedInterpreter::get_string(const char*name) {    return interpreters[0]->get_string(name);}bool StackedInterpreter::run_quietly(const char* path, const char *arg, char *out, bool suppress_error) {    char buf[interpreters.count()][MAX_MUD_BUF];    int i = 0;    bool res = false;        FOREACH(EmbeddedInterpreter*, e, interpreters) {        res = e->run_quietly(path, arg, buf[i], suppress_error) || res;        arg = buf[i++];    }    if (out && res)        strcpy(out, buf[i-1]);    return res;}List<Plugin*> Plugin::plugins;Plugin::Plugin(const char *_filename, void *_handle) : filename(_filename), handle(_handle) {}Plugin::~Plugin() {    dlclose(handle);}// Unload all the scriptsvoid Plugin::done() {    FOREACH(Plugin*,p,plugins)        if (p->doneFunction) {            p->doneFunction();            delete p;        }}// Load shared object and update interpreter settingsPlugin * Plugin::loadPlugin(const char *filename, const char *args) {    char buf[1024];    void *handle;        // Try global path or home directory    snprintf(buf, sizeof(buf), "%s/.mcl/plugins/%s", getenv("HOME"), filename);    if (access(buf, R_OK) < 0) {        snprintf(buf, sizeof(buf), "%s/plugins/%s", MCL_LOCAL_LIBRARY_PATH, filename);        if (access(buf, R_OK) < 0) {            snprintf(buf, sizeof(buf), "%s/plugins/%s", MCL_LIBRARY_PATH, filename);            if (access(buf, R_OK) < 0)                error ("Error loading %s: not found\n"                       "I tried looking for and failed to find:\n"                       "  %s/.mcl/plugins/%s\n"                       "  %s/plugins/%s\n"                       "  %s/plugins/%s\n"                       "If you installed the standard binary distribution, you probably\n"                       "forgot to move the plugin files to one of the above places.\n"                       , filename, getenv("HOME"), filename, MCL_LOCAL_LIBRARY_PATH, filename, MCL_LIBRARY_PATH, filename);        }    }        if (!(handle = dlopen(buf, RTLD_LAZY|RTLD_GLOBAL)))        error ("Error loading %s: %s\n", buf, dlerror());        Plugin *plugin = new Plugin(buf, handle);    plugins.insert(plugin);        // Call the initFunction, it returns an error message in case of error    const char *load_result;        if (!(plugin->initFunction = (InitFunction*)dlsym(handle, "initFunction")))        error ("Error loading %s: modules does not have a initFunction\n", buf);        if ((load_result = plugin->initFunction(args)))        error ("Error loading %s: %s\n", buf, load_result);        // Display some information about the module if the module so wishes    plugin->versionFunction = (VersionFunction*)dlsym(handle, "versionFunction");    plugin->doneFunction = (DoneFunction*)dlsym(handle, "doneFunction");        // Now let's setup the hooks    if ((plugin->createInterpreterFunction = (CreateInterpreterFunction*)dlsym(handle, "createInterpreter"))) {        EmbeddedInterpreter *interp = plugin->createInterpreterFunction();        if (!interp)            error ("Module %s: error creating interpreter", buf);        else {            if (stacked_interp) // If we already have a stacked set of interpreters, add it there                stacked_interp->add(interp);            else if (interp_count == 1) {                stacked_interp = new StackedInterpreter(embed_interp, interp);                embed_interp = stacked_interp;            } else // this is the first interpreter                embed_interp = interp;        }        interp_count++;    }        return plugin;}const char* Plugin::getVersionInformation() {    if (versionFunction)        return versionFunction();    else        return NULL;}void Plugin::displayLoadedPlugins() {    if (plugins.count() == 0)        report("Modules loaded: none");    else {        report("Modules loaded: ");        FOREACH(Plugin*, p, plugins) {            const char *info = p->getVersionInformation();            report("%s: %s", ~p->filename, info ? info : "(no version information)");        }    }}// Load all pluginsvoid Plugin::loadPlugins(const char *plugins) {    char module_name[INPUT_SIZE];    char module_args[INPUT_SIZE];    const char *s = plugins;    char *out;    // module_name [args], module_name [args]...    for (;*s;) {        while (isspace(*s))            s++;        out = module_name;        while (*s && !isspace(*s) && *s != ',')            *out++ = *s++;        *out = NUL;        if (!module_name[0])            continue;        out = module_args;        if (*s == ' ') { // module args follow space            out++;            while(*s && *s != ',')                *out++ = *s++;        }        *out = NUL;        if (*s == ',')            s++;        loadPlugin(Sprintf("%s.so", module_name), module_args);    }}bool NullEmbeddedInterpreter::load_file(const char*, bool) {    return false;}bool NullEmbeddedInterpreter::run_quietly(const char*, const char*, char*,bool) {    return false;}void EmbeddedInterpreter::enable_function(const char *function) {    for (String *s = failed.rewind(); s; s = failed.next())        if (*s == function) {            failed.remove(s);            delete s;        }}void EmbeddedInterpreter::disable_function(const char *function) {    String *s = new String(function);    failed.append(s);}bool EmbeddedInterpreter::isEnabled(const char *function) {    for (String *s = failed.rewind(); s; s = failed.next())        if (*s == function)            return false;    return true;}const char *EmbeddedInterpreter::findFile(const char *filename, const char *suffix) {    // Add suffix if not there already    if (strlen(filename) < strlen(suffix) || strcmp(filename+strlen(filename)-strlen(suffix), suffix))        filename = Sprintf("%s%s", filename, suffix);        const char *full;        // Try first compared to the .mcl directory    if (filename[0] != '/') {        full = Sprintf("%s/.mcl/%s", getenv("HOME"), filename);        if (access(full, R_OK) == 0)            return full;        // Globally installed files        full = Sprintf("/usr/lib/mcl/%s", filename);        if (access(full, R_OK) == 0)            return full;        full = Sprintf("/usr/local/lib/mcl/%s", filename);        if (access(full, R_OK) == 0)            return full;    }        if (access(filename, R_OK) == 0)        return filename;        return NULL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -