Ejemplo n.º 1
0
static void AppendIniArgs(const char *filename, Arglist &Args)
{
	if (auto f = PHYSFSX_openReadBuffered(filename))
	{
		PHYSFSX_gets_line_t<1024> line;
		while (Args.size() < MAX_ARGS && PHYSFSX_fgets(line, f))
		{
			const auto separator = " \t";
			for(char *token = strtok(line, separator); token != NULL; token = strtok(NULL, separator))
			{
				if (*token == ';')
					break;
				Args.push_back(token);
			}
		}
	}
}
Ejemplo n.º 2
0
void CmdLine :: parse (int argc, char** argv, bool strict)
{
    // prepare the parameters and call cmdline_s get_opt

    Arglist arglist;
    Optdict optdict;

    // allocate storage for long options spec
    unsigned longopts_no = 0;
    KeysFormat::iterator kitr;
    char longopts_spec_buf [MAX_LONGOPTS][MAX_LONGOPT_LEN];
    char* longopts_spec [MAX_LONGOPTS];
    for (kitr = keys_format_.begin (); kitr != keys_format_.end (); kitr ++) 
        longopts_no += (*kitr).longopts_.size ();
    if (longopts_no + 1 >= MAX_LONGOPTS)
        ers << "Too many command line options in command line format definition" << ThrowEx(InternalError);

    // fill in options specs and make option->spec map
    std::map <std::string, KeyFormat*> opt2spec;
    std::string shortopts_spec (EMPTY_STR);

    int lidx = 0;
    for (kitr = keys_format_.begin (); kitr != keys_format_.end (); kitr ++)
    {
        // short
        svec::iterator soi = (*kitr).shortopts_.begin ();
        for (; soi != (*kitr).shortopts_.end (); soi ++)
        {
            const char* optstr = (*soi).c_str ();
            shortopts_spec+= optstr;
            if ((*kitr).has_arg_) shortopts_spec += ":";

            std::string keystr ("-");
            keystr.append (optstr);
            opt2spec [keystr] = &(*kitr);
        }
        // long
        svec::iterator loi = (*kitr).longopts_.begin ();
        for (; loi != (*kitr).longopts_.end (); loi ++, lidx ++)
        {
            unsigned lolen = (*loi).length () + 1;
            if ((*kitr).has_arg_) lolen ++;
            if (lolen + 1 >= MAX_LONGOPT_LEN)
                ers << "Command line option " << *loi << " is too long" << Throw;
            // longopts_spec [lidx] = new char [lolen];
            const char* optstr = (*loi).c_str ();
            longopts_spec [lidx] = longopts_spec_buf [lidx];
            strcpy (longopts_spec [lidx], optstr);
            if ((*kitr).has_arg_) strcat (longopts_spec [lidx], "=");

            std::string keystr ("--");
            keystr.append (optstr);
            opt2spec [keystr] = &(*kitr);
        }
    }
    longopts_spec [lidx] = NULL;

    // actually parse command line
    get_opt (argc, argv, shortopts_spec.c_str (), arglist, optdict, longopts_spec);

    // fill in the keys_
    Optdict::iterator oi = optdict.begin ();
    for (;oi != optdict.end (); oi ++)
    {
        const char* key = (*oi).first.c_str ();
        // find what parameter this name corresponds to
        std::map <std::string, KeyFormat*>::iterator k = opt2spec.find (key);
        if (k != opt2spec.end ())
        {
            svec values = (*oi).second;
            if ((*k).second->has_arg_)
            {
                if (values.size () == 0)
                {
                    error_report_ += "\nParameter ";
                    error_report_ += key;
                    error_report_ += "(";
                    error_report_ += (*k).second->name_;
                    error_report_ += ") requires argument";
                    ok_ = false;
                    break;
                }
                const char* val = values [values.size () - 1].c_str ();
                keys_ [(*k).second->name_] = val;
            }
            else
            {
                keys_ [(*k).second->name_] = EMPTY_STR;
            }
            // DEBUG
            // printf ("CMDL PAR '%s' : '%s'", (*k).second->name_.c_str (), val);
        }
    }

    // check weather all non-optional keys are found
    if (ok_ && strict)
    {
        for (kitr = keys_format_.begin (); kitr != keys_format_.end (); kitr ++)
        {
            if (!kitr->optional_)
            {
                std::map<std::string, std::string>::iterator valitr = keys_.find (kitr->name_);
                if (valitr == keys_.end ())
                {
                    // add notes about missing ones to the error_report
                    error_report_ += "Required option missing from command line: ";
                    error_report_ += kitr->name_;
                    error_report_ += "\n";
                    ok_ = false;
                }
            }
        }
    }
    // fill in the arguments_
    if (ok_) std::copy (arglist.begin (), arglist.end (), std::back_inserter (arguments_));

    // check if the number of arguments is valid
    if (strict && ok_ && repeatable_pos_ == -1 && arglist.size () > args_format_.size ())
    {
        // add the note to error_report
        error_report_ += "Too many command-line arguments\n";
        ok_ = false;
    }
    unsigned min_arg_number = ((first_optional_pos_ != -1) ? first_optional_pos_ : 0)
                    + args_format_.size () - ((last_optional_pos_ == -1) ? 0 : last_optional_pos_);
    if (strict && ok_ && arguments_.size () < min_arg_number)
    {
        // add the note to error_report
        error_report_ += "Too few command-line arguments. Please use -h for help.\n";
        ok_ = false;
    }
}