PageRenderTime 49ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/rel-1-3-30rc1-afterbeautify/SWIG/Source/Swig/misc.c

#
C | 998 lines | 963 code | 11 blank | 24 comment | 14 complexity | cd4e957bc2663182b7a783a5472c9ec6 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  1. /* -----------------------------------------------------------------------------
  2. * See the LICENSE file for information on copyright, usage and redistribution
  3. * of SWIG, and the README file for authors - http://www.swig.org/release.html.
  4. *
  5. * misc.c
  6. *
  7. * Miscellaneous functions that don't really fit anywhere else.
  8. * ----------------------------------------------------------------------------- */
  9. char cvsroot_misc_c[] = "$Header$";
  10. #include "swig.h"
  11. #include "swigkeys.h"
  12. #include <errno.h>
  13. #include <ctype.h>
  14. #include <limits.h>
  15. /* -----------------------------------------------------------------------------
  16. * Swig_copy_string()
  17. *
  18. * Duplicate a NULL-terminate string given as a char *.
  19. * ----------------------------------------------------------------------------- */
  20. char *Swig_copy_string(const char *s) {
  21. char *c = 0;
  22. if (s) {
  23. c = (char *) malloc(strlen(s) + 1);
  24. strcpy(c, s);
  25. }
  26. return c;
  27. }
  28. /* -----------------------------------------------------------------------------
  29. * Swig_banner()
  30. *
  31. * Emits the SWIG identifying banner.
  32. * ----------------------------------------------------------------------------- */
  33. void Swig_banner(File *f) {
  34. Printf(f, "/* ----------------------------------------------------------------------------\n\
  35. * This file was automatically generated by SWIG (http://www.swig.org).\n\
  36. * Version %s\n\
  37. * \n\
  38. * This file is not intended to be easily readable and contains a number of \n\
  39. * coding conventions designed to improve portability and efficiency. Do not make\n\
  40. * changes to this file unless you know what you are doing--modify the SWIG \n\
  41. * interface file instead. \n", PACKAGE_VERSION);
  42. /* String too long for ISO compliance */
  43. Printf(f, " * ----------------------------------------------------------------------------- */\n\n");
  44. }
  45. /* -----------------------------------------------------------------------------
  46. * Swig_string_escape()
  47. *
  48. * Takes a string object and produces a string with escape codes added to it.
  49. * ----------------------------------------------------------------------------- */
  50. String *Swig_string_escape(String *s) {
  51. String *ns;
  52. int c;
  53. ns = NewStringEmpty();
  54. while ((c = Getc(s)) != EOF) {
  55. if (c == '\n') {
  56. Printf(ns, "\\n");
  57. } else if (c == '\r') {
  58. Printf(ns, "\\r");
  59. } else if (c == '\t') {
  60. Printf(ns, "\\t");
  61. } else if (c == '\\') {
  62. Printf(ns, "\\\\");
  63. } else if (c == '\'') {
  64. Printf(ns, "\\'");
  65. } else if (c == '\"') {
  66. Printf(ns, "\\\"");
  67. } else if (c == ' ') {
  68. Putc(c, ns);
  69. } else if (!isgraph(c)) {
  70. if (c < 0)
  71. c += UCHAR_MAX + 1;
  72. Printf(ns, "\\%o", c);
  73. } else {
  74. Putc(c, ns);
  75. }
  76. }
  77. return ns;
  78. }
  79. /* -----------------------------------------------------------------------------
  80. * Swig_string_upper()
  81. *
  82. * Takes a string object and returns a copy that is uppercase
  83. * ----------------------------------------------------------------------------- */
  84. String *Swig_string_upper(String *s) {
  85. String *ns;
  86. int c;
  87. ns = NewStringEmpty();
  88. Seek(s, 0, SEEK_SET);
  89. while ((c = Getc(s)) != EOF) {
  90. Putc(toupper(c), ns);
  91. }
  92. return ns;
  93. }
  94. /* -----------------------------------------------------------------------------
  95. * Swig_string_lower()
  96. *
  97. * Takes a string object and returns a copy that is lowercase
  98. * ----------------------------------------------------------------------------- */
  99. String *Swig_string_lower(String *s) {
  100. String *ns;
  101. int c;
  102. ns = NewStringEmpty();
  103. Seek(s, 0, SEEK_SET);
  104. while ((c = Getc(s)) != EOF) {
  105. Putc(tolower(c), ns);
  106. }
  107. return ns;
  108. }
  109. /* -----------------------------------------------------------------------------
  110. * Swig_string_title()
  111. *
  112. * Takes a string object and returns a copy that is lowercase with first letter
  113. * capitalized
  114. * ----------------------------------------------------------------------------- */
  115. String *Swig_string_title(String *s) {
  116. String *ns;
  117. int first = 1;
  118. int c;
  119. ns = NewStringEmpty();
  120. Seek(s, 0, SEEK_SET);
  121. while ((c = Getc(s)) != EOF) {
  122. Putc(first ? toupper(c) : tolower(c), ns);
  123. first = 0;
  124. }
  125. return ns;
  126. }
  127. /* -----------------------------------------------------------------------------
  128. * Swig_string_ccase()
  129. *
  130. * Takes a string object and returns a copy that is lowercase with the first
  131. * letter capitalized and the one following '_', which are removed.
  132. *
  133. * camel_case -> CamelCase
  134. * camelCase -> CamelCase
  135. * ----------------------------------------------------------------------------- */
  136. String *Swig_string_ccase(String *s) {
  137. String *ns;
  138. int first = 1;
  139. int c;
  140. ns = NewStringEmpty();
  141. Seek(s, 0, SEEK_SET);
  142. while ((c = Getc(s)) != EOF) {
  143. if (c == '_') {
  144. first = 1;
  145. continue;
  146. }
  147. Putc(first ? toupper(c) : c, ns);
  148. first = 0;
  149. }
  150. return ns;
  151. }
  152. /* -----------------------------------------------------------------------------
  153. * Swig_string_lccase()
  154. *
  155. * Takes a string object and returns a copy with the character after
  156. * each '_' capitalised, and the '_' removed. The first character is
  157. * also forced to lowercase.
  158. *
  159. * camel_case -> camelCase
  160. * CamelCase -> camelCase
  161. * ----------------------------------------------------------------------------- */
  162. String *Swig_string_lccase(String *s) {
  163. String *ns;
  164. int first = 1;
  165. int after_underscore = 0;
  166. int c;
  167. ns = NewStringEmpty();
  168. Seek(s, 0, SEEK_SET);
  169. while ((c = Getc(s)) != EOF) {
  170. if (c == '_') {
  171. after_underscore = 1;
  172. continue;
  173. }
  174. if (first) {
  175. Putc(tolower(c), ns);
  176. first = 0;
  177. } else {
  178. Putc(after_underscore ? toupper(c) : c, ns);
  179. }
  180. after_underscore = 0;
  181. }
  182. return ns;
  183. }
  184. /* -----------------------------------------------------------------------------
  185. * Swig_string_ucase()
  186. *
  187. * This is the reverse case of ccase, ie
  188. *
  189. * CamelCase -> camel_case
  190. * ----------------------------------------------------------------------------- */
  191. String *Swig_string_ucase(String *s) {
  192. String *ns;
  193. int c;
  194. int lastC = 0;
  195. int underscore = 0;
  196. ns = NewStringEmpty();
  197. /* We insert a underscore when:
  198. 1. Lower case char followed by upper case char
  199. getFoo > get_foo; getFOo > get_foo; GETFOO > getfoo
  200. 2. Number proceded by char
  201. get2D > get_2d; get22D > get_22d; GET2D > get_2d */
  202. Seek(s, 0, SEEK_SET);
  203. while ((c = Getc(s)) != EOF) {
  204. if (isdigit(c) && isalpha(lastC))
  205. underscore = 1;
  206. else if (isupper(c) && isalpha(lastC) && !isupper(lastC))
  207. underscore = 1;
  208. lastC = c;
  209. if (underscore) {
  210. Putc('_', ns);
  211. underscore = 0;
  212. }
  213. Putc(tolower(c), ns);
  214. }
  215. return ns;
  216. }
  217. /* -----------------------------------------------------------------------------
  218. * Swig_string_first_upper()
  219. *
  220. * Make the first character in the string uppercase, leave all the
  221. * rest the same. This is used by the Ruby module to provide backwards
  222. * compatibility with the old way of naming classes and constants. For
  223. * more info see the Ruby documentation.
  224. *
  225. * firstUpper -> FirstUpper
  226. * ----------------------------------------------------------------------------- */
  227. String *Swig_string_first_upper(String *s) {
  228. String *ns = NewStringEmpty();
  229. char *cs = Char(s);
  230. if (cs && cs[0] != 0) {
  231. Putc(toupper(cs[0]), ns);
  232. Append(ns, cs + 1);
  233. }
  234. return ns;
  235. }
  236. /* -----------------------------------------------------------------------------
  237. * Swig_string_first_lower()
  238. *
  239. * Make the first character in the string lowercase, leave all the
  240. * rest the same. This is used by the Ruby module to provide backwards
  241. * compatibility with the old way of naming classes and constants. For
  242. * more info see the Ruby documentation.
  243. *
  244. * firstLower -> FirstLower
  245. * ----------------------------------------------------------------------------- */
  246. String *Swig_string_first_lower(String *s) {
  247. String *ns = NewStringEmpty();
  248. char *cs = Char(s);
  249. if (cs && cs[0] != 0) {
  250. Putc(tolower(cs[0]), ns);
  251. Append(ns, cs + 1);
  252. }
  253. return ns;
  254. }
  255. /* -----------------------------------------------------------------------------
  256. * Swig_string_schemify()
  257. *
  258. * Replace underscores with dashes, to make identifiers look nice to Schemers.
  259. *
  260. * under_scores -> under-scores
  261. * ----------------------------------------------------------------------------- */
  262. String *Swig_string_schemify(String *s) {
  263. String *ns = NewString(s);
  264. Replaceall(ns, "_", "-");
  265. return ns;
  266. }
  267. /* -----------------------------------------------------------------------------
  268. * Swig_string_typecode()
  269. *
  270. * Takes a string with possible type-escapes in it and replaces them with
  271. * real C datatypes.
  272. * ----------------------------------------------------------------------------- */
  273. String *Swig_string_typecode(String *s) {
  274. String *ns;
  275. int c;
  276. String *tc;
  277. ns = NewStringEmpty();
  278. while ((c = Getc(s)) != EOF) {
  279. if (c == '`') {
  280. String *str = 0;
  281. tc = NewStringEmpty();
  282. while ((c = Getc(s)) != EOF) {
  283. if (c == '`')
  284. break;
  285. Putc(c, tc);
  286. }
  287. str = SwigType_str(tc, 0);
  288. Append(ns, str);
  289. Delete(str);
  290. } else {
  291. Putc(c, ns);
  292. if (c == '\'') {
  293. while ((c = Getc(s)) != EOF) {
  294. Putc(c, ns);
  295. if (c == '\'')
  296. break;
  297. if (c == '\\') {
  298. c = Getc(s);
  299. Putc(c, ns);
  300. }
  301. }
  302. } else if (c == '\"') {
  303. while ((c = Getc(s)) != EOF) {
  304. Putc(c, ns);
  305. if (c == '\"')
  306. break;
  307. if (c == '\\') {
  308. c = Getc(s);
  309. Putc(c, ns);
  310. }
  311. }
  312. }
  313. }
  314. }
  315. return ns;
  316. }
  317. /* -----------------------------------------------------------------------------
  318. * Swig_string_mangle()
  319. *
  320. * Take a string and mangle it by stripping all non-valid C identifier
  321. * characters.
  322. *
  323. * This routine skips unnecessary blank spaces, therefore mangling
  324. * 'char *' and 'char*', 'std::pair<int, int >' and
  325. * 'std::pair<int,int>', produce the same result.
  326. *
  327. * However, note that 'long long' and 'long_long' produce different
  328. * mangled strings.
  329. *
  330. * The mangling method still is not 'perfect', for example std::pair and
  331. * std_pair return the same mangling. This is just a little better
  332. * than before, but it seems to be enough for most of the purposes.
  333. *
  334. * Having a perfect mangling will break some examples and code which
  335. * assume, for example, that A::get_value will be mangled as
  336. * A_get_value.
  337. * ----------------------------------------------------------------------------- */
  338. String *Swig_string_mangle(const String *s) {
  339. #if 0
  340. /* old mangling, not suitable for using in macros */
  341. String *t = Copy(s);
  342. char *c = Char(t);
  343. while (*c) {
  344. if (!isalnum(*c))
  345. *c = '_';
  346. c++;
  347. }
  348. return t;
  349. #else
  350. String *result = NewStringEmpty();
  351. int space = 0;
  352. int state = 0;
  353. char *pc, *cb;
  354. String *b = Copy(s);
  355. if (SwigType_istemplate(b)) {
  356. String *st = Swig_symbol_template_deftype(b, 0);
  357. String *sq = Swig_symbol_type_qualify(st, 0);
  358. String *t = SwigType_namestr(sq);
  359. Delete(st);
  360. Delete(sq);
  361. Delete(b);
  362. b = t;
  363. }
  364. pc = cb = StringChar(b);
  365. while (*pc) {
  366. char c = *pc;
  367. if (isalnum((int) c) || (c == '_')) {
  368. state = 1;
  369. if (space && (space == state)) {
  370. StringAppend(result, "_SS_");
  371. }
  372. space = 0;
  373. Printf(result, "%c", (int) c);
  374. } else {
  375. if (isspace((int) c)) {
  376. space = state;
  377. ++pc;
  378. continue;
  379. } else {
  380. state = 3;
  381. space = 0;
  382. }
  383. switch (c) {
  384. case '.':
  385. if ((cb != pc) && (*(pc - 1) == 'p')) {
  386. StringAppend(result, "_");
  387. ++pc;
  388. continue;
  389. } else {
  390. c = 'f';
  391. }
  392. break;
  393. case ':':
  394. if (*(pc + 1) == ':') {
  395. StringAppend(result, "_");
  396. ++pc;
  397. ++pc;
  398. continue;
  399. }
  400. break;
  401. case '*':
  402. c = 'm';
  403. break;
  404. case '&':
  405. c = 'A';
  406. break;
  407. case '<':
  408. c = 'l';
  409. break;
  410. case '>':
  411. c = 'g';
  412. break;
  413. case '=':
  414. c = 'e';
  415. break;
  416. case ',':
  417. c = 'c';
  418. break;
  419. case '(':
  420. c = 'p';
  421. break;
  422. case ')':
  423. c = 'P';
  424. break;
  425. case '[':
  426. c = 'b';
  427. break;
  428. case ']':
  429. c = 'B';
  430. break;
  431. case '^':
  432. c = 'x';
  433. break;
  434. case '|':
  435. c = 'o';
  436. break;
  437. case '~':
  438. c = 'n';
  439. break;
  440. case '!':
  441. c = 'N';
  442. break;
  443. case '%':
  444. c = 'M';
  445. break;
  446. case '?':
  447. c = 'q';
  448. break;
  449. case '+':
  450. c = 'a';
  451. break;
  452. case '-':
  453. c = 's';
  454. break;
  455. case '/':
  456. c = 'd';
  457. break;
  458. default:
  459. break;
  460. }
  461. if (isalpha((int) c)) {
  462. Printf(result, "_S%c_", (int) c);
  463. } else {
  464. Printf(result, "_S%02X_", (int) c);
  465. }
  466. }
  467. ++pc;
  468. }
  469. Delete(b);
  470. return result;
  471. #endif
  472. }
  473. String *Swig_string_emangle(String *s) {
  474. return Swig_string_mangle(s);
  475. }
  476. /* -----------------------------------------------------------------------------
  477. * Swig_scopename_prefix()
  478. *
  479. * Take a qualified name like "A::B::C" and return the scope name.
  480. * In this case, "A::B". Returns NULL if there is no base.
  481. * ----------------------------------------------------------------------------- */
  482. void Swig_scopename_split(String *s, String **rprefix, String **rlast) {
  483. char *tmp = Char(s);
  484. char *c = tmp;
  485. char *cc = c;
  486. char *co = 0;
  487. if (!strstr(c, "::")) {
  488. *rprefix = 0;
  489. *rlast = Copy(s);
  490. }
  491. if ((co = strstr(cc, "operator "))) {
  492. if (co == cc) {
  493. *rprefix = 0;
  494. *rlast = Copy(s);
  495. return;
  496. } else {
  497. *rprefix = NewStringWithSize(cc, co - cc - 2);
  498. *rlast = NewString(co);
  499. return;
  500. }
  501. }
  502. while (*c) {
  503. if ((*c == ':') && (*(c + 1) == ':')) {
  504. cc = c;
  505. c += 2;
  506. } else {
  507. if (*c == '<') {
  508. int level = 1;
  509. c++;
  510. while (*c && level) {
  511. if (*c == '<')
  512. level++;
  513. if (*c == '>')
  514. level--;
  515. c++;
  516. }
  517. } else {
  518. c++;
  519. }
  520. }
  521. }
  522. if (cc != tmp) {
  523. *rprefix = NewStringWithSize(tmp, cc - tmp);
  524. *rlast = NewString(cc + 2);
  525. return;
  526. } else {
  527. *rprefix = 0;
  528. *rlast = Copy(s);
  529. }
  530. }
  531. String *Swig_scopename_prefix(String *s) {
  532. char *tmp = Char(s);
  533. char *c = tmp;
  534. char *cc = c;
  535. char *co = 0;
  536. if (!strstr(c, "::"))
  537. return 0;
  538. if ((co = strstr(cc, "operator "))) {
  539. if (co == cc) {
  540. return 0;
  541. } else {
  542. String *prefix = NewStringWithSize(cc, co - cc - 2);
  543. return prefix;
  544. }
  545. }
  546. while (*c) {
  547. if ((*c == ':') && (*(c + 1) == ':')) {
  548. cc = c;
  549. c += 2;
  550. } else {
  551. if (*c == '<') {
  552. int level = 1;
  553. c++;
  554. while (*c && level) {
  555. if (*c == '<')
  556. level++;
  557. if (*c == '>')
  558. level--;
  559. c++;
  560. }
  561. } else {
  562. c++;
  563. }
  564. }
  565. }
  566. if (cc != tmp) {
  567. return NewStringWithSize(tmp, cc - tmp);
  568. } else {
  569. return 0;
  570. }
  571. }
  572. /* -----------------------------------------------------------------------------
  573. * Swig_scopename_last()
  574. *
  575. * Take a qualified name like "A::B::C" and returns the last. In this
  576. * case, "C".
  577. * ----------------------------------------------------------------------------- */
  578. String *Swig_scopename_last(String *s) {
  579. char *tmp = Char(s);
  580. char *c = tmp;
  581. char *cc = c;
  582. char *co = 0;
  583. if (!strstr(c, "::"))
  584. return NewString(s);
  585. if ((co = strstr(cc, "operator "))) {
  586. return NewString(co);
  587. }
  588. while (*c) {
  589. if ((*c == ':') && (*(c + 1) == ':')) {
  590. cc = c;
  591. c += 2;
  592. } else {
  593. if (*c == '<') {
  594. int level = 1;
  595. c++;
  596. while (*c && level) {
  597. if (*c == '<')
  598. level++;
  599. if (*c == '>')
  600. level--;
  601. c++;
  602. }
  603. } else {
  604. c++;
  605. }
  606. }
  607. }
  608. return NewString(cc + 2);
  609. }
  610. /* -----------------------------------------------------------------------------
  611. * Swig_scopename_first()
  612. *
  613. * Take a qualified name like "A::B::C" and returns the first scope name.
  614. * In this case, "A". Returns NULL if there is no base.
  615. * ----------------------------------------------------------------------------- */
  616. String *Swig_scopename_first(String *s) {
  617. char *tmp = Char(s);
  618. char *c = tmp;
  619. char *co = 0;
  620. if (!strstr(c, "::"))
  621. return 0;
  622. if ((co = strstr(c, "operator "))) {
  623. if (co == c) {
  624. return 0;
  625. }
  626. } else {
  627. co = c + Len(s);
  628. }
  629. while (*c && (c != co)) {
  630. if ((*c == ':') && (*(c + 1) == ':')) {
  631. break;
  632. } else {
  633. if (*c == '<') {
  634. int level = 1;
  635. c++;
  636. while (*c && level) {
  637. if (*c == '<')
  638. level++;
  639. if (*c == '>')
  640. level--;
  641. c++;
  642. }
  643. } else {
  644. c++;
  645. }
  646. }
  647. }
  648. if (*c && (c != tmp)) {
  649. return NewStringWithSize(tmp, c - tmp);
  650. } else {
  651. return 0;
  652. }
  653. }
  654. /* -----------------------------------------------------------------------------
  655. * Swig_scopename_suffix()
  656. *
  657. * Take a qualified name like "A::B::C" and returns the suffix.
  658. * In this case, "B::C". Returns NULL if there is no suffix.
  659. * ----------------------------------------------------------------------------- */
  660. String *Swig_scopename_suffix(String *s) {
  661. char *tmp = Char(s);
  662. char *c = tmp;
  663. char *co = 0;
  664. if (!strstr(c, "::"))
  665. return 0;
  666. if ((co = strstr(c, "operator "))) {
  667. if (co == c)
  668. return 0;
  669. }
  670. while (*c) {
  671. if ((*c == ':') && (*(c + 1) == ':')) {
  672. break;
  673. } else {
  674. if (*c == '<') {
  675. int level = 1;
  676. c++;
  677. while (*c && level) {
  678. if (*c == '<')
  679. level++;
  680. if (*c == '>')
  681. level--;
  682. c++;
  683. }
  684. } else {
  685. c++;
  686. }
  687. }
  688. }
  689. if (*c && (c != tmp)) {
  690. return NewString(c + 2);
  691. } else {
  692. return 0;
  693. }
  694. }
  695. /* -----------------------------------------------------------------------------
  696. * Swig_scopename_check()
  697. *
  698. * Checks to see if a name is qualified with a scope name
  699. * ----------------------------------------------------------------------------- */
  700. int Swig_scopename_check(String *s) {
  701. char *c = Char(s);
  702. char *co = 0;
  703. if ((co = strstr(c, "operator "))) {
  704. if (co == c)
  705. return 0;
  706. }
  707. if (!strstr(c, "::"))
  708. return 0;
  709. while (*c) {
  710. if ((*c == ':') && (*(c + 1) == ':')) {
  711. return 1;
  712. } else {
  713. if (*c == '<') {
  714. int level = 1;
  715. c++;
  716. while (*c && level) {
  717. if (*c == '<')
  718. level++;
  719. if (*c == '>')
  720. level--;
  721. c++;
  722. }
  723. } else {
  724. c++;
  725. }
  726. }
  727. }
  728. return 0;
  729. }
  730. /* -----------------------------------------------------------------------------
  731. * Swig_string_command()
  732. *
  733. * Executes a external command via popen with the string as a command
  734. * line parameter. For example:
  735. *
  736. * Printf(stderr,"%(command:sed 's/[a-z]/\U\\1/' <<<)s","hello") -> Hello
  737. * ----------------------------------------------------------------------------- */
  738. #if defined(HAVE_POPEN)
  739. # if defined(_MSC_VER)
  740. # define popen _popen
  741. # define pclose _pclose
  742. # else
  743. extern FILE *popen(const char *command, const char *type);
  744. extern int pclose(FILE *stream);
  745. # endif
  746. #else
  747. # if defined(_MSC_VER)
  748. # define HAVE_POPEN 1
  749. # define popen _popen
  750. # define pclose _pclose
  751. # endif
  752. #endif
  753. String *Swig_string_command(String *s) {
  754. String *res = NewStringEmpty();
  755. #if defined(HAVE_POPEN)
  756. if (Len(s)) {
  757. char *command = Char(s);
  758. FILE *fp = popen(command, "r");
  759. if (fp) {
  760. char buffer[1025];
  761. while (fscanf(fp, "%1024s", buffer) != EOF) {
  762. Append(res, buffer);
  763. }
  764. pclose(fp);
  765. } else {
  766. Swig_error("SWIG", Getline(s), "Command encoder fails attempting '%s'.\n", s);
  767. exit(1);
  768. }
  769. }
  770. #endif
  771. return res;
  772. }
  773. /* -----------------------------------------------------------------------------
  774. * Swig_string_rxspencer()
  775. *
  776. * Executes a regexp substitution via the RxSpencer library. For example:
  777. *
  778. * Printf(stderr,"gsl%(rxspencer:[GSL_.*_][@1])s","GSL_Hello_") -> gslHello
  779. * ----------------------------------------------------------------------------- */
  780. #if defined(HAVE_RXSPENCER)
  781. #include <sys/types.h>
  782. #include <rxspencer/regex.h>
  783. #define USE_RXSPENCER
  784. #endif
  785. const char *skip_delim(char pb, char pe, const char *ce) {
  786. int end = 0;
  787. int lb = 0;
  788. while (!end && *ce != '\0') {
  789. if (*ce == pb) {
  790. ++lb;
  791. }
  792. if (*ce == pe) {
  793. if (!lb) {
  794. end = 1;
  795. --ce;
  796. } else {
  797. --lb;
  798. }
  799. }
  800. ++ce;
  801. }
  802. return end ? ce : 0;
  803. }
  804. #if defined(USE_RXSPENCER)
  805. String *Swig_string_rxspencer(String *s) {
  806. String *res = 0;
  807. if (Len(s)) {
  808. const char *cs = Char(s);
  809. const char *cb;
  810. const char *ce;
  811. if (*cs == '[') {
  812. int retval;
  813. regex_t compiled;
  814. cb = ++cs;
  815. ce = skip_delim('[', ']', cb);
  816. if (ce) {
  817. char bregexp[512];
  818. strncpy(bregexp, cb, ce - cb);
  819. bregexp[ce - cb] = '\0';
  820. ++ce;
  821. retval = regcomp(&compiled, bregexp, REG_EXTENDED);
  822. if (retval == 0) {
  823. cs = ce;
  824. if (*cs == '[') {
  825. cb = ++cs;
  826. ce = skip_delim('[', ']', cb);
  827. if (ce) {
  828. const char *cvalue = ce + 1;
  829. int nsub = (int) compiled.re_nsub + 1;
  830. regmatch_t *pmatch = (regmatch_t *) malloc(sizeof(regmatch_t) * (nsub));
  831. retval = regexec(&compiled, cvalue, nsub, pmatch, 0);
  832. if (retval != REG_NOMATCH) {
  833. char *spos = 0;
  834. res = NewStringWithSize(cb, ce - cb);
  835. spos = Strchr(res, '@');
  836. while (spos) {
  837. char cd = *(++spos);
  838. if (isdigit(cd)) {
  839. char arg[8];
  840. size_t len;
  841. int i = cd - '0';
  842. sprintf(arg, "@%d", i);
  843. if (i < nsub && (len = pmatch[i].rm_eo - pmatch[i].rm_so)) {
  844. char value[256];
  845. strncpy(value, cvalue + pmatch[i].rm_so, len);
  846. value[len] = 0;
  847. Replaceall(res, arg, value);
  848. } else {
  849. Replaceall(res, arg, "");
  850. }
  851. spos = Strchr(res, '@');
  852. } else if (cd == '@') {
  853. spos = strchr(spos + 1, '@');
  854. }
  855. }
  856. }
  857. free(pmatch);
  858. }
  859. }
  860. }
  861. regfree(&compiled);
  862. }
  863. }
  864. }
  865. if (!res)
  866. res = NewStringEmpty();
  867. return res;
  868. }
  869. #else
  870. String *Swig_string_rxspencer(String *s) {
  871. (void) s;
  872. return NewStringEmpty();
  873. }
  874. #endif
  875. /* -----------------------------------------------------------------------------
  876. * Swig_init()
  877. *
  878. * Initialize the SWIG core
  879. * ----------------------------------------------------------------------------- */
  880. void Swig_init() {
  881. /* Set some useful string encoding methods */
  882. DohEncoding("escape", Swig_string_escape);
  883. DohEncoding("upper", Swig_string_upper);
  884. DohEncoding("lower", Swig_string_lower);
  885. DohEncoding("title", Swig_string_title);
  886. DohEncoding("ctitle", Swig_string_ccase);
  887. DohEncoding("lctitle", Swig_string_lccase);
  888. DohEncoding("utitle", Swig_string_ucase);
  889. DohEncoding("typecode", Swig_string_typecode);
  890. DohEncoding("mangle", Swig_string_emangle);
  891. DohEncoding("command", Swig_string_command);
  892. DohEncoding("rxspencer", Swig_string_rxspencer);
  893. DohEncoding("schemify", Swig_string_schemify);
  894. /* aliases for the case encoders */
  895. DohEncoding("uppercase", Swig_string_upper);
  896. DohEncoding("lowercase", Swig_string_lower);
  897. DohEncoding("camelcase", Swig_string_ccase);
  898. DohEncoding("lowercamelcase", Swig_string_lccase);
  899. DohEncoding("undercase", Swig_string_ucase);
  900. DohEncoding("firstuppercase", Swig_string_first_upper);
  901. DohEncoding("firstlowercase", Swig_string_first_lower);
  902. /* Initialize the swig keys */
  903. Swig_keys_init();
  904. /* Initialize typemaps */
  905. Swig_typemap_init();
  906. /* Initialize symbol table */
  907. Swig_symbol_init();
  908. /* Initialize type system */
  909. SwigType_typesystem_init();
  910. /* Initialize template system */
  911. SwigType_template_init();
  912. }