Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] View of /branches/vis15/src/lib/include/diderot/options-inst.hxx
ViewVC logotype

View of /branches/vis15/src/lib/include/diderot/options-inst.hxx

Parent Directory Parent Directory | Revision Log Revision Log


Revision 3928 - (download) (as text) (annotate)
Sun Jun 5 11:24:36 2016 UTC (3 years, 3 months ago) by jhr
File size: 9638 byte(s)
  Working on merge: runtime code
/*! \file options-inst.hxx
 *
 * This file contains the template code for implementing the options<REAL,INT> template
 * class.  It is included by the "options.hxx" file so that code can be instantiated.
 *
 * \author John Reppy
 */

/*
 * This code is part of the Diderot Project (http://diderot-language.cs.uchicago.edu)
 *
 * COPYRIGHT (c) 2016 The University of Chicago
 * All rights reserved.
 */

#ifndef _DIDEROT_OPTIONS_INST_HXX_
#define _DIDEROT_OPTIONS_INST_HXX_

#ifndef _DIDEROT_OPTIONS_HXX_
# error options-inst.hxx should not be directly included
#endif

#include <sstream>
#include <teem/air.h>
#include <teem/hest.h>

namespace diderot {

    namespace __details {

	/*! The base struct for representing information about a single command-line option.
	 */
	struct option_base {
	    std::string		_name;		//! the option name
	    std::string		_desc;		//! the option description
	    bool		_hasDflt;	//! true if the option has a default value
	    void		*_gv;		//! pointer to the global variable being set

	    option_base (const char *name, const char *desc, void *gv, bool hasDflt)
		: _name(name), _desc(desc), _hasDflt(hasDflt), _gv(gv)
	    { }

	    virtual ~option_base () { }

	  // register_opt the option with hest
	    virtual void register_opt (hestOpt **) = 0;
	  // copy the value specified on the command-line to the global input variable
	    virtual void init_input () = 0;
	};

	/********** flag options **********/

	struct option_flag : public option_base {
	    int			_val;

	    option_flag (const char *name, const char *desc, void *gv)
		: option_base (name, desc, gv, false)
	    { }

	    bool *var () const { return reinterpret_cast<bool *>(this->_gv); }

	    void register_opt (hestOpt **);
	    void init_input ();
	};

	void option_flag::register_opt (hestOpt **hOpt)
	{
	    hestOptAdd (
		hOpt, this->_name.c_str(), nullptr, airTypeInt, 0, 0, &this->_val,
		nullptr, this->_desc.c_str());
	}

	void option_flag::init_input ()
	{
	    *this->var() = (this->_val ? true : false);
	}

	/********** boolean options **********/

	struct option_bool : public option_base {
	    int			_val;

	    option_bool (const char *name, const char *desc, void *gv, bool hasDflt)
		: option_base (name, desc, gv, hasDflt)
	    { }

	    bool *var () const { return reinterpret_cast<bool *>(this->_gv); }

	    void register_opt (hestOpt **);
	    void init_input ();
	};

	void option_bool::register_opt (hestOpt **hOpt)
	{
	    hestOptAdd (
		hOpt, this->_name.c_str(), "bool", airTypeBool, 1, 1, &this->_val,
		this->_hasDflt ? (*this->var() ? "true" : "false") : nullptr,
		this->_desc.c_str());
	}

	void option_bool::init_input ()
	{
	    *this->var() = (this->_val ? true : false);
	}

	/********** integer options **********/

	template<typename INT>
	struct option_int : public option_base {
	    int64_t		_val;

	    option_int (const char *name, const char *desc, void *gv, bool hasDflt)
		: option_base (name, desc, gv, hasDflt)
	    { }

	    INT *var () const { return reinterpret_cast<INT *>(this->_gv); }

	    void register_opt (hestOpt **);
	    void init_input ();
	};

	template<typename INT>
	void option_int<INT>::register_opt (hestOpt **hOpt)
	{
	    if (this->_hasDflt) {
		std::ostringstream os;
		os << *this->var();
		hestOptAdd (
		    hOpt, this->_name.c_str(), "int", airTypeLongInt, 1, 1, &this->_val,
		    os.str().c_str(), this->_desc.c_str());
	    }
	    else {
		hestOptAdd (
		    hOpt, this->_name.c_str(), "int", airTypeLongInt, 1, 1, &this->_val,
		    nullptr, this->_desc.c_str());
	    }
	}

	template<typename INT>
	void option_int<INT>::init_input ()
	{
	    *this->var() = static_cast<INT>(this->_val);
	}

	/********** unsigned integer options **********/

	struct option_uint : public option_base {
	    uint32_t		_val;

	    option_uint (const char *name, const char *desc, void *gv, bool hasDflt)
		: option_base (name, desc, gv, hasDflt)
	    { }

	    uint32_t *var () const { return reinterpret_cast<uint32_t *>(this->_gv); }

	    void register_opt (hestOpt **);
	    void init_input ();
	};

	void option_uint::register_opt (hestOpt **hOpt)
	{
	    if (this->_hasDflt) {
		std::ostringstream os;
		os << *this->var();
		hestOptAdd (
		    hOpt, this->_name.c_str(), "int", airTypeULongInt, 1, 1, &this->_val,
		    os.str().c_str(), this->_desc.c_str());
	    }
	    else {
		hestOptAdd (
		    hOpt, this->_name.c_str(), "int", airTypeULongInt, 1, 1, &this->_val,
		    nullptr, this->_desc.c_str());
	    }
	}

	void option_uint::init_input ()
	{
	    *this->var() = this->_val;
	}

	/********** real options **********/

	template<typename REAL>
	struct option_real : public option_base {
	    int			_dim;
	    double		_val[4];

