1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: Prolog-like file I/O, used by resource system.
4 // Author: Julian Smart
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
15 #if defined(__GNUG__) && !defined(__APPLE__)
16 #pragma interface "wxexpr.h"
19 #include "wx/deprecated/setup.h"
24 #include "wx/string.h"
29 #include "wx/deprecated/expr.h"
34 #define PrologExpr wxExpr
35 #define PrologDatabase wxExprDatabase
36 #define proioErrorHandler wxExprErrorHandler
37 #define PROIO_ERROR_GENERAL 1
38 #define PROIO_ERROR_SYNTAX 2
39 #define PrologNull wxExprNull
40 #define PrologInteger wxExprInteger
41 #define PrologReal wxExprReal
42 #define PrologWord wxExprWord
43 #define PrologString wxExprString
44 #define PrologList wxExprList
45 #define PrologType wxExprType
48 #define WXEXPR_ERROR_GENERAL 1
49 #define WXEXPR_ERROR_SYNTAX 2
51 // Error handler function definition. If app returns TRUE,
52 // carry on processing.
53 typedef bool (*wxExprErrorHandler
) (int errorType
, char *msg
);
55 WXDLLEXPORT_DATA(extern wxExprErrorHandler
) currentwxExprErrorHandler
;
67 class WXDLLEXPORT wxExprDatabase
;
69 class WXDLLEXPORT wxExpr
72 wxObject
*client_data
;
79 wxExpr
*first
; // If is a list expr, points to the first node
82 wxExpr
*next
; // If this is a node in a list, points to the next node
83 wxExpr
*last
; // If is a list expr, points to the last node
85 wxExpr(wxExprType the_type
, wxChar
*word_or_string
, bool allocate
);
86 wxExpr(const wxString
& functor
); // Assume this is a new clause - pass functor
87 wxExpr(wxExprType the_type
, const wxString
& word_or_string
= wxT(""));
88 wxExpr(long the_integer
);
89 wxExpr(double the_real
);
90 wxExpr(wxList
*the_list
);
93 inline wxExprType
Type(void) const { return type
; }
94 inline long IntegerValue(void) const
96 if (type
== wxExprInteger
)
98 else if (type
== wxExprReal
)
99 return (long)value
.real
;
103 inline double RealValue(void) const {
104 if (type
== wxExprReal
)
106 else if (type
== wxExprInteger
)
107 return (double)value
.integer
;
108 else return (double)0.0;
111 inline wxString
WordValue(void) const {
112 if (type
== wxExprWord
)
114 else if (type
== wxExprString
)
115 return wxString(value
.string
);
116 else return wxString(wxT(""));
119 inline wxString
StringValue(void) const {
120 if (type
== wxExprString
)
121 return wxString(value
.string
);
122 else if (type
== wxExprWord
)
123 return wxString(value
.word
);
124 else return wxString(wxT(""));
127 // Get nth arg of clause (starting from 1)
128 wxExpr
*Arg(wxExprType type
, int arg
) const;
130 // Return nth argument of a list expression (starting from zero)
131 wxExpr
*Nth(int arg
) const;
133 // Returns the number of elements in a list expression
134 int Number(void) const;
137 wxExpr
*Copy(void) const;
139 wxExpr
*GetAttributeValueNode(const wxString
& word
) const; // Use only for a clause or list
140 wxExpr
*AttributeValue(const wxString
& word
) const; // Use only for a clause
141 wxString
Functor(void) const; // Only for a clause
142 bool IsFunctor(const wxString
& s
) const; // Only for a clause
143 void WriteClause(FILE* stream
); // Write this expression as a top-level clause
144 void WriteExpr(FILE* stream
); // Write as any other subexpression
146 // Append an expression to a list
147 void Append(wxExpr
*expr
);
148 // Insert at beginning of list
149 void Insert(wxExpr
*expr
);
151 // Get first expr in list
152 inline wxExpr
*GetFirst(void) const { return ((type
== wxExprList
) ? value
.first
: (wxExpr
*)NULL
); }
154 // Get next expr if this is a node in a list
155 inline wxExpr
*GetNext(void) const { return next
; }
157 // Get last expr in list
158 inline wxExpr
*GetLast(void) const { return ((type
== wxExprList
) ? last
: (wxExpr
*)NULL
); }
160 // This should really be called SetAttributeValue since any existing
161 // attribute-value is deleted first.
162 void AddAttributeValue(const wxString
& attribute
, long value
);
163 void AddAttributeValue(const wxString
& attribute
, double value
);
164 void AddAttributeValueWord(const wxString
& attribute
, const wxString
& value
);
165 void AddAttributeValueString(const wxString
& attribute
, const wxString
& value
);
166 void AddAttributeValue(const wxString
& attribute
, wxList
*value
);
167 void AddAttributeValue(const wxString
& attribute
, wxExpr
*value
);
168 void AddAttributeValueStringList(const wxString
& attribute
, wxList
*string_list
);
170 void DeleteAttributeValue(const wxString
& attribute
);
172 bool GetAttributeValue(const wxString
& att
, int& var
) const;
173 bool GetAttributeValue(const wxString
& att
, long& var
) const;
174 bool GetAttributeValue(const wxString
& att
, float& var
) const;
175 bool GetAttributeValue(const wxString
& att
, double& var
) const;
176 bool GetAttributeValue(const wxString
& att
, wxString
& var
) const; // Word OR string -> string
177 bool GetAttributeValue(const wxString
& att
, wxExpr
**var
) const;
179 // Compatibility with old PrologIO
180 inline void AssignAttributeValue(wxChar
*att
, int *var
) const { GetAttributeValue(att
, *var
); }
181 inline void AssignAttributeValue(wxChar
*att
, long *var
) const { GetAttributeValue(att
, *var
); }
182 inline void AssignAttributeValue(wxChar
*att
, float *var
) const { GetAttributeValue(att
, *var
); }
183 inline void AssignAttributeValue(wxChar
*att
, double *var
) const { GetAttributeValue(att
, *var
); }
184 inline void AssignAttributeValue(wxChar
*att
, wxExpr
**var
) const { GetAttributeValue(att
, var
); }
185 void AssignAttributeValue(wxChar
*att
, wxChar
**var
) const ; // Word OR string -> string
187 // Add string items to list if the list attribute exists
188 bool GetAttributeValueStringList(const wxString
& att
, wxList
*var
) const;
190 // Associate other data with this expression, e.g. when reading in a
191 // number of linked items - store C++ object pointer with the expression
192 // so we can index into the wxExpr database and fish out the pointer.
193 inline void SetClientData(wxObject
*data
) { client_data
= data
; }
194 inline wxObject
*GetClientData(void) const { return client_data
; }
196 DECLARE_NO_COPY_CLASS(wxExpr
)
199 class WXDLLEXPORT wxExprDatabase
: public wxList
202 wxNode
*position
; // Where we are in a search
203 wxHashTable
*hash_table
;
204 wxString attribute_to_hash
;
209 wxExprDatabase(wxExprErrorHandler handler
= 0);
211 // Use hashing on both the functor, and the attribute of
212 // specified type (wxExprString or wxExprInteger) and name.
213 // So to find node 45
214 // (i.e. match the clause node(id=45, ...))
215 // it usually requires 1 look-up: the keys for functor and attribute
216 // are added together.
217 // Obviously if the attribute was missing in a clause, it would
218 // fail to be found by this method, but could be retrieved by a
219 // linear search using BeginFind and FindClauseByFunctor,
220 // or just searching through the list as per usual.
222 wxExprDatabase(wxExprType type
, const wxString
& attribute
, int size
= 500,
223 wxExprErrorHandler handler
= 0);
225 ~wxExprDatabase(void);
227 void BeginFind(void) ; // Initialise a search
228 wxExpr
*FindClause(long id
) ; // Find a term based on an integer id attribute
229 // e.g. node(id=23, type=rectangle, ....).
231 // Find on basis of attribute/value pairs, e.g. type=rectangle
232 // This doesn't use hashing; it's a linear search.
233 wxExpr
*FindClause(const wxString
& word
, const wxString
& value
);
234 wxExpr
*FindClause(const wxString
& word
, long value
);
235 wxExpr
*FindClause(const wxString
& word
, double value
);
236 wxExpr
*FindClauseByFunctor(const wxString
& functor
);
238 wxExpr
*HashFind(const wxString
& functor
, const wxString
& value
) const;
239 wxExpr
*HashFind(const wxString
& functor
, long value
) const;
241 void Append(wxExpr
*expr
); // Does cleverer things if hashing is on
242 void ClearDatabase(void);
243 inline int GetErrorCount() const { return noErrors
; }
244 bool Read(const wxString
& filename
);
245 bool ReadFromString(const wxString
& buffer
);
246 bool Write(const wxString
& fileName
);
247 bool Write(FILE* stream
);
250 inline bool ReadProlog(wxChar
*filename
) { return Read(wxString(filename
)); }
251 inline bool ReadPrologFromString(char *buffer
)
253 return ReadFromString(wxString(buffer
, wxConvLibc
));
255 inline void WriteProlog(FILE* stream
) { Write(stream
); }
258 DECLARE_DYNAMIC_CLASS(wxExprDatabase
)
259 DECLARE_NO_COPY_CLASS(wxExprDatabase
)
262 // Function call-style interface - some more convenience wrappers/unwrappers
265 WXDLLEXPORT wxExpr
* wxExprMakeCall(const wxString
& functor
...);
267 #define wxExprMakeInteger(x) (new wxExpr((long)x))
268 #define wxExprMakeReal(x) (new wxExpr((double)x))
269 #define wxExprMakeString(x) (new wxExpr(wxExprString, x))
270 #define wxExprMakeWord(x) (new wxExpr(wxExprWord, x))
271 #define wxExprMake(x) (new wxExpr(x))
274 WXDLLEXPORT
bool wxExprIsFunctor(wxExpr
*expr
, const wxString
& functor
);
276 // Temporary variable for communicating between wxexpr.cpp and YACC/LEX
277 WXDLLEXPORT_DATA(extern wxExprDatabase
*) thewxExprDatabase
;
279 // YACC/LEX can leave memory lying around...
280 extern "C" WXDLLEXPORT
int wxExprCleanUp();
282 #endif // wxUSE_PROLOGIO
284 #endif // _WX_WXEXPRH__