summaryrefslogtreecommitdiff
path: root/src/module.h
blob: 81e5f10b2d653136a0ea8ffed7ce4141385dbf91 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#ifndef MODULE_H_
#define MODULE_H_

#include <string>
#include <vector>
#include <list>
#include <deque>
#include <boost/unordered_map.hpp>
#include <boost/unordered_set.hpp>
#include <time.h>
#include <sys/stat.h>

#include "value.h"
#include "typedefs.h"
#include "localscope.h"
#include "feature.h"

class ModuleInstantiation
{
public:
	ModuleInstantiation(const std::string &name = "")
		: tag_root(false), tag_highlight(false), tag_background(false), recursioncount(0), modname(name) { }
	virtual ~ModuleInstantiation();

	virtual std::string dump(const std::string &indent) const;
	class AbstractNode *evaluate(const class Context *ctx) const;
	std::vector<AbstractNode*> instantiateChildren(const Context *evalctx) const;

	void setPath(const std::string &path) { this->modpath = path; }
	const std::string &path() const { return this->modpath; }
	std::string getAbsolutePath(const std::string &filename) const;

	const std::string &name() const { return this->modname; }
	bool isBackground() const { return this->tag_background; }
	bool isHighlight() const { return this->tag_highlight; }
	bool isRoot() const { return this->tag_root; }

	AssignmentList arguments;
	LocalScope scope;

	bool tag_root;
	bool tag_highlight;
	bool tag_background;
	mutable int recursioncount;
protected:
	std::string modname;
	std::string modpath;

	friend class Module;
};

class IfElseModuleInstantiation : public ModuleInstantiation {
public:
	IfElseModuleInstantiation() : ModuleInstantiation("if") { }
	virtual ~IfElseModuleInstantiation();
	std::vector<AbstractNode*> instantiateElseChildren(const Context *evalctx) const;
	virtual std::string dump(const std::string &indent) const;

	LocalScope else_scope;
};

class AbstractModule
{
private:
        const Feature *feature;
public:
        AbstractModule() : feature(NULL) {}
        AbstractModule(const Feature& feature) : feature(&feature) {}
	virtual ~AbstractModule();
        virtual bool is_enabled() const { return (feature == NULL) || feature->is_enabled(); };
	virtual class AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const class EvalContext *evalctx = NULL) const;
	virtual std::string dump(const std::string &indent, const std::string &name) const;
};

class Module : public AbstractModule
{
public:
	Module() { }
	Module(const Feature& feature) : AbstractModule(feature) { }
	virtual ~Module();

	virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx = NULL) const;
	virtual std::string dump(const std::string &indent, const std::string &name) const;
	static const std::string& stack_element(int n) { return module_stack[n]; };
	static int stack_size() { return module_stack.size(); };

	AssignmentList definition_arguments;

	LocalScope scope;

private:
	static std::deque<std::string> module_stack;
};

// FIXME: A FileModule doesn't have definition arguments, so we shouldn't really
// inherit from a Module
class FileModule : public Module
{
public:
	FileModule() : is_handling_dependencies(false) {}
	virtual ~FileModule() {}

	void setModulePath(const std::string &path) { this->path = path; }
	const std::string &modulePath() const { return this->path; }
	void registerInclude(const std::string &localpath, const std::string &fullpath);
	bool includesChanged() const;
	bool handleDependencies();
	virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx = NULL) const;
	bool hasIncludes() const { return !this->includes.empty(); }
	bool usesLibraries() const { return !this->usedlibs.empty(); }
	bool isHandlingDependencies() const { return this->is_handling_dependencies; }

	typedef boost::unordered_set<std::string> ModuleContainer;
	ModuleContainer usedlibs;
private:
	struct IncludeFile {
		std::string filename;
		bool valid;
		time_t mtime;
	};

	bool include_modified(const IncludeFile &inc) const;

	typedef boost::unordered_map<std::string, struct IncludeFile> IncludeContainer;
	IncludeContainer includes;
	bool is_handling_dependencies;
	std::string path;
};

#endif
contact: Jan Huwald // Impressum