00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 struct gbLink {
00028 oqmlAtom *at;
00029 oqmlAtomList *atlist;
00030
00031 gbLink *prev, *next;
00032
00033 inline gbLink(oqmlAtom *_at) {at = _at; atlist = 0;prev=next=0;}
00034 inline gbLink(oqmlAtomList *_atlist) {atlist = _atlist; at = 0;prev=next=0;}
00035 };
00036
00037
00038
00039 #ifdef GB_TRACE
00040 extern int GB_COUNT;
00041 extern int BR_CND;
00042 extern void break_now();
00043 #endif
00044
00045 inline gbLink *oqmlGarbManager::add_realize(gbLink *link)
00046 {
00047 if (last) {
00048 last->next = link;
00049 link->prev = last;
00050 last = link;
00051 }
00052 else
00053 first = last = link;
00054
00055 count++;
00056 #ifdef GB_TRACE
00057 printf("creating %s link=%p ptr=%p [%d]\n",
00058 link->at ? "atom" : "list",
00059 link,
00060 link->at ? (void *)link->at : (void *)link->atlist,
00061 GB_COUNT);
00062 if (BR_CND && GB_COUNT == BR_CND)
00063 break_now();
00064 GB_COUNT++;
00065 #endif
00066 return link;
00067 }
00068
00069 inline gbLink *oqmlGarbManager::add(oqmlAtom *at)
00070 {
00071 gbLink *link = new gbLink(at);
00072 return add_realize(link);
00073 }
00074
00075 inline gbLink *oqmlGarbManager::add(oqmlAtomList *atlist)
00076 {
00077 gbLink *link = new gbLink(atlist);
00078 return add_realize(link);
00079 }
00080
00081 inline void oqmlGarbManager::add(char *s)
00082 {
00083 str_list.insertObject(s);
00084 }
00085
00086 extern void break_now();
00087
00088 inline void oqmlGarbManager::remove(gbLink *link)
00089 {
00090 if (!link)
00091 return;
00092
00093 if (!garbaging) {
00094
00095 std::list<gbContext *>::iterator begin = ctx_l.begin();
00096 std::list<gbContext *>::iterator end = ctx_l.end();
00097 while (begin != end) {
00098 if ((*begin)->link == link)
00099 (*begin)->link = link->next;
00100 ++begin;
00101 }
00102
00103 if (link->prev)
00104 link->prev->next = link->next;
00105 if (link->next)
00106 link->next->prev = link->prev;
00107
00108 if (last == link)
00109 last = link->prev;
00110 if (first == link)
00111 first = link->next;
00112
00113 count--;
00114 #ifdef GB_TRACE
00115 printf("removing %s link %p\n",
00116 link->at ? "atom" : "list",
00117 link->at ? (void *)link->at : (void *)link->atlist);
00118 #endif
00119 delete link;
00120 }
00121 #ifdef GB_TRACE
00122 else
00123 printf("NOT removing %s link %p\n",
00124 link->at ? "atom" : "list",
00125 link->at ? (void *)link->at : (void *)link->atlist);
00126 #endif
00127 }
00128
00129 inline oqmlAtom::oqmlAtom()
00130 {
00131 type.comp = oqml_False;
00132 next = 0;
00133 refcnt = 0;
00134 recurs = oqml_False;
00135 link = oqmlGarbManager::add(this);
00136 string = (char *)0;
00137 #ifdef DEST_TRACE
00138 printf("new atom %p\n", this);
00139 #endif
00140 }
00141
00142 inline oqmlAtom_oid::oqmlAtom_oid(const Oid &_oid, Class *_class) :
00143 oqmlAtom()
00144 {
00145 type.type = oqmlATOM_OID;
00146 type.cls = _class;
00147 oid = _oid;
00148 }
00149
00150 inline oqmlAtom_obj::oqmlAtom_obj(Object *_o, pointer_int_t _idx,
00151 const Class *_class) : oqmlAtom()
00152 {
00153 type.type = oqmlATOM_OBJ;
00154 type.cls = (Class *)_class;
00155 o = _o;
00156 idx = _idx;
00157
00158 }
00159
00160 inline oqmlAtom_bool::oqmlAtom_bool(oqmlBool _b) : oqmlAtom()
00161 {
00162 type.type = oqmlATOM_BOOL;
00163 type.cls = 0;
00164 b = _b;
00165 }
00166
00167 inline oqmlAtom_nil::oqmlAtom_nil() : oqmlAtom()
00168 {
00169 type.type = oqmlATOM_NIL;
00170 type.cls = 0;
00171 }
00172
00173 inline oqmlAtom_null::oqmlAtom_null() : oqmlAtom()
00174 {
00175 type.type = oqmlATOM_NULL;
00176 type.cls = 0;
00177 }
00178
00179 inline oqmlAtom_int::oqmlAtom_int(eyedblib::int64 _i) : oqmlAtom()
00180 {
00181 type.type = oqmlATOM_INT;
00182 type.cls = 0;
00183 i = _i;
00184 }
00185
00186 inline oqmlAtom_char::oqmlAtom_char(char _c) : oqmlAtom()
00187 {
00188 type.type = oqmlATOM_CHAR;
00189 type.cls = 0;
00190 c = _c;
00191 }
00192
00193 inline oqmlAtom_string::oqmlAtom_string(const char *s) : oqmlAtom()
00194 {
00195 type.type = oqmlATOM_STRING;
00196 type.cls = 0;
00197 type.comp = oqml_True;
00198
00199 shstr = new oqmlSharedString(s);
00200 }
00201
00202 inline
00203 oqmlSharedString::oqmlSharedString(const char *_s)
00204 {
00205 refcnt = 1;
00206 s = strdup(_s);
00207 len = -1;
00208 }
00209
00210 inline void
00211 oqmlSharedString::set(const char *_s)
00212 {
00213 free(s);
00214 s = strdup(_s);
00215 len = -1;
00216 }
00217
00218 inline int
00219 oqmlSharedString::getLen() const
00220 {
00221 return len >= 0 ? len : (const_cast<oqmlSharedString *>(this)->len = strlen(s));
00222 }
00223
00224 inline
00225 oqmlSharedString::~oqmlSharedString()
00226 {
00227 free(s);
00228 }
00229
00230 inline int
00231 oqmlAtom_string::getLen() const
00232 {
00233 return shstr->getLen();
00234 }
00235
00236 inline oqmlAtom_string::oqmlAtom_string(oqmlSharedString *_shstr) :
00237 oqmlAtom()
00238 {
00239 type.type = oqmlATOM_STRING;
00240 type.cls = 0;
00241 type.comp = oqml_True;
00242
00243 shstr = _shstr;
00244 shstr->refcnt++;
00245 }
00246
00247 inline oqmlAtom_struct::oqmlAtom_struct()
00248 {
00249 attr = 0;
00250 attr_cnt = 0;
00251 }
00252
00253 inline oqmlAtom_struct::oqmlAtom_struct(oqml_StructAttr *_attr,
00254 int _attr_cnt)
00255 {
00256 type.type = oqmlATOM_STRUCT;
00257 type.cls = 0;
00258 type.comp = oqml_False;
00259 attr_cnt = _attr_cnt;
00260 attr = _attr;
00261 }
00262
00263 inline oqmlAtom_ident::oqmlAtom_ident(const char *ident,
00264 oqmlSymbolEntry *_entry) : oqmlAtom()
00265 {
00266 entry = _entry;
00267 if (entry) entry->addEntry(this);
00268 type.type = oqmlATOM_IDENT;
00269 type.cls = 0;
00270 type.comp = oqml_False;
00271
00272 shstr = new oqmlSharedString(ident);
00273 }
00274
00275 inline oqmlAtom_ident::oqmlAtom_ident(oqmlSharedString *_shstr,
00276 oqmlSymbolEntry *_entry) : oqmlAtom()
00277 {
00278 entry = _entry;
00279 if (entry) entry->addEntry(this);
00280 type.type = oqmlATOM_IDENT;
00281 type.cls = 0;
00282 type.comp = oqml_False;
00283
00284 shstr = _shstr;
00285 shstr->refcnt++;
00286 }
00287
00288 inline void oqmlAtom_ident::releaseEntry()
00289 {
00290 entry = 0;
00291 }
00292
00293 inline oqmlAtom_double::oqmlAtom_double(double _d) : oqmlAtom()
00294 {
00295 type.type = oqmlATOM_DOUBLE;
00296 type.cls = 0;
00297 d = _d;
00298 }
00299
00300 inline oqmlAtom_node::oqmlAtom_node(oqmlNode *_node) : oqmlAtom()
00301 {
00302 node = _node;
00303 type.type = oqmlATOM_NODE;
00304 type.cls = 0;
00305 evaluated = oqml_False;
00306
00307 }
00308
00309 inline oqmlAtom *oqmlAtom_node::copy()
00310 {
00311 return new oqmlAtom_node(node);
00312 }
00313
00314 inline oqmlAtom_select::oqmlAtom_select(oqmlNode *_node, oqmlNode *_node_orig) : oqmlAtom()
00315 {
00316 node = _node;
00317 node_orig = _node_orig;
00318 type.type = oqmlATOM_SELECT;
00319 type.cls = 0;
00320 evaluated = oqml_False;
00321 indexed = oqml_False;
00322 collatom = 0;
00323 list = 0;
00324 cpcnt = 0;
00325 for (int i = 0; i < OQML_MAX_CPS; i++)
00326 cplists[i] = 0;
00327 }
00328
00329 inline oqmlAtom *oqmlAtom_select::copy()
00330 {
00331 return new oqmlAtom_select(node, node_orig);
00332 }
00333
00334 inline oqmlAtom_coll::oqmlAtom_coll(oqmlAtomList *_list) : oqmlAtom()
00335 {
00336 #ifdef DEST_TRACE
00337 printf("new coll %p\n", this);
00338 #endif
00339 list = _list;
00340 }
00341
00342 inline oqmlAtom_list::oqmlAtom_list(oqmlAtomList *_list) : oqmlAtom_coll(_list)
00343 {
00344 type.type = oqmlATOM_LIST;
00345 type.cls = 0;
00346 }
00347
00348 inline oqmlAtom_set::oqmlAtom_set(oqmlAtomList *_list,
00349 oqmlBool _suppressDoubles) :
00350 oqmlAtom_coll(_list)
00351 {
00352 type.type = oqmlATOM_SET;
00353 type.cls = 0;
00354 if (_suppressDoubles)
00355 suppressDoubles();
00356 }
00357
00358 inline oqmlAtom_bag::oqmlAtom_bag(oqmlAtomList *_list) : oqmlAtom_coll(_list)
00359 {
00360 type.type = oqmlATOM_BAG;
00361 type.cls = 0;
00362 }
00363
00364 inline oqmlAtom_array::oqmlAtom_array(oqmlAtomList *_list) : oqmlAtom_coll(_list)
00365 {
00366 type.type = oqmlATOM_ARRAY;
00367 type.cls = 0;
00368 }
00369
00370 inline oqmlAtom *oqmlAtom_oid::copy()
00371 {
00372 return new oqmlAtom_oid(oid, type.cls);
00373 }
00374
00375 inline oqmlAtom *oqmlAtom_obj::copy()
00376 {
00377
00378
00379 return oqmlObjectManager::registerObject(o);
00380 }
00381
00382 inline Object *oqmlAtom_obj::getObject()
00383 {
00384 return o;
00385 }
00386
00387 inline oqmlAtom *oqmlAtom_bool::copy()
00388 {
00389 return new oqmlAtom_bool(b);
00390 }
00391
00392 inline oqmlAtom *oqmlAtom_nil::copy()
00393 {
00394 return new oqmlAtom_nil;
00395 }
00396
00397 inline oqmlAtom *oqmlAtom_null::copy()
00398 {
00399 return new oqmlAtom_null;
00400 }
00401
00402 inline oqmlAtom *oqmlAtom_int::copy()
00403 {
00404 return new oqmlAtom_int(i);
00405 }
00406
00407 inline oqmlAtom *oqmlAtom_char::copy()
00408 {
00409 return new oqmlAtom_char(c);
00410 }
00411
00412 #define SHARE
00413
00414 inline oqmlAtom *oqmlAtom_string::copy()
00415 {
00416 #ifdef SHARE
00417
00418 return new oqmlAtom_string(shstr);
00419 #else
00420 return new oqmlAtom_string(s);
00421 #endif
00422 }
00423
00424 inline oqmlAtom *oqmlAtom_ident::copy()
00425 {
00426 #ifdef SHARE
00427
00428 return new oqmlAtom_ident(shstr, entry);
00429 #else
00430 return new oqmlAtom_ident(ident, entry);
00431 #endif
00432 }
00433
00434 inline oqmlAtom *oqmlAtom_double::copy()
00435 {
00436 return new oqmlAtom_double(d);
00437 }
00438
00439 inline oqmlAtom *oqmlAtom_list::copy()
00440 {
00441 return new oqmlAtom_list(list);
00442 }
00443
00444 inline oqmlAtom *oqmlAtom_set::copy()
00445 {
00446 return new oqmlAtom_set(list, oqml_False);
00447 }
00448
00449 inline oqmlAtom *oqmlAtom_bag::copy()
00450 {
00451 return new oqmlAtom_bag(list);
00452 }
00453
00454 inline oqmlAtom *oqmlAtom_array::copy()
00455 {
00456 return new oqmlAtom_array(list);
00457 }
00458
00459 inline oqmlAtom *oqmlAtom_struct::copy()
00460 {
00461 return new oqmlAtom_struct(attr, attr_cnt);
00462 }
00463
00464 #define __CMP__(n, o, op) \
00465 if (op == oqmlEQUAL) \
00466 return OQMLBOOL((n) == (o)); \
00467 if (op == oqmlINF) \
00468 return OQMLBOOL((n) < (o)); \
00469 if (op == oqmlINFEQ) \
00470 return OQMLBOOL((n) <= (o)); \
00471 if (op == oqmlSUP) \
00472 return OQMLBOOL((n) > (o)); \
00473 if (op == oqmlSUPEQ) \
00474 return OQMLBOOL((n) >= (o)); \
00475 if (op == oqmlDIFF) \
00476 return OQMLBOOL((n) != (o)); \
00477 return oqml_False
00478
00479 inline oqmlBool oqmlAtom_null::compare(unsigned char *data, int len_data, Bool isnull, oqmlTYPE op) const
00480 {
00481 int n1 = (isnull ? 0 : 1);
00482
00483 __CMP__(0, n1, op);
00484 }
00485
00486 inline oqmlBool oqmlAtom_nil::compare(unsigned char *data, int len_data, Bool isnull, oqmlTYPE op) const
00487 {
00488 return oqml_False;
00489 }
00490
00491 inline oqmlBool oqmlAtom_bool::compare(unsigned char *data, int len_data, Bool isnull, oqmlTYPE op) const
00492 {
00493 if (isnull)
00494 {
00495 if (op == oqmlDIFF)
00496 return oqml_True;
00497 return oqml_False;
00498 }
00499
00500 if (len_data != sizeof(oqmlBool))
00501 return oqml_False;
00502
00503 int n1 = (int)(*(oqmlBool *)data);
00504 int n = (int)b;
00505
00506 __CMP__(n, n1, op);
00507 }
00508
00509 inline oqmlBool oqmlAtom_oid::compare(unsigned char *data, int len_data, Bool isnull, oqmlTYPE op) const
00510 {
00511 if (len_data < sizeof(Oid))
00512 return oqml_False;
00513
00514 Oid noid;
00515 memcpy(&noid, data, sizeof(Oid));
00516
00517 eyedbsm::Oid::NX nnx = noid.getNX();
00518 eyedbsm::Oid::NX nx = oid.getNX();
00519 __CMP__(nnx, nx, op);
00520 }
00521
00522 inline oqmlBool oqmlAtom_obj::compare(unsigned char *data, int len_data, Bool isnull, oqmlTYPE op) const
00523 {
00524 if (len_data < sizeof(Object *))
00525 return oqml_False;
00526
00527 Object *no;
00528 memcpy(&no, data, sizeof(Object *));
00529
00530 __CMP__(no, o, op);
00531 }
00532
00533 inline oqmlBool oqmlAtom_int::compare(unsigned char *data, int len_data,
00534 Bool isnull, oqmlTYPE op) const
00535 {
00536 if (isnull)
00537 {
00538 if (op == oqmlDIFF)
00539 return oqml_True;
00540 return oqml_False;
00541 }
00542
00543 if (len_data == sizeof(eyedblib::int32)+1)
00544 {
00545 eyedblib::int32 ni;
00546 memcpy(&ni, data, sizeof(ni));
00547 __CMP__(ni, i, op);
00548 }
00549
00550 if (len_data == sizeof(eyedblib::int16))
00551 {
00552 eyedblib::int16 ni;
00553 memcpy(&ni, data, sizeof(ni));
00554 __CMP__(ni, i, op);
00555 }
00556
00557 if (len_data == sizeof(eyedblib::int32))
00558 {
00559 eyedblib::int32 ni;
00560 memcpy(&ni, data, sizeof(ni));
00561 __CMP__(ni, i, op);
00562 }
00563
00564 if (len_data == sizeof(eyedblib::int64))
00565 {
00566 eyedblib::int64 ni;
00567 memcpy(&ni, data, sizeof(ni));
00568 __CMP__(ni, i, op);
00569 }
00570
00571 if (op == oqmlDIFF)
00572 return oqml_True;
00573 return oqml_False;
00574 }
00575
00576 inline oqmlBool oqmlAtom_char::compare(unsigned char *data, int len_data, Bool isnull, oqmlTYPE op) const
00577 {
00578 if (isnull)
00579 {
00580 if (op == oqmlDIFF)
00581 return oqml_True;
00582 return oqml_False;
00583 }
00584
00585 if (len_data < sizeof(char))
00586 return oqml_False;
00587
00588 char nc = data[0];
00589 __CMP__(nc, c, op);
00590 }
00591
00592 inline oqmlBool oqmlAtom_string::compare(unsigned char *data, int len_data, Bool isnull, oqmlTYPE op) const
00593 {
00594 if (isnull)
00595 {
00596 if (op == oqmlDIFF)
00597 return oqml_True;
00598 return oqml_False;
00599 }
00600
00601 int cmp;
00602 if (len_data)
00603 cmp = strcmp((char *)data, shstr->s);
00604 else if (data)
00605 cmp = !*shstr->s;
00606 else
00607 cmp = !shstr->s;
00608
00609 __CMP__(cmp, 0, op);
00610 }
00611
00612 inline oqmlBool oqmlAtom_ident::compare(unsigned char *data, int len_data, Bool isnull, oqmlTYPE op) const
00613 {
00614 if (isnull)
00615 {
00616 if (op == oqmlDIFF)
00617 return oqml_True;
00618 return oqml_False;
00619 }
00620
00621 if (len_data < strlen(shstr->s))
00622 return oqml_False;
00623
00624 int cmp = strcmp((char *)data, shstr->s);
00625 __CMP__(cmp, 0, op);
00626 }
00627
00628 inline oqmlBool oqmlAtom_double::compare(unsigned char *data, int len_data, Bool isnull, oqmlTYPE op) const
00629 {
00630 if (isnull)
00631 {
00632 if (op == oqmlDIFF)
00633 return oqml_True;
00634 return oqml_False;
00635 }
00636
00637 if (len_data < sizeof(double))
00638 return oqml_False;
00639
00640 double nd;
00641 memcpy(&nd, data, sizeof(double));
00642
00643 if (op == oqmlEQUAL)
00644 {
00645 double delta = nd - d;
00646 if (delta < 0.)
00647 delta = -delta;
00648 return OQMLBOOL(delta < .0001);
00649 }
00650 else
00651 __CMP__(nd, d, op);
00652 }
00653
00654 inline void oqmlAtom::print(FILE *fd)
00655 {
00656 (void)makeString(fd);
00657 }
00658
00659 inline char *oqmlAtom::getString() const
00660 {
00661 return makeString(0);
00662 }
00663
00664 inline oqmlBool oqmlAtom::compare(unsigned char *, int, Bool, oqmlTYPE) const
00665 {
00666 return oqml_False;
00667 }
00668
00669 #include <assert.h>
00670
00671 inline oqmlAtom::~oqmlAtom()
00672 {
00673 #ifdef DEST_TRACE
00674 printf("deleting atom %p refcnt=%d\n", this, refcnt);
00675 #endif
00676 assert(!refcnt);
00677 if (refcnt)
00678 return;
00679 refcnt = 32000;
00680 oqmlGarbManager::remove(link);
00681 free(string);
00682 }
00683
00684 inline void oqmlAtom_string::set(const char *s)
00685 {
00686 shstr->set(s);
00687 }
00688
00689 inline oqmlAtom_string::~oqmlAtom_string()
00690 {
00691 if (!--shstr->refcnt)
00692 delete shstr;
00693 }
00694
00695 inline oqmlAtom_ident::~oqmlAtom_ident()
00696 {
00697 if (!--shstr->refcnt)
00698 delete shstr;
00699 }
00700
00701 inline oqmlAtom_obj::~oqmlAtom_obj()
00702 {
00703
00704 oqmlStatus *s = oqmlObjectManager::unregisterObject(0, o);
00705 #if 0
00706 if (s) {
00707 fprintf(stderr, "~oqmlAtom_obj error: %s\n", s->msg);
00708 abort();
00709 }
00710 #endif
00711 o = 0;
00712 }
00713
00714 inline oqmlAtom_node::~oqmlAtom_node()
00715 {
00716 }
00717
00718 inline oqmlAtom_select::~oqmlAtom_select()
00719 {
00720 }
00721
00722 inline oqmlAtom_struct::~oqmlAtom_struct()
00723 {
00724 }
00725
00726 inline oqmlBool oqmlAtomType::cmp(const oqmlAtomType &at, Bool autocast)
00727 {
00728
00729
00730
00731
00732 if (type == oqmlATOM_OBJ && at.type == oqmlATOM_OBJ) {
00733 if (cls == 0)
00734 return (oqmlBool)(at.cls == 0);
00735 if (at.cls == 0)
00736 return (oqmlBool)(cls == 0);
00737 return (oqmlBool)cls->compare(at.cls);
00738 }
00739
00740 if (autocast)
00741 {
00742 if ((type == oqmlATOM_DOUBLE && at.type == oqmlATOM_INT) ||
00743 (at.type == oqmlATOM_DOUBLE && type == oqmlATOM_INT))
00744 return oqml_True;
00745 }
00746
00747 return OQMLBOOL(type == at.type && comp == at.comp);
00748 }
00749
00750 inline oqmlAtomList::oqmlAtomList()
00751 {
00752 cnt = 0;
00753 first = last = 0;
00754 link = oqmlGarbManager::add(this);
00755 refcnt = 0;
00756 recurs = oqml_False;
00757 string = (char *)0;
00758 }
00759
00760 inline oqmlAtomList::oqmlAtomList(oqmlAtomList *alist)
00761 {
00762 cnt = 0;
00763 first = last = 0;
00764
00765 refcnt = 0;
00766 recurs = oqml_False;
00767 string = (char *)0;
00768
00769 link = oqmlGarbManager::add(this);
00770
00771 if (!alist)
00772 return;
00773
00774 oqmlAtom *a = alist->first;
00775 while (a)
00776 {
00777 oqmlAtom *next = a->next;
00778 append(a->copy());
00779 a = next;
00780 }
00781 }
00782
00783 inline oqmlAtomList::oqmlAtomList(oqmlAtom *a)
00784 {
00785 cnt = (a ? 1 : 0);
00786 first = last = a;
00787 refcnt = 0;
00788 recurs = oqml_False;
00789 string = (char *)0;
00790 link = oqmlGarbManager::add(this);
00791
00792 if (!a)
00793 return;
00794
00795 a->next = 0;
00796 }
00797
00798 inline oqmlAtomList::~oqmlAtomList()
00799 {
00800 #ifdef DEST_TRACE
00801 printf("deleting list %p refcnt=%d\n", this, refcnt);
00802 #endif
00803 assert(!refcnt);
00804 if (refcnt)
00805 return;
00806
00807 oqmlAtom *a = first;
00808 while (a) {
00809 oqmlAtom *next = a->next;
00810
00811 if (!a->refcnt)
00812 delete a;
00813 a = next;
00814 }
00815
00816 cnt = 0;
00817 oqmlGarbManager::remove(link);
00818 #ifdef DEST_TRACE
00819 printf("end of deleting list %p\n", this);
00820 #endif
00821 refcnt = 64000;
00822 free(string);
00823 }
00824
00825 inline int oqmlAtomList::getFlattenCount() const
00826 {
00827 int count = 0;
00828
00829 oqmlAtom *a = first;
00830 while (a)
00831 {
00832 if (a->type.type == oqmlATOM_LIST)
00833 count += ((oqmlAtom_list *)a)->list->getFlattenCount() + 2;
00834 else
00835 count++;
00836 a = a->next;
00837 }
00838
00839 return count;
00840 }
00841
00842 inline void oqmlAtomList::print(FILE *fd)
00843 {
00844 oqmlAtom *a = first;
00845
00846 fprintf(fd, "(");
00847 while (a)
00848 {
00849 a->print(fd);
00850 a = a->next;
00851 if (a)
00852 fprintf(fd, ", ");
00853 }
00854 fprintf(fd, ")");
00855 }
00856
00857 inline char *oqmlAtomList::getString() const
00858 {
00859 oqmlAtom *a = first;
00860 int sz = 1;
00861 char *b = (char *)malloc(sz);
00862 b[0] = 0;
00863
00864 while (a)
00865 {
00866 char *d = a->getString();
00867 sz += strlen(d) + 2;
00868 b = (char *)realloc(b, sz);
00869 if (a != first)
00870 strcat(b, ", ");
00871 strcat(b, d);
00872 a = a->next;
00873 }
00874
00875 delete string;
00876 ((oqmlAtomList *)this)->string = b;
00877 return b;
00878 }
00879
00880 inline bool detect_cycle(oqmlAtom *a1, oqmlAtom *a2)
00881 {
00882 while (a1) {
00883 while (a2) {
00884 bool r = false;
00885
00886 if (a1 == a2)
00887 r = true;
00888 else if (a1->as_coll() && a2->as_coll())
00889 r = detect_cycle(a1->as_coll()->list->first, a2->as_coll()->list->first);
00890 else if (a1->as_coll())
00891 r = detect_cycle(a1->as_coll()->list->first, a2);
00892
00893 else if (a2->as_coll())
00894 r = detect_cycle(a1, a2->as_coll()->list->first);
00895
00896 if (r)
00897 return true;
00898 a2 = a2->next;
00899 }
00900 a1 = a1->next;
00901 }
00902
00903 return false;
00904 }
00905
00906 inline bool oqmlAtomList::append(oqmlAtom *a, bool incref, bool _detect_cycle)
00907 {
00908 a->next = 0;
00909
00910 if (_detect_cycle && detect_cycle(first, a))
00911 return true;
00912
00913 if (last) {
00914 last->next = a;
00915 last = a;
00916 }
00917 else
00918 first = last = a;
00919
00920 if (incref) {
00921 if (refcnt)
00922 oqmlLock(a, oqml_True);
00923 else if (a->refcnt)
00924 oqmlLock(this, oqml_True);
00925 }
00926
00927 cnt++;
00928
00929 return false;
00930 }
00931
00932 inline bool oqmlAtomList::append(oqmlAtomList *al, oqmlBool dodel, bool _detect_cycle)
00933 {
00934 if (!al)
00935 return false;
00936
00937 if (_detect_cycle && detect_cycle(first, al->first))
00938 return true;
00939
00940 if (refcnt)
00941 oqmlLock(al, oqml_True);
00942 else if (al->refcnt)
00943 oqmlLock(this, oqml_True);
00944
00945 oqmlAtom *a = al->first;
00946
00947 if (!a)
00948 return false;
00949
00950 if (last)
00951 last->next = a;
00952 else
00953 first = a;
00954
00955 last = al->last;
00956
00957 cnt += al->cnt;
00958 if (dodel && !al->refcnt) {
00959 al->first = 0;
00960 al->cnt = 0;
00961 delete al;
00962 }
00963
00964 return false;
00965 }