]>
Commit | Line | Data |
---|---|---|
10b959e3 JS |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: wxexpr.h | |
3 | // Purpose: Prolog-like file I/O, used by resource system. | |
4 | // Author: Julian Smart | |
5 | // Modified by: | |
6 | // Created: 01/02/97 | |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) | |
a6f6393c | 9 | // Licence: wxWindows licence |
10b959e3 JS |
10 | ///////////////////////////////////////////////////////////////////////////// |
11 | ||
34138703 JS |
12 | #ifndef _WX_WXEXPRH__ |
13 | #define _WX_WXEXPRH__ | |
10b959e3 | 14 | |
af49c4b8 | 15 | #if defined(__GNUG__) && !defined(__APPLE__) |
10b959e3 JS |
16 | #pragma interface "wxexpr.h" |
17 | #endif | |
18 | ||
2b5f62a0 | 19 | #if wxUSE_PROLOGIO |
10b959e3 JS |
20 | |
21 | #include "wx/defs.h" | |
22 | #include "wx/string.h" | |
23 | ||
10b959e3 JS |
24 | #include "wx/list.h" |
25 | #include "wx/hash.h" | |
26 | ||
27 | #include "wx/expr.h" | |
28 | ||
2b5f62a0 VZ |
29 | #include <stdio.h> |
30 | ||
10b959e3 JS |
31 | // Compatibility |
32 | #define PrologExpr wxExpr | |
33 | #define PrologDatabase wxExprDatabase | |
34 | #define proioErrorHandler wxExprErrorHandler | |
35 | #define PROIO_ERROR_GENERAL 1 | |
36 | #define PROIO_ERROR_SYNTAX 2 | |
37 | #define PrologNull wxExprNull | |
38 | #define PrologInteger wxExprInteger | |
39 | #define PrologReal wxExprReal | |
40 | #define PrologWord wxExprWord | |
41 | #define PrologString wxExprString | |
42 | #define PrologList wxExprList | |
43 | #define PrologType wxExprType | |
44 | ||
45 | // Error types | |
46 | #define WXEXPR_ERROR_GENERAL 1 | |
47 | #define WXEXPR_ERROR_SYNTAX 2 | |
48 | ||
49 | // Error handler function definition. If app returns TRUE, | |
50 | // carry on processing. | |
51 | typedef bool (*wxExprErrorHandler) (int errorType, char *msg); | |
52 | ||
53 | WXDLLEXPORT_DATA(extern wxExprErrorHandler) currentwxExprErrorHandler; | |
54 | ||
10b959e3 JS |
55 | |
56 | typedef enum { | |
57 | wxExprNull, | |
58 | wxExprInteger, | |
59 | wxExprReal, | |
60 | wxExprWord, | |
61 | wxExprString, | |
62 | wxExprList | |
63 | } wxExprType; | |
64 | ||
65 | class WXDLLEXPORT wxExprDatabase; | |
66 | ||
67 | class WXDLLEXPORT wxExpr | |
68 | { | |
69 | public: | |
70 | wxObject *client_data; | |
71 | wxExprType type; | |
72 | union { | |
73 | long integer; | |
54326285 OK |
74 | wxChar *word; |
75 | wxChar *string; | |
7a11869d | 76 | double real; |
10b959e3 JS |
77 | wxExpr *first; // If is a list expr, points to the first node |
78 | } value; | |
79 | ||
80 | wxExpr *next; // If this is a node in a list, points to the next node | |
81 | wxExpr *last; // If is a list expr, points to the last node | |
82 | ||
54326285 | 83 | wxExpr(wxExprType the_type, wxChar *word_or_string, bool allocate); |
10b959e3 | 84 | wxExpr(const wxString& functor); // Assume this is a new clause - pass functor |
bf604268 | 85 | wxExpr(wxExprType the_type, const wxString& word_or_string = wxT("")); |
10b959e3 | 86 | wxExpr(long the_integer); |
7a11869d | 87 | wxExpr(double the_real); |
10b959e3 JS |
88 | wxExpr(wxList *the_list); |
89 | ~wxExpr(void); | |
90 | ||
91 | inline wxExprType Type(void) const { return type; } | |
92 | inline long IntegerValue(void) const | |
93 | { | |
94 | if (type == wxExprInteger) | |
95 | return value.integer; | |
96 | else if (type == wxExprReal) | |
97 | return (long)value.real; | |
98 | else return 0; | |
99 | } | |
100 | ||
7a11869d | 101 | inline double RealValue(void) const { |
10b959e3 JS |
102 | if (type == wxExprReal) |
103 | return value.real; | |
104 | else if (type == wxExprInteger) | |
7a11869d JS |
105 | return (double)value.integer; |
106 | else return (double)0.0; | |
10b959e3 JS |
107 | } |
108 | ||
109 | inline wxString WordValue(void) const { | |
110 | if (type == wxExprWord) | |
111 | return value.word; | |
112 | else if (type == wxExprString) | |
113 | return wxString(value.string); | |
223d09f6 | 114 | else return wxString(wxT("")); |
10b959e3 JS |
115 | } |
116 | ||
117 | inline wxString StringValue(void) const { | |
118 | if (type == wxExprString) | |
119 | return wxString(value.string); | |
120 | else if (type == wxExprWord) | |
121 | return wxString(value.word); | |
223d09f6 | 122 | else return wxString(wxT("")); |
10b959e3 JS |
123 | } |
124 | ||
125 | // Get nth arg of clause (starting from 1) | |
126 | wxExpr *Arg(wxExprType type, int arg) const; | |
127 | ||
128 | // Return nth argument of a list expression (starting from zero) | |
129 | wxExpr *Nth(int arg) const; | |
130 | ||
131 | // Returns the number of elements in a list expression | |
132 | int Number(void) const; | |
133 | ||
134 | // Make a clone | |
135 | wxExpr *Copy(void) const; | |
136 | ||
137 | wxExpr *GetAttributeValueNode(const wxString& word) const; // Use only for a clause or list | |
138 | wxExpr *AttributeValue(const wxString& word) const; // Use only for a clause | |
139 | wxString Functor(void) const; // Only for a clause | |
140 | bool IsFunctor(const wxString& s) const; // Only for a clause | |
fd15d8f1 RR |
141 | void WriteClause(FILE* stream); // Write this expression as a top-level clause |
142 | void WriteExpr(FILE* stream); // Write as any other subexpression | |
10b959e3 JS |
143 | |
144 | // Append an expression to a list | |
145 | void Append(wxExpr *expr); | |
146 | // Insert at beginning of list | |
147 | void Insert(wxExpr *expr); | |
148 | ||
149 | // Get first expr in list | |
150 | inline wxExpr *GetFirst(void) const { return ((type == wxExprList) ? value.first : (wxExpr*)NULL); } | |
151 | ||
152 | // Get next expr if this is a node in a list | |
153 | inline wxExpr *GetNext(void) const { return next; } | |
154 | ||
155 | // Get last expr in list | |
156 | inline wxExpr *GetLast(void) const { return ((type == wxExprList) ? last : (wxExpr*)NULL); } | |
157 | ||
158 | // This should really be called SetAttributeValue since any existing | |
159 | // attribute-value is deleted first. | |
160 | void AddAttributeValue(const wxString& attribute, long value); | |
7a11869d | 161 | void AddAttributeValue(const wxString& attribute, double value); |
10b959e3 JS |
162 | void AddAttributeValueWord(const wxString& attribute, const wxString& value); |
163 | void AddAttributeValueString(const wxString& attribute, const wxString& value); | |
164 | void AddAttributeValue(const wxString& attribute, wxList *value); | |
165 | void AddAttributeValue(const wxString& attribute, wxExpr *value); | |
166 | void AddAttributeValueStringList(const wxString& attribute, wxList *string_list); | |
167 | ||
168 | void DeleteAttributeValue(const wxString& attribute); | |
169 | ||
170 | bool GetAttributeValue(const wxString& att, int& var) const; | |
171 | bool GetAttributeValue(const wxString& att, long& var) const; | |
172 | bool GetAttributeValue(const wxString& att, float& var) const; | |
7a11869d | 173 | bool GetAttributeValue(const wxString& att, double& var) const; |
10b959e3 JS |
174 | bool GetAttributeValue(const wxString& att, wxString& var) const; // Word OR string -> string |
175 | bool GetAttributeValue(const wxString& att, wxExpr **var) const; | |
176 | ||
177 | // Compatibility with old PrologIO | |
54326285 OK |
178 | inline void AssignAttributeValue(wxChar *att, int *var) const { GetAttributeValue(att, *var); } |
179 | inline void AssignAttributeValue(wxChar *att, long *var) const { GetAttributeValue(att, *var); } | |
180 | inline void AssignAttributeValue(wxChar *att, float *var) const { GetAttributeValue(att, *var); } | |
181 | inline void AssignAttributeValue(wxChar *att, double *var) const { GetAttributeValue(att, *var); } | |
182 | inline void AssignAttributeValue(wxChar *att, wxExpr **var) const { GetAttributeValue(att, var); } | |
183 | void AssignAttributeValue(wxChar *att, wxChar **var) const ; // Word OR string -> string | |
10b959e3 JS |
184 | |
185 | // Add string items to list if the list attribute exists | |
186 | bool GetAttributeValueStringList(const wxString& att, wxList *var) const; | |
187 | ||
188 | // Associate other data with this expression, e.g. when reading in a | |
189 | // number of linked items - store C++ object pointer with the expression | |
190 | // so we can index into the wxExpr database and fish out the pointer. | |
191 | inline void SetClientData(wxObject *data) { client_data = data; } | |
192 | inline wxObject *GetClientData(void) const { return client_data; } | |
22f3361e VZ |
193 | |
194 | DECLARE_NO_COPY_CLASS(wxExpr) | |
10b959e3 JS |
195 | }; |
196 | ||
197 | class WXDLLEXPORT wxExprDatabase: public wxList | |
198 | { | |
a6f6393c VZ |
199 | private: |
200 | wxNode *position; // Where we are in a search | |
201 | wxHashTable *hash_table; | |
202 | wxString attribute_to_hash; | |
203 | ||
204 | public: | |
205 | int noErrors; | |
206 | ||
207 | wxExprDatabase(wxExprErrorHandler handler = 0); | |
208 | ||
209 | // Use hashing on both the functor, and the attribute of | |
210 | // specified type (wxExprString or wxExprInteger) and name. | |
211 | // So to find node 45 | |
212 | // (i.e. match the clause node(id=45, ...)) | |
213 | // it usually requires 1 look-up: the keys for functor and attribute | |
214 | // are added together. | |
215 | // Obviously if the attribute was missing in a clause, it would | |
216 | // fail to be found by this method, but could be retrieved by a | |
217 | // linear search using BeginFind and FindClauseByFunctor, | |
218 | // or just searching through the list as per usual. | |
219 | ||
220 | wxExprDatabase(wxExprType type, const wxString& attribute, int size = 500, | |
221 | wxExprErrorHandler handler = 0); | |
222 | ||
223 | ~wxExprDatabase(void); | |
224 | ||
225 | void BeginFind(void) ; // Initialise a search | |
226 | wxExpr *FindClause(long id) ; // Find a term based on an integer id attribute | |
227 | // e.g. node(id=23, type=rectangle, ....). | |
228 | ||
229 | // Find on basis of attribute/value pairs, e.g. type=rectangle | |
230 | // This doesn't use hashing; it's a linear search. | |
231 | wxExpr *FindClause(const wxString& word, const wxString& value); | |
232 | wxExpr *FindClause(const wxString& word, long value); | |
233 | wxExpr *FindClause(const wxString& word, double value); | |
234 | wxExpr *FindClauseByFunctor(const wxString& functor); | |
235 | ||
236 | wxExpr *HashFind(const wxString& functor, const wxString& value) const; | |
237 | wxExpr *HashFind(const wxString& functor, long value) const; | |
238 | ||
239 | void Append(wxExpr *expr); // Does cleverer things if hashing is on | |
240 | void ClearDatabase(void); | |
241 | inline int GetErrorCount() const { return noErrors; } | |
242 | bool Read(const wxString& filename); | |
243 | bool ReadFromString(const wxString& buffer); | |
244 | bool Write(const wxString& fileName); | |
fd15d8f1 | 245 | bool Write(FILE* stream); |
a6f6393c VZ |
246 | |
247 | // Compatibility | |
54326285 | 248 | inline bool ReadProlog(wxChar *filename) { return Read(wxString(filename)); } |
bf604268 MB |
249 | inline bool ReadPrologFromString(char *buffer) |
250 | { | |
251 | return ReadFromString(wxString(buffer, wxConvLibc)); | |
252 | } | |
fd15d8f1 | 253 | inline void WriteProlog(FILE* stream) { Write(stream); } |
a6f6393c VZ |
254 | |
255 | private: | |
256 | DECLARE_DYNAMIC_CLASS(wxExprDatabase) | |
22f3361e | 257 | DECLARE_NO_COPY_CLASS(wxExprDatabase) |
10b959e3 JS |
258 | }; |
259 | ||
260 | // Function call-style interface - some more convenience wrappers/unwrappers | |
261 | ||
262 | // Make a call | |
184b5d99 | 263 | WXDLLEXPORT wxExpr* wxExprMakeCall(const wxString& functor ...); |
10b959e3 JS |
264 | |
265 | #define wxExprMakeInteger(x) (new wxExpr((long)x)) | |
7a11869d | 266 | #define wxExprMakeReal(x) (new wxExpr((double)x)) |
10b959e3 JS |
267 | #define wxExprMakeString(x) (new wxExpr(wxExprString, x)) |
268 | #define wxExprMakeWord(x) (new wxExpr(wxExprWord, x)) | |
269 | #define wxExprMake(x) (new wxExpr(x)) | |
270 | ||
271 | // Checks functor | |
184b5d99 | 272 | WXDLLEXPORT bool wxExprIsFunctor(wxExpr *expr, const wxString& functor); |
10b959e3 JS |
273 | |
274 | // Temporary variable for communicating between wxexpr.cpp and YACC/LEX | |
275 | WXDLLEXPORT_DATA(extern wxExprDatabase*) thewxExprDatabase; | |
276 | ||
277 | // YACC/LEX can leave memory lying around... | |
184b5d99 | 278 | extern "C" WXDLLEXPORT int wxExprCleanUp(); |
10b959e3 | 279 | |
2b5f62a0 VZ |
280 | #endif // wxUSE_PROLOGIO |
281 | ||
282 | #endif // _WX_WXEXPRH__ | |
10b959e3 | 283 |