Esempio n. 1
0
int opt_store_int_2(char *arg, void *data){
    char     * tab[3];
    char     * end;
    int        i = 0;
    unsigned * p = data;
    unsigned   val1, val2;

    assert(arg && data);
    tab[i] = strtok(arg, ",");
    if (!tab[i]) {
         opt_err("this option requires two values seperated by ','");
    }

    while (tab[i] != NULL) {
        i++;
        tab[i] = strtok(NULL,",");
        if (i == 3 ) {
         opt_err("this option requires two values seperated by ','");
        }
        if (i < 2 && !tab[i]) {
         opt_err("this option requires two values seperated by ','");
        }
    }

    ////
    if (i != 2) {
        opt_err("this option requires two values seperated by ','");
    }
    /////

    val1 = strtol(tab[0], &end, 10);
    errno = 0;
    if (end == tab[0] || end[0])
        opt_err("the first value of %s must be an integer");
    if (errno == ERANGE || val1 < p[1] || val1 > p[2]) {
        opt_err_pfx();
        fprintf(stderr, "the first value of %s must be in the range %d to %d",
                opt_name(), p[1], p[2]);
        opt_err_sfx();
    }
    p[0] = val1;

     val2 = strtol(tab[1], &end, 10);
    errno = 0;
      if (end == tab[0] || end[0])
        opt_err("the second value of %s must be an integer");
    if (errno == ERANGE || val2 < p[4] || val2 > p[5]) {
        opt_err_pfx();
        fprintf(stderr, "the second value of %s must be in the range %d to %d",
                opt_name(), p[4], p[5]);
        opt_err_sfx();
    }
    p[3] = val2;
    p[6] = 1;
    return 0;
 }
