You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
183 lines
4.7 KiB
183 lines
4.7 KiB
#ifndef GFXSCRIPT_INCLUDED // -*- C++ -*-
|
|
#define GFXSCRIPT_INCLUDED
|
|
#if !defined(__GNUC__)
|
|
# pragma once
|
|
#endif
|
|
|
|
/************************************************************************
|
|
|
|
Simple low-level file format scripting support.
|
|
|
|
This is the THIRD major revision of this code. It represents a
|
|
significant departure from the previous scripting structure.
|
|
|
|
$Id: script.h 443 2005-06-14 00:53:40Z garland $
|
|
|
|
************************************************************************/
|
|
|
|
#include "gfx.h"
|
|
#include <vector>
|
|
#include <string>
|
|
#include <map>
|
|
//#include <hash_map>
|
|
|
|
namespace gfx
|
|
{
|
|
|
|
// Define a set of exceptions that can occur during script parsing
|
|
//
|
|
namespace script
|
|
{
|
|
struct Error
|
|
{
|
|
std::string msg;
|
|
Error(const std::string& m) : msg(m) {}
|
|
};
|
|
|
|
struct SyntaxError : public Error
|
|
{ SyntaxError(const std::string& m) : Error(m) {} };
|
|
|
|
struct NameError : public Error
|
|
{ NameError(const std::string& m) : Error(m) {} };
|
|
|
|
struct IOError : public Error
|
|
{ IOError(const std::string& m) : Error(m) {} };
|
|
}
|
|
|
|
|
|
// These return codes are deprecated and will be going away in the near
|
|
// future. Start using the exceptions defined above instead.
|
|
enum {
|
|
SCRIPT_OK = 0,
|
|
SCRIPT_ERR_UNDEF,
|
|
SCRIPT_ERR_SYNTAX,
|
|
SCRIPT_ERR_UNSUPPORTED,
|
|
SCRIPT_ERR_NOFILE,
|
|
SCRIPT_END
|
|
};
|
|
|
|
class CmdLine
|
|
{
|
|
public:
|
|
typedef std::string::size_type index_type;
|
|
typedef std::pair<index_type, index_type> range_type;
|
|
|
|
const std::string &line;
|
|
range_type op;
|
|
std::vector<range_type> tokens;
|
|
|
|
std::string substr(const range_type& r) const
|
|
{ return line.substr(r.first, r.second-r.first);}
|
|
|
|
std::string token_to_string(int i) const;
|
|
double token_to_double(int i) const;
|
|
float token_to_float(int i) const;
|
|
int token_to_int(int i) const;
|
|
std::string rest_to_string(int i) const;
|
|
|
|
|
|
CmdLine(const std::string &l) : line(l) { }
|
|
|
|
std::string opname() const { return substr(op); }
|
|
int argcount() const { return tokens.size(); }
|
|
std::string argline() const;
|
|
|
|
int collect_as_strings(std::vector<std::string> &v, int offset=0) const;
|
|
int collect_as_numbers(std::vector<double> &v, int offset=0) const;
|
|
int collect_as_numbers(std::vector<int> &v, int offset=0) const;
|
|
|
|
int collect_as_numbers(double *v, int size, int offset=0) const;
|
|
int collect_as_numbers(float *v, int size, int offset=0) const;
|
|
int collect_as_numbers(int *v, int size, int offset=0) const;
|
|
};
|
|
|
|
typedef int (*CmdHandler)(const CmdLine&);
|
|
|
|
struct CmdObject
|
|
{
|
|
virtual ~CmdObject() {}
|
|
virtual int operator()(const CmdLine& cmd) = 0;
|
|
};
|
|
|
|
struct CmdFunction : public CmdObject
|
|
{
|
|
CmdHandler fn;
|
|
CmdFunction(CmdHandler f) { fn=f; }
|
|
virtual int operator()(const CmdLine& cmd) { return (*fn)(cmd); }
|
|
};
|
|
|
|
template<class T> struct CmdMethod : public CmdObject
|
|
{
|
|
typedef int (T::*member_handler)(const CmdLine&);
|
|
T *self;
|
|
member_handler fn;
|
|
|
|
CmdMethod(T &obj, member_handler p) { self=&obj; fn=p; }
|
|
virtual int operator()(const CmdLine& cmd) { return (self->*fn)(cmd); }
|
|
};
|
|
|
|
template<class T> struct CmdMethod2 : public CmdObject
|
|
{
|
|
typedef void (T::*member_handler)(const CmdLine&);
|
|
T *self;
|
|
member_handler fn;
|
|
|
|
CmdMethod2(T &obj, member_handler p) { self=&obj; fn=p; }
|
|
virtual int operator()(const CmdLine& cmd)
|
|
{
|
|
(self->*fn)(cmd);
|
|
return SCRIPT_OK;
|
|
}
|
|
};
|
|
|
|
//typedef std::hash_map< std::string, CmdHandler > CmdTable;
|
|
typedef std::map< std::string, CmdObject* > CmdTable;
|
|
|
|
class CmdEnv
|
|
{
|
|
private:
|
|
CmdTable script_commands;
|
|
|
|
int script_include(const CmdLine&);
|
|
int script_ignore(const CmdLine&);
|
|
int script_end(const CmdLine&);
|
|
int script_eval(const CmdLine&);
|
|
|
|
std::vector<CmdEnv*> scopes;
|
|
|
|
public:
|
|
CmdEnv();
|
|
virtual ~CmdEnv();
|
|
|
|
void register_command(const std::string& name, CmdObject *fn);
|
|
CmdObject *lookup_command(const std::string& name);
|
|
|
|
void register_command(const std::string& name, CmdHandler proc);
|
|
|
|
template<class T> inline void register_method(const std::string& name,
|
|
T *obj,
|
|
int (T::*fn)(const CmdLine&))
|
|
{ register_command(name, new CmdMethod<T>(*obj, fn)); }
|
|
|
|
template<class T> inline void register_method(const std::string& name,
|
|
T *obj,
|
|
void (T::*fn)(const CmdLine&))
|
|
{ register_command(name, new CmdMethod2<T>(*obj, fn)); }
|
|
|
|
void ignore_command(const std::string& name);
|
|
|
|
void register_vocabulary(const std::string& name, CmdEnv *env);
|
|
void begin_scope(CmdEnv *subenv);
|
|
void end_scope();
|
|
|
|
int do_line(const std::string& line);
|
|
int do_stream(std::istream& in);
|
|
int do_file(const std::string& filename);
|
|
int do_string(const std::string& line);
|
|
};
|
|
|
|
} // namespace gfx
|
|
|
|
// GFXSCRIPT_INCLUDED
|
|
#endif
|