swig/Source/Swig/misc.c
Marcelo Matus 7a77a7feb9 several clean/speed ups
git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@7887 626c5289-ae23-0410-ae9c-e8d60b6d4f22
2005-11-27 02:58:24 +00:00

593 lines
13 KiB
C

/* -----------------------------------------------------------------------------
* misc.c
*
* Miscellaneous functions that don't really fit anywhere else.
*
* Author(s) : David Beazley (beazley@cs.uchicago.edu)
*
* Copyright (C) 1999-2000. The University of Chicago
* See the file LICENSE for information on usage and redistribution.
* ----------------------------------------------------------------------------- */
char cvsroot_misc_c[] = "$Header$";
#include "swig.h"
#include <ctype.h>
#include <limits.h>
/* -----------------------------------------------------------------------------
* Swig_copy_string()
*
* Duplicate a NULL-terminate string given as a char *.
* ----------------------------------------------------------------------------- */
char *
Swig_copy_string(const char *s) {
char *c = 0;
if (s) {
c = (char *) malloc(strlen(s)+1);
strcpy(c,s);
}
return c;
}
/* -----------------------------------------------------------------------------
* Swig_banner()
*
* Emits the SWIG identifying banner.
* ----------------------------------------------------------------------------- */
void
Swig_banner(File *f) {
Printf(f,
"/* ----------------------------------------------------------------------------\n\
* This file was automatically generated by SWIG (http://www.swig.org).\n\
* Version %s\n\
* \n\
* This file is not intended to be easily readable and contains a number of \n\
* coding conventions designed to improve portability and efficiency. Do not make\n\
* changes to this file unless you know what you are doing--modify the SWIG \n\
* interface file instead. \n", PACKAGE_VERSION);
/* String too long for ISO compliance */
Printf(f,
" * ----------------------------------------------------------------------------- */\n\n");
}
/* -----------------------------------------------------------------------------
* Swig_string_escape()
*
* Takes a string object and produces a string with escape codes added to it.
* ----------------------------------------------------------------------------- */
String *Swig_string_escape(String *s) {
String *ns;
int c;
ns = NewString("");
while ((c = Getc(s)) != EOF) {
if (c == '\n') {
Printf(ns,"\\n");
} else if (c == '\r') {
Printf(ns,"\\r");
} else if (c == '\t') {
Printf(ns,"\\t");
} else if (c == '\\') {
Printf(ns,"\\\\");
} else if (c == '\'') {
Printf(ns,"\\'");
} else if (c == '\"') {
Printf(ns,"\\\"");
} else if (c == ' ') {
Putc(c,ns);
} else if (!isgraph(c)) {
if (c < 0) c += UCHAR_MAX +1;
Printf(ns,"\\%o", c);
} else {
Putc(c,ns);
}
}
return ns;
}
/* -----------------------------------------------------------------------------
* Swig_string_upper()
*
* Takes a string object and returns a copy that is uppercase
* ----------------------------------------------------------------------------- */
String *Swig_string_upper(String *s) {
String *ns;
int c;
ns = NewString("");
Seek(s,0,SEEK_SET);
while ((c = Getc(s)) != EOF) {
Putc(toupper(c),ns);
}
return ns;
}
/* -----------------------------------------------------------------------------
* Swig_string_lower()
*
* Takes a string object and returns a copy that is lowercase
* ----------------------------------------------------------------------------- */
String *Swig_string_lower(String *s) {
String *ns;
int c;
ns = NewString("");
Seek(s,0,SEEK_SET);
while ((c = Getc(s)) != EOF) {
Putc(tolower(c),ns);
}
return ns;
}
/* -----------------------------------------------------------------------------
* Swig_string_title()
*
* Takes a string object and returns a copy that is lowercase with first letter
* capitalized
* ----------------------------------------------------------------------------- */
String *Swig_string_title(String *s) {
String *ns;
int first = 1;
int c;
ns = NewString("");
Seek(s,0,SEEK_SET);
while ((c = Getc(s)) != EOF) {
Putc(first ? toupper(c) : tolower(c),ns);
first = 0;
}
return ns;
}
/* -----------------------------------------------------------------------------
* Swig_string_typecode()
*
* Takes a string with possible type-escapes in it and replaces them with
* real C datatypes.
* ----------------------------------------------------------------------------- */
String *Swig_string_typecode(String *s) {
String *ns;
int c;
String *tc;
ns = NewString("");
while ((c = Getc(s)) != EOF) {
if (c == '`') {
String *str = 0;
tc = NewString("");
while ((c = Getc(s)) != EOF) {
if (c == '`') break;
Putc(c,tc);
}
str = SwigType_str(tc,0);
Append(ns,str);
Delete(str);
} else {
Putc(c,ns);
if (c == '\'') {
while ((c = Getc(s)) != EOF) {
Putc(c,ns);
if (c == '\'') break;
if (c == '\\') {
c = Getc(s);
Putc(c,ns);
}
}
} else if (c == '\"') {
while ((c = Getc(s)) != EOF) {
Putc(c,ns);
if (c == '\"') break;
if (c == '\\') {
c = Getc(s);
Putc(c,ns);
}
}
}
}
}
return ns;
}
/* -----------------------------------------------------------------------------
* Swig_string_mangle()
*
* Take a string and mangle it by stripping all non-valid C identifier
* characters.
*
* This routine skips unnecessary blank spaces, therefore mangling
* 'char *' and 'char*', 'std::pair<int, int >' and
* 'std::pair<int,int>', produce the same result.
*
* However, note that 'long long' and 'long_long' produce different
* mangled strings.
*
* The mangling method still is not 'perfect', for example std::pair and
* std_pair return the same mangling. This is just a little better
* than before, but it seems to be enough for most of the purposes.
*
* Having a perfect mangling will break some examples and code which
* assume, for example, that A::get_value will be mangled as
* A_get_value.
* ----------------------------------------------------------------------------- */
String *Swig_string_mangle(const String *s) {
#if 0
/* old mangling, not suitable for using in macros */
String *t = Copy(s);
char *c = Char(t);
while (*c) {
if (!isalnum(*c)) *c = '_';
c++;
}
return t;
#else
String *result = NewString("");
int space = 0;
int state = 0;
char *pc, *cb;
String *b = Copy(s);
if (SwigType_istemplate(b)) {
String *st = Swig_symbol_template_deftype(b, 0);
String *sq = Swig_symbol_type_qualify(st,0);
String *t = SwigType_namestr(sq);
Delete(st);
Delete(sq);
Delete(b);
b = t ;
}
pc = cb = Char(b);
while (*pc) {
char c = *pc;
if (isalnum((int)c) || (c == '_')) {
state = 1;
if (space && (space == state)) {
Append(result,"_SS_");
}
space = 0;
Printf(result,"%c",(int)c);
} else {
if (isspace((int)c)) {
space = state;
++pc;
continue;
} else {
state = 3;
space = 0;
}
switch(c) {
case '.':
if ((cb != pc) && (*(pc - 1) == 'p')) {
Append(result,"_");
++pc;
continue;
} else {
c = 'f';
}
break;
case ':':
if (*(pc + 1) == ':') {
Append(result,"_");
++pc; ++pc;
continue;
}
break;
case '*':
c = 'm';
break;
case '&':
c = 'A';
break;
case '<':
c = 'l';
break;
case '>':
c = 'g';
break;
case '=':
c = 'e';
break;
case ',':
c = 'c';
break;
case '(':
c = 'p';
break;
case ')':
c = 'P';
break;
case '[':
c = 'b';
break;
case ']':
c = 'B';
break;
case '^':
c = 'x';
break;
case '|':
c = 'o';
break;
case '~':
c = 'n';
break;
case '!':
c = 'N';
break;
case '%':
c = 'M';
break;
case '?':
c = 'q';
break;
case '+':
c = 'a';
break;
case '-':
c = 's';
break;
case '/':
c = 'd';
break;
default:
break;
}
if (isalpha((int)c)) {
Printf(result,"_S%c_",(int)c);
} else{
Printf(result,"_S%02X_",(int)c);
}
}
++pc;
}
Delete(b);
return result;
#endif
}
/* -----------------------------------------------------------------------------
* Swig_scopename_prefix()
*
* Take a qualified name like "A::B::C" and return the scope name.
* In this case, "A::B". Returns NULL if there is no base.
* ----------------------------------------------------------------------------- */
String *
Swig_scopename_prefix(String *s) {
char *tmp = Char(s);
char *c = tmp;
char *cc = c;
char *co = 0;
if (!strstr(c,"::")) return 0;
if ((co = strstr(cc,"operator "))) {
if (co == cc) {
return 0;
} else {
String *prefix = NewStringWithSize(cc, co - cc - 2);
return prefix;
}
}
while (*c) {
if ((*c == ':') && (*(c+1) == ':')) {
cc = c;
c += 2;
} else {
if (*c == '<') {
int level = 1;
c++;
while (*c && level) {
if (*c == '<') level++;
if (*c == '>') level--;
c++;
}
} else {
c++;
}
}
}
if (cc != tmp) {
return NewStringWithSize(tmp, cc - tmp);
} else {
return 0;
}
}
/* -----------------------------------------------------------------------------
* Swig_scopename_last()
*
* Take a qualified name like "A::B::C" and returns the last. In this
* case, "C".
* ----------------------------------------------------------------------------- */
String *
Swig_scopename_last(String *s) {
char *tmp = Char(s);
char *c = tmp;
char *cc = c;
char *co = 0;
if (!strstr(c,"::")) return NewString(s);
if ((co = strstr(cc,"operator "))) {
return NewString(co);
}
while (*c) {
if ((*c == ':') && (*(c+1) == ':')) {
cc = c;
c += 2;
} else {
if (*c == '<') {
int level = 1;
c++;
while (*c && level) {
if (*c == '<') level++;
if (*c == '>') level--;
c++;
}
} else {
c++;
}
}
}
return NewString(cc+2);
}
/* -----------------------------------------------------------------------------
* Swig_scopename_first()
*
* Take a qualified name like "A::B::C" and returns the first scope name.
* In this case, "A". Returns NULL if there is no base.
* ----------------------------------------------------------------------------- */
String *
Swig_scopename_first(String *s) {
char *tmp = Char(s);
char *c = tmp;
char *co = 0;
if (!strstr(c,"::")) return 0;
if ((co = strstr(c,"operator "))) {
if (co == c) {
return 0;
}
} else {
co = c + Len(s);
}
while (*c && (c != co)) {
if ((*c == ':') && (*(c+1) == ':')) {
break;
} else {
if (*c == '<') {
int level = 1;
c++;
while (*c && level) {
if (*c == '<') level++;
if (*c == '>') level--;
c++;
}
} else {
c++;
}
}
}
if (*c && (c != tmp)) {
return NewStringWithSize(tmp, c - tmp);
} else {
return 0;
}
}
/* -----------------------------------------------------------------------------
* Swig_scopename_suffix()
*
* Take a qualified name like "A::B::C" and returns the suffix.
* In this case, "B::C". Returns NULL if there is no suffix.
* ----------------------------------------------------------------------------- */
String *
Swig_scopename_suffix(String *s) {
char *tmp = Char(s);
char *c = tmp;
char *co = 0;
if (!strstr(c,"::")) return 0;
if ((co = strstr(c,"operator "))) {
if (co == c) return 0;
}
while (*c) {
if ((*c == ':') && (*(c+1) == ':')) {
break;
} else {
if (*c == '<') {
int level = 1;
c++;
while (*c && level) {
if (*c == '<') level++;
if (*c == '>') level--;
c++;
}
} else {
c++;
}
}
}
if (*c && (c != tmp)) {
return NewString(c+2);
} else {
return 0;
}
}
/* -----------------------------------------------------------------------------
* Swig_scopename_check()
*
* Checks to see if a name is qualified with a scope name
* ----------------------------------------------------------------------------- */
int Swig_scopename_check(String *s) {
char *c = Char(s);
char *co = 0;
if ((co = strstr(c,"operator "))) {
if (co == c) return 0;
}
if (!strstr(c,"::")) return 0;
while (*c) {
if ((*c == ':') && (*(c+1) == ':')) {
return 1;
} else {
if (*c == '<') {
int level = 1;
c++;
while (*c && level) {
if (*c == '<') level++;
if (*c == '>') level--;
c++;
}
} else {
c++;
}
}
}
return 0;
}
/* -----------------------------------------------------------------------------
* Swig_init()
*
* Initialize the SWIG core
* ----------------------------------------------------------------------------- */
void
Swig_init() {
/* Set some useful string encoding methods */
DohEncoding("escape", Swig_string_escape);
DohEncoding("upper", Swig_string_upper);
DohEncoding("lower", Swig_string_lower);
DohEncoding("title", Swig_string_title);
DohEncoding("typecode",Swig_string_typecode);
/* Initialize typemaps */
Swig_typemap_init();
/* Initialize symbol table */
Swig_symbol_init();
/* Initialize type system */
SwigType_typesystem_init();
/* Initialize template system */
SwigType_template_init();
}