/tags/rel-1-3-premerge/SWIG/Source/DOH/Doh/string.c

# · C · 911 lines · 702 code · 100 blank · 109 comment · 173 complexity · 5386643fbdbe25e2861f644e15db2850 MD5 · raw file

  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. char cvsroot_string_c[] = "$Header$";
  13. #include "dohint.h"
  14. extern DohObjInfo DohStringType;
  15. typedef struct String {
  16. DOH *file;
  17. int line;
  18. int maxsize; /* Max size allocated */
  19. int len; /* Current length */
  20. int hashkey; /* Hash key value */
  21. int sp; /* Current position */
  22. char *str; /* String data */
  23. } String;
  24. /* -----------------------------------------------------------------------------
  25. * void *String_data() - Return as a 'void *'
  26. * ----------------------------------------------------------------------------- */
  27. static void *
  28. String_data(DOH *so) {
  29. String *s = (String *) ObjData(so);
  30. s->str[s->len] = 0;
  31. return (void *) s->str;
  32. }
  33. /* -----------------------------------------------------------------------------
  34. * int String_dump() - Serialize a string onto out
  35. * ----------------------------------------------------------------------------- */
  36. static int
  37. String_dump(DOH *so, DOH *out) {
  38. int nsent;
  39. int ret;
  40. String *s = (String *) ObjData(so);
  41. nsent = 0;
  42. while (nsent < s->len) {
  43. ret = Write(out,s->str+nsent,(s->len-nsent));
  44. if (ret < 0) return ret;
  45. nsent += ret;
  46. }
  47. return nsent;
  48. }
  49. /* -----------------------------------------------------------------------------
  50. * CopyString() - Copy a string
  51. * ----------------------------------------------------------------------------- */
  52. static DOH *
  53. CopyString(DOH *so) {
  54. int max;
  55. String *str;
  56. String *s = (String *) ObjData(so);
  57. str = (String *) DohMalloc(sizeof(String));
  58. str->hashkey = -1;
  59. str->sp = s->sp;
  60. str->line = s->line;
  61. str->file = s->file;
  62. if (str->file) Incref(str->file);
  63. max = s->maxsize;
  64. str->str = (char *) DohMalloc(max+1);
  65. memmove(str->str, s->str, max);
  66. str->maxsize= max;
  67. str->len = s->len;
  68. str->str[str->len] = 0;
  69. return DohObjMalloc(&DohStringType,str);
  70. }
  71. /* -----------------------------------------------------------------------------
  72. * DelString() - Delete a string
  73. * ----------------------------------------------------------------------------- */
  74. static void
  75. DelString(DOH *so) {
  76. String *s = (String *) ObjData(so);
  77. s->hashkey = -1;
  78. s->str = 0;
  79. DohFree(s->str);
  80. DohFree(s);
  81. }
  82. /* -----------------------------------------------------------------------------
  83. * String_len() - Length of a string
  84. * ----------------------------------------------------------------------------- */
  85. static int
  86. String_len(DOH *so) {
  87. String *s = (String *) ObjData(so);
  88. return s->len;
  89. }
  90. /* -----------------------------------------------------------------------------
  91. * int String_cmp() - Compare two strings
  92. * ----------------------------------------------------------------------------- */
  93. static int
  94. String_cmp(DOH *so1, DOH *so2)
  95. {
  96. String *s1, *s2;
  97. char *c1, *c2;
  98. int maxlen,i;
  99. s1 = (String *) ObjData(so1);
  100. s2 = (String *) ObjData(so2);
  101. maxlen = s1->len;
  102. if (s2->len < maxlen) maxlen = s2->len;
  103. c1 = s1->str;
  104. c2 = s2->str;
  105. for (i = 0; i < maxlen; i++,c1++,c2++) {
  106. if (*c1 != *c2) break;
  107. }
  108. if (i < maxlen) {
  109. if (*c1 < *c2) return -1;
  110. else return 1;
  111. }
  112. if (s1->len == s2->len) return 0;
  113. if (s1->len > s2->len) return 1;
  114. return -1;
  115. }
  116. /* -----------------------------------------------------------------------------
  117. * int String_hash() - Compute string hash value
  118. * ----------------------------------------------------------------------------- */
  119. static int
  120. String_hash(DOH *so) {
  121. String *s = (String *) ObjData(so);
  122. char *c;
  123. int i, h = 0, len;
  124. if (s->hashkey >= 0) return s->hashkey;
  125. c = s->str;
  126. len = s->len > 50 ? 50 : s->len;
  127. for (i = 0; i < len; i++) {
  128. h = (((h << 5) + *(c++)));
  129. }
  130. h = h & 0x7fffffff;
  131. s->hashkey = h;
  132. return h;
  133. }
  134. /* -----------------------------------------------------------------------------
  135. * static add(String *s, const char *newstr) - Append to s
  136. * ----------------------------------------------------------------------------- */
  137. static void
  138. add(String *s, const char *newstr) {
  139. int oldlen, newlen, newmaxsize, l, i, sp;
  140. char *tc;
  141. if (!newstr) return;
  142. s->hashkey = -1;
  143. l = (int) strlen(newstr);
  144. oldlen = s->len;
  145. newlen = oldlen+l + 1;
  146. if (newlen >= s->maxsize-1) {
  147. newmaxsize = 2*s->maxsize;
  148. if (newlen >= newmaxsize -1) newmaxsize = newlen + 1;
  149. s->str = (char *) DohRealloc(s->str,newmaxsize);
  150. assert(s->str);
  151. s->maxsize = newmaxsize;
  152. }
  153. tc = s->str;
  154. strcpy(tc+oldlen,newstr);
  155. sp = s->sp;
  156. if (sp >= oldlen) {
  157. tc += sp;
  158. for (i = sp; i < oldlen+l; i++,tc++) {
  159. if (*tc == '\n') s->line++;
  160. }
  161. s->sp = oldlen+l;
  162. }
  163. s->len += l;
  164. }
  165. /* -----------------------------------------------------------------------------
  166. * void String_clear() - Clear a string
  167. * ----------------------------------------------------------------------------- */
  168. static void
  169. String_clear(DOH *so)
  170. {
  171. String *s = (String *) ObjData(so);
  172. s->hashkey = -1;
  173. s->len = 0;
  174. *(s->str) = 0;
  175. s->sp = 0;
  176. s->line = 1;
  177. }
  178. /* -----------------------------------------------------------------------------
  179. * void String_insert() - Insert a string
  180. * ----------------------------------------------------------------------------- */
  181. static int
  182. String_insert(DOH *so, int pos, DOH *str)
  183. {
  184. String *s = (String *) ObjData(so);
  185. char *nstr;
  186. int len;
  187. char *data;
  188. data = (char *) DohData(str);
  189. nstr = s->str;
  190. s->hashkey = -1;
  191. if (pos == DOH_END) {
  192. add(s, data);
  193. return 0;
  194. }
  195. if (pos < 0) pos = 0;
  196. else if (pos > s->len) pos = s->len;
  197. /* See if there is room to insert the new data */
  198. len = Len(str);
  199. while (s->maxsize <= s->len+len) {
  200. s->str = (char *) DohRealloc(s->str,2*s->maxsize);
  201. assert(s->str);
  202. s->maxsize *= 2;
  203. }
  204. memmove(s->str+pos+len, s->str+pos, (s->len - pos));
  205. memcpy(s->str+pos,data,len);
  206. if (s->sp >= pos) {
  207. int i;
  208. for (i = 0; i < len; i++) {
  209. if (data[i] == '\n') s->line++;
  210. }
  211. s->sp+=len;
  212. }
  213. s->len += len;
  214. s->str[s->len] = 0;
  215. return 0;
  216. }
  217. /* -----------------------------------------------------------------------------
  218. * int String_delitem() - Delete a character
  219. * ----------------------------------------------------------------------------- */
  220. static int
  221. String_delitem(DOH *so, int pos)
  222. {
  223. String *s = (String *) ObjData(so);
  224. s->hashkey = -1;
  225. if (pos == DOH_END) pos = s->len-1;
  226. if (pos == DOH_BEGIN) pos = 0;
  227. if (s->len == 0) return 0;
  228. if (s->sp > pos) {
  229. s->sp--;
  230. assert (s->sp >= 0);
  231. if (s->str[pos] == '\n') s->line--;
  232. }
  233. memmove(s->str+pos, s->str+pos+1, ((s->len-1) - pos));
  234. s->len--;
  235. s->str[s->len] = 0;
  236. return 0;
  237. }
  238. /* -----------------------------------------------------------------------------
  239. * DOH *String_str() - Returns a string (used by printing commands)
  240. * ----------------------------------------------------------------------------- */
  241. static DOH *
  242. String_str(DOH *so)
  243. {
  244. String *s = (String *) ObjData(so);
  245. s->str[s->len] = 0;
  246. return NewString(s->str);
  247. }
  248. /* -----------------------------------------------------------------------------
  249. * int String_read() - Read data from a string
  250. * ----------------------------------------------------------------------------- */
  251. static int
  252. String_read(DOH *so, void *buffer, int len)
  253. {
  254. int reallen, retlen;
  255. char *cb;
  256. String *s = (String *) ObjData(so);
  257. if ((s->sp + len) > s->len) reallen = (s->len - s->sp);
  258. else reallen = len;
  259. cb = (char *) buffer;
  260. retlen = reallen;
  261. if (reallen > 0) {
  262. memmove(cb, s->str+s->sp, reallen);
  263. s->sp += reallen;
  264. }
  265. return retlen;
  266. }
  267. /* -----------------------------------------------------------------------------
  268. * int String_write() - Write data to a string
  269. * ----------------------------------------------------------------------------- */
  270. static int
  271. String_write(DOH *so, void *buffer, int len)
  272. {
  273. int newlen;
  274. String *s = (String *) ObjData(so);
  275. s->hashkey = -1;
  276. if (s->sp > s->len) s->sp = s->len;
  277. newlen = s->sp + len+1;
  278. if (newlen > s->maxsize) {
  279. s->str = (char *) DohRealloc(s->str,newlen);
  280. assert(s->str);
  281. s->maxsize = newlen;
  282. s->len = s->sp + len;
  283. }
  284. if ((s->sp+len) > s->len) s->len = s->sp + len;
  285. memmove(s->str+s->sp,buffer,len);
  286. s->sp += len;
  287. s->str[s->len] = 0;
  288. return len;
  289. }
  290. /* -----------------------------------------------------------------------------
  291. * int String_seek() - Seek to a new position
  292. * ----------------------------------------------------------------------------- */
  293. static int
  294. String_seek(DOH *so, long offset, int whence)
  295. {
  296. int pos, nsp, inc;
  297. int prev;
  298. String *s = (String *) ObjData(so);
  299. if (whence == SEEK_SET) pos = 0;
  300. else if (whence == SEEK_CUR) pos = s->sp;
  301. else if (whence == SEEK_END) {
  302. pos = s->len;
  303. offset = -offset;
  304. }
  305. else pos = s->sp;
  306. nsp = pos + offset;
  307. if (nsp < 0)
  308. nsp = 0;
  309. if (s->len > 0 && nsp >= s->len)
  310. nsp = s->len-1;
  311. inc = (nsp > s->sp) ? 1 : -1;
  312. {
  313. register int sp = s->sp;
  314. register char *tc = s->str;
  315. register int len = s->len;
  316. while (sp != nsp) {
  317. prev = sp + inc;
  318. if (prev>=0 && prev<=len && tc[prev] == '\n')
  319. s->line += inc;
  320. sp+=inc;
  321. }
  322. s->sp = sp;
  323. }
  324. assert (s->sp >= 0);
  325. return 0;
  326. }
  327. /* -----------------------------------------------------------------------------
  328. * long String_tell() - Return current position
  329. * ----------------------------------------------------------------------------- */
  330. static long
  331. String_tell(DOH *so)
  332. {
  333. String *s = (String *) ObjData(so);
  334. return (long) (s->sp);
  335. }
  336. /* -----------------------------------------------------------------------------
  337. * int String_putc()
  338. * ----------------------------------------------------------------------------- */
  339. static int
  340. String_putc(DOH *so, int ch)
  341. {
  342. register int len, maxsize, sp;
  343. String *s = (String *) ObjData(so);
  344. s->hashkey = -1;
  345. len = s->len;
  346. sp = s->sp;
  347. if (sp >= len) {
  348. register char *tc;
  349. maxsize = s->maxsize;
  350. if (len > (maxsize-2)) {
  351. s->str = (char *) DohRealloc(s->str,2*maxsize);
  352. assert(s->str);
  353. s->maxsize = 2*maxsize;
  354. }
  355. tc = s->str + len;
  356. *(tc++) = ch;
  357. if (sp >= len) {
  358. s->sp = len+1;
  359. *tc = 0;
  360. if (ch == '\n') s->line++;
  361. }
  362. s->len = len+1;
  363. } else {
  364. s->str[s->sp++] = (char) ch;
  365. if (ch == '\n') s->line++;
  366. }
  367. return ch;
  368. }
  369. /* -----------------------------------------------------------------------------
  370. * int String_getc()
  371. * ----------------------------------------------------------------------------- */
  372. static int
  373. String_getc(DOH *so)
  374. {
  375. int c;
  376. String *s = (String *) ObjData(so);
  377. if (s->sp >= s->len)
  378. c = EOF;
  379. else
  380. c = (int) s->str[s->sp++];
  381. if (c == '\n') s->line++;
  382. return c;
  383. }
  384. /* -----------------------------------------------------------------------------
  385. * int String_ungetc()
  386. * ----------------------------------------------------------------------------- */
  387. static int
  388. String_ungetc(DOH *so, int ch)
  389. {
  390. String *s = (String *) ObjData(so);
  391. if (ch == EOF) return ch;
  392. if (s->sp <= 0) return EOF;
  393. s->sp--;
  394. if (ch == '\n') s->line--;
  395. return ch;
  396. }
  397. /* -----------------------------------------------------------------------------
  398. * replace_simple(String *str, char *token, char *rep, int flags, int count)
  399. *
  400. * Replaces count non-overlapping occurrences of token with rep in a string.
  401. * ----------------------------------------------------------------------------- */
  402. static char *
  403. end_quote(char *s)
  404. {
  405. char qc;
  406. char *q;
  407. qc = *s;
  408. while (1) {
  409. q = strpbrk(s+1,"\"\'");
  410. if (!q) return 0;
  411. if ((*q == qc) && (*(q-1) != '\\')) return q;
  412. s = q;
  413. }
  414. }
  415. static char *
  416. match_simple(char *base, char *s, char *token, int tokenlen)
  417. {
  418. return strstr(s,token);
  419. }
  420. static char *
  421. match_identifier(char *base, char *s, char *token, int tokenlen)
  422. {
  423. while (s) {
  424. s = strstr(s,token);
  425. if (!s) return 0;
  426. if ((s > base) && (isalnum(*(s-1)) || (*(s-1) == '_'))) {
  427. s += tokenlen;
  428. continue;
  429. }
  430. if (isalnum(*(s+tokenlen)) || (*(s+tokenlen) == '_')) {
  431. s += tokenlen;
  432. continue;
  433. }
  434. return s;
  435. }
  436. return 0;
  437. }
  438. static int
  439. replace_simple(String *str, char *token, char *rep, int flags, int count, char *(*match)(char *, char *, char *, int))
  440. {
  441. int tokenlen; /* Length of the token */
  442. int replen; /* Length of the replacement */
  443. int delta, expand = 0;
  444. int ic;
  445. int rcount = 0;
  446. int noquote = 0;
  447. char *c, *s, *t, *first;
  448. char *q, *q2;
  449. register char *base;
  450. int i;
  451. str->hashkey = -1;
  452. /* Figure out if anything gets replaced */
  453. if (!strlen(token)) return 0;
  454. base = str->str;
  455. tokenlen = strlen(token);
  456. s = (*match)(base,base,token,tokenlen);
  457. if (!s) return 0; /* No matches. Who cares */
  458. if (flags & DOH_REPLACE_NOQUOTE) noquote = 1;
  459. /* If we are not replacing inside quotes, we need to do a little extra work */
  460. if (noquote) {
  461. q = strpbrk(base,"\"\'");
  462. if (!q) {
  463. noquote = 0; /* Well, no quotes to worry about. Oh well */
  464. } else {
  465. while (q && (q < s)) {
  466. /* First match was found inside a quote. Try to find another match */
  467. q2 = end_quote(q);
  468. if (!q2) {
  469. return 0;
  470. }
  471. if (q2 > s)
  472. s = (*match)(base,q2+1,token,tokenlen);
  473. if (!s) return 0; /* Oh well, no matches */
  474. q = strpbrk(q2+1,"\"\'");
  475. if (!q) noquote = 0; /* No more quotes */
  476. }
  477. }
  478. }
  479. first = s;
  480. replen = strlen(rep);
  481. delta = (replen - tokenlen);
  482. if (delta <= 0) {
  483. /* String is either shrinking or staying the same size */
  484. /* In this case, we do the replacement in place without memory reallocation */
  485. ic = count;
  486. t = s; /* Target of memory copies */
  487. while (ic && s) {
  488. if (replen) {
  489. memcpy(t,rep,replen);
  490. t += replen;
  491. }
  492. rcount++;
  493. expand += delta;
  494. /* Find the next location */
  495. s += tokenlen;
  496. if (ic == 1) break;
  497. c = (*match)(base,s,token,tokenlen);
  498. if (noquote) {
  499. q = strpbrk(s,"\"\'");
  500. if (!q) {
  501. noquote = 0;
  502. } else {
  503. while (q && (q < c)) {
  504. /* First match was found inside a quote. Try to find another match */
  505. q2 = end_quote(q);
  506. if (!q2) {
  507. c = 0;
  508. break;
  509. }
  510. if (q2 > c)
  511. c = (*match)(base,q2+1,token,tokenlen);
  512. if (!c) break;
  513. q = strpbrk(q2+1,"\"\'");
  514. if (!q) noquote = 0; /* No more quotes */
  515. }
  516. }
  517. }
  518. if (delta) {
  519. if (c) {
  520. memmove(t,s,c-s);
  521. t += (c-s);
  522. } else {
  523. memmove(t,s,(str->str + str->len) - s + 1);
  524. }
  525. } else {
  526. t += (c-s);
  527. }
  528. s = c;
  529. ic--;
  530. }
  531. if (s && delta) {
  532. memmove(t,s,(str->str + str->len) - s + 1);
  533. }
  534. str->len += expand;
  535. str->str[str->len] = 0;
  536. if (str->sp >= str->len) str->sp += expand; /* Fix the end of file pointer */
  537. return rcount;
  538. }
  539. /* The string is expanding as a result of the replacement */
  540. /* Figure out how much expansion is going to occur and allocate a new string */
  541. {
  542. char *ns;
  543. int newsize;
  544. rcount++;
  545. ic = count -1;
  546. s += tokenlen;
  547. while (ic && (c = (*match)(base,s,token,tokenlen))) {
  548. if (noquote) {
  549. q = strpbrk(s,"\"\'");
  550. if (!q) {
  551. break;
  552. } else {
  553. while (q && (q < c)) {
  554. /* First match was found inside a quote. Try to find another match */
  555. q2 = end_quote(q);
  556. if (!q2) {
  557. c = 0;
  558. break;
  559. }
  560. if (q2 > c)
  561. c = (*match)(base,q2+1,token,tokenlen);
  562. if (!c) break;
  563. q = strpbrk(q2+1,"\"\'");
  564. }
  565. }
  566. }
  567. if (c) {
  568. rcount++;
  569. ic--;
  570. s = c + tokenlen;
  571. } else {
  572. break;
  573. }
  574. }
  575. expand = delta*rcount; /* Total amount of expansion for the replacement */
  576. newsize = str->maxsize;
  577. while ((str->len + expand) >= newsize) newsize *= 2;
  578. ns = (char *) DohMalloc(newsize);
  579. assert(ns);
  580. t = ns;
  581. s = first;
  582. /* Copy the first part of the string */
  583. if (first > str->str) {
  584. memcpy(t,str->str,(first - str->str));
  585. t += (first-str->str);
  586. }
  587. for (i = 0; i < rcount; i++) {
  588. memcpy(t,rep,replen);
  589. t += replen;
  590. s += tokenlen;
  591. c = (*match)(base,s,token,tokenlen);
  592. if (noquote) {
  593. q = strpbrk(s,"\"\'");
  594. if (!q) {
  595. noquote = 0;
  596. } else {
  597. while (q && (q < c)) {
  598. /* First match was found inside a quote. Try to find another match */
  599. q2 = end_quote(q);
  600. if (!q2) {
  601. c = 0;
  602. break;
  603. }
  604. if (q2 > c)
  605. c = (*match)(base,q2+1,token,tokenlen);
  606. if (!c) break;
  607. q = strpbrk(q2+1,"\"\'");
  608. if (!q) noquote = 0; /* No more quotes */
  609. }
  610. }
  611. }
  612. if (i < (rcount - 1)) {
  613. memcpy(t,s,c-s);
  614. t += (c-s);
  615. } else {
  616. memcpy(t,s,(str->str + str->len) - s + 1);
  617. }
  618. s = c;
  619. }
  620. c = str->str;
  621. str->str = ns;
  622. if (str->sp >= str->len) str->sp += expand;
  623. str->len += expand;
  624. str->str[str->len] = 0;
  625. str->maxsize = newsize;
  626. DohFree(c);
  627. return rcount;
  628. }
  629. }
  630. /* -----------------------------------------------------------------------------
  631. * int String_replace()
  632. * ----------------------------------------------------------------------------- */
  633. static int
  634. String_replace(DOH *stro, DOH *token, DOH *rep, int flags)
  635. {
  636. int count = -1;
  637. String *str = (String *) ObjData(stro);
  638. if (flags & DOH_REPLACE_FIRST) count = 1;
  639. if (flags & DOH_REPLACE_ID) {
  640. return replace_simple(str,Char(token),Char(rep),flags, count, match_identifier);
  641. } else {
  642. return replace_simple(str,Char(token), Char(rep), flags, count, match_simple);
  643. }
  644. }
  645. /* -----------------------------------------------------------------------------
  646. * void String_chop(DOH *str)
  647. * ----------------------------------------------------------------------------- */
  648. static void
  649. String_chop(DOH *so)
  650. {
  651. char *c;
  652. String *str = (String *) ObjData(so);
  653. /* Replace trailing whitespace */
  654. c = str->str + str->len - 1;
  655. while ((str->len > 0) && (isspace(*c))) {
  656. if (str->sp >= str->len) {
  657. str->sp--;
  658. if (*c == '\n') str->line--;
  659. }
  660. str->len--;
  661. c--;
  662. }
  663. str->str[str->len] = 0;
  664. assert (str->sp >= 0);
  665. str->hashkey = -1;
  666. }
  667. static void
  668. String_setfile(DOH *so, DOH *file)
  669. {
  670. DOH *fo;
  671. String *str = (String *) ObjData(so);
  672. if (!DohCheck(file)) {
  673. fo = NewString(file);
  674. Decref(fo);
  675. } else fo = file;
  676. Incref(fo);
  677. Delete(str->file);
  678. str->file = fo;
  679. }
  680. static DOH *
  681. String_getfile(DOH *so)
  682. {
  683. String *str = (String *) ObjData(so);
  684. return str->file;
  685. }
  686. static void
  687. String_setline(DOH *so, int line)
  688. {
  689. String *str = (String *) ObjData(so);
  690. str->line = line;
  691. }
  692. static int
  693. String_getline(DOH *so)
  694. {
  695. String *str = (String *) ObjData(so);
  696. return str->line;
  697. }
  698. static DohListMethods StringListMethods = {
  699. 0, /* doh_getitem */
  700. 0, /* doh_setitem */
  701. String_delitem, /* doh_delitem */
  702. String_insert, /* doh_insitem */
  703. 0, /* doh_first */
  704. 0, /* doh_next */
  705. };
  706. static DohFileMethods StringFileMethods = {
  707. String_read,
  708. String_write,
  709. String_putc,
  710. String_getc,
  711. String_ungetc,
  712. String_seek,
  713. String_tell,
  714. 0, /* close */
  715. };
  716. static DohStringMethods StringStringMethods = {
  717. String_replace,
  718. String_chop,
  719. };
  720. DohObjInfo DohStringType = {
  721. "String", /* objname */
  722. DelString, /* doh_del */
  723. CopyString, /* doh_copy */
  724. String_clear, /* doh_clear */
  725. String_str, /* doh_str */
  726. String_data, /* doh_data */
  727. String_dump, /* doh_dump */
  728. String_len, /* doh_len */
  729. String_hash, /* doh_hash */
  730. String_cmp, /* doh_cmp */
  731. String_setfile, /* doh_setfile */
  732. String_getfile, /* doh_getfile */
  733. String_setline, /* doh_setline */
  734. String_getline, /* doh_getline */
  735. 0, /* doh_mapping */
  736. &StringListMethods, /* doh_sequence */
  737. &StringFileMethods, /* doh_file */
  738. &StringStringMethods, /* doh_string */
  739. 0, /* doh_position */
  740. 0,
  741. };
  742. #define INIT_MAXSIZE 16
  743. /* -----------------------------------------------------------------------------
  744. * NewString(const char *c) - Create a new string
  745. * ----------------------------------------------------------------------------- */
  746. DOHString *
  747. DohNewString(const DOH *so)
  748. {
  749. int l = 0, max;
  750. String *str;
  751. char *s;
  752. if (DohCheck(so)) s = Char(so);
  753. else s = (char *) so;
  754. str = (String *) DohMalloc(sizeof(String));
  755. str->hashkey = -1;
  756. str->sp = 0;
  757. str->line = 1;
  758. str->file = 0;
  759. max = INIT_MAXSIZE;
  760. if (s) {
  761. l = (int) strlen(s);
  762. if ((l+1) > max) max = l+1;
  763. }
  764. str->str = (char *) DohMalloc(max);
  765. str->maxsize = max;
  766. if (s) {
  767. strcpy(str->str,s);
  768. str->len = l;
  769. str->sp = l;
  770. } else {
  771. str->str[0] = 0;
  772. str->len = 0;
  773. }
  774. return DohObjMalloc(&DohStringType,str);
  775. }
  776. /* -----------------------------------------------------------------------------
  777. * NewStringf(DOH *fmt, ...)
  778. *
  779. * Create a new string from a list of objects.
  780. * ----------------------------------------------------------------------------- */
  781. DOHString *
  782. DohNewStringf(const DOH *fmt, ...)
  783. {
  784. va_list ap;
  785. DOH *r;
  786. va_start(ap,fmt);
  787. r = NewString("");
  788. DohvPrintf(r,Char(fmt),ap);
  789. va_end(ap);
  790. return (DOHString *) r;
  791. }
  792. /* -----------------------------------------------------------------------------
  793. * Strcmp()
  794. * Strncmp()
  795. * Strstr()
  796. * Strchr()
  797. *
  798. * Some utility functions.
  799. * ----------------------------------------------------------------------------- */
  800. int DohStrcmp(const DOHString_or_char *s1, const DOHString_or_char *s2) {
  801. return strcmp(Char(s1),Char(s2));
  802. }
  803. int DohStrncmp(const DOHString_or_char *s1, const DOHString_or_char *s2, int n) {
  804. return strncmp(Char(s1),Char(s2),n);
  805. }
  806. char *DohStrstr(const DOHString_or_char *s1, const DOHString_or_char *s2) {
  807. return strstr(Char(s1),Char(s2));
  808. }
  809. char *DohStrchr(const DOHString_or_char *s1, int ch) {
  810. return strchr(Char(s1),ch);
  811. }