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); } } } }
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; } }