Mercurial > hg > camir-aes2014
comparison toolboxes/graph_visualisation/include/graphviz/cgraph.h @ 0:e9a9cd732c1e tip
first hg version after svn
author | wolffd |
---|---|
date | Tue, 10 Feb 2015 15:05:51 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:e9a9cd732c1e |
---|---|
1 /* $Id: cgraph.h,v 1.16 2009/07/10 21:10:32 erg Exp $ $Revision: 1.16 $ */ | |
2 /* vim:set shiftwidth=4 ts=8: */ | |
3 | |
4 /********************************************************** | |
5 * This software is part of the graphviz package * | |
6 * http://www.graphviz.org/ * | |
7 * * | |
8 * Copyright (c) 1994-2004 AT&T Corp. * | |
9 * and is licensed under the * | |
10 * Common Public License, Version 1.0 * | |
11 * by AT&T Corp. * | |
12 * * | |
13 * Information and Software Systems Research * | |
14 * AT&T Research, Florham Park NJ * | |
15 **********************************************************/ | |
16 | |
17 #ifndef ATT_GRAPH_H | |
18 #define ATT_GRAPH_H | |
19 | |
20 #include "cdt.h" | |
21 | |
22 #ifdef __cplusplus | |
23 extern "C" { | |
24 #endif | |
25 | |
26 #ifndef FALSE | |
27 #define FALSE (0) | |
28 #endif | |
29 #ifndef TRUE | |
30 #define TRUE (!FALSE) | |
31 #endif | |
32 #ifndef NOT | |
33 #define NOT(x) (!(x)) | |
34 #endif | |
35 #ifndef NIL | |
36 #define NIL(type) ((type)0) | |
37 #endif | |
38 #define NILgraph NIL(Agraph_t*) | |
39 #define NILnode NIL(Agnode_t*) | |
40 #define NILedge NIL(Agedge_t*) | |
41 #define NILsym NIL(Agsym_t*) | |
42 | |
43 /* forward struct type declarations */ | |
44 typedef struct Agtag_s Agtag_t; | |
45 typedef struct Agobj_s Agobj_t; /* generic object header */ | |
46 typedef struct Agraph_s Agraph_t; /* graph, subgraph (or hyperedge) */ | |
47 typedef struct Agnode_s Agnode_t; /* node (atom) */ | |
48 typedef struct Agedge_s Agedge_t; /* node pair */ | |
49 typedef struct Agdesc_s Agdesc_t; /* graph descriptor */ | |
50 typedef struct Agmemdisc_s Agmemdisc_t; /* memory allocator */ | |
51 typedef struct Agiddisc_s Agiddisc_t; /* object ID allocator */ | |
52 typedef struct Agiodisc_s Agiodisc_t; /* IO services */ | |
53 typedef struct Agdisc_s Agdisc_t; /* union of client discipline methods */ | |
54 typedef struct Agdstate_s Agdstate_t; /* client state (closures) */ | |
55 typedef struct Agsym_s Agsym_t; /* string attribute descriptors */ | |
56 typedef struct Agattr_s Agattr_t; /* string attribute container */ | |
57 typedef struct Agcbdisc_s Agcbdisc_t; /* client event callbacks */ | |
58 typedef struct Agcbstack_s Agcbstack_t; /* enclosing state for cbdisc */ | |
59 typedef struct Agclos_s Agclos_t; /* common fields for graph/subgs */ | |
60 typedef struct Agrec_s Agrec_t; /* generic runtime record */ | |
61 typedef struct Agdatadict_s Agdatadict_t; /* set of dictionaries per graph */ | |
62 typedef struct Agedgepair_s Agedgepair_t; /* the edge object */ | |
63 typedef struct Agsubnode_s Agsubnode_t; | |
64 | |
65 /* Header of a user record. These records are attached by client programs | |
66 dynamically at runtime. A unique string ID must be given to each record | |
67 attached to the same object. Cgraph has functions to create, search for, | |
68 and delete these records. The records are maintained in a circular list, | |
69 with obj->data pointing somewhere in the list. The search function has | |
70 an option to lock this pointer on a given record. The application must | |
71 be written so only one such lock is outstanding at a time. */ | |
72 | |
73 struct Agrec_s { | |
74 char *name; | |
75 Agrec_t *next; | |
76 /* following this would be any programmer-defined data */ | |
77 }; | |
78 | |
79 /* Object tag for graphs, nodes, and edges. While there may be several structs | |
80 for a given node or edges, there is only one unique ID (per main graph). */ | |
81 struct Agtag_s { | |
82 unsigned objtype:2; /* see literal tags below */ | |
83 unsigned mtflock:1; /* move-to-front lock, see above */ | |
84 unsigned attrwf:1; /* attrs written (parity, write.c) */ | |
85 unsigned seq:(sizeof(unsigned) * 8 - 4); /* sequence no. */ | |
86 unsigned long id; /* client ID */ | |
87 }; | |
88 | |
89 /* object tags */ | |
90 #define AGRAPH 0 /* can't exceed 2 bits. see Agtag_t. */ | |
91 #define AGNODE 1 | |
92 #define AGOUTEDGE 2 | |
93 #define AGINEDGE 3 /* (1 << 1) indicates an edge tag. */ | |
94 #define AGEDGE AGOUTEDGE /* synonym in object kind args */ | |
95 | |
96 /* a generic graph/node/edge header */ | |
97 struct Agobj_s { | |
98 Agtag_t tag; | |
99 Agrec_t *data; | |
100 }; | |
101 | |
102 #define AGTAG(obj) (((Agobj_t*)(obj))->tag) | |
103 #define AGTYPE(obj) (AGTAG(obj).objtype) | |
104 #define AGID(obj) (AGTAG(obj).id) | |
105 #define AGSEQ(obj) (AGTAG(obj).seq) | |
106 #define AGATTRWF(obj) (AGTAG(obj).attrwf) | |
107 #define AGDATA(obj) (((Agobj_t*)(obj))->data) | |
108 | |
109 /* This is the node struct allocated per graph (or subgraph). It resides | |
110 in the n_dict of the graph. The node set is maintained by libdict, but | |
111 transparently to libgraph callers. Every node may be given an optional | |
112 string name at its time of creation, or it is permissible to pass NIL(char*) | |
113 for the name. */ | |
114 | |
115 struct Agsubnode_s { /* the node-per-graph-or-subgraph record */ | |
116 Dtlink_t seq_link; /* must be first */ | |
117 Dtlink_t id_link; | |
118 Agnode_t *node; /* the object */ | |
119 Dtlink_t *in_id, *out_id; /* by node/ID for random access */ | |
120 Dtlink_t *in_seq, *out_seq; /* by node/sequence for serial access */ | |
121 }; | |
122 | |
123 struct Agnode_s { | |
124 Agobj_t base; | |
125 Agraph_t *root; | |
126 Agsubnode_t mainsub; /* embedded for main graph */ | |
127 }; | |
128 | |
129 struct Agedge_s { | |
130 Agobj_t base; | |
131 Dtlink_t id_link; /* main graph only */ | |
132 Dtlink_t seq_link; | |
133 Agnode_t *node; /* the endpoint node */ | |
134 }; | |
135 | |
136 struct Agedgepair_s { | |
137 Agedge_t out, in; | |
138 }; | |
139 | |
140 struct Agdesc_s { /* graph descriptor */ | |
141 unsigned directed:1; /* if edges are asymmetric */ | |
142 unsigned strict:1; /* if multi-edges forbidden */ | |
143 unsigned no_loop:1; /* if no loops */ | |
144 unsigned maingraph:1; /* if this is the top level graph */ | |
145 unsigned flatlock:1; /* if sets are flattened into lists in cdt */ | |
146 unsigned no_write:1; /* if a temporary subgraph */ | |
147 unsigned has_attrs:1; /* if string attr tables should be initialized */ | |
148 unsigned has_cmpnd:1; /* if may contain collapsed nodes */ | |
149 }; | |
150 | |
151 /* disciplines for external resources needed by libgraph */ | |
152 | |
153 struct Agmemdisc_s { /* memory allocator */ | |
154 void *(*open) (void); /* independent of other resources */ | |
155 void *(*alloc) (void *state, size_t req); | |
156 void *(*resize) (void *state, void *ptr, size_t old, size_t req); | |
157 void (*free) (void *state, void *ptr); | |
158 void (*close) (void *state); | |
159 }; | |
160 | |
161 struct Agiddisc_s { /* object ID allocator */ | |
162 void *(*open) (Agraph_t * g); /* associated with a graph */ | |
163 long (*map) (void *state, int objtype, char *str, unsigned long *id, | |
164 int createflag); | |
165 long (*alloc) (void *state, int objtype, unsigned long id); | |
166 void (*free) (void *state, int objtype, unsigned long id); | |
167 char *(*print) (void *state, int objtype, unsigned long id); | |
168 void (*close) (void *state); | |
169 }; | |
170 | |
171 struct Agiodisc_s { | |
172 int (*afread) (void *chan, char *buf, int bufsize); | |
173 int (*putstr) (void *chan, const char *str); | |
174 int (*flush) (void *chan); /* sync */ | |
175 /* error messages? */ | |
176 }; | |
177 | |
178 struct Agdisc_s { /* user's discipline */ | |
179 Agmemdisc_t *mem; | |
180 Agiddisc_t *id; | |
181 Agiodisc_t *io; | |
182 }; | |
183 | |
184 /* default resource disciplines */ | |
185 #if !defined(_BLD_cgraph) && defined(GVDLL) | |
186 #define extern __declspec(dllimport) | |
187 #endif | |
188 | |
189 /*visual studio*/ | |
190 #ifdef WIN32_DLL | |
191 #ifndef CGRAPH_EXPORTS | |
192 #define extern __declspec(dllimport) | |
193 #endif | |
194 #endif | |
195 /*end visual studio*/ | |
196 | |
197 extern Agmemdisc_t AgMemDisc; | |
198 extern Agiddisc_t AgIdDisc; | |
199 extern Agiodisc_t AgIoDisc; | |
200 | |
201 extern Agdisc_t AgDefaultDisc; | |
202 #undef extern | |
203 | |
204 struct Agdstate_s { | |
205 void *mem; | |
206 void *id; | |
207 /* IO must be initialized and finalized outside Cgraph, | |
208 * and channels (FILES) are passed as void* arguments. */ | |
209 }; | |
210 | |
211 typedef void (*agobjfn_t) (Agraph_t * g, Agobj_t * obj, void *arg); | |
212 typedef void (*agobjupdfn_t) (Agraph_t * g, Agobj_t * obj, void *arg, | |
213 Agsym_t * sym); | |
214 | |
215 struct Agcbdisc_s { | |
216 struct { | |
217 agobjfn_t ins; | |
218 agobjupdfn_t mod; | |
219 agobjfn_t del; | |
220 } graph, node, edge; | |
221 }; | |
222 | |
223 struct Agcbstack_s { /* object event callbacks */ | |
224 Agcbdisc_t *f; /* methods */ | |
225 void *state; /* closure */ | |
226 Agcbstack_t *prev; /* kept in a stack, unlike other disciplines */ | |
227 }; | |
228 | |
229 struct Agclos_s { | |
230 Agdisc_t disc; /* resource discipline functions */ | |
231 Agdstate_t state; /* resource closures */ | |
232 Dict_t *strdict; /* shared string dict */ | |
233 unsigned long seq[3]; /* local object sequence number counter */ | |
234 Agcbstack_t *cb; /* user and system callback function stacks */ | |
235 unsigned char callbacks_enabled; /* issue user callbacks or hold them? */ | |
236 Dict_t *lookup_by_name[3]; | |
237 Dict_t *lookup_by_id[3]; | |
238 }; | |
239 | |
240 struct Agraph_s { | |
241 Agobj_t base; | |
242 Agdesc_t desc; | |
243 Dtlink_t link; | |
244 Dict_t *n_seq; /* the node set in sequence */ | |
245 Dict_t *n_id; /* the node set indexed by ID */ | |
246 Dict_t *e_seq, *e_id; /* holders for edge sets */ | |
247 Dict_t *g_dict; /* subgraphs - descendants */ | |
248 Agraph_t *parent, *root; /* subgraphs - ancestors */ | |
249 Agclos_t *clos; /* shared resources */ | |
250 }; | |
251 | |
252 | |
253 #if _PACKAGE_ast | |
254 /* fine control of object callbacks */ | |
255 # if defined(_BLD_cgraph) && defined(__EXPORT__) | |
256 # define extern __EXPORT__ | |
257 # endif | |
258 # if !defined(_BLD_cgraph) && defined(__IMPORT__) | |
259 # define extern __IMPORT__ | |
260 # endif | |
261 #endif | |
262 | |
263 extern void agpushdisc(Agraph_t * g, Agcbdisc_t * disc, void *state); | |
264 extern int agpopdisc(Agraph_t * g, Agcbdisc_t * disc); | |
265 extern int agcallbacks(Agraph_t * g, int flag); /* return prev value */ | |
266 | |
267 /* graphs */ | |
268 extern Agraph_t *agopen(char *name, Agdesc_t desc, Agdisc_t * disc); | |
269 extern int agclose(Agraph_t * g); | |
270 extern Agraph_t *agread(void *chan, Agdisc_t * disc); | |
271 extern void agreadline(int); | |
272 extern void agsetfile(char *); | |
273 extern Agraph_t *agconcat(Agraph_t * g, void *chan, Agdisc_t * disc); | |
274 extern int agwrite(Agraph_t * g, void *chan); | |
275 extern int agisdirected(Agraph_t * g); | |
276 extern int agisundirected(Agraph_t * g); | |
277 extern int agisstrict(Agraph_t * g); | |
278 extern int agissimple(Agraph_t * g); | |
279 | |
280 /* nodes */ | |
281 extern Agnode_t *agnode(Agraph_t * g, char *name, int createflag); | |
282 extern Agnode_t *agidnode(Agraph_t * g, unsigned long id, int createflag); | |
283 extern Agnode_t *agsubnode(Agraph_t * g, Agnode_t * n, int createflag); | |
284 extern Agnode_t *agfstnode(Agraph_t * g); | |
285 extern Agnode_t *agnxtnode(Agraph_t * g, Agnode_t * n); | |
286 extern Agnode_t *aglstnode(Agraph_t * g); | |
287 extern Agnode_t *agprvnode(Agraph_t * g, Agnode_t * n); | |
288 | |
289 extern Agsubnode_t *agsubrep(Agraph_t * g, Agnode_t * n); | |
290 | |
291 /* edges */ | |
292 extern Agedge_t *agedge(Agraph_t * g, Agnode_t * t, Agnode_t * h, | |
293 char *name, int createflag); | |
294 extern Agedge_t *agidedge(Agraph_t * g, Agnode_t * t, Agnode_t * h, | |
295 unsigned long id, int createflag); | |
296 extern Agedge_t *agsubedge(Agraph_t * g, Agedge_t * e, int createflag); | |
297 extern Agedge_t *agfstin(Agraph_t * g, Agnode_t * n); | |
298 extern Agedge_t *agnxtin(Agraph_t * g, Agedge_t * e); | |
299 extern Agedge_t *agfstout(Agraph_t * g, Agnode_t * n); | |
300 extern Agedge_t *agnxtout(Agraph_t * g, Agedge_t * e); | |
301 extern Agedge_t *agfstedge(Agraph_t * g, Agnode_t * n); | |
302 extern Agedge_t *agnxtedge(Agraph_t * g, Agedge_t * e, Agnode_t * n); | |
303 | |
304 /* generic */ | |
305 extern Agraph_t *agraphof(void* obj); | |
306 extern Agraph_t *agroot(void* obj); | |
307 extern int agcontains(Agraph_t *, void *); | |
308 extern char *agnameof(void *); | |
309 extern int agrelabel(void *obj, char *name); /* scary */ | |
310 extern int agrelabel_node(Agnode_t * n, char *newname); | |
311 extern int agdelete(Agraph_t * g, void *obj); | |
312 extern long agdelsubg(Agraph_t * g, Agraph_t * sub); /* could be agclose */ | |
313 extern int agdelnode(Agraph_t * g, Agnode_t * arg_n); | |
314 extern int agdeledge(Agraph_t * g, Agedge_t * arg_e); | |
315 extern int agobjkind(void *); | |
316 | |
317 /* strings */ | |
318 extern char *agstrdup(Agraph_t *, char *); | |
319 extern char *agstrdup_html(Agraph_t *, char *); | |
320 extern int aghtmlstr(char *); | |
321 extern char *agstrbind(Agraph_t * g, char *); | |
322 extern int agstrfree(Agraph_t *, char *); | |
323 extern char *agstrcanon(char *, char *); | |
324 char *agcanonStr(char *str); /* manages its own buf */ | |
325 | |
326 /* definitions for dynamic string attributes */ | |
327 struct Agattr_s { /* dynamic string attributes */ | |
328 Agrec_t h; /* common data header */ | |
329 Dict_t *dict; /* shared dict to interpret attr field */ | |
330 char **str; /* the attribute string values */ | |
331 }; | |
332 | |
333 struct Agsym_s { /* symbol in one of the above dictionaries */ | |
334 Dtlink_t link; | |
335 char *name; /* attribute's name */ | |
336 char *defval; /* its default value for initialization */ | |
337 int id; /* its index in attr[] */ | |
338 unsigned char kind; /* referent object type */ | |
339 unsigned char fixed; /* immutable value */ | |
340 }; | |
341 | |
342 struct Agdatadict_s { /* set of dictionaries per graph */ | |
343 Agrec_t h; /* installed in list of graph recs */ | |
344 struct { | |
345 Dict_t *n, *e, *g; | |
346 } dict; | |
347 }; | |
348 | |
349 extern Agsym_t *agattr(Agraph_t * g, int kind, char *name, char *value); | |
350 extern Agsym_t *agattrsym(void *obj, char *name); | |
351 extern Agsym_t *agnxtattr(Agraph_t * g, int kind, Agsym_t * attr); | |
352 extern int agcopyattr(void *oldobj, void *newobj); | |
353 | |
354 extern void *agbindrec(void *obj, char *name, unsigned int size, | |
355 int move_to_front); | |
356 extern Agrec_t *aggetrec(void *obj, char *name, int move_to_front); | |
357 extern int agdelrec(void *obj, char *name); | |
358 extern void aginit(Agraph_t * g, int kind, char *rec_name, int rec_size, | |
359 int move_to_front); | |
360 extern void agclean(Agraph_t * g, int kind, char *rec_name); | |
361 | |
362 extern char *agget(void *obj, char *name); | |
363 extern char *agxget(void *obj, Agsym_t * sym); | |
364 extern int agset(void *obj, char *name, char *value); | |
365 extern int agxset(void *obj, Agsym_t * sym, char *value); | |
366 extern int agsafeset(void* obj, char* name, char* value, char* def); | |
367 | |
368 /* defintions for subgraphs */ | |
369 extern Agraph_t *agsubg(Agraph_t * g, char *name, int cflag); /* constructor */ | |
370 extern Agraph_t *agidsubg(Agraph_t * g, unsigned long id, int cflag); /* constructor */ | |
371 extern Agraph_t *agfstsubg(Agraph_t * g), *agnxtsubg(Agraph_t * subg); | |
372 extern Agraph_t *agparent(Agraph_t * g); | |
373 | |
374 /* set cardinality */ | |
375 extern int agnnodes(Agraph_t * g), agnedges(Agraph_t * g); | |
376 extern int agdegree(Agraph_t * g, Agnode_t * n, int in, int out); | |
377 extern int agcountuniqedges(Agraph_t * g, Agnode_t * n, int in, int out); | |
378 | |
379 /* memory */ | |
380 extern void *agalloc(Agraph_t * g, size_t size); | |
381 extern void *agrealloc(Agraph_t * g, void *ptr, size_t oldsize, | |
382 size_t size); | |
383 extern void agfree(Agraph_t * g, void *ptr); | |
384 extern struct _vmalloc_s *agheap(Agraph_t * g); | |
385 | |
386 /* an engineering compromise is a joy forever */ | |
387 extern void aginternalmapclearlocalnames(Agraph_t * g); | |
388 | |
389 #define agnew(g,t) ((t*)agalloc(g,sizeof(t))) | |
390 #define agnnew(g,n,t) ((t*)agalloc(g,(n)*sizeof(t))) | |
391 | |
392 /* error handling */ | |
393 typedef enum { AGWARN, AGERR, AGMAX, AGPREV } agerrlevel_t; | |
394 extern agerrlevel_t agerrno; | |
395 extern void agseterr(agerrlevel_t); | |
396 extern char *aglasterr(void); | |
397 extern int agerr(agerrlevel_t level, char *fmt, ...); | |
398 extern void agerrorf(char *fmt, ...); | |
399 extern void agwarningf(char *fmt, ...); | |
400 extern int agerrors(void); | |
401 | |
402 /* data access macros */ | |
403 /* this assumes that e[0] is out and e[1] is inedge, see edgepair in edge.c */ | |
404 #define AGIN2OUT(e) ((e)-1) | |
405 #define AGOUT2IN(e) ((e)+1) | |
406 #define AGOPP(e) ((AGTYPE(e)==AGINEDGE)?AGIN2OUT(e):AGOUT2IN(e)) | |
407 #define AGMKOUT(e) (AGTYPE(e) == AGOUTEDGE? (e): AGIN2OUT(e)) | |
408 #define AGMKIN(e) (AGTYPE(e) == AGINEDGE? (e): AGOUT2IN(e)) | |
409 #define AGTAIL(e) (AGMKIN(e)->node) | |
410 #define AGHEAD(e) (AGMKOUT(e)->node) | |
411 #define agtail(e) AGTAIL(e) | |
412 #define aghead(e) AGHEAD(e) | |
413 #define agopp(e) AGOPP(e) | |
414 | |
415 #define TAILPORT_ID "tailport" | |
416 #define HEADPORT_ID "headport" | |
417 | |
418 #if _PACKAGE_ast | |
419 # if !defined(_BLD_cgraph) && defined(__IMPORT__) | |
420 # define extern __IMPORT__ | |
421 # endif | |
422 #endif | |
423 #if !defined(_BLD_cgraph) && defined(GVDLL) | |
424 #define extern __declspec(dllimport) | |
425 #endif | |
426 | |
427 extern Agdesc_t Agdirected, Agstrictdirected, Agundirected, | |
428 Agstrictundirected; | |
429 | |
430 #undef extern | |
431 | |
432 /* fast graphs */ | |
433 void agflatten(Agraph_t * g, int flag); | |
434 typedef Agsubnode_t Agnoderef_t; | |
435 typedef Dtlink_t Agedgeref_t; | |
436 | |
437 #define AGHEADPOINTER(g) ((Agnoderef_t*)(g->n_seq->data->hh._head)) | |
438 #define AGRIGHTPOINTER(rep) ((Agnoderef_t*)((rep)->seq_link.right?((void*)((rep)->seq_link.right) - offsetof(Agsubnode_t,seq_link)):0)) | |
439 #define AGLEFTPOINTER(rep) ((Agnoderef_t*)((rep)->seq_link.hl._left?((void*)((rep)->seq_link.hl._left) - offsetof(Agsubnode_t,seq_link)):0)) | |
440 | |
441 #define FIRSTNREF(g) (agflatten(g,1), AGHEADPOINTER(g)) | |
442 | |
443 #define NEXTNREF(g,rep) (AGRIGHTPOINTER(rep) == AGHEADPOINTER(g)?0:AGRIGHTPOINTER(rep)) | |
444 | |
445 #define PREVNREF(g,rep) (((rep)==AGHEADPOINTER(g))?0:(AGLEFTPOINTER(rep))) | |
446 | |
447 #define LASTNREF(g) (agflatten(g,1), AGHEADPOINTER(g)?AGLEFTPOINTER(AGHEADPOINTER(g)):0) | |
448 #define NODEOF(rep) ((rep)->node) | |
449 | |
450 #define FIRSTOUTREF(g,sn) (agflatten(g,1), (sn)->out_seq) | |
451 #define LASTOUTREF(g,sn) (agflatten(g,1), (Agedgeref_t*)dtlast(sn->out_seq)) | |
452 #define FIRSTINREF(g,sn) (agflatten(g,1), (sn)->in_seq) | |
453 #define NEXTEREF(g,rep) ((rep)->right) | |
454 #define PREVEREF(g,rep) ((rep)->hl._left) | |
455 /* this is expedient but a bit slimey because it "knows" that dict entries of both nodes | |
456 and edges are embedded in main graph objects but allocated separately in subgraphs */ | |
457 #define AGSNMAIN(sn) ((sn)==(&((sn)->node->mainsub))) | |
458 #define EDGEOF(sn,rep) (AGSNMAIN(sn)?((Agedge_t*)((unsigned char*)(rep) - offsetof(Agedge_t,seq_link))) : ((Dthold_t*)(rep))->obj) | |
459 | |
460 #undef extern | |
461 #if _PACKAGE_ast | |
462 _END_EXTERNS_ | |
463 #endif | |
464 #ifdef __cplusplus | |
465 } | |
466 #endif | |
467 #endif |