PageRenderTime 54ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

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