Changed internal handling of string literals. Added new typemap specification syntax with strings.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@704 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Dave Beazley 2000-08-28 20:15:08 +00:00
commit b746069e7d
10 changed files with 219 additions and 107 deletions

View file

@ -301,6 +301,16 @@ DohvPrintf(DOH *so, const char *format, va_list ap)
}
} else {
if (!doh) doh = "";
if (strlen(encoder)) {
DOH *s = NewString(doh);
Seek(s,0, SEEK_SET);
enc = encode(encoder,s);
Delete(s);
doh = Char(enc);
} else {
enc = 0;
}
maxwidth = maxwidth+strlen(newformat)+strlen((char *) doh);
*(fmt++) = 's';
*fmt = 0;
@ -314,6 +324,7 @@ DohvPrintf(DOH *so, const char *format, va_list ap)
if (stemp != obuffer) {
DohFree(stemp);
}
if (enc) Delete(enc);
}
} else {
*(fmt++) = *p;

View file

@ -772,6 +772,8 @@ GUILE::declare_const (char *name, char *, SwigType *type, char *value)
Printf (f_header, "static %s %s = ", SwigType_lstr(type,0), var_name);
if (SwigType_type(type) == T_STRING) {
Printf (f_header, "\"%s\";\n", value);
} else if (SwigType_type(type) == T_CHAR) {
Printf (f_header, "\'%s\';\n", value);
} else {
Printf (f_header, "%s;\n", value);
}

View file

@ -41,7 +41,7 @@ public :
void initialize ();
void headers (void);
void close (void);
void set_module (char *, char **);
void set_module (char *);
void set_init (char *);
void create_command (char *, char *) { };
};

View file

