PageRenderTime 62ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/trunk/Source/Swig/misc.c

#
C | 1287 lines | 927 code | 121 blank | 239 comment | 311 complexity | e1a0f30cf30503996addf1091e7d84db MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  1. /* -----------------------------------------------------------------------------
  2. * This file is part of SWIG, which is licensed as a whole under version 3
  3. * (or any later version) of the GNU General Public License. Some additional
  4. * terms also apply to certain portions of SWIG. The full details of the SWIG
  5. * license and copyrights can be found in the LICENSE and COPYRIGHT files
  6. * included with the SWIG source code as distributed by the SWIG developers
  7. * and at http://www.swig.org/legal.html.
  8. *
  9. * misc.c
  10. *
  11. * Miscellaneous functions that don't really fit anywhere else.
  12. * ----------------------------------------------------------------------------- */
  13. char cvsroot_misc_c[] = "$Id: misc.c 12904 2012-01-27 20:55:32Z wsfulton $";
  14. #include "swig.h"
  15. #include <errno.h>
  16. #include <ctype.h>
  17. #include <limits.h>
  18. #include <sys/types.h>
  19. #include <sys/stat.h>
  20. #ifdef _WIN32
  21. #include <direct.h>
  22. #ifndef S_ISDIR
  23. #define S_ISDIR(mode) (((mode) & S_IFDIR) == S_IFDIR)
  24. #endif
  25. #endif
  26. static char *fake_version = 0;
  27. /* -----------------------------------------------------------------------------
  28. * Swig_copy_string()
  29. *
  30. * Duplicate a NULL-terminate string given as a char *.
  31. * ----------------------------------------------------------------------------- */
  32. char *Swig_copy_string(const char *s) {
  33. char *c = 0;
  34. if (s) {
  35. c = (char *) malloc(strlen(s) + 1);
  36. strcpy(c, s);
  37. }
  38. return c;
  39. }
  40. /* -----------------------------------------------------------------------------
  41. * Swig_set_fakeversion()
  42. *
  43. * Version string override
  44. * ----------------------------------------------------------------------------- */
  45. void Swig_set_fakeversion(const char *version) {
  46. fake_version = Swig_copy_string(version);
  47. }
  48. /* -----------------------------------------------------------------------------
  49. * Swig_package_version()
  50. *
  51. * Return the package string containing the version number
  52. * ----------------------------------------------------------------------------- */
  53. const char *Swig_package_version(void) {
  54. return fake_version ? fake_version : PACKAGE_VERSION;
  55. }
  56. /* -----------------------------------------------------------------------------
  57. * Swig_banner()
  58. *
  59. * Emits the SWIG identifying banner for the C/C++ wrapper file.
  60. * ----------------------------------------------------------------------------- */
  61. void Swig_banner(File *f) {
  62. Printf(f, "/* ----------------------------------------------------------------------------\n\
  63. * This file was automatically generated by SWIG (http://www.swig.org).\n\
  64. * Version %s\n\
  65. * \n\
  66. * This file is not intended to be easily readable and contains a number of \n\
  67. * coding conventions designed to improve portability and efficiency. Do not make\n\
  68. * changes to this file unless you know what you are doing--modify the SWIG \n\
  69. * interface file instead. \n", Swig_package_version());
  70. /* String too long for ISO compliance */
  71. Printf(f, " * ----------------------------------------------------------------------------- */\n");
  72. }
  73. /* -----------------------------------------------------------------------------
  74. * Swig_banner_target_lang()
  75. *
  76. * Emits a SWIG identifying banner in the target language
  77. * ----------------------------------------------------------------------------- */
  78. void Swig_banner_target_lang(File *f, const_String_or_char_ptr commentchar) {
  79. Printf(f, "%s This file was automatically generated by SWIG (http://www.swig.org).\n", commentchar);
  80. Printf(f, "%s Version %s\n", commentchar, Swig_package_version());
  81. Printf(f, "%s\n", commentchar);
  82. Printf(f, "%s Do not make changes to this file unless you know what you are doing--modify\n", commentchar);
  83. Printf(f, "%s the SWIG interface file instead.\n", commentchar);
  84. }
  85. /* -----------------------------------------------------------------------------
  86. * Swig_strip_c_comments()
  87. *
  88. * Return a new string with C comments stripped from the input string. NULL is
  89. * returned if there aren't any comments.
  90. * ----------------------------------------------------------------------------- */
  91. String *Swig_strip_c_comments(const String *s) {
  92. const char *c = Char(s);
  93. const char *comment_begin = 0;
  94. const char *comment_end = 0;
  95. String *stripped = 0;
  96. while (*c) {
  97. if (!comment_begin && *c == '/') {
  98. ++c;
  99. if (!*c)
  100. break;
  101. if (*c == '*')
  102. comment_begin = c-1;
  103. } else if (comment_begin && !comment_end && *c == '*') {
  104. ++c;
  105. if (*c == '/') {
  106. comment_end = c;
  107. break;
  108. }
  109. }
  110. ++c;
  111. }
  112. if (comment_begin && comment_end) {
  113. int size = comment_begin - Char(s);
  114. String *stripmore = 0;
  115. stripped = NewStringWithSize(s, size);
  116. Printv(stripped, comment_end + 1, NIL);
  117. do {
  118. stripmore = Swig_strip_c_comments(stripped);
  119. if (stripmore) {
  120. Delete(stripped);
  121. stripped = stripmore;
  122. }
  123. } while (stripmore);
  124. }
  125. return stripped;
  126. }
  127. /* -----------------------------------------------------------------------------
  128. * is_directory()
  129. * ----------------------------------------------------------------------------- */
  130. static int is_directory(String *directory) {
  131. int last = Len(directory) - 1;
  132. int statres;
  133. struct stat st;
  134. char *dir = Char(directory);
  135. if (dir[last] == SWIG_FILE_DELIMITER[0]) {
  136. /* remove trailing slash - can cause S_ISDIR to fail on Windows, at least */
  137. dir[last] = 0;
  138. statres = stat(dir, &st);
  139. dir[last] = SWIG_FILE_DELIMITER[0];
  140. } else {
  141. statres = stat(dir, &st);
  142. }
  143. return (statres == 0 && S_ISDIR(st.st_mode));
  144. }
  145. /* -----------------------------------------------------------------------------
  146. * Swig_new_subdirectory()
  147. *
  148. * Create the subdirectory only if the basedirectory already exists as a directory.
  149. * basedirectory can be NULL or empty to indicate current directory.
  150. * ----------------------------------------------------------------------------- */
  151. String *Swig_new_subdirectory(String *basedirectory, String *subdirectory) {
  152. String *error = 0;
  153. struct stat st;
  154. int current_directory = basedirectory ? (Len(basedirectory) == 0 ? 1 : 0) : 0;
  155. if (current_directory || is_directory(basedirectory)) {
  156. Iterator it;
  157. String *dir = basedirectory ? NewString(basedirectory) : NewString("");
  158. List *subdirs = Split(subdirectory, SWIG_FILE_DELIMITER[0], INT_MAX);
  159. for (it = First(subdirs); it.item; it = Next(it)) {
  160. int statdir;
  161. String *subdirectory = it.item;
  162. Printf(dir, "%s", subdirectory);
  163. statdir = stat(Char(dir), &st);
  164. if (statdir == 0) {
  165. Printf(dir, SWIG_FILE_DELIMITER);
  166. if (S_ISDIR(st.st_mode)) {
  167. continue;
  168. } else {
  169. error = NewStringf("Cannot create directory %s", dir);
  170. break;
  171. }
  172. } else {
  173. #ifdef _WIN32
  174. int result = _mkdir(Char(dir));
  175. #else
  176. int result = mkdir(Char(dir), 0777);
  177. #endif
  178. Printf(dir, SWIG_FILE_DELIMITER);
  179. if (result != 0 && errno != EEXIST) {
  180. error = NewStringf("Cannot create directory %s", dir);
  181. break;
  182. }
  183. }
  184. }
  185. } else {
  186. error = NewStringf("Cannot create subdirectory %s under the base directory %s. Either the base does not exist as a directory or it is not readable.", subdirectory, basedirectory);
  187. }
  188. return error;
  189. }
  190. /* -----------------------------------------------------------------------------
  191. * Swig_filename_correct()
  192. *
  193. * Corrects filename paths by removing duplicate delimeters and on non-unix
  194. * systems use the correct delimeter across the whole name.
  195. * ----------------------------------------------------------------------------- */
  196. void Swig_filename_correct(String *filename) {
  197. int network_path = 0;
  198. if (Len(filename) >= 2) {
  199. const char *fname = Char(filename);
  200. if (fname[0] == '\\' && fname[1] == '\\')
  201. network_path = 1;
  202. if (fname[0] == '/' && fname[1] == '/')
  203. network_path = 1;
  204. }
  205. #if defined(_WIN32) || defined(MACSWIG)
  206. /* accept Unix path separator on non-Unix systems */
  207. Replaceall(filename, "/", SWIG_FILE_DELIMITER);
  208. #endif
  209. #if defined(__CYGWIN__)
  210. /* accept Windows path separator in addition to Unix path separator */
  211. Replaceall(filename, "\\", SWIG_FILE_DELIMITER);
  212. #endif
  213. /* remove all duplicate file name delimiters */
  214. while (Replaceall(filename, SWIG_FILE_DELIMITER SWIG_FILE_DELIMITER, SWIG_FILE_DELIMITER)) {
  215. }
  216. /* Network paths can start with a double slash on Windows - unremove the duplicate slash we just removed */
  217. if (network_path)
  218. Insert(filename, 0, SWIG_FILE_DELIMITER);
  219. }
  220. /* -----------------------------------------------------------------------------
  221. * Swig_filename_escape()
  222. *
  223. * Escapes backslashes in filename - for Windows
  224. * ----------------------------------------------------------------------------- */
  225. String *Swig_filename_escape(String *filename) {
  226. String *adjusted_filename = Copy(filename);
  227. Swig_filename_correct(adjusted_filename);
  228. #if defined(_WIN32) /* Note not on Cygwin else filename is displayed with double '/' */
  229. Replaceall(adjusted_filename, "\\", "\\\\");
  230. #endif
  231. return adjusted_filename;
  232. }
  233. /* -----------------------------------------------------------------------------
  234. * Swig_filename_unescape()
  235. *
  236. * Remove double backslash escaping in filename - for Windows
  237. * ----------------------------------------------------------------------------- */
  238. void Swig_filename_unescape(String *filename) {
  239. (void)filename;
  240. #if defined(_WIN32)
  241. Replaceall(filename, "\\\\", "\\");
  242. #endif
  243. }
  244. /* -----------------------------------------------------------------------------
  245. * Swig_string_escape()
  246. *
  247. * Takes a string object and produces a string with escape codes added to it.
  248. * ----------------------------------------------------------------------------- */
  249. String *Swig_string_escape(String *s) {
  250. String *ns;
  251. int c;
  252. ns = NewStringEmpty();
  253. while ((c = Getc(s)) != EOF) {
  254. if (c == '\n') {
  255. Printf(ns, "\\n");
  256. } else if (c == '\r') {
  257. Printf(ns, "\\r");
  258. } else if (c == '\t') {
  259. Printf(ns, "\\t");
  260. } else if (c == '\\') {
  261. Printf(ns, "\\\\");
  262. } else if (c == '\'') {
  263. Printf(ns, "\\'");
  264. } else if (c == '\"') {
  265. Printf(ns, "\\\"");
  266. } else if (c == ' ') {
  267. Putc(c, ns);
  268. } else if (!isgraph(c)) {
  269. if (c < 0)
  270. c += UCHAR_MAX + 1;
  271. Printf(ns, "\\%o", c);
  272. } else {
  273. Putc(c, ns);
  274. }
  275. }
  276. return ns;
  277. }
  278. /* -----------------------------------------------------------------------------
  279. * Swig_string_upper()
  280. *
  281. * Takes a string object and returns a copy that is uppercase
  282. * ----------------------------------------------------------------------------- */
  283. String *Swig_string_upper(String *s) {
  284. String *ns;
  285. int c;
  286. ns = NewStringEmpty();
  287. Seek(s, 0, SEEK_SET);
  288. while ((c = Getc(s)) != EOF) {
  289. Putc(toupper(c), ns);
  290. }
  291. return ns;
  292. }
  293. /* -----------------------------------------------------------------------------
  294. * Swig_string_lower()
  295. *
  296. * Takes a string object and returns a copy that is lowercase
  297. * ----------------------------------------------------------------------------- */
  298. String *Swig_string_lower(String *s) {
  299. String *ns;
  300. int c;
  301. ns = NewStringEmpty();
  302. Seek(s, 0, SEEK_SET);
  303. while ((c = Getc(s)) != EOF) {
  304. Putc(tolower(c), ns);
  305. }
  306. return ns;
  307. }
  308. /* -----------------------------------------------------------------------------
  309. * Swig_string_title()
  310. *
  311. * Takes a string object and returns a copy that is lowercase with first letter
  312. * capitalized
  313. * ----------------------------------------------------------------------------- */
  314. String *Swig_string_title(String *s) {
  315. String *ns;
  316. int first = 1;
  317. int c;
  318. ns = NewStringEmpty();
  319. Seek(s, 0, SEEK_SET);
  320. while ((c = Getc(s)) != EOF) {
  321. Putc(first ? toupper(c) : tolower(c), ns);
  322. first = 0;
  323. }
  324. return ns;
  325. }
  326. /* -----------------------------------------------------------------------------
  327. * Swig_string_ccase()
  328. *
  329. * Takes a string object and returns a copy that is lowercase with the first
  330. * letter capitalized and the one following '_', which are removed.
  331. *
  332. * camel_case -> CamelCase
  333. * camelCase -> CamelCase
  334. * ----------------------------------------------------------------------------- */
  335. String *Swig_string_ccase(String *s) {
  336. String *ns;
  337. int first = 1;
  338. int c;
  339. ns = NewStringEmpty();
  340. Seek(s, 0, SEEK_SET);
  341. while ((c = Getc(s)) != EOF) {
  342. if (c == '_') {
  343. first = 1;
  344. continue;
  345. }
  346. Putc(first ? toupper(c) : c, ns);
  347. first = 0;
  348. }
  349. return ns;
  350. }
  351. /* -----------------------------------------------------------------------------
  352. * Swig_string_lccase()
  353. *
  354. * Takes a string object and returns a copy with the character after
  355. * each '_' capitalised, and the '_' removed. The first character is
  356. * also forced to lowercase.
  357. *
  358. * camel_case -> camelCase
  359. * CamelCase -> camelCase
  360. * ----------------------------------------------------------------------------- */
  361. String *Swig_string_lccase(String *s) {
  362. String *ns;
  363. int first = 1;
  364. int after_underscore = 0;
  365. int c;
  366. ns = NewStringEmpty();
  367. Seek(s, 0, SEEK_SET);
  368. while ((c = Getc(s)) != EOF) {
  369. if (c == '_') {
  370. after_underscore = 1;
  371. continue;
  372. }
  373. if (first) {
  374. Putc(tolower(c), ns);
  375. first = 0;
  376. } else {
  377. Putc(after_underscore ? toupper(c) : c, ns);
  378. }
  379. after_underscore = 0;
  380. }
  381. return ns;
  382. }
  383. /* -----------------------------------------------------------------------------
  384. * Swig_string_ucase()
  385. *
  386. * This is the reverse case of ccase, ie
  387. *
  388. * CamelCase -> camel_case
  389. * get2D -> get_2d
  390. * asFloat2 -> as_float2
  391. * ----------------------------------------------------------------------------- */
  392. String *Swig_string_ucase(String *s) {
  393. String *ns;
  394. int c;
  395. int lastC = 0;
  396. int nextC = 0;
  397. int underscore = 0;
  398. ns = NewStringEmpty();
  399. /* We insert a underscore when:
  400. 1. Lower case char followed by upper case char
  401. getFoo > get_foo; getFOo > get_foo; GETFOO > getfoo
  402. 2. Number proceded by char and not end of string
  403. get2D > get_2d; get22D > get_22d; GET2D > get_2d
  404. but:
  405. asFloat2 > as_float2
  406. */
  407. Seek(s, 0, SEEK_SET);
  408. while ((c = Getc(s)) != EOF) {
  409. nextC = Getc(s); Ungetc(nextC, s);
  410. if (isdigit(c) && isalpha(lastC) && nextC != EOF)
  411. underscore = 1;
  412. else if (isupper(c) && isalpha(lastC) && !isupper(lastC))
  413. underscore = 1;
  414. lastC = c;
  415. if (underscore) {
  416. Putc('_', ns);
  417. underscore = 0;
  418. }
  419. Putc(tolower(c), ns);
  420. }
  421. return ns;
  422. }
  423. /* -----------------------------------------------------------------------------
  424. * Swig_string_first_upper()
  425. *
  426. * Make the first character in the string uppercase, leave all the
  427. * rest the same. This is used by the Ruby module to provide backwards
  428. * compatibility with the old way of naming classes and constants. For
  429. * more info see the Ruby documentation.
  430. *
  431. * firstUpper -> FirstUpper
  432. * ----------------------------------------------------------------------------- */
  433. String *Swig_string_first_upper(String *s) {
  434. String *ns = NewStringEmpty();
  435. char *cs = Char(s);
  436. if (cs && cs[0] != 0) {
  437. Putc(toupper((int)cs[0]), ns);
  438. Append(ns, cs + 1);
  439. }
  440. return ns;
  441. }
  442. /* -----------------------------------------------------------------------------
  443. * Swig_string_first_lower()
  444. *
  445. * Make the first character in the string lowercase, leave all the
  446. * rest the same. This is used by the Ruby module to provide backwards
  447. * compatibility with the old way of naming classes and constants. For
  448. * more info see the Ruby documentation.
  449. *
  450. * firstLower -> FirstLower
  451. * ----------------------------------------------------------------------------- */
  452. String *Swig_string_first_lower(String *s) {
  453. String *ns = NewStringEmpty();
  454. char *cs = Char(s);
  455. if (cs && cs[0] != 0) {
  456. Putc(tolower((int)cs[0]), ns);
  457. Append(ns, cs + 1);
  458. }
  459. return ns;
  460. }
  461. /* -----------------------------------------------------------------------------
  462. * Swig_string_schemify()
  463. *
  464. * Replace underscores with dashes, to make identifiers look nice to Schemers.
  465. *
  466. * under_scores -> under-scores
  467. * ----------------------------------------------------------------------------- */
  468. String *Swig_string_schemify(String *s) {
  469. String *ns = NewString(s);
  470. Replaceall(ns, "_", "-");
  471. return ns;
  472. }
  473. /* -----------------------------------------------------------------------------
  474. * Swig_string_typecode()
  475. *
  476. * Takes a string with possible type-escapes in it and replaces them with
  477. * real C datatypes.
  478. * ----------------------------------------------------------------------------- */
  479. String *Swig_string_typecode(String *s) {
  480. String *ns;
  481. int c;
  482. String *tc;
  483. ns = NewStringEmpty();
  484. while ((c = Getc(s)) != EOF) {
  485. if (c == '`') {
  486. String *str = 0;
  487. tc = NewStringEmpty();
  488. while ((c = Getc(s)) != EOF) {
  489. if (c == '`')
  490. break;
  491. Putc(c, tc);
  492. }
  493. str = SwigType_str(tc, 0);
  494. Append(ns, str);
  495. Delete(str);
  496. } else {
  497. Putc(c, ns);
  498. if (c == '\'') {
  499. while ((c = Getc(s)) != EOF) {
  500. Putc(c, ns);
  501. if (c == '\'')
  502. break;
  503. if (c == '\\') {
  504. c = Getc(s);
  505. Putc(c, ns);
  506. }
  507. }
  508. } else if (c == '\"') {
  509. while ((c = Getc(s)) != EOF) {
  510. Putc(c, ns);
  511. if (c == '\"')
  512. break;
  513. if (c == '\\') {
  514. c = Getc(s);
  515. Putc(c, ns);
  516. }
  517. }
  518. }
  519. }
  520. }
  521. return ns;
  522. }
  523. /* -----------------------------------------------------------------------------
  524. * Swig_string_mangle()
  525. *
  526. * Take a string and mangle it by stripping all non-valid C identifier
  527. * characters.
  528. *
  529. * This routine skips unnecessary blank spaces, therefore mangling
  530. * 'char *' and 'char*', 'std::pair<int, int >' and
  531. * 'std::pair<int,int>', produce the same result.
  532. *
  533. * However, note that 'long long' and 'long_long' produce different
  534. * mangled strings.
  535. *
  536. * The mangling method still is not 'perfect', for example std::pair and
  537. * std_pair return the same mangling. This is just a little better
  538. * than before, but it seems to be enough for most of the purposes.
  539. *
  540. * Having a perfect mangling will break some examples and code which
  541. * assume, for example, that A::get_value will be mangled as
  542. * A_get_value.
  543. * ----------------------------------------------------------------------------- */
  544. String *Swig_string_mangle(const String *s) {
  545. #if 0
  546. /* old mangling, not suitable for using in macros */
  547. String *t = Copy(s);
  548. char *c = Char(t);
  549. while (*c) {
  550. if (!isalnum(*c))
  551. *c = '_';
  552. c++;
  553. }
  554. return t;
  555. #else
  556. String *result = NewStringEmpty();
  557. int space = 0;
  558. int state = 0;
  559. char *pc, *cb;
  560. String *b = Copy(s);
  561. if (SwigType_istemplate(b)) {
  562. String *st = Swig_symbol_template_deftype(b, 0);
  563. String *sq = Swig_symbol_type_qualify(st, 0);
  564. String *t = SwigType_namestr(sq);
  565. Delete(st);
  566. Delete(sq);
  567. Delete(b);
  568. b = t;
  569. }
  570. pc = cb = Char(b);
  571. while (*pc) {
  572. char c = *pc;
  573. if (isalnum((int) c) || (c == '_')) {
  574. state = 1;
  575. if (space && (space == state)) {
  576. Append(result, "_SS_");
  577. }
  578. space = 0;
  579. Printf(result, "%c", (int) c);
  580. } else {
  581. if (isspace((int) c)) {
  582. space = state;
  583. ++pc;
  584. continue;
  585. } else {
  586. state = 3;
  587. space = 0;
  588. }
  589. switch (c) {
  590. case '.':
  591. if ((cb != pc) && (*(pc - 1) == 'p')) {
  592. Append(result, "_");
  593. ++pc;
  594. continue;
  595. } else {
  596. c = 'f';
  597. }
  598. break;
  599. case ':':
  600. if (*(pc + 1) == ':') {
  601. Append(result, "_");
  602. ++pc;
  603. ++pc;
  604. continue;
  605. }
  606. break;
  607. case '*':
  608. c = 'm';
  609. break;
  610. case '&':
  611. c = 'A';
  612. break;
  613. case '<':
  614. c = 'l';
  615. break;
  616. case '>':
  617. c = 'g';
  618. break;
  619. case '=':
  620. c = 'e';
  621. break;
  622. case ',':
  623. c = 'c';
  624. break;
  625. case '(':
  626. c = 'p';
  627. break;
  628. case ')':
  629. c = 'P';
  630. break;
  631. case '[':
  632. c = 'b';
  633. break;
  634. case ']':
  635. c = 'B';
  636. break;
  637. case '^':
  638. c = 'x';
  639. break;
  640. case '|':
  641. c = 'o';
  642. break;
  643. case '~':
  644. c = 'n';
  645. break;
  646. case '!':
  647. c = 'N';
  648. break;
  649. case '%':
  650. c = 'M';
  651. break;
  652. case '?':
  653. c = 'q';
  654. break;
  655. case '+':
  656. c = 'a';
  657. break;
  658. case '-':
  659. c = 's';
  660. break;
  661. case '/':
  662. c = 'd';
  663. break;
  664. default:
  665. break;
  666. }
  667. if (isalpha((int) c)) {
  668. Printf(result, "_S%c_", (int) c);
  669. } else {
  670. Printf(result, "_S%02X_", (int) c);
  671. }
  672. }
  673. ++pc;
  674. }
  675. Delete(b);
  676. return result;
  677. #endif
  678. }
  679. String *Swig_string_emangle(String *s) {
  680. return Swig_string_mangle(s);
  681. }
  682. /* -----------------------------------------------------------------------------
  683. * Swig_scopename_prefix()
  684. *
  685. * Take a qualified name like "A::B::C" and return the scope name.
  686. * In this case, "A::B". Returns NULL if there is no base.
  687. * ----------------------------------------------------------------------------- */
  688. void Swig_scopename_split(const String *s, String **rprefix, String **rlast) {
  689. char *tmp = Char(s);
  690. char *c = tmp;
  691. char *cc = c;
  692. char *co = 0;
  693. if (!strstr(c, "::")) {
  694. *rprefix = 0;
  695. *rlast = Copy(s);
  696. }
  697. co = strstr(cc, "operator ");
  698. if (co) {
  699. if (co == cc) {
  700. *rprefix = 0;
  701. *rlast = Copy(s);
  702. return;
  703. } else {
  704. *rprefix = NewStringWithSize(cc, co - cc - 2);
  705. *rlast = NewString(co);
  706. return;
  707. }
  708. }
  709. while (*c) {
  710. if ((*c == ':') && (*(c + 1) == ':')) {
  711. cc = c;
  712. c += 2;
  713. } else {
  714. if (*c == '<') {
  715. int level = 1;
  716. c++;
  717. while (*c && level) {
  718. if (*c == '<')
  719. level++;
  720. if (*c == '>')
  721. level--;
  722. c++;
  723. }
  724. } else {
  725. c++;
  726. }
  727. }
  728. }
  729. if (cc != tmp) {
  730. *rprefix = NewStringWithSize(tmp, cc - tmp);
  731. *rlast = NewString(cc + 2);
  732. return;
  733. } else {
  734. *rprefix = 0;
  735. *rlast = Copy(s);
  736. }
  737. }
  738. String *Swig_scopename_prefix(const String *s) {
  739. char *tmp = Char(s);
  740. char *c = tmp;
  741. char *cc = c;
  742. char *co = 0;
  743. if (!strstr(c, "::"))
  744. return 0;
  745. co = strstr(cc, "operator ");
  746. if (co) {
  747. if (co == cc) {
  748. return 0;
  749. } else {
  750. String *prefix = NewStringWithSize(cc, co - cc - 2);
  751. return prefix;
  752. }
  753. }
  754. while (*c) {
  755. if ((*c == ':') && (*(c + 1) == ':')) {
  756. cc = c;
  757. c += 2;
  758. } else {
  759. if (*c == '<') {
  760. int level = 1;
  761. c++;
  762. while (*c && level) {
  763. if (*c == '<')
  764. level++;
  765. if (*c == '>')
  766. level--;
  767. c++;
  768. }
  769. } else {
  770. c++;
  771. }
  772. }
  773. }
  774. if (cc != tmp) {
  775. return NewStringWithSize(tmp, cc - tmp);
  776. } else {
  777. return 0;
  778. }
  779. }
  780. /* -----------------------------------------------------------------------------
  781. * Swig_scopename_last()
  782. *
  783. * Take a qualified name like "A::B::C" and returns the last. In this
  784. * case, "C".
  785. * ----------------------------------------------------------------------------- */
  786. String *Swig_scopename_last(const String *s) {
  787. char *tmp = Char(s);
  788. char *c = tmp;
  789. char *cc = c;
  790. char *co = 0;
  791. if (!strstr(c, "::"))
  792. return NewString(s);
  793. co = strstr(cc, "operator ");
  794. if (co) {
  795. return NewString(co);
  796. }
  797. while (*c) {
  798. if ((*c == ':') && (*(c + 1) == ':')) {
  799. cc = c;
  800. c += 2;
  801. } else {
  802. if (*c == '<') {
  803. int level = 1;
  804. c++;
  805. while (*c && level) {
  806. if (*c == '<')
  807. level++;
  808. if (*c == '>')
  809. level--;
  810. c++;
  811. }
  812. } else {
  813. c++;
  814. }
  815. }
  816. }
  817. return NewString(cc + 2);
  818. }
  819. /* -----------------------------------------------------------------------------
  820. * Swig_scopename_first()
  821. *
  822. * Take a qualified name like "A::B::C" and returns the first scope name.
  823. * In this case, "A". Returns NULL if there is no base.
  824. * ----------------------------------------------------------------------------- */
  825. String *Swig_scopename_first(const String *s) {
  826. char *tmp = Char(s);
  827. char *c = tmp;
  828. char *co = 0;
  829. if (!strstr(c, "::"))
  830. return 0;
  831. co = strstr(c, "operator ");
  832. if (co) {
  833. if (co == c) {
  834. return 0;
  835. }
  836. } else {
  837. co = c + Len(s);
  838. }
  839. while (*c && (c != co)) {
  840. if ((*c == ':') && (*(c + 1) == ':')) {
  841. break;
  842. } else {
  843. if (*c == '<') {
  844. int level = 1;
  845. c++;
  846. while (*c && level) {
  847. if (*c == '<')
  848. level++;
  849. if (*c == '>')
  850. level--;
  851. c++;
  852. }
  853. } else {
  854. c++;
  855. }
  856. }
  857. }
  858. if (*c && (c != tmp)) {
  859. return NewStringWithSize(tmp, c - tmp);
  860. } else {
  861. return 0;
  862. }
  863. }
  864. /* -----------------------------------------------------------------------------
  865. * Swig_scopename_suffix()
  866. *
  867. * Take a qualified name like "A::B::C" and returns the suffix.
  868. * In this case, "B::C". Returns NULL if there is no suffix.
  869. * ----------------------------------------------------------------------------- */
  870. String *Swig_scopename_suffix(const String *s) {
  871. char *tmp = Char(s);
  872. char *c = tmp;
  873. char *co = 0;
  874. if (!strstr(c, "::"))
  875. return 0;
  876. co = strstr(c, "operator ");
  877. if (co) {
  878. if (co == c)
  879. return 0;
  880. }
  881. while (*c) {
  882. if ((*c == ':') && (*(c + 1) == ':')) {
  883. break;
  884. } else {
  885. if (*c == '<') {
  886. int level = 1;
  887. c++;
  888. while (*c && level) {
  889. if (*c == '<')
  890. level++;
  891. if (*c == '>')
  892. level--;
  893. c++;
  894. }
  895. } else {
  896. c++;
  897. }
  898. }
  899. }
  900. if (*c && (c != tmp)) {
  901. return NewString(c + 2);
  902. } else {
  903. return 0;
  904. }
  905. }
  906. /* -----------------------------------------------------------------------------
  907. * Swig_scopename_check()
  908. *
  909. * Checks to see if a name is qualified with a scope name, examples:
  910. * foo -> 0
  911. * ::foo -> 1
  912. * foo::bar -> 1
  913. * foo< ::bar > -> 0
  914. * ----------------------------------------------------------------------------- */
  915. int Swig_scopename_check(const String *s) {
  916. char *c = Char(s);
  917. char *co = strstr(c, "operator ");
  918. if (co) {
  919. if (co == c)
  920. return 0;
  921. }
  922. if (!strstr(c, "::"))
  923. return 0;
  924. while (*c) {
  925. if ((*c == ':') && (*(c + 1) == ':')) {
  926. return 1;
  927. } else {
  928. if (*c == '<') {
  929. int level = 1;
  930. c++;
  931. while (*c && level) {
  932. if (*c == '<')
  933. level++;
  934. if (*c == '>')
  935. level--;
  936. c++;
  937. }
  938. } else {
  939. c++;
  940. }
  941. }
  942. }
  943. return 0;
  944. }
  945. /* -----------------------------------------------------------------------------
  946. * Swig_string_command()
  947. *
  948. * Executes a external command via popen with the string as a command
  949. * line parameter. For example:
  950. *
  951. * Printf(stderr,"%(command:sed 's/[a-z]/\U\\1/' <<<)s","hello") -> Hello
  952. * ----------------------------------------------------------------------------- */
  953. #if defined(HAVE_POPEN)
  954. # if defined(_MSC_VER)
  955. # define popen _popen
  956. # define pclose _pclose
  957. # else
  958. extern FILE *popen(const char *command, const char *type);
  959. extern int pclose(FILE *stream);
  960. # endif
  961. #else
  962. # if defined(_MSC_VER)
  963. # define HAVE_POPEN 1
  964. # define popen _popen
  965. # define pclose _pclose
  966. # endif
  967. #endif
  968. String *Swig_string_command(String *s) {
  969. String *res = NewStringEmpty();
  970. #if defined(HAVE_POPEN)
  971. if (Len(s)) {
  972. char *command = Char(s);
  973. FILE *fp = popen(command, "r");
  974. if (fp) {
  975. char buffer[1025];
  976. while (fscanf(fp, "%1024s", buffer) != EOF) {
  977. Append(res, buffer);
  978. }
  979. pclose(fp);
  980. } else {
  981. Swig_error("SWIG", Getline(s), "Command encoder fails attempting '%s'.\n", s);
  982. exit(1);
  983. }
  984. }
  985. #endif
  986. return res;
  987. }
  988. /* -----------------------------------------------------------------------------
  989. * Swig_string_strip()
  990. *
  991. * Strip given prefix from identifiers
  992. *
  993. * Printf(stderr,"%(strip:[wx])s","wxHello") -> Hello
  994. * ----------------------------------------------------------------------------- */
  995. String *Swig_string_strip(String *s) {
  996. String *ns;
  997. if (!Len(s)) {
  998. ns = NewString(s);
  999. } else {
  1000. const char *cs = Char(s);
  1001. const char *ce = Strchr(cs, ']');
  1002. if (*cs != '[' || !ce) {
  1003. ns = NewString(s);
  1004. } else {
  1005. String *fmt = NewStringf("%%.%ds", ce-cs-1);
  1006. String *prefix = NewStringf(fmt, cs+1);
  1007. if (0 == Strncmp(ce+1, prefix, Len(prefix))) {
  1008. ns = NewString(ce+1+Len(prefix));
  1009. } else {
  1010. ns = NewString(ce+1);
  1011. }
  1012. }
  1013. }
  1014. return ns;
  1015. }
  1016. #ifdef HAVE_PCRE
  1017. #include <pcre.h>
  1018. static int split_regex_pattern_subst(String *s, String **pattern, String **subst, const char **input)
  1019. {
  1020. const char *pats, *pate;
  1021. const char *subs, *sube;
  1022. /* Locate the search pattern */
  1023. const char *p = Char(s);
  1024. if (*p++ != '/') goto err_out;
  1025. pats = p;
  1026. p = strchr(p, '/');
  1027. if (!p) goto err_out;
  1028. pate = p;
  1029. /* Locate the substitution string */
  1030. subs = ++p;
  1031. p = strchr(p, '/');
  1032. if (!p) goto err_out;
  1033. sube = p;
  1034. *pattern = NewStringWithSize(pats, pate - pats);
  1035. *subst = NewStringWithSize(subs, sube - subs);
  1036. *input = p + 1;
  1037. return 1;
  1038. err_out:
  1039. Swig_error("SWIG", Getline(s), "Invalid regex substitution: '%s'.\n", s);
  1040. exit(1);
  1041. }
  1042. String *replace_captures(int num_captures, const char *input, String *subst, int captures[], String *pattern, String *s)
  1043. {
  1044. String *result = NewStringEmpty();
  1045. const char *p = Char(subst);
  1046. while (*p) {
  1047. /* Copy part without substitutions */
  1048. const char *q = strchr(p, '\\');
  1049. if (!q) {
  1050. Write(result, p, strlen(p));
  1051. break;
  1052. }
  1053. Write(result, p, q - p);
  1054. p = q + 1;
  1055. /* Handle substitution */
  1056. if (*p == '\0') {
  1057. Putc('\\', result);
  1058. } else if (isdigit((unsigned char)*p)) {
  1059. int group = *p++ - '0';
  1060. if (group < num_captures) {
  1061. int l = captures[group*2], r = captures[group*2 + 1];
  1062. if (l != -1) {
  1063. Write(result, input + l, r - l);
  1064. }
  1065. } else {
  1066. Swig_error("SWIG", Getline(s), "PCRE capture replacement failed while matching \"%s\" using \"%s\" - request for group %d is greater than the number of captures %d.\n",
  1067. Char(pattern), input, group, num_captures-1);
  1068. }
  1069. }
  1070. }
  1071. return result;
  1072. }
  1073. /* -----------------------------------------------------------------------------
  1074. * Swig_string_regex()
  1075. *
  1076. * Executes a regular expression substitution. For example:
  1077. *
  1078. * Printf(stderr,"gsl%(regex:/GSL_.*_/\\1/)s","GSL_Hello_") -> gslHello
  1079. * ----------------------------------------------------------------------------- */
  1080. String *Swig_string_regex(String *s) {
  1081. const int pcre_options = 0;
  1082. String *res = 0;
  1083. pcre *compiled_pat = 0;
  1084. const char *pcre_error, *input;
  1085. int pcre_errorpos;
  1086. String *pattern = 0, *subst = 0;
  1087. int captures[30];
  1088. if (split_regex_pattern_subst(s, &pattern, &subst, &input)) {
  1089. int rc;
  1090. compiled_pat = pcre_compile(
  1091. Char(pattern), pcre_options, &pcre_error, &pcre_errorpos, NULL);
  1092. if (!compiled_pat) {
  1093. Swig_error("SWIG", Getline(s), "PCRE compilation failed: '%s' in '%s':%i.\n",
  1094. pcre_error, Char(pattern), pcre_errorpos);
  1095. exit(1);
  1096. }
  1097. rc = pcre_exec(compiled_pat, NULL, input, strlen(input), 0, 0, captures, 30);
  1098. if (rc >= 0) {
  1099. res = replace_captures(rc, input, subst, captures, pattern, s);
  1100. } else if (rc != PCRE_ERROR_NOMATCH) {
  1101. Swig_error("SWIG", Getline(s), "PCRE execution failed: error %d while matching \"%s\" using \"%s\".\n",
  1102. rc, Char(pattern), input);
  1103. exit(1);
  1104. }
  1105. }
  1106. DohDelete(pattern);
  1107. DohDelete(subst);
  1108. pcre_free(compiled_pat);
  1109. return res ? res : NewStringEmpty();
  1110. }
  1111. String *Swig_pcre_version(void) {
  1112. return NewStringf("PCRE Version: %s", pcre_version());
  1113. }
  1114. #else
  1115. String *Swig_string_regex(String *s) {
  1116. Swig_error("SWIG", Getline(s), "PCRE regex support not enabled in this SWIG build.\n");
  1117. exit(1);
  1118. }
  1119. String *Swig_pcre_version(void) {
  1120. return NewStringf("PCRE not used");
  1121. }
  1122. #endif
  1123. /* -----------------------------------------------------------------------------
  1124. * Swig_init()
  1125. *
  1126. * Initialize the SWIG core
  1127. * ----------------------------------------------------------------------------- */
  1128. void Swig_init() {
  1129. /* Set some useful string encoding methods */
  1130. DohEncoding("escape", Swig_string_escape);
  1131. DohEncoding("upper", Swig_string_upper);
  1132. DohEncoding("lower", Swig_string_lower);
  1133. DohEncoding("title", Swig_string_title);
  1134. DohEncoding("ctitle", Swig_string_ccase);
  1135. DohEncoding("lctitle", Swig_string_lccase);
  1136. DohEncoding("utitle", Swig_string_ucase);
  1137. DohEncoding("typecode", Swig_string_typecode);
  1138. DohEncoding("mangle", Swig_string_emangle);
  1139. DohEncoding("command", Swig_string_command);
  1140. DohEncoding("schemify", Swig_string_schemify);
  1141. DohEncoding("strip", Swig_string_strip);
  1142. DohEncoding("regex", Swig_string_regex);
  1143. /* aliases for the case encoders */
  1144. DohEncoding("uppercase", Swig_string_upper);
  1145. DohEncoding("lowercase", Swig_string_lower);
  1146. DohEncoding("camelcase", Swig_string_ccase);
  1147. DohEncoding("lowercamelcase", Swig_string_lccase);
  1148. DohEncoding("undercase", Swig_string_ucase);
  1149. DohEncoding("firstuppercase", Swig_string_first_upper);
  1150. DohEncoding("firstlowercase", Swig_string_first_lower);
  1151. /* Initialize typemaps */
  1152. Swig_typemap_init();
  1153. /* Initialize symbol table */
  1154. Swig_symbol_init();
  1155. /* Initialize type system */
  1156. SwigType_typesystem_init();
  1157. /* Initialize template system */
  1158. SwigType_template_init();
  1159. }