/trunk/Source/DOH/base.c
C | 957 lines | 631 code | 125 blank | 201 comment | 148 complexity | 9b47118af697d0167f3b276ce2ad8964 MD5 | raw file
1/* ----------------------------------------------------------------------------- 2 * This file is part of SWIG, which is licensed as a whole under version 3 3 * (or any later version) of the GNU General Public License. Some additional 4 * terms also apply to certain portions of SWIG. The full details of the SWIG 5 * license and copyrights can be found in the LICENSE and COPYRIGHT files 6 * included with the SWIG source code as distributed by the SWIG developers 7 * and at http://www.swig.org/legal.html. 8 * 9 * base.c 10 * 11 * This file contains the function entry points for dispatching methods on 12 * DOH objects. A number of small utility functions are also included. 13 * ----------------------------------------------------------------------------- */ 14 15char cvsroot_base_c[] = "$Id: base.c 12946 2012-03-23 15:23:47Z drjoe $"; 16 17#include "dohint.h" 18 19/* ----------------------------------------------------------------------------- 20 * DohDelete() 21 * ----------------------------------------------------------------------------- */ 22 23#ifndef SWIG_DEBUG_DELETE 24#define SWIG_DEBUG_DELETE 0 25#endif 26 27void DohDelete(DOH *obj) { 28 DohBase *b = (DohBase *) obj; 29 DohObjInfo *objinfo; 30 31 if (!obj) 32 return; 33 if (!DohCheck(b)) { 34#if SWIG_DEBUG_DELETE 35 fputs("DOH: Fatal error. Attempt to delete a non-doh object.\n", stderr); 36 abort(); 37#else 38 assert(0); 39#endif 40 return; 41 } 42 if (b->flag_intern) 43 return; 44 assert(b->refcount > 0); 45 b->refcount--; 46 if (b->refcount <= 0) { 47 objinfo = b->type; 48 if (objinfo->doh_del) { 49 (objinfo->doh_del) (b); 50 } else { 51 if (b->data) 52 DohFree(b->data); 53 } 54 DohObjFree(b); 55 } 56} 57 58/* ----------------------------------------------------------------------------- 59 * DohCopy() 60 * ----------------------------------------------------------------------------- */ 61 62DOH *DohCopy(const DOH *obj) { 63 DohBase *b = (DohBase *) obj; 64 DohObjInfo *objinfo; 65 66 if (!obj) 67 return 0; 68 if (!DohCheck(b)) { 69#if SWIG_DEBUG_DELETE 70 fputs("DOH: Fatal error. Attempt to copy a non-doh object.\n", stderr); 71 abort(); 72#else 73 assert(0); 74#endif 75 return 0; 76 } 77 objinfo = b->type; 78 if (objinfo->doh_copy) { 79 DohBase *bc = (DohBase *) (objinfo->doh_copy) (b); 80 if ((bc) && b->meta) { 81 bc->meta = Copy(b->meta); 82 } 83 return (DOH *) bc; 84 } 85 return 0; 86} 87 88void DohIncref(DOH *obj) { 89 Incref(obj); 90} 91 92/* ----------------------------------------------------------------------------- 93 * DohClear() 94 * ----------------------------------------------------------------------------- */ 95 96void DohClear(DOH *obj) { 97 DohBase *b = (DohBase *) obj; 98 DohObjInfo *objinfo = b->type; 99 if (objinfo->doh_clear) 100 (objinfo->doh_clear) (b); 101} 102 103/* ----------------------------------------------------------------------------- 104 * DohStr() 105 * ----------------------------------------------------------------------------- */ 106 107DOH *DohStr(const DOH *obj) { 108 char buffer[512]; 109 DohBase *b = (DohBase *) obj; 110 DohObjInfo *objinfo; 111 if (DohCheck(b)) { 112 objinfo = b->type; 113 if (objinfo->doh_str) { 114 return (objinfo->doh_str) (b); 115 } 116 sprintf(buffer, "<Object '%s' at %p>", objinfo->objname, (void *) b); 117 return NewString(buffer); 118 } else { 119 return NewString(obj); 120 } 121} 122 123/* ----------------------------------------------------------------------------- 124 * DohDump() 125 * ----------------------------------------------------------------------------- */ 126 127int DohDump(const DOH *obj, DOH *out) { 128 DohBase *b = (DohBase *) obj; 129 DohObjInfo *objinfo = b->type; 130 if (objinfo->doh_dump) { 131 return (objinfo->doh_dump) (b, out); 132 } 133 return 0; 134} 135 136/* ----------------------------------------------------------------------------- 137 * DohLen() - Defaults to strlen() if not a DOH object 138 * ----------------------------------------------------------------------------- */ 139int DohLen(const DOH *obj) { 140 DohBase *b = (DohBase *) obj; 141 DohObjInfo *objinfo; 142 if (!b) 143 return 0; 144 if (DohCheck(b)) { 145 objinfo = b->type; 146 if (objinfo->doh_len) { 147 return (objinfo->doh_len) (b); 148 } 149 return 0; 150 } else { 151 return strlen((char *) obj); 152 } 153} 154 155/* ----------------------------------------------------------------------------- 156 * DohHashVal() 157 * ----------------------------------------------------------------------------- */ 158 159int DohHashval(const DOH *obj) { 160 DohBase *b = (DohBase *) obj; 161 DohObjInfo *objinfo; 162 /* obj is already checked and/or converted into DohBase* */ 163 /* if (DohCheck(b)) */ 164 { 165 objinfo = b->type; 166 if (objinfo->doh_hashval) { 167 return (objinfo->doh_hashval) (b); 168 } 169 } 170 return 0; 171} 172 173/* ----------------------------------------------------------------------------- 174 * DohData() 175 * ----------------------------------------------------------------------------- */ 176 177void *DohData(const DOH *obj) { 178 DohBase *b = (DohBase *) obj; 179 DohObjInfo *objinfo; 180 if (DohCheck(obj)) { 181 objinfo = b->type; 182 if (objinfo->doh_data) { 183 return (objinfo->doh_data) (b); 184 } 185 return 0; 186 } 187 return (void *) obj; 188} 189 190/* ----------------------------------------------------------------------------- 191 * RawData() 192 * ----------------------------------------------------------------------------- */ 193 194static void *RawData(DohBase *b) { 195 DohObjInfo *objinfo = b->type; 196 return (objinfo->doh_data) ? (objinfo->doh_data) (b) : 0; 197} 198 199 200/* ----------------------------------------------------------------------------- 201 * DohCmp() 202 * ----------------------------------------------------------------------------- */ 203 204int DohCmp(const DOH *obj1, const DOH *obj2) { 205 DohBase *b1, *b2; 206 DohObjInfo *b1info, *b2info; 207 int c1, c2; 208 b1 = (DohBase *) obj1; 209 b2 = (DohBase *) obj2; 210 c1 = DohCheck(b1); 211 c2 = DohCheck(b2); 212 /* most of the times, obj2 is a plain c string */ 213 if (!c1 || !c2) { 214 if ((b1 == 0) && (b2 == 0)) 215 return 0; 216 if (b1 && !b2) 217 return 1; 218 if (!b1 && b2) 219 return -1; 220 return strcmp((char *) (c1 ? RawData(b1) : (void *) obj1), (char *) (c2 ? RawData(b2) : (void *) obj2)); 221 } 222 b1info = b1->type; 223 b2info = b2->type; 224 if ((b1info == b2info) && (b1info->doh_cmp)) 225 return (b1info->doh_cmp) (b1, b2); 226 return 1; 227} 228 229/* ----------------------------------------------------------------------------- 230 * DohEqual() 231 * ----------------------------------------------------------------------------- */ 232 233int DohEqual(const DOH *obj1, const DOH *obj2) { 234 DohBase *b1 = (DohBase *) obj1; 235 DohBase *b2 = (DohBase *) obj2; 236 if (!b1) { 237 return !b2; 238 } else if (!b2) { 239 return 0; 240 } else { 241 DohObjInfo *b1info = 0; 242 DohObjInfo *b2info = 0; 243 if (DohCheck(b1)) { 244 b1info = b1->type; 245 if (DohCheck(b2)) { 246 b2info = b2->type; 247 } else { 248 int len = (b1info->doh_len) (b1); 249 char *cobj = (char *) obj2; 250 return len == (int) strlen(cobj) ? (memcmp(RawData(b1), cobj, len) == 0) : 0; 251 } 252 } else if (DohCheck(b2)) { 253 int len = (b2->type->doh_len) (b2); 254 char *cobj = (char *) obj1; 255 return len == (int) strlen(cobj) ? (memcmp(RawData(b2), cobj, len) == 0) : 0; 256 } else { 257 return strcmp((char *) obj1, (char *) obj2) == 0; 258 } 259 260 if (!b1info) { 261 return obj1 == obj2; 262 } else if ((b1info == b2info)) { 263 return b1info->doh_equal ? (b1info->doh_equal) (b1, b2) : (b1info->doh_cmp ? (b1info->doh_cmp) (b1, b2) == 0 : (b1 == b2)); 264 } else { 265 return 0; 266 } 267 } 268} 269 270/* ----------------------------------------------------------------------------- 271 * DohFirst() 272 * ----------------------------------------------------------------------------- */ 273 274DohIterator DohFirst(DOH *obj) { 275 DohIterator iter; 276 DohBase *b; 277 DohObjInfo *binfo; 278 279 b = (DohBase *) obj; 280 if (DohCheck(b)) { 281 binfo = b->type; 282 if (binfo->doh_first) { 283 return (binfo->doh_first) (b); 284 } 285 } 286 iter.object = 0; 287 iter.item = 0; 288 iter.key = 0; 289 iter._current = 0; 290 iter._index = 0; 291 return iter; 292} 293 294/* ----------------------------------------------------------------------------- 295 * DohNext() 296 * ----------------------------------------------------------------------------- */ 297 298DohIterator DohNext(DohIterator iter) { 299 DohIterator niter; 300 301 if (iter.object) { 302 DohBase *b; 303 DohObjInfo *binfo; 304 305 b = (DohBase *) iter.object; 306 binfo = b->type; 307 if (binfo->doh_next) { 308 return (binfo->doh_next) (iter); 309 } 310 } 311 niter = iter; 312 return niter; 313} 314 315/* ----------------------------------------------------------------------------- 316 * DohIsMapping() 317 * ----------------------------------------------------------------------------- */ 318int DohIsMapping(const DOH *obj) { 319 DohBase *b = (DohBase *) obj; 320 DohObjInfo *objinfo; 321 if (!DohCheck(b)) 322 return 0; 323 objinfo = b->type; 324 if (objinfo->doh_hash) 325 return 1; 326 else 327 return 0; 328} 329 330/* ----------------------------------------------------------------------------- 331 * DohGetattr() 332 * ----------------------------------------------------------------------------- */ 333 334DOH *DohGetattr(DOH *obj, const DOH *name) { 335 DohBase *b = (DohBase *) obj; 336 DohObjInfo *objinfo = b->type; 337 if (objinfo->doh_hash && objinfo->doh_hash->doh_getattr) { 338 DOH *r = (objinfo->doh_hash->doh_getattr) (b, (DOH *) name); 339 return (r == DohNone) ? 0 : r; 340 } 341 return 0; 342} 343 344/* ----------------------------------------------------------------------------- 345 * DohSetattr() 346 * ----------------------------------------------------------------------------- */ 347 348int DohSetattr(DOH *obj, const DOH *name, const DOH *value) { 349 DohBase *b = (DohBase *) obj; 350 DohObjInfo *objinfo = b->type; 351 if (objinfo->doh_hash && objinfo->doh_hash->doh_setattr) { 352 return (objinfo->doh_hash->doh_setattr) (b, (DOH *) name, (DOH *) value); 353 } 354 return 0; 355} 356 357/* ----------------------------------------------------------------------------- 358 * DohDelattr() 359 * ----------------------------------------------------------------------------- */ 360 361int DohDelattr(DOH *obj, const DOH *name) { 362 DohBase *b = (DohBase *) obj; 363 DohObjInfo *objinfo = b->type; 364 if (objinfo->doh_hash && objinfo->doh_hash->doh_delattr) { 365 return (objinfo->doh_hash->doh_delattr) (b, (DOH *) name); 366 } 367 return 0; 368} 369 370/* ----------------------------------------------------------------------------- 371 * DohCheckattr() 372 * ----------------------------------------------------------------------------- */ 373 374int DohCheckattr(DOH *obj, const DOH *name, const DOH *value) { 375 DOH *attr = Getattr(obj,name); 376 if (!attr) return 0; 377 return DohEqual(attr,value); 378} 379 380/* ----------------------------------------------------------------------------- 381 * DohKeys() 382 * ----------------------------------------------------------------------------- */ 383 384DOH *DohKeys(DOH *obj) { 385 DohBase *b = (DohBase *) obj; 386 DohObjInfo *objinfo = b->type; 387 if (objinfo && objinfo->doh_hash->doh_keys) { 388 return (objinfo->doh_hash->doh_keys) (b); 389 } 390 return 0; 391} 392 393/* ----------------------------------------------------------------------------- 394 * DohGetInt() 395 * ----------------------------------------------------------------------------- */ 396 397int DohGetInt(DOH *obj, const DOH *name) { 398 DOH *val; 399 val = Getattr(obj, (DOH *) name); 400 if (!val) 401 return 0; 402 if (DohIsString(val)) { 403 return atoi((char *) Data(val)); 404 } 405 return 0; 406} 407 408/* ----------------------------------------------------------------------------- 409 * DohGetDouble() 410 * ----------------------------------------------------------------------------- */ 411 412double DohGetDouble(DOH *obj, const DOH *name) { 413 DOH *val; 414 val = Getattr(obj, (DOH *) name); 415 if (!val) 416 return 0; 417 if (DohIsString(val)) { 418 return atof((char *) Data(val)); 419 } 420 return 0; 421} 422 423/* ----------------------------------------------------------------------------- 424 * DohGetChar() 425 * ----------------------------------------------------------------------------- */ 426 427char *DohGetChar(DOH *obj, const DOH *name) { 428 DOH *val; 429 val = Getattr(obj, (DOH *) name); 430 if (!val) 431 return 0; 432 if (DohIsString(val)) { 433 return (char *) Data(val); 434 } 435 return 0; 436} 437 438/* ----------------------------------------------------------------------------- 439 * DohGetFlagAttr() / DohGetFlag() 440 * A flag is unset if the attribute (name) does not exist on the node (obj), 441 * or it is set to "0". If the attribute is set to any other value, 442 * the flag is set. 443 * 444 * DohGetFlag() returns if the flag is set or not 445 * DohGetFlagAttr() returns the flag value if is set, NULL otherwise 446 * ----------------------------------------------------------------------------- */ 447 448 449DOH *DohGetFlagAttr(DOH *obj, const DOH *name) { 450 DOH *val = Getattr(obj, (DOH *) name); 451 if (!val) { 452 return NULL; 453 } else { 454 const char *cval = Char(val); 455 if (!cval) 456 return val; 457 return (strcmp(cval, "0") != 0) ? val : NULL; 458 } 459} 460 461int DohGetFlag(DOH *obj, const DOH *name) { 462 return DohGetFlagAttr(obj, name) ? 1 : 0; 463} 464 465 466/* ----------------------------------------------------------------------------- 467 * DohGetVoid() 468 * ----------------------------------------------------------------------------- */ 469 470void *DohGetVoid(DOH *obj, const DOH *name) { 471 DOH *val; 472 val = Getattr(obj, (DOH *) name); 473 if (!val) 474 return 0; 475 return (void *) Data(val); 476} 477 478/* ----------------------------------------------------------------------------- 479 * DohSetInt() 480 * ----------------------------------------------------------------------------- */ 481 482void DohSetInt(DOH *obj, const DOH *name, int value) { 483 DOH *temp; 484 temp = NewStringEmpty(); 485 Printf(temp, "%d", value); 486 Setattr(obj, (DOH *) name, temp); 487} 488 489/* ----------------------------------------------------------------------------- 490 * DohSetDouble() 491 * ----------------------------------------------------------------------------- */ 492 493void DohSetDouble(DOH *obj, const DOH *name, double value) { 494 DOH *temp; 495 temp = NewStringEmpty(); 496 Printf(temp, "%0.17f", value); 497 Setattr(obj, (DOH *) name, temp); 498} 499 500/* ----------------------------------------------------------------------------- 501 * DohSetChar() 502 * ----------------------------------------------------------------------------- */ 503 504void DohSetChar(DOH *obj, const DOH *name, char *value) { 505 Setattr(obj, (DOH *) name, NewString(value)); 506} 507 508/* ----------------------------------------------------------------------------- 509 * DohSetFlag() 510 * ----------------------------------------------------------------------------- */ 511 512void DohSetFlagAttr(DOH *obj, const DOH *name, const DOH *attr) { 513 Setattr(obj, (DOH *) name, attr ? attr : NewString("0")); 514} 515 516void DohSetFlag(DOH *obj, const DOH *name) { 517 Setattr(obj, (DOH *) name, NewString("1")); 518} 519 520/* ----------------------------------------------------------------------------- 521 * DohSetVoid() 522 * ----------------------------------------------------------------------------- */ 523 524void DohSetVoid(DOH *obj, const DOH *name, void *value) { 525 Setattr(obj, (DOH *) name, NewVoid(value, 0)); 526} 527 528/* ----------------------------------------------------------------------------- 529 * DohIsSequence() 530 * ----------------------------------------------------------------------------- */ 531 532int DohIsSequence(const DOH *obj) { 533 DohBase *b = (DohBase *) obj; 534 DohObjInfo *objinfo; 535 if (!DohCheck(b)) 536 return 0; 537 objinfo = b->type; 538 if (objinfo->doh_list) 539 return 1; 540 else 541 return 0; 542} 543 544/* ----------------------------------------------------------------------------- 545 * DohGetitem() 546 * ----------------------------------------------------------------------------- */ 547 548DOH *DohGetitem(DOH *obj, int index) { 549 DohBase *b = (DohBase *) obj; 550 DohObjInfo *objinfo = b->type; 551 if (objinfo->doh_list && objinfo->doh_list->doh_getitem) { 552 return (objinfo->doh_list->doh_getitem) (b, index); 553 } 554 return 0; 555} 556 557/* ----------------------------------------------------------------------------- 558 * DohSetitem() 559 * ----------------------------------------------------------------------------- */ 560 561int DohSetitem(DOH *obj, int index, const DOH *value) { 562 DohBase *b = (DohBase *) obj; 563 DohObjInfo *objinfo = b->type; 564 if (objinfo->doh_list && objinfo->doh_list->doh_setitem) { 565 return (objinfo->doh_list->doh_setitem) (b, index, (DOH *) value); 566 } 567 return -1; 568} 569 570/* ----------------------------------------------------------------------------- 571 * DohDelitem() 572 * ----------------------------------------------------------------------------- */ 573 574int DohDelitem(DOH *obj, int index) { 575 DohBase *b = (DohBase *) obj; 576 DohObjInfo *objinfo = b->type; 577 if (objinfo->doh_list && objinfo->doh_list->doh_delitem) { 578 return (objinfo->doh_list->doh_delitem) (b, index); 579 } 580 return -1; 581} 582 583/* ----------------------------------------------------------------------------- 584 * DohInsertitem() 585 * ----------------------------------------------------------------------------- */ 586 587int DohInsertitem(DOH *obj, int index, const DOH *value) { 588 DohBase *b = (DohBase *) obj; 589 DohObjInfo *objinfo = b->type; 590 if (objinfo->doh_list && objinfo->doh_list->doh_insitem) { 591 return (objinfo->doh_list->doh_insitem) (b, index, (DOH *) value); 592 } 593 return -1; 594} 595 596 597/* ----------------------------------------------------------------------------- 598 * DohDelslice() 599 * ----------------------------------------------------------------------------- */ 600 601int DohDelslice(DOH *obj, int sindex, int eindex) { 602 DohBase *b = (DohBase *) obj; 603 DohObjInfo *objinfo = b->type; 604 if (objinfo->doh_list && objinfo->doh_list->doh_delslice) { 605 return (objinfo->doh_list->doh_delslice) (b, sindex, eindex); 606 } 607 return -1; 608} 609 610/* ----------------------------------------------------------------------------- 611 * DohIsFile() 612 * ----------------------------------------------------------------------------- */ 613 614int DohIsFile(const DOH *obj) { 615 DohBase *b = (DohBase *) obj; 616 DohObjInfo *objinfo; 617 if (!DohCheck(b)) 618 return 0; 619 objinfo = b->type; 620 if (objinfo->doh_file) 621 return 1; 622 else 623 return 0; 624} 625 626/* ----------------------------------------------------------------------------- 627 * DohRead() 628 * ----------------------------------------------------------------------------- */ 629 630int DohRead(DOH *obj, void *buffer, int length) { 631 DohBase *b = (DohBase *) obj; 632 DohObjInfo *objinfo; 633 if (DohCheck(obj)) { 634 objinfo = b->type; 635 if ((objinfo->doh_file) && (objinfo->doh_file->doh_read)) { 636 return (objinfo->doh_file->doh_read) (b, buffer, length); 637 } 638 return -1; 639 } 640 /* Hmmm. Not a file. Maybe it's a real FILE */ 641 return fread(buffer, 1, length, (FILE *) b); 642} 643 644/* ----------------------------------------------------------------------------- 645 * DohWrite() 646 * ----------------------------------------------------------------------------- */ 647 648int DohWrite(DOH *obj, const void *buffer, int length) { 649 DohBase *b = (DohBase *) obj; 650 DohObjInfo *objinfo; 651 if (DohCheck(obj)) { 652 objinfo = b->type; 653 if ((objinfo->doh_file) && (objinfo->doh_file->doh_write)) { 654 return (objinfo->doh_file->doh_write) (b, buffer, length); 655 } 656 return -1; 657 } 658 /* Hmmm. Not a file. Maybe it's a real FILE */ 659 return fwrite(buffer, 1, length, (FILE *) b); 660} 661 662/* ----------------------------------------------------------------------------- 663 * DohSeek() 664 * ----------------------------------------------------------------------------- */ 665 666int DohSeek(DOH *obj, long offset, int whence) { 667 DohBase *b = (DohBase *) obj; 668 DohObjInfo *objinfo; 669 if (DohCheck(obj)) { 670 objinfo = b->type; 671 if ((objinfo->doh_file) && (objinfo->doh_file->doh_seek)) { 672 return (objinfo->doh_file->doh_seek) (b, offset, whence); 673 } 674 return -1; 675 } 676 return fseek((FILE *) b, offset, whence); 677} 678 679/* ----------------------------------------------------------------------------- 680 * DohTell() 681 * ----------------------------------------------------------------------------- */ 682 683long DohTell(DOH *obj) { 684 DohBase *b = (DohBase *) obj; 685 DohObjInfo *objinfo; 686 if (DohCheck(obj)) { 687 objinfo = b->type; 688 if ((objinfo->doh_file) && (objinfo->doh_file->doh_tell)) { 689 return (objinfo->doh_file->doh_tell) (b); 690 } 691 return -1; 692 } 693 return ftell((FILE *) b); 694} 695 696/* ----------------------------------------------------------------------------- 697 * DohGetc() 698 * ----------------------------------------------------------------------------- */ 699 700int DohGetc(DOH *obj) { 701 static DOH *lastdoh = 0; 702 DohBase *b = (DohBase *) obj; 703 DohObjInfo *objinfo; 704 if (obj == lastdoh) { 705 objinfo = b->type; 706 return (objinfo->doh_file->doh_getc) (b); 707 } 708 if (DohCheck(obj)) { 709 objinfo = b->type; 710 if (objinfo->doh_file->doh_getc) { 711 lastdoh = obj; 712 return (objinfo->doh_file->doh_getc) (b); 713 } 714 return EOF; 715 } 716 return fgetc((FILE *) b); 717} 718 719/* ----------------------------------------------------------------------------- 720 * DohPutc() 721 * ----------------------------------------------------------------------------- */ 722 723int DohPutc(int ch, DOH *obj) { 724 static DOH *lastdoh = 0; 725 DohBase *b = (DohBase *) obj; 726 DohObjInfo *objinfo; 727 728 if (obj == lastdoh) { 729 objinfo = b->type; 730 return (objinfo->doh_file->doh_putc) (b, ch); 731 } 732 if (DohCheck(obj)) { 733 objinfo = b->type; 734 if (objinfo->doh_file->doh_putc) { 735 lastdoh = obj; 736 return (objinfo->doh_file->doh_putc) (b, ch); 737 } 738 return EOF; 739 } 740 return fputc(ch, (FILE *) b); 741} 742 743/* ----------------------------------------------------------------------------- 744 * DohUngetc() 745 * ----------------------------------------------------------------------------- */ 746 747int DohUngetc(int ch, DOH *obj) { 748 DohBase *b = (DohBase *) obj; 749 DohObjInfo *objinfo; 750 if (DohCheck(obj)) { 751 objinfo = b->type; 752 if (objinfo->doh_file->doh_ungetc) { 753 return (objinfo->doh_file->doh_ungetc) (b, ch); 754 } 755 return EOF; 756 } 757 return ungetc(ch, (FILE *) b); 758} 759 760/* ----------------------------------------------------------------------------- 761 * DohClose() 762 * ----------------------------------------------------------------------------- */ 763 764int DohClose(DOH *obj) { 765 DohBase *b = (DohBase *) obj; 766 DohObjInfo *objinfo; 767 if (DohCheck(obj)) { 768 objinfo = b->type; 769 if (objinfo->doh_file->doh_close) { 770 return (objinfo->doh_file->doh_close) (b); 771 } 772 return 0; 773 } 774 return fclose((FILE *) obj); 775} 776 777/* ----------------------------------------------------------------------------- 778 * DohIsString() 779 * ----------------------------------------------------------------------------- */ 780 781int DohIsString(const DOH *obj) { 782 DohBase *b = (DohBase *) obj; 783 DohObjInfo *objinfo; 784 if (!DohCheck(b)) 785 return 0; 786 objinfo = b->type; 787 if (objinfo->doh_string) 788 return 1; 789 else 790 return 0; 791} 792 793/* ----------------------------------------------------------------------------- 794 * DohReplace() 795 * ----------------------------------------------------------------------------- */ 796 797int DohReplace(DOH *src, const DOH *token, const DOH *rep, int flags) { 798 DohBase *b = (DohBase *) src; 799 DohObjInfo *objinfo; 800 if (!token) 801 return 0; 802 if (!rep) 803 rep = ""; 804 if (DohIsString(src)) { 805 objinfo = b->type; 806 if (objinfo->doh_string->doh_replace) { 807 return (objinfo->doh_string->doh_replace) (b, (DOH *) token, (DOH *) rep, flags); 808 } 809 } 810 return 0; 811} 812 813/* ----------------------------------------------------------------------------- 814 * DohChop() 815 * ----------------------------------------------------------------------------- */ 816 817void DohChop(DOH *src) { 818 DohBase *b = (DohBase *) src; 819 DohObjInfo *objinfo; 820 if (DohIsString(src)) { 821 objinfo = b->type; 822 if (objinfo->doh_string->doh_chop) { 823 (objinfo->doh_string->doh_chop) (b); 824 } 825 } 826} 827 828/* ----------------------------------------------------------------------------- 829 * DohSetFile() 830 * ----------------------------------------------------------------------------- */ 831void DohSetfile(DOH *ho, DOH *file) { 832 DohBase *h = (DohBase *) ho; 833 DohObjInfo *objinfo; 834 if (!h) 835 return; 836 objinfo = h->type; 837 if (objinfo->doh_setfile) 838 (objinfo->doh_setfile) (h, file); 839} 840 841/* ----------------------------------------------------------------------------- 842 * DohGetFile() 843 * ----------------------------------------------------------------------------- */ 844DOH *DohGetfile(const DOH *ho) { 845 DohBase *h = (DohBase *) ho; 846 DohObjInfo *objinfo; 847 if (!h) 848 return 0; 849 objinfo = h->type; 850 if (objinfo->doh_getfile) 851 return (objinfo->doh_getfile) (h); 852 return 0; 853} 854 855/* ----------------------------------------------------------------------------- 856 * DohSetLine() 857 * ----------------------------------------------------------------------------- */ 858void DohSetline(DOH *ho, int l) { 859 DohBase *h = (DohBase *) ho; 860 DohObjInfo *objinfo; 861 if (!h) 862 return; 863 objinfo = h->type; 864 if (objinfo->doh_setline) 865 (objinfo->doh_setline) (h, l); 866} 867 868/* ----------------------------------------------------------------------------- 869 * DohGetLine() 870 * ----------------------------------------------------------------------------- */ 871int DohGetline(const DOH *ho) { 872 DohBase *h = (DohBase *) ho; 873 DohObjInfo *objinfo; 874 if (!h) 875 return 0; 876 objinfo = h->type; 877 if (objinfo->doh_getline) 878 return (objinfo->doh_getline) (h); 879 return 0; 880} 881 882/* ----------------------------------------------------------------------------- 883 * DohGetmeta() 884 * ----------------------------------------------------------------------------- */ 885 886DOH *DohGetmeta(DOH *ho, const DOH *name) { 887 DohBase *h = (DohBase *) ho; 888 if (!DohCheck(ho)) 889 return 0; 890 if (!h->meta) 891 return 0; 892 return DohGetattr(h->meta, name); 893} 894 895/* ----------------------------------------------------------------------------- 896 * DohGetmeta() 897 * ----------------------------------------------------------------------------- */ 898 899int DohSetmeta(DOH *ho, const DOH *name, const DOH *value) { 900 DohBase *h = (DohBase *) ho; 901 if (!DohCheck(ho)) 902 return 0; 903 if (!h->meta) 904 h->meta = NewHash(); 905 return DohSetattr(h->meta, name, value); 906} 907 908/* ----------------------------------------------------------------------------- 909 * DohDelmeta() 910 * ----------------------------------------------------------------------------- */ 911 912int DohDelmeta(DOH *ho, const DOH *name) { 913 DohBase *h = (DohBase *) ho; 914 if (!DohCheck(ho)) 915 return 0; 916 if (!h->meta) 917 return 0; 918 return DohDelattr(h->meta, name); 919} 920 921/* ----------------------------------------------------------------------------- 922 * DohSetmark() 923 * ----------------------------------------------------------------------------- */ 924 925void DohSetmark(DOH *ho, int x) { 926 DohBase *h = (DohBase *) ho; 927 h->flag_usermark = x; 928} 929 930int DohGetmark(DOH *ho) { 931 DohBase *h = (DohBase *) ho; 932 return h->flag_usermark; 933} 934 935/* ----------------------------------------------------------------------------- 936 * DohCall() 937 * 938 * Invokes a function via DOH. A Function is represented by a hash table with 939 * the following attributes: 940 * 941 * "builtin" - Pointer to built-in function (if any) 942 * 943 * (Additional attributes may be added later) 944 * 945 * Returns a DOH object with result on success. Returns NULL on error 946 * ----------------------------------------------------------------------------- */ 947 948DOH *DohCall(DOH *func, DOH *args) { 949 DOH *result; 950 DOH *(*builtin) (DOH *); 951 952 builtin = (DOH *(*)(DOH *)) GetVoid(func, "builtin"); 953 if (!builtin) 954 return 0; 955 result = (*builtin) (args); 956 return result; 957}