Esempio n. 2
0
static void badchoice(const char **choices, const char *arg)
{
    int i;

    for (i = 0; !EMPTY(choices[i]); ++i)
        ;
    if (choices[i]) {
        const char *temp = choices[i];
        choices[i] = choices[0];
        choices[0] = temp;
        return;
    }
    opt_err_pfx();
    fprintf(stderr, "invalid choice '%s' for option %s",
            arg, opt_name());
    opt_err_sfx();
}
Esempio n. 3
0
int opt_store_choice_abbr(char *arg, void *data)
{
    const char **choices = data, *temp;
    int i, j;

    assert(arg && data);
    for (i = 0; choices[i] && (strstr(choices[i], arg) != choices[i]
                               || !choices[i][0]); ++i)
        ;
    if (!choices[i]) {
        badchoice(choices, arg);
        return 0;
    }
    for (j = i + 1; choices[j] && (strstr(choices[j], arg) != choices[j]
                                   || !choices[j][0]); ++j)
        ;
    if (choices[j]) {
        opt_err_pfx();
        fprintf(
            stderr, "ambiguous choice '%s' for option %s\n%*s(%s",
            arg,
            opt_name(),
            (int) strlen(globals.prog) + 2,
            "",
            choices[i]
        );
        for (;;) {
            i = j;
            for (j = i + 1;
                 choices[j] && (strstr(choices[j], arg) != choices[j]
                                || !choices[j][0]); ++j)
                ;
            if (!choices[j]) {
                fprintf(stderr, " or %s?)", choices[i]);
                opt_err_sfx();
            }
            fprintf(stderr, ", %s", choices[i]);
        }
    }
    temp = choices[i];
    choices[i] = choices[0];
    choices[0] = temp;
    return 0;
}
Esempio n. 4
0
/**
    @brief Initializes syslog at the first log usage.

    We cannot initialize log in a constructor of static object because log may be used in
    constructors of other static objects (search for "static initialization order fiasco").
    So let us initialize log at the first usage, and take care about multithreaded applications too.
*/
static
void
init(
) {

    // `syslog' should be initialized once.
    // Cannot use `mutex_t' here because: (1) `mutex_t' uses logger,
    // (2) we need statically initialized mutex.
    static pthread_mutex_t mutex  = PTHREAD_MUTEX_INITIALIZER;
    static bool volatile   inited = false;

    if ( ! inited ) {

        int error;

        static string_t const action = "syslog initialization";

        error = pthread_mutex_lock( & mutex );
        // Cannot use `PTHERR' macro here because the macro uses logger.
        if ( error ) {
            throw sys_err_t( _SOURCE_LOCATION_, "", action, "pthread_mutex_lock", error );
        };

        if ( ! inited ) {
            int options = LOG_CONS | LOG_PID;
            // We cannot use `get_opt' (or `get_bool_opt') here, because they use logger.
            if ( getenv( opt_name( "LOG_PERROR" ).c_str() ) ) {
                options |= LOG_PERROR;
            }; // if
            openlog( NULL, options, LOG_USER );
        };

        inited = true;

        error = pthread_mutex_unlock( & mutex );
        if ( error ) {
            throw sys_err_t( _SOURCE_LOCATION_, "", action, "pthread_mutex_unlock", error );
        };

    };

}; // init
Esempio n. 5
0
int opt_store_double_lim(char *arg, void *data)
{
    char *end;
    double val;
    double *p = data;

    assert(arg && data);
    errno = 0;
    val = strtod(arg, &end);
    if (end == arg || end[0])
        opt_err("the value of %s must be a number");
    if (errno == ERANGE || val < p[1] || val > p[2]) {
        opt_err_pfx();
        fprintf(stderr, "the value of %s must be in the range %g to %g",
                opt_name(), p[1], p[2]);
        opt_err_sfx();
    }
    p[0] = val;
    return 0;
}
Esempio n. 6
0
int opt_store_int_lim(char *arg, void *data)
{
    char *end;
    long val;
    int *p = data;

    assert(arg && data);
    errno = 0;
    val = strtol(arg, &end, 10);
    if (end == arg || end[0])
        opt_err("the value of %s must be an integer");
    if (errno == ERANGE || val < p[1] || val > p[2]) {
        opt_err_pfx();
        fprintf(stderr, "the value of %s must be in the range %d to %d",
                opt_name(), p[1], p[2]);
        opt_err_sfx();
    }
    p[0] = val;
    return 0;
}
Esempio n. 7
0
// FIXME: simulate MakeInstanceFilename(vbam.ini) using subkeys (Slave%d/*)
void load_opts()
{
    // just for sanity...
    bool did_init = false;

    if (did_init)
        return;

    did_init = true;

    // Translations can't be initialized in static structures (before locale
    // is initialized), so do them now
    for (int i = 0; i < num_opts; i++)
        opts[i].desc = wxGetTranslation(opts[i].desc);

    // enumvals should not be translated, since they would cause config file
    // change after lang change
    // instead, translate when presented to user
    wxFileConfig* cfg = wxGetApp().cfg;
    cfg->SetPath(wxT("/"));
    // enure there are no unknown options present
    // note that items cannot be deleted until after loop or loop will fail
    wxArrayString item_del, grp_del;
    long grp_idx;
    wxString s;
    bool cont;

    for (cont = cfg->GetFirstEntry(s, grp_idx); cont;
         cont = cfg->GetNextEntry(s, grp_idx)) {
        //wxLogWarning(_("Invalid option %s present; removing if possible"), s.c_str());
        item_del.push_back(s);
    }

    // Date of last online update check;
    gopts.last_update = cfg->Read(wxT("General/LastUpdated"), (long)0);
    cfg->Read(wxT("General/LastUpdatedFileName"), &gopts.last_updated_filename);
    std::sort(&opts[0], &opts[num_opts], opt_lt);

    for (cont = cfg->GetFirstGroup(s, grp_idx); cont;
         cont = cfg->GetNextGroup(s, grp_idx)) {
        // ignore wxWidgets-managed global library settings
        if (s == wxT("wxWindows"))
            continue;

        // ignore file history
        if (s == wxT("Recent"))
            continue;

        cfg->SetPath(s);
        int poff = s.size();
        long entry_idx;
        wxString e;

        for (cont = cfg->GetFirstGroup(e, entry_idx); cont;
             cont = cfg->GetNextGroup(e, entry_idx)) {
            // the only one with subgroups
            if (s == wxT("Joypad") && e.size() == 1 && e[0] >= wxT('1') && e[0] <= wxT('4')) {
                s.append(wxT('/'));
                s.append(e);
                s.append(wxT('/'));
                int poff2 = s.size();
                cfg->SetPath(e);
                long key_idx;

                for (cont = cfg->GetFirstGroup(e, key_idx); cont;
                     cont = cfg->GetNextGroup(e, key_idx)) {
                    s.append(e);
                    //wxLogWarning(_("Invalid option group %s present; removing if possible"), s.c_str());
                    grp_del.push_back(s);
                    s.resize(poff2);
                }

                for (cont = cfg->GetFirstEntry(e, key_idx); cont;
                     cont = cfg->GetNextEntry(e, key_idx)) {
                    int i;

                    for (i = 0; i < NUM_KEYS; i++)
                        if (e == joynames[i])
                            break;

                    if (i == NUM_KEYS) {
                        s.append(e);
                        //wxLogWarning(_("Invalid option %s present; removing if possible"), s.c_str());
                        item_del.push_back(s);
                        s.resize(poff2);
                    }
                }

                s.resize(poff);
                cfg->SetPath(wxT("/"));
                cfg->SetPath(s);
            } else {
                s.append(wxT('/'));
                s.append(e);
                //wxLogWarning(_("Invalid option group %s present; removing if possible"), s.c_str());
                grp_del.push_back(s);
                s.resize(poff);
            }
        }

        for (cont = cfg->GetFirstEntry(e, entry_idx); cont;
             cont = cfg->GetNextEntry(e, entry_idx)) {
            // kb options come from a different list
            if (s == wxT("Keyboard")) {
                const cmditem dummy = new_cmditem(e);

                if (!std::binary_search(&cmdtab[0], &cmdtab[ncmds], dummy, cmditem_lt)) {
                    s.append(wxT('/'));
                    s.append(e);
                    //wxLogWarning(_("Invalid option %s present; removing if possible"), s.c_str());
                    item_del.push_back(s);
                    s.resize(poff);
                }
            } else {
                s.append(wxT('/'));
                s.append(e);
                opt_desc dummy = new_opt_desc(s);
                wxString opt_name(dummy.opt);

                if (!std::binary_search(&opts[0], &opts[num_opts], dummy, opt_lt) && opt_name != wxT("General/LastUpdated") && opt_name != wxT("General/LastUpdatedFileName")) {
                    //wxLogWarning(_("Invalid option %s present; removing if possible"), s.c_str());
                    item_del.push_back(s);
                }

                s.resize(poff);
            }
        }

        cfg->SetPath(wxT("/"));
    }

    for (size_t i = 0; i < item_del.size(); i++)
        cfg->DeleteEntry(item_del[i]);

    for (size_t i = 0; i < grp_del.size(); i++)
        cfg->DeleteGroup(grp_del[i]);

    // now read actual values and set to default if unset
    // config file will be updated with unset options
    cfg->SetRecordDefaults();

    for (int i = 0; i < num_opts; i++) {
        opt_desc& opt = opts[i];

        if (opt.stropt) {
            //Fix provided by nhdailey
            cfg->Read(opt.opt, opt.stropt, *opt.stropt);
            opt.curstr = *opt.stropt;
        } else if (!opt.enumvals.empty()) {
            auto enum_opts = str_split(opt.enumvals.MakeLower(), wxT("|"));
            opt.curint     = *opt.intopt;
            bool gotit     = cfg->Read(opt.opt, &s); s.MakeLower();

            if (gotit && !s.empty()) {
                const auto found_pos = vec_find(enum_opts, s);
                const bool matched   = ((int)found_pos != wxNOT_FOUND);

                if (!matched) {
                    opt.curint = 0;
                    const wxString ev  = opt.enumvals;
                    const wxString evx = wxGetTranslation(ev);
                    bool isx = wxStrcmp(ev, evx) != 0;
                    // technically, the translation for this string could incorproate
                    // the equals sign if necessary instead of doing it this way
                    wxLogWarning(_("Invalid value %s for option %s; valid values are %s%s%s"),
                        s.c_str(), opt.opt.c_str(), ev.c_str(),
                        isx ? wxT(" = ") : wxEmptyString,
                        isx ? evx.c_str() : wxEmptyString);
                    // write first option
                    cfg->Write(opt.opt, enum_opts[0]);
                } else
                    opt.curint = found_pos;

                *opt.intopt = opt.curint;
            } else {
                cfg->Write(opt.opt, enum_opts[opt.curint]);
            }
        } else if (opt.intopt) {
            cfg->Read(opt.opt, &opt.curint, *opt.intopt);

            if (opt.curint < opt.min || opt.curint > opt.max) {
                wxLogWarning(_("Invalid value %d for option %s; valid values are %d - %d"), opt.curint, opt.opt.c_str(), opt.min, opt.max);
            } else
                *opt.intopt = opt.curint;
        } else if (opt.doubleopt) {
            cfg->Read(opt.opt, &opt.curdouble, *opt.doubleopt);

            if (opt.curdouble < opt.min || opt.curdouble > opt.max) {
                wxLogWarning(_("Invalid value %f for option %s; valid values are %f - %f"), opt.curdouble, opt.opt.c_str(), opt.min, opt.max);
            } else
                *opt.doubleopt = opt.curdouble;
        } else if (opt.uintopt) {
            int val;
            cfg->Read(opt.opt, &val, *opt.uintopt);
            opt.curuint = val;

            if (opt.curuint < opt.min || opt.curuint > opt.max) {
                wxLogWarning(_("Invalid value %f for option %s; valid values are %f - %f"), opt.curuint, opt.opt.c_str(), opt.min, opt.max);
            } else
                *opt.uintopt = opt.curuint;
        } else if (opt.boolopt) {
            cfg->Read(opt.opt, opt.boolopt, *opt.boolopt);
            opt.curbool = *opt.boolopt;
        }
    }

    // GB/Palette[0-2] is special
    for (int i = 0; i < 3; i++) {
        wxString optn;
        optn.Printf(wxT("GB/Palette%d"), i);
        wxString val;
        const opt_desc dummy = new_opt_desc(optn);
        opt_desc* opt = std::lower_bound(&opts[0], &opts[num_opts], dummy, opt_lt);
        wxString entry;

        for (int j = 0; j < 8; j++) {
            // stupid wxString.Printf doesn't support printing at offset
            entry.Printf(wxT("%04X,"), (int)systemGbPalette[i * 8 + j]);
            val.append(entry);
        }

        val.resize(val.size() - 1);
        cfg->Read(optn, &val, val);
        opt->curstr = val;

        for (int j = 0, cpos = 0; j < 8; j++) {
            int start = cpos;
            cpos = val.find(wxT(','), cpos);

            if ((size_t)cpos == wxString::npos)
                cpos = val.size();

            long ival;
            // ignoring errors; if the value is bad, palette will be corrupt
            // -- tough.
            // stupid wxString.ToLong doesn't support start @ offset
            entry = val.substr(start, cpos - start);
            entry.ToLong(&ival, 16);
            systemGbPalette[i * 8 + j] = ival;

            if ((size_t)cpos != val.size())
                cpos++;
        }
    }

    // joypad is special
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < NUM_KEYS; j++) {
            wxString optname;
            optname.Printf(wxT("Joypad/%d/%s"), i + 1, joynames[j].c_str());
            bool gotit = cfg->Read(optname, &s);

            if (gotit) {
                gopts.joykey_bindings[i][j] = wxJoyKeyTextCtrl::FromString(s);

                if (s.size() && !gopts.joykey_bindings[i][j].size())
                    wxLogWarning(_("Invalid key binding %s for %s"), s.c_str(), optname.c_str());
            } else {
                s = wxJoyKeyTextCtrl::ToString(gopts.joykey_bindings[i][j]);
                cfg->Write(optname, s);
            }
        }
    }

    // keyboard is special
    // Keyboard does not get written with defaults
    wxString kbopt(wxT("Keyboard/"));
    int kboff = kbopt.size();

    for (int i = 0; i < ncmds; i++) {
        kbopt.resize(kboff);
        kbopt.append(cmdtab[i].cmd);

        if (cfg->Read(kbopt, &s) && s.size()) {
            wxAcceleratorEntry_v val = wxKeyTextCtrl::FromString(s);

            if (!val.size())
                wxLogWarning(_("Invalid key binding %s for %s"), s.c_str(), kbopt.c_str());
            else {
                for (size_t j = 0; j < val.size(); j++)
                    val[j].Set(val[j].GetFlags(), val[j].GetKeyCode(),
                        cmdtab[i].cmd_id);

                gopts.accels.insert(gopts.accels.end(),
                    val.begin(), val.end());
            }
        }
    }

    // recent is special
    // Recent does not get written with defaults
    cfg->SetPath(wxT("/Recent"));
    gopts.recent->Load(*cfg);
    cfg->SetPath(wxT("/"));
    cfg->Flush();
}
Esempio n. 8
0
void opt_err(const char *msg)
{
    opt_err_pfx();
    fprintf(stderr, msg, opt_name());
    opt_err_sfx();
}