@ -356,7 +356,7 @@ PERL5::close(void) {
Printf(f_wrappers,"%s",type_table);
Delete(type_table);
Printf(stdout,"::: Perl shadow :::\n\n%s",classes);
/* Printf(stdout,"::: Perl shadow :::\n\n%s",classes); */
Printf(f_init,"\t ST(0) = &PL_sv_yes;\n");
Printf(f_init,"\t XSRETURN(1);\n");
@ -1114,14 +1114,15 @@ PERL5::declare_const(char *name, char *, SwigType *type, char *value)
Printf(f_header,"%s\n",setpv);
have_char_func = 1;
}
Printv(vinit, tab4, "swig_setpv(\"", package, "::", name, "\", \"", value, "\");\n",0);
Printf(vinit," swig_setpv(\"%s::%s\",\"%s\");\n", package, name, value);
break;
case T_STRING:
if (!have_char_func) {
Printf(f_header,"%s\n",setpv);
have_char_func = 1;
}
Printv(vinit, tab4, "swig_setpv(\"", package, "::", name, "\", \"", value, "\");\n",0);
Printf(vinit," swig_setpv(\"%s::%s\",\"%s\");\n", package, name, value);
break;
case T_POINTER: case T_ARRAY: case T_REFERENCE:
@ -1711,6 +1712,7 @@ PERL5::cpp_destructor(char *name, char *newname) {
Printv(pcode,
"sub DESTROY {\n",
tab4, "return unless $_[0]->isa('HASH');\n",
tab4, "my $self = tied(%{$_[0]});\n",
tab4, "delete $ITERATORS{$self};\n",
tab4, "if (exists $OWNER{$self}) {\n",

View file

@ -883,10 +883,10 @@ PYTHON::declare_const(char *name, char *, SwigType *type, char *value) {
Printv(const_code, tab4, "{ SWIG_PY_FLOAT, \"", name, "\", 0, (double) ", value, ", 0,0},\n", 0);
break;
case T_CHAR :
Printv(const_code, tab4, "{ SWIG_PY_STRING, \"", name, "\", 0, 0, (void *) \"", value, "\", 0},\n", 0);
Printf(const_code," { SWIG_PY_STRING, \"%s\", 0, 0, (void *) \"%s\", 0 }, \n", name, value);
break;
case T_STRING:
Printv(const_code,tab4, "{ SWIG_PY_STRING, \"", name, "\", 0, 0, (void *) \"", value, "\", 0},\n", 0);
Printf(const_code," { SWIG_PY_STRING, \"%s\", 0, 0, (void *) \"%s\", 0 }, \n", name, value);
break;
case T_POINTER: case T_ARRAY: case T_REFERENCE:
SwigType_remember(type);

View file

@ -143,9 +143,8 @@ int SWIG_main(int argc, char *argv[], Language *l) {
extern void parser_init(void);
DOH *libfiles = 0;
{
// Printf(stdout,"%s\n", SwigType_lcaststr("a(20).a(10).f(int,q(const).p.double).int","a"));
}
/* This registers a function for producing escaped strings */
DohEncoding("escape",Swig_string_escape);
#ifdef MACSWIG
try {

View file

@ -74,7 +74,7 @@ static int InArray = 0; // Used when an array declaration
static DOHString *ArrayString = 0; // Array type attached to parameter names
static DOHString *ArrayBackup = 0;
static char *DefArg = 0; // Default argument hack
static char *ConstChar = 0; // Used to store raw character constants
static String *ConstChar = 0; // Used to store raw character constants
static ParmList *tm_parm = 0; // Parameter list used to hold typemap parameters
static DOHHash *name_hash = 0; // Hash table containing renamings
char *objc_construct = (char *) "new"; // Objective-C constructor
@ -122,6 +122,17 @@ void parser_init() {
temp_type = NewString("");
}
static void my_cplus_declare_const(char *name, char *iname, SwigType *type, char *value) {
String *tval;
if (value) {
tval = NewStringf("%(escape)s",value);
cplus_declare_const(name,iname,type,Char(tval));
Delete(tval);
} else {
cplus_declare_const(name,iname,type,value);
}
}
static TMParm *NewTMParm() {
TMParm *tmp = (TMParm *) malloc(sizeof(TMParm));
tmp->next = 0;
@ -135,71 +146,6 @@ static void add_pointers(SwigType *t, int npointer) {
}
}
//-----------------------------------------------------------------------
// void format_string(char *str)
//
// Replace all of the escape sequences in the string str. It is
// assumed that the new string is smaller than the original!
//-----------------------------------------------------------------------
static void format_string(char *str) {
char *newstr, *c,*c1;
int state;
if (!str) return;
newstr = Swig_copy_string(str);
c = newstr;
c1 = str;
state = 0;
while (*c) {
switch(state) {
case 0:
if (*c == '\\')
state = 1;
else {
*(c1++) = *c;
state = 0;
}
break;
case 1:
// We're in a simple escape sequence figure out what to do
switch(*c) {
case 'n':
*(c1++) = '\n';
break;
case 'f':
*(c1++) = '\f';
break;
case 'r':
*(c1++) = '\r';
break;
case 't':
*(c1++) = '\t';
break;
case '\\':
*(c1++) = '\\';
break;
case '\"':
*(c1++) = '\"';
break;
case '\'':
*(c1++) = '\'';
break;
default:
*(c1++) = '\\';
*(c1++) = *c;
}
state = 0;
break;
default:
*(c1++) = *c;
state = 0;
}
c++;
}
*c1 = 0;
free(newstr);
}
// Emit an external function declaration
static void emit_extern_func(char *decl, SwigType *t, ParmList *L, int extern_type, DOHFile *f) {
@ -398,7 +344,9 @@ void create_constant(char *name, SwigType *type, char *value) {
input_file, line_number, name);
} else {
if (!WrapExtern) { // Only wrap the constant if not in %extern mode
lang->declare_const(name, name, type, value);
String *tval = NewStringf("%(escape)s",value);
lang->declare_const(name, name, type, Char(tval));
Delete(tval);
}
}
scanner_clear_start();
@ -1081,6 +1029,39 @@ statement : INCLUDE STRING LBRACE {
free($3);
}
/* Create a new typemap */
| TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list STRING {
TMParm *p;
skip_brace();
p = $7;
while (p) {
if (strcmp($3,typemap_lang) == 0)
Swig_typemap_register($5,Gettype(p->p),Getname(p->p), $8, p->args);
p = p->next;
}
free($3);
free($5);
}
/* Create a new typemap in current language */
| TYPEMAP LPAREN tm_method RPAREN tm_list STRING {
if (!typemap_lang) {
Printf(stderr,"SWIG internal error. No typemap_lang specified.\n");
Printf(stderr,"typemap on %s : Line %d. will be ignored.\n",input_file,line_number);
FatalError();
} else {
TMParm *p;
skip_brace();
p = $5;
while (p) {
Swig_typemap_register($3,Gettype(p->p),Getname(p->p), $6, p->args);
p = p->next;
}
}
free($3);
}
/* Clear a typemap */
| TYPEMAP LPAREN ID COMMA tm_method RPAREN tm_list SEMI {
@ -1512,7 +1493,7 @@ pname : ID def_args {
$$ = $1;
InArray = 0;
if ($2.type == T_CHAR)
DefArg = Swig_copy_string(ConstChar);
DefArg = Swig_copy_string(Char(ConstChar));
else
DefArg = Swig_copy_string($2.id);
if ($2.id) free($2.id);
@ -1757,22 +1738,20 @@ opt_int : TYPE_INT { }
definetype : { scanner_check_typedef(); } expr {
$$ = $2;
scanner_ignore_typedef();
if (ConstChar) free(ConstChar);
if (ConstChar) Delete(ConstChar);
ConstChar = 0;
}
| STRING {
$$.id = $1;
$$.type = T_CHAR;
if (ConstChar) free(ConstChar);
ConstChar = (char *) malloc(strlen($1)+3);
sprintf(ConstChar,"\"%s\"",$1);
if (ConstChar) Delete(ConstChar);
ConstChar = NewStringf("\"%(escape)s\"",$1);
}
| CHARCONST {
$$.id = $1;
$$.type = T_CHAR;
if (ConstChar) free(ConstChar);
ConstChar = (char *) malloc(strlen($1)+3);
sprintf(ConstChar,"'%s'",$1);
if (ConstChar) Delete(ConstChar);
ConstChar = NewStringf("'%(escape)s'", $1);
}
;
@ -2382,7 +2361,7 @@ cpp_member : type declaration LPAREN parms RPAREN cpp_end {
if (SwigType_isconst($1)) {
iname = make_name($2.id);
if (iname == $2.id) iname = 0;
cplus_declare_const($2.id,iname, $1, $3.id);
my_cplus_declare_const($2.id,iname, $1, $3.id);
} else {
iname = make_name($2.id);
if (iname == $2.id) iname = 0;
@ -2678,7 +2657,7 @@ cpp_enumlist : cpp_enumlist COMMA cpp_edecl {}
cpp_edecl : ID {
if (cplus_mode == CPLUS_PUBLIC) {
temp_typeptr = NewSwigType(T_INT);
cplus_declare_const($1, (char *) 0, temp_typeptr, (char *) 0);
my_cplus_declare_const($1, (char *) 0, temp_typeptr, (char *) 0);
Delete(temp_typeptr);
scanner_clear_start();
}
@ -2686,8 +2665,8 @@ cpp_edecl : ID {
| ID EQUAL etype {
if (cplus_mode == CPLUS_PUBLIC) {
temp_typeptr = NewSwigType(T_INT);
cplus_declare_const($1,(char *) 0, temp_typeptr,(char *) 0);
// OLD : Bug with value cplus_declare_const($1,(char *) 0, temp_typeptr,$3.id);
my_cplus_declare_const($1,(char *) 0, temp_typeptr,(char *) 0);
// OLD : Bug with value my_cplus_declare_const($1,(char *) 0, temp_typeptr,$3.id);
Delete(temp_typeptr);
scanner_clear_start();
}
@ -2695,7 +2674,7 @@ cpp_edecl : ID {
| NAME LPAREN ID RPAREN ID {
if (cplus_mode == CPLUS_PUBLIC) {
temp_typeptr = NewSwigType(T_INT);
cplus_declare_const($5, $3, temp_typeptr, (char *) 0);
my_cplus_declare_const($5, $3, temp_typeptr, (char *) 0);
Delete(temp_typeptr);
scanner_clear_start();
}
@ -2703,7 +2682,7 @@ cpp_edecl : ID {
| NAME LPAREN ID RPAREN ID EQUAL etype {
if (cplus_mode == CPLUS_PUBLIC) {
temp_typeptr = NewSwigType(T_INT);
cplus_declare_const($5,$3, temp_typeptr, (char *) 0);
my_cplus_declare_const($5,$3, temp_typeptr, (char *) 0);
Delete(temp_typeptr);
scanner_clear_start();
}
@ -3125,7 +3104,6 @@ stylelist : ID stylearg styletail {
$$ = $3;
$$.names[$$.count] = Swig_copy_string($1);
$$.values[$$.count] = Swig_copy_string($2);
format_string($$.values[$$.count]);
$$.count++;
}
;
@ -3135,7 +3113,6 @@ styletail : styletail COMMA ID stylearg {
$$ = $1;
$$.names[$$.count] = Swig_copy_string($3);
$$.values[$$.count] = Swig_copy_string($4);
format_string($$.values[$$.count]);
$$.count++;
}
| empty {

View file

@ -340,6 +340,99 @@ void skip_decl(void) {
}
}
}
/* This function is called when a backslash is found in a string */
static void get_escape() {
int result = 0;
int state = 0;
char c;
while(1) {
c = nextchar();
if (c == 0) break;
switch(state) {
case 0:
if (c == 'n') {
yytext[yylen-1] = '\n';
return;
}
if (c == 'r') {
yytext[yylen-1] = '\r';
return;
}
if (c == 't') {
yytext[yylen-1] = '\t';
return;
}
if (c == 'a') {
yytext[yylen-1] = '\a';
return;
}
if (c == 'b') {
yytext[yylen-1] = '\b';
return;
}
if (c == 'f') {
yytext[yylen-1] = '\f';
return;
}
if (c == '\\') {
yytext[yylen-1] = '\\';
return;
}
if (c == 'v') {
yytext[yylen-1] = '\v';
return;
}
if (c == 'e') {
yytext[yylen-1] = '\e';
return;
}
if (c == '\'') {
yytext[yylen-1] = '\'';
return;
}
if (c == '\"') {
yytext[yylen-1] = '\"';
return;
}
if (c == '0') {
state = 10;
}
else if (c == 'x') {
state = 20;
} else {
yytext[yylen-1] = '\\';
yytext[yylen] = c;
yylen++;
return;
}
break;
case 10:
if (!isdigit(c)) {
retract(1);
yytext[yylen-1] = (char) result;
return;
}
result = (result << 3) + (c - '0');
yylen--;
break;
case 20:
if (!isxdigit(c)) {
retract(1);
yytext[yylen-1] = (char) result;
return;
}
if (isdigit(c))
result = (result << 4) + (c - '0');
else
result = (result << 4) + (10 + tolower(c) - 'a');
yylen--;
break;
}
}
return;
}
/**************************************************************
* int yylook()
@ -361,7 +454,7 @@ int yylook(void) {
switch(state) {
case 0 :
if((c = nextchar()) == 0) return(0);
if((c = nextchar()) == 0) return (0);
/* Process delimeters */
@ -513,16 +606,11 @@ int yylook(void) {
yylval.id = Swig_copy_string(yytext+1);
return(STRING);
} else if (c == '\\') {
state = 21; /* Possibly an escape sequence. */
yylen--;
get_escape();
break;
} else state = 2;
break;
case 21: /* An escape sequence. get next character, then go
back to processing strings */
if ((c = nextchar()) == 0) return 0;
state = 2;
break;
case 3: /* a CPP directive */
if (( c= nextchar()) == 0) return 0;
@ -760,18 +848,15 @@ int yylook(void) {
case 9:
if ((c = nextchar()) == 0) return (0);
if (c == '\\') state = 91;
else if (c == '\'') {
if (c == '\\') {
yylen--;
get_escape();
} else if (c == '\'') {
yytext[yylen-1] = 0;
yylval.id = Swig_copy_string(yytext+1);
return(CHARCONST);
}
break;
case 91:
if ((c = nextchar()) == 0) return 0;
state = 9;
break;
case 100:
if ((c = nextchar()) == 0) return (0);

View file

@ -13,6 +13,7 @@ static char cvsroot[] = "$Header$";
#include "swig.h"
#include "swigver.h"
#include <ctype.h>
/* -----------------------------------------------------------------------------
* Swig_copy_string()
@ -99,5 +100,39 @@ DOH *Swig_temp_result(DOH *x) {
return x;
}
/* -----------------------------------------------------------------------------
* 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)) {
Printf(ns,"\\0%o", c);
} else {
Putc(c,ns);
}
}
return ns;
}

View file

@ -277,6 +277,7 @@ extern DOH *Swig_map_match(Hash *ruleset, Hash *parms, int *nmatch);
extern char *Swig_copy_string(const char *c);
extern void Swig_banner(File *f);
extern DOH *Swig_temp_result(DOH *x);
extern String *Swig_string_escape(String *s);
/* --- C Wrappers --- */
extern String *Swig_clocal(SwigType *t, String_or_char *name, String_or_char *value);