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
static void ReadCmdArgs(Inilist &ini, Arglist &Args)
{
	for (Arglist::iterator pp = Args.begin(), end = Args.end(); pp != end; ++pp)
	{
		const char *p = pp->c_str();
	// System Options

		if (!d_stricmp(p, "-help") || !d_stricmp(p, "-h") || !d_stricmp(p, "-?") || !d_stricmp(p, "?"))
			CGameArg.SysShowCmdHelp = true;
		else if (!d_stricmp(p, "-nonicefps"))
			CGameArg.SysNoNiceFPS = true;
		else if (!d_stricmp(p, "-maxfps"))
			CGameArg.SysMaxFPS = arg_integer(pp, end);
		else if (!d_stricmp(p, "-hogdir"))
			CGameArg.SysHogDir = arg_string(pp, end);
#if PHYSFS_VER_MAJOR >= 2
		else if (!d_stricmp(p, "-add-missions-dir"))
			CGameArg.SysMissionDir = arg_string(pp, end);
#endif
		else if (!d_stricmp(p, "-nohogdir"))
		{
			/* No effect on non-Unix.  Ignore it so that players can
			 * pass it via a cross-platform ini.
			 */
#if defined(__unix__)
			CGameArg.SysNoHogDir = true;
#endif
		}
		else if (!d_stricmp(p, "-use_players_dir"))
			CGameArg.SysUsePlayersDir = static_cast<int8_t>(- (sizeof(PLAYER_DIRECTORY_TEXT) - 1));
		else if (!d_stricmp(p, "-lowmem"))
			CGameArg.SysLowMem = true;
		else if (!d_stricmp(p, "-pilot"))
			CGameArg.SysPilot = arg_string(pp, end);
		else if (!d_stricmp(p, "-record-demo-format"))
			CGameArg.SysRecordDemoNameTemplate = arg_string(pp, end);
		else if (!d_stricmp(p, "-auto-record-demo"))
			CGameArg.SysAutoRecordDemo = true;
		else if (!d_stricmp(p, "-window"))
			CGameArg.SysWindow = true;
		else if (!d_stricmp(p, "-noborders"))
			CGameArg.SysNoBorders = true;
		else if (!d_stricmp(p, "-notitles"))
			CGameArg.SysNoTitles = true;
#if defined(DXX_BUILD_DESCENT_II)
		else if (!d_stricmp(p, "-nomovies"))
			GameArg.SysNoMovies 		= 1;
#endif
		else if (!d_stricmp(p, "-autodemo"))
			CGameArg.SysAutoDemo = true;

	// Control Options

		else if (!d_stricmp(p, "-nocursor"))
			CGameArg.CtlNoCursor 		= true;
		else if (!d_stricmp(p, "-nomouse"))
			CGameArg.CtlNoMouse 		= true;
		else if (!d_stricmp(p, "-nojoystick"))
		{
#if DXX_MAX_JOYSTICKS
			CGameArg.CtlNoJoystick		= 1;
#endif
		}
		else if (!d_stricmp(p, "-nostickykeys"))
			CGameArg.CtlNoStickyKeys	= true;

	// Sound Options

		else if (!d_stricmp(p, "-nosound"))
			CGameArg.SndNoSound		= 1;
		else if (!d_stricmp(p, "-nomusic"))
			CGameArg.SndNoMusic = true;
#if defined(DXX_BUILD_DESCENT_II)
		else if (!d_stricmp(p, "-sound11k"))
			GameArg.SndDigiSampleRate 		= SAMPLE_RATE_11K;
#endif
		else if (!d_stricmp(p, "-nosdlmixer"))
		{
#if DXX_USE_SDLMIXER
			CGameArg.SndDisableSdlMixer = true;
#endif
		}

	// Graphics Options

		else if (!d_stricmp(p, "-lowresfont"))
			CGameArg.GfxSkipHiresFNT = true;
#if defined(DXX_BUILD_DESCENT_II)
		else if (!d_stricmp(p, "-lowresgraphics"))
			GameArg.GfxSkipHiresGFX	= 1;
		else if (!d_stricmp(p, "-lowresmovies"))
			GameArg.GfxSkipHiresMovie 		= 1;
#endif
#if DXX_USE_OGL
	// OpenGL Options

		else if (!d_stricmp(p, "-gl_fixedfont"))
			CGameArg.OglFixedFont = true;
		else if (!d_stricmp(p, "-gl_syncmethod"))
			CGameArg.OglSyncMethod = arg_enum<SyncGLMethod>(pp, end);
		else if (!d_stricmp(p, "-gl_syncwait"))
			CGameArg.OglSyncWait = arg_integer(pp, end);
		else if (!d_stricmp(p, "-gl_darkedges"))
			CGameArg.OglDarkEdges = true;
#endif

	// Multiplayer Options

#if DXX_USE_UDP
		else if (!d_stricmp(p, "-udp_hostaddr"))
			CGameArg.MplUdpHostAddr = arg_string(pp, end);
		else if (!d_stricmp(p, "-udp_hostport"))
			/* Peers use -udp_myport to change, so peer cannot set a
			 * privileged port.
			 */
			arg_port_number(pp, end, CGameArg.MplUdpHostPort, false);
		else if (!d_stricmp(p, "-udp_myport"))
		{
			arg_port_number(pp, end, CGameArg.MplUdpMyPort, false);
		}
		else if (!d_stricmp(p, "-no-tracker"))
		{
			/* Always recognized.  No-op if tracker support compiled
			 * out. */
#if DXX_USE_TRACKER
			CGameArg.MplTrackerAddr.clear();
#endif
		}
#if DXX_USE_TRACKER
		else if (!d_stricmp(p, "-tracker_hostaddr"))
		{
			CGameArg.MplTrackerAddr = arg_string(pp, end);
		}
		else if (!d_stricmp(p, "-tracker_hostport"))
			arg_port_number(pp, end, CGameArg.MplTrackerPort, true);
#endif
#endif

#if defined(DXX_BUILD_DESCENT_I)
		else if (!d_stricmp(p, "-nobm"))
			GameArg.EdiNoBm 		= 1;
#elif defined(DXX_BUILD_DESCENT_II)
#if DXX_USE_EDITOR
	// Editor Options

		else if (!d_stricmp(p, "-autoload"))
			GameArg.EdiAutoLoad = arg_string(pp, end);
		else if (!d_stricmp(p, "-macdata"))
			GameArg.EdiMacData 		= 1;
		else if (!d_stricmp(p, "-hoarddata"))
			GameArg.EdiSaveHoardData 	= 1;
#endif
#endif

	// Debug Options

		else if (!d_stricmp(p, "-debug"))
			CGameArg.DbgVerbose 	= CON_DEBUG;
		else if (!d_stricmp(p, "-verbose"))
			CGameArg.DbgVerbose 	= CON_VERBOSE;

		else if (!d_stricmp(p, "-no-grab"))
			CGameArg.DbgForbidConsoleGrab = true;
		else if (!d_stricmp(p, "-safelog"))
			CGameArg.DbgSafelog = true;
		else if (!d_stricmp(p, "-norun"))
			CGameArg.DbgNoRun = true;
		else if (!d_stricmp(p, "-renderstats"))
			CGameArg.DbgRenderStats = true;
		else if (!d_stricmp(p, "-text"))
			CGameArg.DbgAltTex = arg_string(pp, end);
		else if (!d_stricmp(p, "-tmap"))
			CGameArg.DbgTexMap = arg_string(pp, end);
		else if (!d_stricmp(p, "-showmeminfo"))
			CGameArg.DbgShowMemInfo 		= 1;
		else if (!d_stricmp(p, "-nodoublebuffer"))
			CGameArg.DbgNoDoubleBuffer = true;
		else if (!d_stricmp(p, "-bigpig"))
			CGameArg.DbgNoCompressPigBitmap = true;
		else if (!d_stricmp(p, "-16bpp"))
			CGameArg.DbgBpp		= 16;

#if DXX_USE_OGL
		else if (!d_stricmp(p, "-gl_oldtexmerge"))
			CGameArg.DbgUseOldTextureMerge = true;
		else if (!d_stricmp(p, "-gl_intensity4_ok"))
			CGameArg.DbgGlIntensity4Ok = arg_integer(pp, end);
		else if (!d_stricmp(p, "-gl_luminance4_alpha4_ok"))
			CGameArg.DbgGlLuminance4Alpha4Ok = arg_integer(pp, end);
		else if (!d_stricmp(p, "-gl_rgba2_ok"))
			CGameArg.DbgGlRGBA2Ok = arg_integer(pp, end);
		else if (!d_stricmp(p, "-gl_readpixels_ok"))
			CGameArg.DbgGlReadPixelsOk = arg_integer(pp, end);
		else if (!d_stricmp(p, "-gl_gettexlevelparam_ok"))
			CGameArg.DbgGlGetTexLevelParamOk = arg_integer(pp, end);
#else
		else if (!d_stricmp(p, "-hwsurface"))
			CGameArg.DbgSdlHWSurface = true;
		else if (!d_stricmp(p, "-asyncblit"))
			CGameArg.DbgSdlASyncBlit = true;
#endif
		else if (!d_stricmp(p, "-ini"))
		{
			ini.emplace_back(arg_string(pp, end));
			if (ini.size() > 10)
				throw nesting_depth_exceeded();
			ReadIniArgs(ini);
		}
		else
			throw unhandled_argument(std::move(*pp));
	}
}
Ejemplo n.º 3
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;
    }
}