source: tags/ms_r18q1/ARBDB/gb_aci.h

Last change on this file was 16766, checked in by westram, 6 years ago
File size: 7.9 KB
Line 
1// =============================================================== //
2//                                                                 //
3//   File      : gb_aci.h                                          //
4//   Purpose   :                                                   //
5//                                                                 //
6//   Institute of Microbiology (Technical University Munich)       //
7//   http://www.arb-home.de/                                       //
8//                                                                 //
9// =============================================================== //
10
11#ifndef GB_ACI_H
12#define GB_ACI_H
13
14#ifndef ARB_STR_H
15#include <arb_str.h>
16#endif
17#ifndef ARBDBT_H
18#include "arbdbt.h"
19#endif
20#ifndef _GLIBCXX_VECTOR
21#include <vector>
22#endif
23#ifndef _GLIBCXX_MAP
24#include <map>
25#endif
26
27#define gb_assert(cond) arb_assert(cond)
28
29typedef SmartMallocPtr(char) GBL;
30
31class GBL_streams {
32    std::vector<GBL> content;
33
34public:
35    void insert(char *copy) { content.push_back(copy); }
36    void insert(GBL smartie) { content.push_back(smartie); }
37    const char *get(int idx) const { gb_assert(idx<size()); return &*content[idx]; }
38    GBL get_smart(int idx) const { gb_assert(idx<size()); return content[idx]; }
39    int size() const { return content.size(); }
40    bool empty() const { return content.empty(); }
41
42    void erase() { content.clear(); }
43
44    char *concatenated() const;
45    void swap(GBL_streams& other) { std::swap(content, other.content); }
46};
47
48class GBL_command_arguments;
49typedef GB_ERROR (*GBL_COMMAND)(GBL_command_arguments *args);
50
51struct GBL_command_definition {
52    const char  *identifier; // command identifier (alphanumeric)
53    GBL_COMMAND  function;   // function to execute
54
55    bool is_defined() const { return identifier && function; }
56    bool is_sentinel() const { return !identifier && !function; }
57};
58
59// ------------------------
60//      command lookup
61
62class GBL_command_lookup_table : virtual Noncopyable {
63    struct ccp_less {
64        bool operator()(const char *s1, const char *s2) const {
65            return ARB_stricmp(s1, s2) < 0;
66        }
67    };
68
69    typedef std::map<const char*,GBL_COMMAND,ccp_less> CmdMap;
70
71    CmdMap defined;
72
73public:
74    GBL_command_lookup_table(const GBL_command_definition *table, unsigned size);
75    virtual ~GBL_command_lookup_table() {}
76
77    virtual GBL_COMMAND lookup(const char *identifier) const {
78        CmdMap::const_iterator found = defined.find(identifier);
79        return found == defined.end() ? NULp : found->second;
80    }
81};
82
83const GBL_command_lookup_table& ACI_get_standard_commands(); // provides access to commands defined in adlang1.cxx
84
85enum GBL_customization_mode {
86    DENY_SUBSTITUTION,
87    PERMIT_SUBSTITUTION,
88};
89
90class GBL_custom_command_lookup_table : public GBL_command_lookup_table {
91    const GBL_command_lookup_table& base_table;
92
93    void warn_about_overwritten_commands(const GBL_command_definition *custom_table, unsigned custom_size) const;
94public:
95    GBL_custom_command_lookup_table(const GBL_command_definition    *custom_table,
96                                    unsigned                         custom_size,
97                                    const GBL_command_lookup_table&  extending_this,
98                                    GBL_customization_mode           cmode = DENY_SUBSTITUTION) :
99        GBL_command_lookup_table(custom_table, custom_size),
100        base_table(extending_this)
101    {
102        if (cmode == DENY_SUBSTITUTION) {
103            warn_about_overwritten_commands(custom_table, custom_size);
104        }
105    }
106    ~GBL_custom_command_lookup_table() OVERRIDE {}
107
108    GBL_COMMAND lookup(const char *identifier) const OVERRIDE {
109        GBL_COMMAND cmd = GBL_command_lookup_table::lookup(identifier);
110        if (!cmd) cmd   = base_table.lookup(identifier);
111        return cmd;
112    }
113};
114
115// -------------------------------
116//      execution environment
117
118class GBL_env : virtual Noncopyable {
119    // provides an environment for running ACI commands
120
121    GBDATA *gb_main;               // database to use
122    char   *default_tree_name;     // if we have a default tree, its name is specified here (NULp otherwise)
123
124    const GBL_command_lookup_table& std_cmds;
125
126public:
127    GBL_env(GBDATA *gbMain, const char *treeName, const GBL_command_lookup_table& cmds = ACI_get_standard_commands()) :
128        gb_main(gbMain),
129        default_tree_name(nulldup(treeName)),
130        std_cmds(cmds)
131    {}
132
133    ~GBL_env() { free(default_tree_name); }
134
135    GBDATA *get_gb_main() const { return gb_main; }
136    const char *get_treename() const { return default_tree_name; }
137
138    GBL_COMMAND lookup_command(const char *identifier) const { return std_cmds.lookup(identifier); }
139};
140
141class GBL_call_env : virtual Noncopyable {
142    // provides a specific call environment (for one item)
143
144    GBDATA *gb_ref; // the database entry on which the command is applied (may be species, gene, experiment, group and maybe more)
145
146    const GBL_env& env;
147
148public:
149    GBL_call_env(GBDATA *gbd, const GBL_env& env_) : gb_ref(gbd), env(env_) {}
150    virtual ~GBL_call_env() {}
151
152    GBDATA *get_ref() const { return gb_ref; }
153    const GBL_env& get_env() const { return env; }
154
155    GBDATA *get_gb_main() const { return env.get_gb_main(); }
156    const char *get_treename() const { return env.get_treename(); }
157
158    char *interpret_subcommand(const char *input, const char *command) const { // @@@ should take command in pre-parsed format
159        return GB_command_interpreter_in_env(input, command, *this); // @@@ swap this function with GB_command_interpreter_in_env!
160    }
161};
162
163class GBL_maybe_itemless_call_env : public GBL_call_env {
164    GBL_env env;
165public:
166    GBL_maybe_itemless_call_env(GBDATA *gb_main, GBDATA *gb_item) :
167        GBL_call_env(gb_item, env),
168        env(gb_main, NULp)
169    {
170        gb_assert(gb_main);
171        gb_assert(get_gb_main());
172    }
173};
174
175struct GBL_simple_call_env : public GBL_maybe_itemless_call_env { // only useable if gb_item always exists (i.e. never is NULp)
176    GBL_simple_call_env(GBDATA *gb_item) :
177        GBL_maybe_itemless_call_env(GB_get_root(gb_item), gb_item)
178    {}
179};
180
181// -------------------------
182//      execution state
183
184class GBL_command_arguments : virtual Noncopyable {
185    // provides arguments, input, output + environment
186
187    const GBL_call_env&  callEnv;
188    const char          *cmdName; // the name of the current command (used for error messages)
189
190    GBL_streams &param;
191#if defined(ASSERTION_USED)
192    bool params_checked;
193#endif
194
195public:
196
197    GBL_streams &input;
198    GBL_streams &output;
199
200    GBL_command_arguments(const GBL_call_env& cenv_,
201                          const char *command_,
202                          GBL_streams& input_,
203                          GBL_streams& param_,
204                          GBL_streams& output_)
205        : callEnv(cenv_),
206          cmdName(command_),
207          param(param_),
208          input(input_),
209          output(output_)
210    {
211#if defined(ASSERTION_USED)
212        params_checked = false;
213#endif
214    }
215    ~GBL_command_arguments() {
216        gb_assert(params_checked);
217    }
218
219    GBDATA *get_ref() const { return callEnv.get_ref(); }
220    const GBL_call_env& get_callEnv() const { return callEnv; }
221    const GBL_env& get_env() const { return callEnv.get_env(); }
222
223    GBDATA *get_gb_main() const { return callEnv.get_gb_main(); }
224    const char *get_treename() const { return callEnv.get_treename(); }
225    const char *get_cmdName() const { return cmdName; }
226
227    const GBL_streams& get_param_streams() const { return param; }
228    int param_count() const { return param.size(); }
229    const char *get_param(int idx) const { return param.get(idx); }
230    const char *get_optional_param(int idx, const char *defaultValue) const { return idx>=0 && idx<param.size() ? param.get(idx) : defaultValue; }
231    GBL get_param_smart(int idx) const { return param.get_smart(idx); }
232
233#if defined(ASSERTION_USED)
234    bool set_params_checked() {
235        if (params_checked) return false;
236        params_checked = true;
237        return true;
238    }
239#endif
240};
241
242#else
243#error gb_aci.h included twice
244#endif // GB_ACI_H
245
246
Note: See TracBrowser for help on using the repository browser.