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