	    option_real (const char *name, const char *desc, int dim, void *gv, bool hasDflt)
		: option_base (name, desc, gv, hasDflt), _dim(dim)
	    { }

	    REAL *var () const { return reinterpret_cast<REAL *>(this->_gv); }

	    void register_opt (hestOpt **);
	    void init_input ();
	};

	template<typename REAL>
	void option_real<REAL>::register_opt (hestOpt **hOpt)
	{
	    const char *valName = nullptr;
	    if (this->_dim == 1) { valName = "x"; }
	    else if (this->_dim == 2) { valName = "x y"; }
	    else if (this->_dim == 3) { valName = "x y z"; }
	    else if (this->_dim == 4) { valName = "x y z w"; }

	    if (this->_hasDflt) {
		std::ostringstream os;
		os << this->var()[0];
		for (int i = 1;  i < this->_dim;  i++) {
		    os << " " << this->var()[1];
		}
		hestOptAdd (
		    hOpt, this->_name.c_str(), valName, airTypeDouble, this->_dim, this->_dim, &this->_val,
		    os.str().c_str(), this->_desc.c_str());
	    }
	    else {
		hestOptAdd (
		    hOpt, this->_name.c_str(), valName, airTypeDouble, this->_dim, this->_dim &this->_val,
		    nullptr, this->_desc.c_str());
	    }
	}

	template<typename REAL>
	void option_real<REAL>::init_input ()
	{
	    for (int i = 0;  i < this->_dim;  i++) {
		this->var()[i] = static_cast<REAL>(this->_val[i]);
	    }
	}

	/********** string options **********/

	struct option_string : public option_base {
	    char		*_val;

	    option_string (const char *name, const char *desc, void *gv, bool hasDflt)
		: option_base (name, desc, gv, hasDflt)
	    { }

	    std::string *var () const { return reinterpret_cast<std::string *>(this->_gv); }

	    void register_opt (hestOpt **);
	    void init_input ();
	};

	void option_string::register_opt (hestOpt **hOpt)
	{
	    if (this->_hasDflt) {
		hestOptAdd (
		    hOpt, this->_name.c_str(), "str", airTypeString, 1, 1, &this->_val,
		    this->var()->c_str(), this->_desc.c_str());
	    }
	    else {
		hestOptAdd (
		    hOpt, this->_name.c_str(), "str", airTypeString, 1, 1, &this->_val,
		    nullptr, this->_desc.c_str());
	    }
	}

	void option_string::init_input ()
	{
	    *this->var() = this->_val;
	}

    } // namespace __details

    /******************** class options ********************/

    template <typename REAL, typename INT>
    options<REAL,INT>::options (const char *info)
	: _progInfo((info == nullptr) ? "" : info)
    {
    }

    template <typename REAL, typename INT>
    options<REAL,INT>::~options ()
    {
	for (auto it = this->_opts.begin();  it != this->_opts.end();  it++) {
	    delete it;
	}
    }

    template <typename REAL, typename INT>
    void options<REAL,INT>::addFlag (const char *name, const char *desc, bool *gv)
    {
	this->_opts.push_back (new __details::option_flag(name, desc, gv));
    }

    template <typename REAL, typename INT>
    void options<REAL,INT>::add (const char *name, const char *desc, bool *gv, bool hasDflt)
    {
	this->_opts.push_back (new __details::option_bool(name, desc, gv, hasDflt));
    }

    template <typename REAL, typename INT>
    void options<REAL,INT>::add (const char *name, const char *desc, uint32_t *gv, bool hasDflt)
    {
	this->_opts.push_back (new __details::option_uint(name, desc, gv, hasDflt));
    }

    template <typename REAL, typename INT>
    void options<REAL,INT>::add (const char *name, const char *desc, INT *gv, bool hasDflt)
    {
	this->_opts.push_back (new __details::option_int<INT>(name, desc, gv, hasDflt));
    }

    template <typename REAL, typename INT>
    void options<REAL,INT>::add (const char *name, const char *desc, int dim, REAL *gv, bool hasDflt)
    {
	this->_opts.push_back (new __details::option_real<REAL>(name, desc, dim, gv, hasDflt));
    }

    template <typename REAL, typename INT>
    void options<REAL,INT>::add (const char *name, const char *desc, std::string *gv, bool hasDflt)
    {
	this->_opts.push_back (new __details::option_string(name, desc, gv, hasDflt));
    }

    template <typename REAL, typename INT>
    void options<REAL,INT>::process (int argc, const char **argv)
    {
	static const char *me = "Diderot_ProcessOptions";

	airArray *mop = airMopNew();
	hestOpt *hopt = nullptr;
	hestParm *hparm = hestParmNew();
	hparm->noArgsIsNoProblem = AIR_TRUE;
	airMopAdd (mop, hparm, (airMopper)hestParmFree, airMopAlways);

      // register options with hest
	for (auto it = this->_opts.begin();  it != this->_opts.end();  it++) {
	    it->register_opt ();
	}

	hestParseOrDie (
	    hopt, argc-1, argv+1, hparm, argv[0],
	    this->_progInfo.c_str(),
	    AIR_TRUE, AIR_TRUE, AIR_TRUE);
	airMopAdd(mop, hopt, (airMopper)hestOptFree, airMopAlways);
	airMopAdd(mop, hopt, (airMopper)hestParseFree, airMopAlways);

      // copy option values back into input variables
	for (auto it = this->_opts.begin();  it != this->_opts.end();  it++) {
	    it->init_input ();
	}

	airMopOkay(mop);

    }

} // namespace diderot

#endif // !_DIDEROT_OPTIONS_INST_HXX_

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0