1 /***********************************************************************
2 *                                                                      *
3 *               This software is part of the ast package               *
4 *          Copyright (c) 2002-2013 AT&T Intellectual Property          *
5 *                      and is licensed under the                       *
6 *                 Eclipse Public License, Version 1.0                  *
7 *                    by AT&T Intellectual Property                     *
8 *                                                                      *
9 *                A copy of the License is available at                 *
10 *          http://www.eclipse.org/org/documents/epl-v10.html           *
11 *         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
12 *                                                                      *
13 *              Information and Software Systems Research               *
14 *                            AT&T Research                             *
15 *                           Florham Park NJ                            *
16 *                                                                      *
17 *               Glenn Fowler <glenn.s.fowler@gmail.com>                *
18 *                                                                      *
19 ***********************************************************************/
20 #pragma prototyped
21 /*
22  * C expression library interface
23  *
24  * Glenn Fowler
25  * AT&T Research
26  */
27 
28 #ifndef _CX_H
29 #define _CX_H
30 
31 #include <ast.h>
32 #include <math.h>
33 #include <dt.h>
34 #include <vmalloc.h>
35 
36 #define CX_ID		"cx"
37 #define CX_VERSION	20110811L
38 
39 /* Cx_t.flags */
40 
41 #define CX_DEBUG	(1<<0)			/* debug trace		*/
42 #define CX_QUIET	(1<<1)			/* no non-fatal messages*/
43 #define CX_REGRESS	(1<<2)			/* regression output	*/
44 #define CX_TRACE	(1<<3)			/* algorithm trace	*/
45 #define CX_VALIDATE	(1<<4)			/* validate constraints	*/
46 #define CX_VERBOSE	(1<<5)			/* verbose feedback	*/
47 
48 #define CX_BALANCED	(1<<6)			/* cx input () balanced	*/
49 #define CX_INCLUDE	(1<<7)			/* include cxpush()	*/
50 #define CX_FLAGS	(1L<<8)			/* first caller flag	*/
51 
52 /* _CX_HEADER_.flags */
53 
54 #define CX_NORMALIZED	0x00000001
55 #define CX_INITIALIZED	0x00000002
56 #define CX_REFERENCED	0x00000004
57 #define CX_DEPRECATED	0x00000008
58 #define CX_VISITED	0x00000010
59 #define CX_IGNORECASE	0x00000020
60 #define CX_SCHEMA	0x00000040
61 
62 /* Cxmember_t.flags */
63 
64 #define CX_VIRTUAL	0x0001
65 
66 /* Cxpart_t.flags */
67 
68 #define CX_ALL		0x0001
69 
70 /* Cxtype_t.representation */
71 
72 #define CX_void		0
73 #define CX_number	1
74 #define CX_string	2
75 #define CX_pointer	3
76 #define CX_reference	4
77 #define CX_buffer	5		/* allocated separately		*/
78 #define CX_type		6
79 #define CX_bool		7
80 
81 /* Cxformat_t.flags */
82 
83 #define CX_STRING	0x0001
84 #define CX_INTEGER	0x0002
85 #define CX_UNSIGNED	0x0004
86 #define CX_FLOAT	0x0008
87 #define CX_BUFFER	0x0010
88 #define CX_BINARY	0x0020
89 #define CX_MULTIPLE	0x0100
90 #define CX_FREE		0x0200
91 #define CX_NUL		0x0400
92 #define CX_VARIABLE	0x0800
93 #define CX_QUOTEALL	0x1000
94 #define CX_LONG		0x2000
95 
96 #define CX_ASSIGN	01
97 #define CX_X2		02
98 #define CX_UNARY	04
99 #define CX_ATTR		3
100 
101 #define CX_OPNAME	"0+&/>~<~%*!|-^CDeGLnpRJSst"
102 
103 #define CX_NOP		(( 0))
104 
105 #define CX_ADD		(( 1<<CX_ATTR))
106 #define CX_AND		(( 2<<CX_ATTR))
107 #define CX_DIV		(( 3<<CX_ATTR))
108 #define CX_GT		(( 4<<CX_ATTR))
109 #define CX_INV		(( 5<<CX_ATTR)|CX_UNARY)
110 #define CX_LT		(( 6<<CX_ATTR))
111 #define CX_MAT		(( 7<<CX_ATTR))
112 #define CX_MOD		(( 8<<CX_ATTR))
113 #define CX_MPY		(( 9<<CX_ATTR))
114 #define CX_NOT		((10<<CX_ATTR)|CX_UNARY)
115 #define CX_OR		((11<<CX_ATTR))
116 #define CX_SUB		((12<<CX_ATTR))
117 #define CX_XOR		((13<<CX_ATTR))
118 
119 #define CX_CALL		((14<<CX_ATTR)|CX_UNARY)
120 #define CX_DEL		((15<<CX_ATTR))
121 #define CX_END		((16<<CX_ATTR))
122 #define CX_GET		((17<<CX_ATTR)|CX_UNARY)
123 #define CX_LOG		((18<<CX_ATTR)|CX_UNARY)
124 #define CX_NUM		((19<<CX_ATTR))
125 #define CX_POP		((20<<CX_ATTR))
126 #define CX_REF		(CX_AND|CX_UNARY)
127 #define CX_RET		((21<<CX_ATTR)|CX_UNARY)
128 #define CX_SC0		((22<<CX_ATTR))
129 #define CX_SC1		(CX_SC0|CX_X2)
130 #define CX_SET		((23<<CX_ATTR)|CX_ASSIGN)
131 #define CX_STR		((24<<CX_ATTR))
132 #define CX_TST		((25<<CX_ATTR))
133 #define CX_OPERATORS	((26<<CX_ATTR))
134 
135 #define CX_CAST		(CX_SET|CX_UNARY)
136 #define CX_EQ		(CX_SET|CX_X2)
137 #define CX_ANDAND	(CX_AND|CX_X2)
138 #define CX_OROR		(CX_OR|CX_X2)
139 #define CX_LSH		(CX_LT|CX_X2)
140 #define CX_RSH		(CX_GT|CX_X2)
141 #define CX_UPLUS	(CX_ADD|CX_UNARY)
142 #define CX_UMINUS	(CX_SUB|CX_UNARY)
143 
144 #define CX_MATCH	(CX_MAT|CX_ASSIGN)
145 #define CX_NOMATCH	(CX_MAT)
146 
147 #define CX_GE		(CX_GT|CX_ASSIGN)
148 #define CX_LE		(CX_LT|CX_ASSIGN)
149 #define CX_NE		((CX_NOT&~CX_UNARY)|CX_ASSIGN)
150 
151 #define CX_CTYPE_ALPHA	(1<<0)
152 #define CX_CTYPE_DIGIT	(1<<1)
153 #define CX_CTYPE_FLOAT	(1<<2)
154 #define CX_CTYPE_SPACE	(1<<3)
155 
156 #define CXMIN(a,b)	(((a)<(b))?(a):(b))
157 #define CXMAX(a,b)	(((a)>(b))?(a):(b))
158 
159 #define CXINTEGER(n)	((Cxinteger_t)(n))
160 #define CXUNSIGNED(n)	((Cxunsigned_t)CXINTEGER(n))
161 
162 #define CXDETAILS(d,f,t,v) \
163 	((d)?(d):((d)=(f)&&(f)->details?(f)->details:(t)->format.details?(t)->format.details:(v)))
164 
165 #define CX_HEADER_INIT	{{0},0}
166 #define CX_SCHEMA_INIT	{{0},CX_SCHEMA}
167 #define CX_CALLOUT_INIT(op,type1,type2,callout,description) \
168 	{0,description,CX_HEADER_INIT,op,(Cxtype_t*)type1,(Cxtype_t*)type2,callout},
169 #define CX_FUNCTION_INIT(name,type,function,prototype,description) \
170 	{name,description,CX_HEADER_INIT,function,(Cxtype_t*)type,prototype},
171 #define CX_RECODE_INIT(op,type1,type2,recode,description) \
172 	{0,description,CX_HEADER_INIT,op,(Cxtype_t*)type1,(Cxtype_t*)type2,recode},
173 #define CX_TYPE_INIT(name,base,external,internal,match,description) \
174 	{name,description,CX_HEADER_INIT,(Cxtype_t*)base,0,external,internal,0,0,0,0,CX_HEADER_INIT,match},
175 #define CX_VARIABLE_INIT(name,type,index,description) \
176 	{name,description,CX_HEADER_INIT,0,(Cxtype_t*)type,0,index},
177 
178 #define cxrepresentation(t)	((t)->representation)
179 #define cxisbool(t)		(cxrepresentation(t)==CX_bool)
180 #define cxisbuffer(t)		(cxrepresentation(t)==CX_buffer)
181 #define cxislogical(t)		(cxrepresentation(t)==CX_bool||cxrepresentation(t)==CX_number)
182 #define cxisnumber(t)		(cxrepresentation(t)==CX_number)
183 #define cxisstring(t)		(cxrepresentation(t)==CX_string)
184 #define cxisvoid(t)		(cxrepresentation(t)==CX_void)
185 
186 #define cxsize(t,v)	((cxisstring(t)||cxisbuffer(t))?((v)->buffer.size):0)
187 
188 #if ! _ast_fltmax_double
189 #undef	strtod
190 #define strtod(a,b)	strtold(a,b)
191 #undef	strntod
192 #define strntod(a,b,c)	strntold(a,b,c)
193 #endif
194 
195 typedef _ast_fltmax_t Cxnumber_t;
196 typedef      uint32_t Cxflags_t;
197 typedef      intmax_t Cxinteger_t;
198 typedef     uintmax_t Cxunsigned_t;
199 
200 struct Cx_s; typedef struct Cx_s Cx_t;
201 struct Cxarray_s; typedef struct Cxarray_s Cxarray_t;
202 struct Cxconstraint_s; typedef struct Cxconstraint_s Cxconstraint_t;
203 struct Cxdisc_s; typedef struct Cxdisc_s Cxdisc_t;
204 struct Cxedit_s; typedef struct Cxedit_s Cxedit_t;
205 struct Cxexpr_s; typedef struct Cxexpr_s Cxexpr_t;
206 struct Cxformat_s; typedef struct Cxformat_s Cxformat_t;
207 struct Cxinstruction_s; typedef struct Cxinstruction_s Cxinstruction_t;
208 struct Cxitem_s; typedef struct Cxitem_s Cxitem_t;
209 struct Cxlib_s; typedef struct Cxlib_s Cxlib_t;
210 struct Cxmatch_s; typedef struct Cxmatch_s Cxmatch_t;
211 struct Cxmap_s; typedef struct Cxmap_s Cxmap_t;
212 struct Cxmember_s; typedef struct Cxmember_s Cxmember_t;
213 struct Cxop_s; typedef struct Cxop_s Cxop_t;
214 struct Cxoperand_s; typedef struct Cxoperand_s Cxoperand_t;
215 struct Cxpart_s; typedef struct Cxpart_s Cxpart_t;
216 struct Cxquery_s; typedef struct Cxquery_s Cxquery_t;
217 struct Cxreference_s; typedef struct Cxreference_s Cxreference_t;
218 struct Cxstate_s; typedef struct Cxstate_s Cxstate_t;
219 struct Cxstructure_s; typedef struct Cxstructure_s Cxstructure_t;
220 struct Cxtype_s; typedef struct Cxtype_s Cxtype_t;
221 struct Cxvariable_s; typedef struct Cxvariable_s Cxvariable_t;
222 
223 struct Cxop_s				/* callout/recode op		*/
224 {
225 	int		code;		/* op code			*/
226 	Cxtype_t*	type1;		/* operand 1 type		*/
227 	Cxtype_t*	type2;		/* operand 2 type		*/
228 };
229 
230 #define _CX_HEADER_ \
231 	const char*	name;		/* key name			*/ \
232 	const char*	description;	/* description			*/
233 
234 #define _CX_HEADER_LINK_ \
235 	Dtlink_t	link;		/* dictionary link		*/ \
236 	uint16_t	flags;		/* cx header flags		*/ \
237 	uint16_t	index;		/* member index			*/
238 
239 #define _CX_NAME_HEADER_ \
240 	_CX_HEADER_ \
241 	struct \
242 	{ \
243 	_CX_HEADER_LINK_ \
244 	}		header;
245 
246 #define _CX_LIST_HEADER_ \
247 	_CX_HEADER_ \
248 	struct \
249 	{ \
250 	_CX_HEADER_LINK_ \
251 	Dtlink_t	list; \
252 	}		header;
253 
254 #define _CX_CODE_HEADER_ \
255 	_CX_NAME_HEADER_ \
256 	Cxop_t		op;		/* operator			*/
257 
258 typedef struct Cxheader_s		/* name/description header	*/
259 {
260 	_CX_HEADER_
261 } Cxheader_t;
262 
263 typedef struct Cxnameheader_s		/* name key dict element header	*/
264 {
265 	_CX_NAME_HEADER_
266 } Cxnameheader_t;
267 
268 typedef struct Cxlistheader_s		/* list key dict element header	*/
269 {
270 	_CX_LIST_HEADER_
271 } Cxlistheader_t;
272 
273 typedef struct Cxcodeheader_s		/* code key dict element header	*/
274 {
275 	_CX_CODE_HEADER_
276 } Cxcodeheader_t;
277 
278 typedef struct Cxbuffer_s		/* buffer type			*/
279 {
280 	void*		data;		/* data pointer			*/
281 	uint32_t	size;		/* data size			*/
282 	uint32_t	elements;	/* sizeof() elements		*/
283 } Cxbuffer_t;
284 
285 typedef struct Cxstring_s		/* string type			*/
286 {
287 	char*		data;		/* data pointer			*/
288 	size_t		size;		/* data size			*/
289 } Cxstring_t;
290 
291 typedef union Cxvalue_u			/* fundamental types		*/
292 {
293 	Cxbuffer_t	buffer;		/* sized buffer			*/
294 	Cxnumber_t	number;		/* long/double number		*/
295 	void*		pointer;	/* generic pointer		*/
296 	Cxstring_t	string;		/* 0-terminated string		*/
297 	Cxtype_t*	type;		/* type				*/
298 	Cxvariable_t*	variable;	/* variable reference		*/
299 } Cxvalue_t;
300 
301 typedef int	(*Cxcallout_f)	(Cx_t*, Cxinstruction_t*, Cxoperand_t*,
302 				 Cxoperand_t*, Cxoperand_t*, void*, Cxdisc_t*);
303 typedef int	(*Cxconstraint_f)(Cx_t*, Cxvalue_t*, void*, Cxdisc_t*);
304 typedef int	(*Cxdone_f)	(Cx_t*, void*, Cxdisc_t*);
305 typedef ssize_t	(*Cxexternal_f)	(Cx_t*, Cxtype_t*, const char*, Cxformat_t*,
306 				 Cxvalue_t*, char*, size_t, Cxdisc_t*);
307 typedef int	(*Cxfunction_f)	(Cx_t*, Cxvariable_t*, Cxoperand_t*,
308 				 Cxoperand_t*, int, void*, Cxdisc_t*);
309 typedef void*	(*Cxinit_f)	(void*, Cxdisc_t*);
310 typedef ssize_t	(*Cxinternal_f)	(Cx_t*, Cxtype_t*, const char*, Cxformat_t*,
311 				 Cxoperand_t*, const char*, size_t, Vmalloc_t*,
312 				 Cxdisc_t*);
313 typedef Cxlib_t*(*Cxload_f)	(const char*, Cxdisc_t*);
314 typedef char*	(*Cxlocation_f)	(Cx_t*, void*, Cxdisc_t*);
315 typedef void*	(*Cxmatchcomp_f)(Cx_t*, Cxtype_t*, Cxtype_t*, Cxvalue_t*, Cxdisc_t*);
316 typedef int	(*Cxmatchexec_f)(Cx_t*, void*, Cxtype_t*, Cxvalue_t*, Cxdisc_t*);
317 typedef int	(*Cxmatchfree_f)(Cx_t*, void*, Cxdisc_t*);
318 typedef char*	(*Cxnum2str_f)	(Cx_t*, Cxunsigned_t, Cxdisc_t*);
319 typedef int	(*Cxquery_f)	(Cx_t*, Cxexpr_t*, void*, Cxdisc_t*);
320 typedef int	(*Cxrecode_f)	(Cx_t*, Cxexpr_t*, Cxinstruction_t*,
321 				 Cxinstruction_t*, Cxinstruction_t*, void*,
322 				 Cxdisc_t*);
323 typedef int	(*Cxstr2num_f)	(Cx_t*, const char*, size_t, Cxunsigned_t*, Cxdisc_t*);
324 
325 struct Cxoperand_s			/* expression operand		*/
326 {
327 	Cxtype_t*	type;		/* type				*/
328 	int		refs;		/* reference count		*/
329 	Cxvalue_t	value;		/* value			*/
330 };
331 
332 struct Cxitem_s				/* map item			*/
333 {
334 	Cxitem_t*	next;		/* next item			*/
335 	const char*	name;		/* item name			*/
336 	Cxunsigned_t	mask;		/* local mask			*/
337 	Cxunsigned_t	value;		/* item value			*/
338 	Cxmap_t*	map;		/* optional map on value match	*/
339 #ifdef _CX_ITEM_PRIVATE_
340 	_CX_ITEM_PRIVATE_
341 #endif
342 };
343 
344 struct Cxedit_s				/* edit list element		*/
345 {
346 	_CX_NAME_HEADER_
347 	Cxedit_t*	next;		/* next in list			*/
348 	Cxinit_f	initf;		/* called at cxaddedit()	*/
349 	Cxnum2str_f	num2strf;	/* num=>str function		*/
350 	Cxstr2num_f	str2numf;	/* str=>num function		*/
351 	void*		data;		/* private data			*/
352 #ifdef _CX_EDIT_PRIVATE_
353 	_CX_EDIT_PRIVATE_
354 #endif
355 };
356 
357 struct Cxpart_s				/* map part			*/
358 {
359 	Cxpart_t*	next;		/* next part			*/
360 	Cxunsigned_t	shift;		/* local shift			*/
361 	Cxunsigned_t	mask;		/* local mask			*/
362 	Cxitem_t*	item;		/* item list			*/
363 	Cxflags_t	flags;		/* flags			*/
364 	Cxtype_t*	type;		/* item value type		*/
365 	Cxedit_t*	num2str;	/* num=>str edit list		*/
366 	Cxedit_t*	str2num;	/* str=>num edit list		*/
367 	Cxedit_t*	edit;		/* str=>str edit list		*/
368 };
369 
370 struct Cxmap_s				/* str<=>num map		*/
371 {
372 	_CX_NAME_HEADER_
373 	Cxunsigned_t	shift;		/* global shift			*/
374 	Cxunsigned_t	mask;		/* global mask			*/
375 	Cxpart_t*	part;		/* part list			*/
376 	Dt_t*		str2num;	/* str=>num dict		*/
377 	Dt_t*		num2str;	/* pure value num=>str dict	*/
378 	Cxmap_t*	map;		/* indirect reference		*/
379 };
380 
381 struct Cxconstraint_s			/* value constraints		*/
382 {
383 	_CX_NAME_HEADER_
384 	Cxinit_f	initf;		/* called at cxaddconstraint()	*/
385 	Cxconstraint_f	constraintf;	/* external constraint function	*/
386 	Cxvalue_t*	def;		/* default value		*/
387 	Cxvalue_t*	min;		/* numeric minimum		*/
388 	Cxvalue_t*	max;		/* numeric maximum		*/
389 	const char*	expression;	/* expression on ``.''		*/
390 	const char*	pattern;	/* string match pattern		*/
391 	void*		data;		/* private data			*/
392 #ifdef _CX_CONSTRAINT_PRIVATE_
393 	_CX_CONSTRAINT_PRIVATE_
394 #endif
395 };
396 
397 struct Cxformat_s			/* format info			*/
398 {
399 	const char*	description;	/* external details description	*/
400 	char*		details;	/* default external details	*/
401 	unsigned short	flags;		/* flags			*/
402 	short		width;		/* width in bytes		*/
403 	short		print;		/* print width hint		*/
404 	short		base;		/* base				*/
405 	short		fill;		/* fill character		*/
406 	short		code;		/* code set			*/
407 	short		delimiter;	/* delimiter			*/
408 	short		escape;		/* escape			*/
409 	short		quotebegin;	/* quotebegin			*/
410 	short		quoteend;	/* quoteend			*/
411 	short		fixedpoint;	/* fixed point width		*/
412 	short		unused;		/* not used			*/
413 	Cxmap_t*	map;		/* str<=>num map		*/
414 	Cxconstraint_t*	constraint;	/* value constraints		*/
415 };
416 
417 struct Cxreference_s			/* member reference		*/
418 {
419 	Cxreference_t*	next;		/* submember			*/
420 	Cxvariable_t*	variable;	/* member variable		*/
421 	Cxmember_t*	member;		/* member info			*/
422 };
423 
424 struct Cxarray_s			/* array info			*/
425 {
426 	Cxvariable_t*	variable;	/* variable size value		*/
427 	size_t		size;		/* fixed or max size		*/
428 	short		delimiter;	/* value delimiter		*/
429 };
430 
431 struct Cxstructure_s			/* structure info		*/
432 {
433 	Cxvariable_t*	parent;		/* parent structure		*/
434 	Cxvariable_t*	members;	/* member list (children)	*/
435 	Cxvariable_t*	next;		/* next member (sibling)	*/
436 	size_t		size;		/* size				*/
437 	int		level;		/* structure level		*/
438 };
439 
440 struct Cxvariable_s			/* variable info		*/
441 {
442 	_CX_LIST_HEADER_
443 	Cxfunction_f	function;	/* pointer if function		*/
444 	Cxtype_t*	type;		/* value type			*/
445 	const char*	prototype;	/* (proto)type name		*/
446 	unsigned long	index;		/* caller defined index		*/
447 	Cxformat_t	format;		/* format info			*/
448 	void*		data;		/* caller defined data		*/
449 	Cxreference_t*	reference;	/* member reference list	*/
450 	Cxtype_t*	member;		/* member type			*/
451 	Cxarray_t*	array;		/* array info			*/
452 	Cxstructure_t*	structure;	/* structure info		*/
453 };
454 
455 struct Cxmatch_s			/* type match info		*/
456 {
457 	_CX_NAME_HEADER_
458 	Cxmatchcomp_f	compf;		/* match pattern compile	*/
459 	Cxmatchexec_f	execf;		/* match pattern exec		*/
460 	Cxmatchfree_f	freef;		/* match pattern free		*/
461 };
462 
463 struct Cxmember_s			/* type member info		*/
464 {
465 	Cxcallout_f	getf;		/* get member value		*/
466 	Cxcallout_f	setf;		/* set member value		*/
467 	Dt_t*		members;	/* Cxvariable_t member dict	*/
468 	Cxflags_t	flags;		/* CX_* member flags		*/
469 };
470 
471 struct Cxtype_s				/* type info			*/
472 {
473 	_CX_NAME_HEADER_
474 	Cxtype_t*	base;		/* base type			*/
475 	Cxinit_f	initf;		/* called at cxaddtype()	*/
476 	Cxexternal_f	externalf;	/* internal => external		*/
477 	Cxinternal_f	internalf;	/* external => internal		*/
478 	unsigned short	representation;	/* fundamental type index	*/
479 	unsigned short	index;		/* caller defined index		*/
480 	unsigned short	size;		/* sizeof() size in bytes	*/
481 	unsigned short	element;	/* element size in bytes	*/
482 	Cxformat_t	format;		/* format defaults		*/
483 	Cxmatch_t*	match;		/* match info			*/
484 	Cxmember_t*	member;		/* member info			*/
485 	Cxtype_t**	generic;	/* generic implementation table	*/
486 	Cxtype_t*	fundamental;	/* fundamental type		*/
487 	void*		data;		/* private data			*/
488 };
489 
490 typedef struct Cxcallout_s		/* op code callout		*/
491 {
492 	_CX_CODE_HEADER_
493 	Cxcallout_f	callout;	/* callout function		*/
494 } Cxcallout_t;
495 
496 typedef struct Cxrecode_s		/* recode callout		*/
497 {
498 	_CX_CODE_HEADER_
499 	Cxrecode_f	recode;		/* callout function		*/
500 } Cxrecode_t;
501 
502 struct Cxinstruction_s			/* parsed instruction		*/
503 {
504 	int		op;		/* op code			*/
505 	int		pp;		/* stack push(>0) pop(<0) count	*/
506 	Cxtype_t*	type;		/* return type			*/
507 	Cxvalue_t	data;		/* optional data		*/
508 	Cxcallout_f	callout;	/* callout function		*/
509 };
510 
511 struct Cxdisc_s				/* user discipline		*/
512 {
513 	unsigned long	version;	/* interface version		*/
514 	Error_f		errorf;		/* error function		*/
515 	Cxload_f	loadf;		/* library load function	*/
516 	Cxlocation_f	locationf;	/* input location function	*/
517 	const char*	ps1;		/* primary prompt		*/
518 	const char*	ps2;		/* secondary prompt		*/
519 	const char*	map;		/* map file			*/
520 };
521 
522 struct Cxquery_s			/* query			*/
523 {
524 	_CX_NAME_HEADER_
525 	Cxquery_f	beg;		/* called before first eval	*/
526 	Cxquery_f	sel;		/* select current data		*/
527 	Cxquery_f	act;		/* act on selected data		*/
528 	Cxquery_f	end;		/* called after last eval	*/
529 	const char*	method;		/* caller specific method match	*/
530 	Cxquery_f	ref;		/* compile-time reference	*/
531 #ifdef _CX_QUERY_PRIVATE_
532 	_CX_QUERY_PRIVATE_
533 #endif
534 };
535 
536 struct Cxmeth_s; typedef struct Cxmeth_s Cxmeth_t;
537 
538 struct Cxlib_s				/* Cxdisc_t.loadf library info	*/
539 {
540 	_CX_NAME_HEADER_
541 	const char**	libraries;	/* library list			*/
542 	Cxmeth_t*	meth;		/* caller method		*/
543 	Cxtype_t*	types;		/* type table			*/
544 	Cxcallout_t*	callouts;	/* callout table		*/
545 	Cxrecode_t*	recodes;	/* recode table			*/
546 	Cxmap_t**	maps;		/* map table			*/
547 	Cxquery_t*	queries;	/* query table			*/
548 	Cxconstraint_t*	constraints;	/* constraint table		*/
549 	Cxedit_t*	edits;		/* edit table			*/
550 	Cxvariable_t*	functions;	/* function table		*/
551 
552 	void*		pad[7];		/* pad for future expansion	*/
553 
554 	/* the remaining are set by Cxdisc_t.loadf			*/
555 
556 	const char*	path;		/* library path name		*/
557 };
558 
559 struct Cxexpr_s				/* compiled expression node	*/
560 {
561 	Cxexpr_t*	parent;		/* parent			*/
562 	Cxexpr_t*	group;		/* group			*/
563 	Cxexpr_t*	next;		/* next sibling			*/
564 	Cxexpr_t*	pass;		/* pass branch			*/
565 	Cxexpr_t*	fail;		/* fail branch			*/
566 	Cxquery_t*	query;		/* query callouts		*/
567 	const char*	file;		/* output file			*/
568 	Sfio_t*		op;		/* output stream for file	*/
569 	void*		data;		/* query private data		*/
570 	char**		argv;		/* query argv			*/
571 	Cxunsigned_t	queried;	/* # records queried		*/
572 	Cxunsigned_t	selected;	/* # records selected		*/
573 #ifdef _CX_EXPR_PRIVATE_
574 	_CX_EXPR_PRIVATE_
575 #endif
576 };
577 
578 struct Cxstate_s			/* cx library global state	*/
579 {
580 	Dt_t*		libraries;	/* Dsslib_t dictionary (ouch)	*/
581 	Dt_t*		methods;	/* Cxnameheader_t dictionary	*/
582 	Dt_t*		types;		/* Cxtype_t dictionary		*/
583 	Dt_t*		callouts;	/* Cxcallout_t dictionary	*/
584 	Dt_t*		recodes;	/* Cxrecode_t dictionary	*/
585 	Dt_t*		maps;		/* Cxmap_t dictionary		*/
586 	Dt_t*		queries;	/* Cxquery_t dictionary		*/
587 	Dt_t*		constraints;	/* Cxconstraint_t dictionary	*/
588 	Dt_t*		edits;		/* Cxedit_t dictionary		*/
589 	Dt_t*		variables;	/* Cxvariable_t dictionary	*/
590 	Cxtype_t*	type_bool;	/* bool fundamental type	*/
591 	Cxtype_t*	type_buffer;	/* buffer fundamental type	*/
592 	Cxtype_t*	type_number;	/* number fundamental type	*/
593 	Cxtype_t*	type_reference;	/* reference fundamental type	*/
594 	Cxtype_t*	type_string;	/* string fundamental type	*/
595 	Cxtype_t*	type_type_t;	/* type				*/
596 	Cxtype_t*	type_void;	/* void fundamental type	*/
597 #ifdef _CX_STATE_PRIVATE_
598 	_CX_STATE_PRIVATE_
599 #endif
600 };
601 
602 struct Cx_s				/* interface handle		*/
603 {
604 	const char*	id;		/* interface id			*/
605 	Vmalloc_t*	vm;		/* handle memory		*/
606 	Vmalloc_t*	em;		/* eval memory			*/
607 	Vmalloc_t*	rm;		/* record memory		*/
608 	Cxflags_t	flags;		/* CX_* flags			*/
609 	Cxflags_t	test;		/* test mask			*/
610 	int		eof;		/* input at eof			*/
611 	int		error;		/* error occurred		*/
612 	int		interactive;	/* interactive input		*/
613 	Cxstate_t*	state;		/* global state			*/
614 	Cxdisc_t*	disc;		/* user discipline		*/
615 	Sfio_t*		buf;		/* tmp buffer stream		*/
616 	void*		caller;		/* caller defined handle	*/
617 	Dt_t*		variables;	/* sorted variable symbol table	*/
618 	Dt_t*		fields;		/* order variable field list	*/
619 	Dt_t*		types;		/* Cxtype_t dictionary		*/
620 	Dt_t*		callouts;	/* Cxcallout_t dictionary	*/
621 	Dt_t*		recodes;	/* Cxrecode_t dictionary	*/
622 	Dt_t*		maps;		/* Cxmap_t dictionary		*/
623 	Dt_t*		queries;	/* Cxquery_t dictionary		*/
624 	Dt_t*		constraints;	/* Cxconstraint_t dictionary	*/
625 	Dt_t*		edits;		/* Cxedit_t dictionary		*/
626 	Cx_t*		scope;		/* next scope			*/
627 	unsigned char*	ctype;		/* ctype table			*/
628 #ifdef _CX_PRIVATE_
629 	_CX_PRIVATE_
630 #endif
631 };
632 
633 #define cxinit(d,e)	(memset(d,0,sizeof(Cxdisc_t)),(d)->version=CX_VERSION,(d)->errorf=(Error_f)(e),cxstate(d))
634 
635 #if _BLD_cx && defined(__EXPORT__)
636 #define extern		__EXPORT__
637 #endif
638 
639 extern Cxstate_t*	cxstate(Cxdisc_t*);
640 
641 extern Cx_t*		cxopen(Cxflags_t, Cxflags_t, Cxdisc_t*);
642 extern Cx_t*		cxscope(Cx_t*, Cx_t*, Cxflags_t, Cxflags_t, Cxdisc_t*);
643 extern int		cxclose(Cx_t*);
644 
645 extern void*		cxpush(Cx_t*, const char*, Sfio_t*, const char*, ssize_t, Cxflags_t);
646 extern int		cxpop(Cx_t*, void*);
647 extern ssize_t		cxtell(Cx_t*);
648 extern Cxexpr_t*	cxcomp(Cx_t*);
649 extern int		cxbeg(Cx_t*, Cxexpr_t*, const char*);
650 extern int		cxeval(Cx_t*, Cxexpr_t*, void*, Cxoperand_t*);
651 extern int		cxend(Cx_t*, Cxexpr_t*);
652 extern int		cxlist(Cx_t*, Cxexpr_t*, Sfio_t*);
653 extern int		cxfree(Cx_t*, Cxexpr_t*);
654 extern int		cxcast(Cx_t*, Cxoperand_t*, Cxvariable_t*, Cxtype_t*, void*, const char*);
655 extern size_t		cxsizeof(Cx_t*, Cxvariable_t*, Cxtype_t*, Cxvalue_t*);
656 extern ssize_t		cxmembers(Cx_t*, Cxtype_t*, const char*, Cxformat_t*, Cxvalue_t*, char*, size_t, Cxdisc_t*);
657 
658 extern char*		cxcontext(Cx_t*);
659 extern char*		cxlocation(Cx_t*, void*);
660 
661 extern void		cxcodetrace(Cx_t*, const char*, Cxinstruction_t*, unsigned int, Cxoperand_t*, Cxoperand_t*);
662 extern char*		cxcodename(int);
663 extern char*		cxopname(int, Cxtype_t*, Cxtype_t*);
664 
665 extern int		cxaddcallout(Cx_t*, Cxcallout_t*, Cxdisc_t*);
666 extern int		cxaddconstraint(Cx_t*, Cxconstraint_t*, Cxdisc_t*);
667 extern int		cxaddedit(Cx_t*, Cxedit_t*, Cxdisc_t*);
668 extern int		cxaddmap(Cx_t*, Cxmap_t*, Cxdisc_t*);
669 extern int		cxaddquery(Cx_t*, Cxquery_t*, Cxdisc_t*);
670 extern int		cxaddrecode(Cx_t*, Cxrecode_t*, Cxdisc_t*);
671 extern int		cxaddtype(Cx_t*, Cxtype_t*, Cxdisc_t*);
672 extern int		cxaddvariable(Cx_t*, Cxvariable_t*, Cxdisc_t*);
673 
674 extern Cxtype_t*	cxattr(Cx_t*, const char*, char**, Cxformat_t*, Cxdisc_t*);
675 extern Cxcallout_f	cxcallout(Cx_t*, int, Cxtype_t*, Cxtype_t*, Cxdisc_t*);
676 extern Cxconstraint_t*	cxconstraint(Cx_t*, const char*, Cxdisc_t*);
677 extern Cxedit_t*	cxedit(Cx_t*, const char*, Cxdisc_t*);
678 extern Cxvariable_t*	cxfunction(Cx_t*, const char*, Cxdisc_t*);
679 extern Cxmap_t*		cxmap(Cx_t*, const char*, Cxdisc_t*);
680 extern Cxquery_t*	cxquery(Cx_t*, const char*, Cxdisc_t*);
681 extern Cxrecode_f	cxrecode(Cx_t*, int, Cxtype_t*, Cxtype_t*, Cxdisc_t*);
682 extern Cxtype_t*	cxtype(Cx_t*, const char*, Cxdisc_t*);
683 extern Cxvariable_t*	cxvariable(Cx_t*, const char*, Cxtype_t*, Cxdisc_t*);
684 
685 extern int 		cxnum2str(Cx_t*, Cxformat_t*, Cxunsigned_t, char**);
686 extern int		cxstr2num(Cx_t*, Cxformat_t*, const char*, size_t, Cxunsigned_t*);
687 
688 extern int		cxsub(Cx_t*, Cxedit_t*, Cxoperand_t*);
689 extern int		cxsuball(Cx_t*, Cxpart_t*, Cxoperand_t*);
690 
691 extern char*		cxcvt(Cx_t*, const char*, size_t);
692 
693 extern int		cxatfree(Cx_t*, Cxexpr_t*, Cxdone_f, void*);
694 
695 #undef	extern
696 
697 #endif
698