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

📄 config.cc

📁 Unix下的MUD客户端程序
💻 CC
📖 第 1 页 / 共 2 页
字号:
        }        // An option? (weirdness so we can have an empty line after =)        else if (1 == sscanf (buf, "%[^=] =%n", name, &len) && buf[len-1] == '=') {            int i, option_value;            value = buf+len;            while (isspace(*value))                value++;            for (i = 0; option_table[i].name; i++)                if (!strcasecmp (option_table[i].name, name)) {                                        if (option_table[i].ptype == pt_string)                        setStringOption(option_table[i].option, value);                    else {                        if (option_table[i].ptype == pt_char)                            option_value = value[0];                        else                            if ((1 != sscanf(value, "0x%x", &option_value))                                && (1 != sscanf(value, "%d", &option_value)))                                error ("Malformed number: %s\n",value);                        setOption (option_table[i].option, option_value);                    }                    break;                }                        if (!option_table[i].name) { // hmm, not found                for (i = 0; obsolete_options[i]; i++)                    if (!strcasecmp(name, obsolete_options[i]))                        goto NEXT_LINE;                                error ("Unrecognized option in configuration file: %s", name);            }        }                else if (!strcmp(keyword, "mud")) {            if (1 != sscanf(rest, "%s {", name))                error ("Invalid MUD line: Must be MUD <mudname> {");            readMUD(fp, name);        }        else					// mud data. or nothing.        {            match = sscanf (buf, " %512s %512s %d%n", mudname, hostname, &port, &count);                        if (match <= 0)                continue;            else if (match != 3)                error ("Invalid line: You did not specify a valid configuration option, or you did\n"                       "not specify a full MUD definition (MUD name, hostname and port):\n%s\n", buf);                        if (1 != sscanf (buf + count, " %[^\n]", commands))                commands[0] = NUL;                        mud_list->insert ((last_mud = new MUD (mudname, hostname, port, &globalMUD, commands)));        }            NEXT_LINE:        ;    }        fclose (fp);}// Parse this MUD command which can appear within a MUD { } section or in the old-style formatvoid Config::parseMUDLine(const char *keyword, const char *buf, MUD *mud) {    char name[INPUT_SIZE], value[INPUT_SIZE];        if (!strcmp(keyword, "macro")) {        if (2 != sscanf (buf, "%s %[^\n]", name, value))            error ("Invalid Macro format, must be Macro <key> <command>:\n%s\n", buf);                int key = key_lookup(name);                if (key < 0)            error ("Unknown key in macro definition: %s", buf);        mud->macro_list.insert(new Macro(key,value));    }    else if (!strcmp(keyword, "alias")) {        if (2 != sscanf (buf, "%s %[^\n]", name, value)) // alias?            error ("Invalid Alias format, must be Alias <name> <commands>:\n%s\n", buf);        mud->alias_list.insert(new Alias(name,value));    }    else if (!strcmp(keyword, "action")) {        String res;        Action *ac = Action::parse(buf, res, Action::Trigger);                if (!ac)            error (res);                mud->action_list.insert(ac);    }    else if (!strcmp(keyword, "subst")) {        String res;        Action *ac = Action::parse(buf, res, Action::Replacement);                if (!ac)            error (res);                mud->action_list.insert(ac);    } else        error ("Uh, parsedMUDLine() called with invalid keyword %s?!", keyword);}// Read in the data about a MUDvoid Config::readMUD(FILE *fp, const char *mudname) {    MUD *mud = new MUD(mudname, "", 0, &globalMUD);    char buf[INPUT_SIZE], name[INPUT_SIZE];    char keyword[INPUT_SIZE];    char *nl;    const char *s;    bool done = false;    int port;        while ((fgets(buf, sizeof(buf), fp))) {        if ((nl = strchr(buf, '\n')))            *nl = NUL;                for (s = buf; *s && isspace(*s); s++)            ;                if (*s == '}') {            done = true;            break;        }                if (*s == '#' || !*s)            continue;                s = one_argument(s, keyword, true);                if (!strcmp(keyword, "macro") ||            !strcmp(keyword, "alias") ||            !strcmp(keyword, "action") ||            !strcmp(keyword, "subst")) {            parseMUDLine(keyword, s, mud);        } else if (!strcmp(keyword, "host")) {            if (2 != sscanf(s, "%s %d", name, &port))                error ("Invalid Host line in MUD %s definition: %s", mudname, s);            mud->setHost(name, port);        } else if (!strcmp(keyword, "inherit")) {            MUD *parent = mud_list->find(s);            if (!parent)                error ("Parent MUD %s not found in MUD %s definition", s, mudname);            mud->inherits = parent;        } else if (!strcmp(keyword, "commands")) {            mud->commands = s;        } else            error ("Invalid keyword %s within mud %s definition:\n%s\n", keyword, mudname, buf);    }        if (!done)        error ("MUD entry %s was not propertly terminated with a }\n", mudname);    mud_list->insert(mud);}MUD * Config::findMud (const char *name) {	return mud_list->find(name);}static const char *type_to_string(ptype_t t) {    switch (t) {    case pt_int:  return "<num>";    case pt_hex:  return "<hex color>";    case pt_char: return "<char>";    case pt_bool: return "<0|1>";    default:        return "<???>";    }}// Parse command line optionsint Config::parseOptions (int argc, char **argv) {    int i,c;    char option_string[max_option*2+1];    char *pc;        // Build an option string based on the option_table    for (pc = option_string, i = 0; option_table[i].opt_char; i++) {        if (option_table[i].opt_char != '?')  {            *pc++ = option_table[i].opt_char;            if (option_table[i].ptype == pt_int || option_table[i].ptype == pt_hex || option_table[i].ptype == pt_string)                *pc++ = ':';            else if (option_table[i].ptype == pt_bool) {                *pc++ = ':';                *pc++ = ':';            }        }    }        *pc++ = '@'; *pc++ = ':';    *pc++ = 'x'; *pc++ = ':';    *pc = NUL;        while( (c = getopt(argc,argv, option_string)) != EOF)  {        // Help requested or error ocurred, show options        if (c == '?' || c == 'h')  {            fprintf (stderr,                     "\nmcl - my MUD client version %s\n"                     "Usage: mcl [options] [mud alias]\n\n",                     versionToString(VERSION)                    );                        for (i = 0; option_table[i].opt_char; i++)                if (option_table[i].opt_char != '?') {                    fprintf(stderr, "-%c%-10s\t%s",                            option_table[i].opt_char,                            type_to_string(option_table[i].ptype),                            option_table[i].description);                                        if (option_table[i].ptype == pt_int) {                        fprintf(stderr, " (%d-%d)", option_table[i].min, option_table[i].max);                    }                    fprintf(stderr, "\n");                }                        exit (EXIT_FAILURE);        } else if (c == '@') { // Recovering from alt-T            extern int session_fd;            session_fd = atoi(optarg);        } else if (c == 'x') { // execute command            interpreter.add(optarg);        } else            for (i = 0; option_table[i].opt_char; i++)	                if (option_table[i].opt_char == c)                {                    if (option_table[i].ptype == pt_int) // Integer option                        setOption(option_table[i].option, atoi(optarg));                    else if (option_table[i].ptype == pt_char) // char                        setOption(option_table[i].option, optarg[0]);                    else if (option_table[i].ptype == pt_string)                        setStringOption(option_table[i].option, optarg);                    else // Toggle (hmm, we don't even have any boolean options now?                    {                        if (optarg)                            setOption(option_table[i].option, atoi(optarg) ? true : false);                        else                            setOption(option_table[i].option, true);                    }                                        break;					                }    }        // Validate options        bool failed = false;        for (i = 0; option_table[i].name; i++)        if (getOption(option_table[i].option) > option_table[i].max) {            fprintf (stderr, "Option '%s' has value %d (max is %d)\n",                     option_table[i].name,                     getOption(option_table[i].option), option_table[i].max);                        failed = true;        } else if (getOption(option_table[i].option) < option_table[i].min) {            fprintf (stderr, "Option '%s' has value %d (min is %d)\n",                     option_table[i].name,                     getOption(option_table[i].option), option_table[i].min);                        failed = true;        }        if (failed)        error ("One or more options had values outside allowed range.");        return optind;}// Load config. If fname == NULL, use ~/.mclrcConfig::Config (const char *fname) {	// Set all config options to default values	for (int i = 0; option_table[i].name; i++)        setOption (option_table[i].option, option_table[i].default_value);    // Move this later to a table once there is more than one string option    setStringOption(opt_plugins, "perl");    setStringOption(opt_chat_download, Sprintf("%s/.mcl/downloads/", getenv("HOME")));    setStringOption(opt_chat_interfaces, "ppp0 eth0 lo");    Load(fname);    String icon_file = getStringOption(opt_chat_icon);    if (icon_file.len() && access(icon_file, R_OK) != 0)        error ("Icon file %s was specified, but does not exist", ~icon_file);}// Save the configurationvoid Config::Save(const char *fname) {    struct stat stat_buf;    String name;        if (fname == NULL)        name = filename;    else        name = fname;        // Check that there have been no modifications    if (stat(name, &stat_buf) == 0 && stat_buf.st_mtime != save_time)        fprintf(stderr, "Configuration file was NOT saved. It has been changed since it was last loaded!\n");    else  {        FILE *fp = fopen (name, "w");        if (!fp)            return;                fprintf (fp, "# mcl configuration file, generated by mcl v%s on %s\n",                 versionToString(VERSION), ctime(&current_time));                for (int i = 0; option_table[i].name; i++) {            if (option_table[i].ptype == pt_string)                fprintf(fp, "# %s\n%s=%s\n\n", option_table[i].description, option_table[i].name, ~getStringOption(option_table[i].option));            else {                if (!config->getOption(opt_nodefaults) || ( getOption(option_table[i].option) != option_table[i].default_value))                    fprintf (fp, option_table[i].ptype == pt_hex ? "# %s\n%s=0x%02x\n\n" : option_table[i].ptype == pt_char ? "# %s\n%s=%c\n\n" : "# %s\n%s=%d\n\n",                             option_table[i].description,                             option_table[i].name,                             getOption(option_table[i].option));            }        }                globalMUD.write(fp, true);                // Save all MUDs but those marked as temporary        FOREACH(MUD*, mud, (*mud_list))            if (mud->name != "temp") {                fprintf(fp, "\n");                mud->write(fp, false);            }                fclose (fp);    }}Config::~Config() {    if (!getOption(opt_readonly))        Save();}void Config::compileActions() {    for (MUD* mud= mud_list->rewind(); mud; mud = mud_list->next())        if (strcmp(mud->name, "temp")) {            // Actions            FOREACH(Action*, action, mud->action_list)                action->compile();        }        FOREACH(Action*, action2, globalMUD.action_list)        action2->compile();    }

⌨️ 快捷键说明

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