/tags/rel-1-3-25/SWIG/Source/DOH/string.c
C | 1045 lines | 815 code | 110 blank | 120 comment | 217 complexity | c2dd5caa4012185f12164cced656bb6c MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
1/* ----------------------------------------------------------------------------- 2 * string.c 3 * 4 * Implements a string object that supports both sequence operations and 5 * file semantics. 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_string_c[] = "$Header$"; 14 15#include "dohint.h" 16 17extern DohObjInfo DohStringType; 18 19typedef struct String { 20 DOH *file; 21 int line; 22 int maxsize; /* Max size allocated */ 23 int len; /* Current length */ 24 int hashkey; /* Hash key value */ 25 int sp; /* Current position */ 26 char *str; /* String data */ 27} String; 28 29/* ----------------------------------------------------------------------------- 30 * void *String_data() - Return as a 'void *' 31 * ----------------------------------------------------------------------------- */ 32 33static void * 34String_data(DOH *so) { 35 String *s = (String *) ObjData(so); 36 s->str[s->len] = 0; 37 return (void *) s->str; 38} 39 40/* ----------------------------------------------------------------------------- 41 * int String_dump() - Serialize a string onto out 42 * ----------------------------------------------------------------------------- */ 43 44static int 45String_dump(DOH *so, DOH *out) { 46 int nsent; 47 int ret; 48 String *s = (String *) ObjData(so); 49 nsent = 0; 50 while (nsent < s->len) { 51 ret = Write(out,s->str+nsent,(s->len-nsent)); 52 if (ret < 0) return ret; 53 nsent += ret; 54 } 55 return nsent; 56} 57 58/* ----------------------------------------------------------------------------- 59 * CopyString() - Copy a string 60 * ----------------------------------------------------------------------------- */ 61 62static DOH * 63CopyString(DOH *so) { 64 int max; 65 String *str; 66 String *s = (String *) ObjData(so); 67 str = (String *) DohMalloc(sizeof(String)); 68 str->hashkey = -1; 69 str->sp = s->sp; 70 str->line = s->line; 71 str->file = s->file; 72 if (str->file) Incref(str->file); 73 max = s->maxsize; 74 str->str = (char *) DohMalloc(max+1); 75 memmove(str->str, s->str, max); 76 str->maxsize= max; 77 str->len = s->len; 78 str->str[str->len] = 0; 79 80 return DohObjMalloc(&DohStringType,str); 81} 82 83/* ----------------------------------------------------------------------------- 84 * DelString() - Delete a string 85 * ----------------------------------------------------------------------------- */ 86 87static void 88DelString(DOH *so) { 89 String *s = (String *) ObjData(so); 90 s->hashkey = -1; 91 DohFree(s->str); 92 s->str = 0; 93 DohFree(s); 94} 95 96/* ----------------------------------------------------------------------------- 97 * String_len() - Length of a string 98 * ----------------------------------------------------------------------------- */ 99 100static int 101String_len(DOH *so) { 102 String *s = (String *) ObjData(so); 103 return s->len; 104} 105 106 107/* ----------------------------------------------------------------------------- 108 * int String_cmp() - Compare two strings 109 * ----------------------------------------------------------------------------- */ 110 111static int 112String_cmp(DOH *so1, DOH *so2) 113{ 114 String * s1 = (String *) ObjData(so1); 115 String * s2 = (String *) ObjData(so2); 116 register char *c1 = s1->str; 117 register char *c2 = s2->str; 118#if 0 119 /* this should be faster ? */ 120 return strcmp(c1, c2); 121#else 122 register int len1 = s1->len; 123 register int len2 = s2->len; 124 if (len1 < len2) { 125 register char *ce = c1 + len1; 126 for (; c1 != ce ; ++c1, ++c2) { 127 if (*c1 != *c2) return ((*c1 < *c2) ? -1 : 1); 128 } 129 return -1; 130 } else { 131 register char *ce = c2 + len2; 132 for (; c2 != ce ; ++c1, ++c2) { 133 if (*c1 != *c2) return ((*c1 < *c2) ? -1 : 1); 134 } 135 return (len1 == len2) ? 0 : 1; 136 } 137#endif 138} 139 140/* ----------------------------------------------------------------------------- 141 * int String_hash() - Compute string hash value 142 * ----------------------------------------------------------------------------- */ 143 144static int 145String_hash(DOH *so) { 146 String *s = (String *) ObjData(so); 147 char *c; 148 int i, h = 0, len; 149 150 if (s->hashkey >= 0) return s->hashkey; 151 c = s->str; 152 len = s->len > 50 ? 50 : s->len; 153 for (i = 0; i < len; i++) { 154 h = (((h << 5) + *(c++))); 155 } 156 h = h & 0x7fffffff; 157 s->hashkey = h; 158 return h; 159} 160 161/* ----------------------------------------------------------------------------- 162 * static add(String *s, const char *newstr) - Append to s 163 * ----------------------------------------------------------------------------- */ 164 165static void 166add(String *s, const char *newstr) { 167 int oldlen, newlen, newmaxsize, l, i, sp; 168 char *tc; 169 if (!newstr) return; 170 s->hashkey = -1; 171 l = (int) strlen(newstr); 172 oldlen = s->len; 173 newlen = oldlen+l + 1; 174 if (newlen >= s->maxsize-1) { 175 newmaxsize = 2*s->maxsize; 176 if (newlen >= newmaxsize -1) newmaxsize = newlen + 1; 177 s->str = (char *) DohRealloc(s->str,newmaxsize); 178 assert(s->str); 179 s->maxsize = newmaxsize; 180 } 181 tc = s->str; 182 strcpy(tc+oldlen,newstr); 183 sp = s->sp; 184 if (sp >= oldlen) { 185 tc += sp; 186 for (i = sp; i < oldlen+l; i++,tc++) { 187 if (*tc == '\n') s->line++; 188 } 189 s->sp = oldlen+l; 190 } 191 s->len += l; 192} 193 194/* ----------------------------------------------------------------------------- 195 * void String_clear() - Clear a string 196 * ----------------------------------------------------------------------------- */ 197 198static void 199String_clear(DOH *so) 200{ 201 String *s = (String *) ObjData(so); 202 s->hashkey = -1; 203 s->len = 0; 204 *(s->str) = 0; 205 s->sp = 0; 206 s->line = 1; 207} 208 209/* ----------------------------------------------------------------------------- 210 * void String_insert() - Insert a string 211 * ----------------------------------------------------------------------------- */ 212 213static int 214String_insert(DOH *so, int pos, DOH *str) 215{ 216 String *s = (String *) ObjData(so); 217 char *nstr; 218 int len; 219 char *data; 220 221 data = (char *) DohData(str); 222 nstr = s->str; 223 224 s->hashkey = -1; 225 if (pos == DOH_END) { 226 add(s, data); 227 return 0; 228 } 229 230 if (pos < 0) pos = 0; 231 else if (pos > s->len) pos = s->len; 232 233 /* See if there is room to insert the new data */ 234 len = Len(str); 235 while (s->maxsize <= s->len+len) { 236 s->str = (char *) DohRealloc(s->str,2*s->maxsize); 237 assert(s->str); 238 s->maxsize *= 2; 239 } 240 memmove(s->str+pos+len, s->str+pos, (s->len - pos)); 241 memcpy(s->str+pos,data,len); 242 if (s->sp >= pos) { 243 int i; 244 245 for (i = 0; i < len; i++) { 246 if (data[i] == '\n') s->line++; 247 } 248 s->sp+=len; 249 } 250 s->len += len; 251 s->str[s->len] = 0; 252 return 0; 253} 254 255/* ----------------------------------------------------------------------------- 256 * int String_delitem() - Delete a character 257 * ----------------------------------------------------------------------------- */ 258 259static int 260String_delitem(DOH *so, int pos) 261{ 262 String *s = (String *) ObjData(so); 263 s->hashkey = -1; 264 if (pos == DOH_END) pos = s->len-1; 265 if (pos == DOH_BEGIN) pos = 0; 266 if (s->len == 0) return 0; 267 268 if (s->sp > pos) { 269 s->sp--; 270 assert (s->sp >= 0); 271 if (s->str[pos] == '\n') s->line--; 272 } 273 memmove(s->str+pos, s->str+pos+1, ((s->len-1) - pos)); 274 s->len--; 275 s->str[s->len] = 0; 276 return 0; 277} 278 279/* ----------------------------------------------------------------------------- 280 * int String_delslice() - Delete a range 281 * ----------------------------------------------------------------------------- */ 282 283static int 284String_delslice(DOH *so, int sindex, int eindex) { 285 String *s = (String *) ObjData(so); 286 int size; 287 s->hashkey = -1; 288 if (eindex == DOH_END) eindex = s->len; 289 if (sindex == DOH_BEGIN) sindex = 0; 290 if (s->len == 0) return 0; 291 292 size = eindex - sindex; 293 if (s->sp > eindex) { 294 /* Adjust the file pointer and line count */ 295 char *c = s->str + sindex; 296 int i; 297 for (i = 0; i < size; i++) { 298 if (*c == '\n') s->line--; 299 } 300 s->sp -= size; 301 assert(s->sp >= 0); 302 } 303 memmove(s->str+sindex,s->str+eindex, ((s->len-size) - sindex)); 304 s->len -= size; 305 s->str[s->len] = 0; 306 return 0; 307} 308 309/* ----------------------------------------------------------------------------- 310 * DOH *String_str() - Returns a string (used by printing commands) 311 * ----------------------------------------------------------------------------- */ 312 313static DOH * 314String_str(DOH *so) 315{ 316 String *s = (String *) ObjData(so); 317 s->str[s->len] = 0; 318 return NewString(s->str); 319} 320 321/* ----------------------------------------------------------------------------- 322 * int String_read() - Read data from a string 323 * ----------------------------------------------------------------------------- */ 324 325static int 326String_read(DOH *so, void *buffer, int len) 327{ 328 int reallen, retlen; 329 char *cb; 330 String *s = (String *) ObjData(so); 331 if ((s->sp + len) > s->len) reallen = (s->len - s->sp); 332 else reallen = len; 333 334 cb = (char *) buffer; 335 retlen = reallen; 336 337 if (reallen > 0) { 338 memmove(cb, s->str+s->sp, reallen); 339 s->sp += reallen; 340 } 341 return retlen; 342} 343 344/* ----------------------------------------------------------------------------- 345 * int String_write() - Write data to a string 346 * ----------------------------------------------------------------------------- */ 347static int 348String_write(DOH *so, void *buffer, int len) 349{ 350 int newlen; 351 String *s = (String *) ObjData(so); 352 s->hashkey = -1; 353 if (s->sp > s->len) s->sp = s->len; 354 newlen = s->sp + len+1; 355 if (newlen > s->maxsize) { 356 s->str = (char *) DohRealloc(s->str,newlen); 357 assert(s->str); 358 s->maxsize = newlen; 359 s->len = s->sp + len; 360 } 361 if ((s->sp+len) > s->len) s->len = s->sp + len; 362 memmove(s->str+s->sp,buffer,len); 363 s->sp += len; 364 s->str[s->len] = 0; 365 return len; 366} 367 368/* ----------------------------------------------------------------------------- 369 * int String_seek() - Seek to a new position 370 * ----------------------------------------------------------------------------- */ 371 372static int 373String_seek(DOH *so, long offset, int whence) 374{ 375 int pos, nsp, inc; 376 int prev; 377 String *s = (String *) ObjData(so); 378 if (whence == SEEK_SET) pos = 0; 379 else if (whence == SEEK_CUR) pos = s->sp; 380 else if (whence == SEEK_END) { 381 pos = s->len; 382 offset = -offset; 383 } 384 else pos = s->sp; 385 386 nsp = pos + offset; 387 if (nsp < 0) 388 nsp = 0; 389 if (s->len > 0 && nsp >= s->len) 390 nsp = s->len-1; 391 392 inc = (nsp > s->sp) ? 1 : -1; 393 394 { 395 register int sp = s->sp; 396 register char *tc = s->str; 397 register int len = s->len; 398 while (sp != nsp) { 399 prev = sp + inc; 400 if (prev>=0 && prev<=len && tc[prev] == '\n') 401 s->line += inc; 402 sp+=inc; 403 } 404 s->sp = sp; 405 } 406 assert (s->sp >= 0); 407 return 0; 408} 409 410/* ----------------------------------------------------------------------------- 411 * long String_tell() - Return current position 412 * ----------------------------------------------------------------------------- */ 413 414static long 415String_tell(DOH *so) 416{ 417 String *s = (String *) ObjData(so); 418 return (long) (s->sp); 419} 420 421/* ----------------------------------------------------------------------------- 422 * int String_putc() 423 * ----------------------------------------------------------------------------- */ 424 425static int 426String_putc(DOH *so, int ch) 427{ 428 register int len, maxsize, sp; 429 String *s = (String *) ObjData(so); 430 s->hashkey = -1; 431 len = s->len; 432 sp = s->sp; 433 if (sp >= len) { 434 register char *tc; 435 maxsize = s->maxsize; 436 if (len > (maxsize-2)) { 437 s->str = (char *) DohRealloc(s->str,2*maxsize); 438 assert(s->str); 439 s->maxsize = 2*maxsize; 440 } 441 tc = s->str + len; 442 *(tc++) = ch; 443 if (sp >= len) { 444 s->sp = len+1; 445 *tc = 0; 446 if (ch == '\n') s->line++; 447 } 448 s->len = len+1; 449 } else { 450 s->str[s->sp++] = (char) ch; 451 if (ch == '\n') s->line++; 452 } 453 return ch; 454} 455 456/* ----------------------------------------------------------------------------- 457 * int String_getc() 458 * ----------------------------------------------------------------------------- */ 459 460static int 461String_getc(DOH *so) 462{ 463 int c; 464 String *s = (String *) ObjData(so); 465 if (s->sp >= s->len) 466 c = EOF; 467 else 468 c = (int) s->str[s->sp++]; 469 if (c == '\n') s->line++; 470 return c; 471} 472 473/* ----------------------------------------------------------------------------- 474 * int String_ungetc() 475 * ----------------------------------------------------------------------------- */ 476 477static int 478String_ungetc(DOH *so, int ch) 479{ 480 String *s = (String *) ObjData(so); 481 if (ch == EOF) return ch; 482 if (s->sp <= 0) return EOF; 483 s->sp--; 484 if (ch == '\n') s->line--; 485 return ch; 486} 487 488 489/* ----------------------------------------------------------------------------- 490 * replace_simple(String *str, char *token, char *rep, int flags, int count) 491 * 492 * Replaces count non-overlapping occurrences of token with rep in a string. 493 * ----------------------------------------------------------------------------- */ 494 495static char * 496end_quote(char *s) 497{ 498 char *qs; 499 char qc; 500 char *q; 501 char *nl; 502 qc = *s; 503 qs = s; 504 while (1) { 505 q = strpbrk(s+1,"\"\'"); 506 nl = strchr(s+1,'\n'); 507 if (nl && (nl < q)) { 508 /* A new line appears before the end of the string */ 509 if (*(nl-1) == '\\') { 510 s = nl+1; 511 continue; 512 } 513 /* String was terminated by a newline. Wing it */ 514 return qs; 515 } 516 if (!q && nl) { 517 return qs; 518 } 519 if (!q) return 0; 520 if ((*q == qc) && (*(q-1) != '\\')) return q; 521 s = q; 522 } 523} 524 525static char * 526match_simple(char *base, char *s, char *token, int tokenlen) 527{ 528 (void)base; 529 (void)tokenlen; 530 return strstr(s,token); 531} 532 533static char * 534match_identifier(char *base, char *s, char *token, int tokenlen) 535{ 536 while (s) { 537 s = strstr(s,token); 538 if (!s) return 0; 539 if ((s > base) && (isalnum((int) *(s-1)) || (*(s-1) == '_'))) { 540 s += tokenlen; 541 continue; 542 } 543 if (isalnum((int)*(s+tokenlen)) || (*(s+tokenlen) == '_')) { 544 s += tokenlen; 545 continue; 546 } 547 return s; 548 } 549 return 0; 550} 551 552 553static char * 554match_identifier_begin(char *base, char *s, char *token, int tokenlen) 555{ 556 while (s) { 557 s = strstr(s,token); 558 if (!s) return 0; 559 if ((s > base) && (isalnum((int)*(s-1)) || (*(s-1) == '_'))) { 560 s += tokenlen; 561 continue; 562 } 563 return s; 564 } 565 return 0; 566} 567 568static char * 569match_identifier_end(char *base, char *s, char *token, int tokenlen) 570{ 571 (void)base; 572 while (s) { 573 s = strstr(s,token); 574 if (!s) return 0; 575 if (isalnum((int)*(s+tokenlen)) || (*(s+tokenlen) == '_')) { 576 s += tokenlen; 577 continue; 578 } 579 return s; 580 } 581 return 0; 582} 583 584static int 585replace_simple(String *str, char *token, char *rep, int flags, int count, char *(*match)(char *, char *, char *, int)) 586{ 587 int tokenlen; /* Length of the token */ 588 int replen; /* Length of the replacement */ 589 int delta, expand = 0; 590 int ic; 591 int rcount = 0; 592 int noquote = 0; 593 char *c, *s, *t, *first; 594 char *q, *q2; 595 register char *base; 596 int i; 597 598 str->hashkey = -1; 599 600 /* Figure out if anything gets replaced */ 601 if (!strlen(token)) return 0; 602 603 base = str->str; 604 tokenlen = strlen(token); 605 s = (*match)(base,base,token,tokenlen); 606 607 if (!s) return 0; /* No matches. Who cares */ 608 609 if (flags & DOH_REPLACE_NOQUOTE) noquote = 1; 610 611 /* If we are not replacing inside quotes, we need to do a little extra work */ 612 if (noquote) { 613 q = strpbrk(base,"\"\'"); 614 if (!q) { 615 noquote = 0; /* Well, no quotes to worry about. Oh well */ 616 } else { 617 while (q && (q < s)) { 618 /* First match was found inside a quote. Try to find another match */ 619 q2 = end_quote(q); 620 if (!q2) { 621 return 0; 622 } 623 if (q2 > s) { 624 /* Find next match */ 625 s = (*match)(base,q2+1,token,tokenlen); 626 } 627 if (!s) return 0; /* Oh well, no matches */ 628 q = strpbrk(q2+1,"\"\'"); 629 if (!q) noquote = 0; /* No more quotes */ 630 } 631 } 632 } 633 634 first = s; 635 replen = strlen(rep); 636 637 delta = (replen - tokenlen); 638 639 if (delta <= 0) { 640 /* String is either shrinking or staying the same size */ 641 /* In this case, we do the replacement in place without memory reallocation */ 642 ic = count; 643 t = s; /* Target of memory copies */ 644 while (ic && s) { 645 if (replen) { 646 memcpy(t,rep,replen); 647 t += replen; 648 } 649 rcount++; 650 expand += delta; 651 /* Find the next location */ 652 s += tokenlen; 653 if (ic == 1) break; 654 c = (*match)(base,s,token,tokenlen); 655 656 if (noquote) { 657 q = strpbrk(s,"\"\'"); 658 if (!q) { 659 noquote = 0; 660 } else { 661 while (q && (q < c)) { 662 /* First match was found inside a quote. Try to find another match */ 663 q2 = end_quote(q); 664 if (!q2) { 665 c = 0; 666 break; 667 } 668 if (q2 > c) 669 c = (*match)(base,q2+1,token,tokenlen); 670 if (!c) break; 671 q = strpbrk(q2+1,"\"\'"); 672 if (!q) noquote = 0; /* No more quotes */ 673 } 674 } 675 } 676 if (delta) { 677 if (c) { 678 memmove(t,s,c-s); 679 t += (c-s); 680 } else { 681 memmove(t,s,(str->str + str->len) - s + 1); 682 } 683 } else { 684 t += (c-s); 685 } 686 s = c; 687 ic--; 688 } 689 if (s && delta) { 690 memmove(t,s,(str->str + str->len) - s + 1); 691 } 692 str->len += expand; 693 str->str[str->len] = 0; 694 if (str->sp >= str->len) str->sp += expand; /* Fix the end of file pointer */ 695 return rcount; 696 } 697 /* The string is expanding as a result of the replacement */ 698 /* Figure out how much expansion is going to occur and allocate a new string */ 699 { 700 char *ns; 701 int newsize; 702 703 rcount++; 704 ic = count -1; 705 s += tokenlen; 706 while (ic && (c = (*match)(base,s,token,tokenlen))) { 707 if (noquote) { 708 q = strpbrk(s,"\"\'"); 709 if (!q) { 710 break; 711 } else { 712 while (q && (q < c)) { 713 /* First match was found inside a quote. Try to find another match */ 714 q2 = end_quote(q); 715 if (!q2) { 716 c = 0; 717 break; 718 } 719 if (q2 > c) { 720 c = (*match)(base,q2+1,token,tokenlen); 721 if (!c) break; 722 } 723 q = strpbrk(q2+1,"\"\'"); 724 if (!q) noquote = 0; 725 } 726 } 727 } 728 if (c) { 729 rcount++; 730 ic--; 731 s = c + tokenlen; 732 } else { 733 break; 734 } 735 } 736 737 expand = delta*rcount; /* Total amount of expansion for the replacement */ 738 newsize = str->maxsize; 739 while ((str->len + expand) >= newsize) newsize *= 2; 740 741 ns = (char *) DohMalloc(newsize); 742 assert(ns); 743 t = ns; 744 s = first; 745 746 /* Copy the first part of the string */ 747 if (first > str->str) { 748 memcpy(t,str->str,(first - str->str)); 749 t += (first-str->str); 750 } 751 for (i = 0; i < rcount; i++) { 752 memcpy(t,rep,replen); 753 t += replen; 754 s += tokenlen; 755 c = (*match)(base,s,token,tokenlen); 756 if (noquote) { 757 q = strpbrk(s,"\"\'"); 758 if (!q) { 759 noquote = 0; 760 } else { 761 while (q && (q < c)) { 762 /* First match was found inside a quote. Try to find another match */ 763 q2 = end_quote(q); 764 if (!q2) { 765 c = 0; 766 break; 767 } 768 if (q2 > c) { 769 c = (*match)(base,q2+1,token,tokenlen); 770 if (!c) break; 771 } 772 q = strpbrk(q2+1,"\"\'"); 773 if (!q) noquote = 0; /* No more quotes */ 774 } 775 } 776 } 777 if (i < (rcount - 1)) { 778 memcpy(t,s,c-s); 779 t += (c-s); 780 } else { 781 memcpy(t,s,(str->str + str->len) - s + 1); 782 } 783 s = c; 784 } 785 c = str->str; 786 str->str = ns; 787 if (str->sp >= str->len) str->sp += expand; 788 str->len += expand; 789 str->str[str->len] = 0; 790 str->maxsize = newsize; 791 DohFree(c); 792 return rcount; 793 } 794} 795 796/* ----------------------------------------------------------------------------- 797 * int String_replace() 798 * ----------------------------------------------------------------------------- */ 799 800static int 801String_replace(DOH *stro, DOH *token, DOH *rep, int flags) 802{ 803 int count = -1; 804 String *str = (String *) ObjData(stro); 805 806 if (flags & DOH_REPLACE_FIRST) count = 1; 807 808 if (flags & DOH_REPLACE_ID_END) { 809 return replace_simple(str,Char(token),Char(rep),flags, count, match_identifier_end); 810 } else if (flags & DOH_REPLACE_ID_BEGIN) { 811 return replace_simple(str,Char(token),Char(rep),flags, count, match_identifier_begin); 812 } else if (flags & DOH_REPLACE_ID) { 813 return replace_simple(str,Char(token),Char(rep),flags, count, match_identifier); 814 } else { 815 return replace_simple(str,Char(token), Char(rep), flags, count, match_simple); 816 } 817} 818 819/* ----------------------------------------------------------------------------- 820 * void String_chop(DOH *str) 821 * ----------------------------------------------------------------------------- */ 822 823static void 824String_chop(DOH *so) 825{ 826 char *c; 827 String *str = (String *) ObjData(so); 828 /* Replace trailing whitespace */ 829 c = str->str + str->len - 1; 830 while ((str->len > 0) && (isspace((int)*c))) { 831 if (str->sp >= str->len) { 832 str->sp--; 833 if (*c == '\n') str->line--; 834 } 835 str->len--; 836 c--; 837 } 838 str->str[str->len] = 0; 839 assert (str->sp >= 0); 840 str->hashkey = -1; 841} 842 843static void 844String_setfile(DOH *so, DOH *file) 845{ 846 DOH *fo; 847 String *str = (String *) ObjData(so); 848 849 if (!DohCheck(file)) { 850 fo = NewString(file); 851 Decref(fo); 852 } else fo = file; 853 Incref(fo); 854 Delete(str->file); 855 str->file = fo; 856} 857 858static DOH * 859String_getfile(DOH *so) 860{ 861 String *str = (String *) ObjData(so); 862 return str->file; 863} 864 865static void 866String_setline(DOH *so, int line) 867{ 868 String *str = (String *) ObjData(so); 869 str->line = line; 870} 871 872static int 873String_getline(DOH *so) 874{ 875 String *str = (String *) ObjData(so); 876 return str->line; 877} 878 879static DohListMethods StringListMethods = { 880 0, /* doh_getitem */ 881 0, /* doh_setitem */ 882 String_delitem, /* doh_delitem */ 883 String_insert, /* doh_insitem */ 884 String_delslice, /* doh_delslice */ 885}; 886 887static DohFileMethods StringFileMethods = { 888 String_read, 889 String_write, 890 String_putc, 891 String_getc, 892 String_ungetc, 893 String_seek, 894 String_tell, 895 0, /* close */ 896}; 897 898static DohStringMethods StringStringMethods = { 899 String_replace, 900 String_chop, 901}; 902 903DohObjInfo DohStringType = { 904 "String", /* objname */ 905 DelString, /* doh_del */ 906 CopyString, /* doh_copy */ 907 String_clear, /* doh_clear */ 908 String_str, /* doh_str */ 909 String_data, /* doh_data */ 910 String_dump, /* doh_dump */ 911 String_len, /* doh_len */ 912 String_hash, /* doh_hash */ 913 String_cmp, /* doh_cmp */ 914 0, /* doh_first */ 915 0, /* doh_next */ 916 String_setfile, /* doh_setfile */ 917 String_getfile, /* doh_getfile */ 918 String_setline, /* doh_setline */ 919 String_getline, /* doh_getline */ 920 0, /* doh_mapping */ 921 &StringListMethods, /* doh_sequence */ 922 &StringFileMethods, /* doh_file */ 923 &StringStringMethods, /* doh_string */ 924 0, /* doh_position */ 925 0, 926}; 927 928 929#define INIT_MAXSIZE 16 930 931/* ----------------------------------------------------------------------------- 932 * NewString(const char *c) - Create a new string 933 * ----------------------------------------------------------------------------- */ 934 935DOHString * 936DohNewString(const DOH *so) 937{ 938 int l = 0, max; 939 String *str; 940 char *s; 941 if (DohCheck(so)) s = Char(so); 942 else s = (char *) so; 943 str = (String *) DohMalloc(sizeof(String)); 944 str->hashkey = -1; 945 str->sp = 0; 946 str->line = 1; 947 str->file = 0; 948 max = INIT_MAXSIZE; 949 if (s) { 950 l = (int) strlen(s); 951 if ((l+1) > max) max = l+1; 952 } 953 str->str = (char *) DohMalloc(max); 954 str->maxsize = max; 955 if (s) { 956 strcpy(str->str,s); 957 str->len = l; 958 str->sp = l; 959 } else { 960 str->str[0] = 0; 961 str->len = 0; 962 } 963 return DohObjMalloc(&DohStringType,str); 964} 965 966 967/* ----------------------------------------------------------------------------- 968 * NewStringWithSize(const char *c, int len) - Create a new string 969 * ----------------------------------------------------------------------------- */ 970 971DOHString * 972DohNewStringWithSize(const DOH *so, int len) 973{ 974 int l = 0, max; 975 String *str; 976 char *s; 977 if (DohCheck(so)) s = Char(so); 978 else s = (char *) so; 979 str = (String *) DohMalloc(sizeof(String)); 980 str->hashkey = -1; 981 str->sp = 0; 982 str->line = 1; 983 str->file = 0; 984 max = INIT_MAXSIZE; 985 if (s) { 986 l = (int) len; 987 if ((l+1) > max) max = l+1; 988 } 989 str->str = (char *) DohMalloc(max); 990 str->maxsize = max; 991 if (s) { 992 strncpy(str->str,s,len); 993 str->len = l; 994 str->sp = l; 995 } else { 996 str->str[0] = 0; 997 str->len = 0; 998 } 999 return DohObjMalloc(&DohStringType,str); 1000} 1001 1002/* ----------------------------------------------------------------------------- 1003 * NewStringf(DOH *fmt, ...) 1004 * 1005 * Create a new string from a list of objects. 1006 * ----------------------------------------------------------------------------- */ 1007 1008DOHString * 1009DohNewStringf(const DOH *fmt, ...) 1010{ 1011 va_list ap; 1012 DOH *r; 1013 va_start(ap,fmt); 1014 r = NewString(""); 1015 DohvPrintf(r,Char(fmt),ap); 1016 va_end(ap); 1017 return (DOHString *) r; 1018} 1019 1020/* ----------------------------------------------------------------------------- 1021 * Strcmp() 1022 * Strncmp() 1023 * Strstr() 1024 * Strchr() 1025 * 1026 * Some utility functions. 1027 * ----------------------------------------------------------------------------- */ 1028 1029int DohStrcmp(const DOHString_or_char *s1, const DOHString_or_char *s2) { 1030 return strcmp(Char(s1),Char(s2)); 1031} 1032 1033int DohStrncmp(const DOHString_or_char *s1, const DOHString_or_char *s2, int n) { 1034 return strncmp(Char(s1),Char(s2),n); 1035} 1036 1037char *DohStrstr(const DOHString_or_char *s1, const DOHString_or_char *s2) { 1038 char* p1 = Char(s1); 1039 char* p2 = Char(s2); 1040 return p1 == 0 || p2 == 0 || *p2 == '\0' ? p1 : strstr(p1,p2); 1041} 1042 1043char *DohStrchr(const DOHString_or_char *s1, int ch) { 1044 return strchr(Char(s1),ch); 1045}