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