C# 'out' or 'ref' removal improvements in director typemaps.

- Add support to DOH Replace for not replacing inside C comments
- Fix removing 'out' or 'ref' when these are present in C comments
  in cstype typemaps.

Closes #1628
This commit is contained in:
William S Fulton 2019-11-26 19:39:28 +00:00
parent 6fb345feb2
commit 18b2dcd222
5 changed files with 126 additions and 13 deletions

View File

@ -10,8 +10,8 @@
%typemap(ctype) int* readLen, int* writeLen "/*ctype*/ int*" %typemap(ctype) int* readLen, int* writeLen "/*ctype*/ int*"
%typemap(imtype) int* readLen, int* writeLen "/*imtype*/ out int" %typemap(imtype) int* readLen, int* writeLen "/*imtype*/ out int"
%typemap(cstype) int* readLen "/*cstype*/ out int" %typemap(cstype) int* readLen "/*cstype*/ out int"
//%typemap(cstype) int* writeLen "/*out cstype out*/ out int" // Note for below: 'out' used in typemap comment
%apply int *readLen { int* writeLen } // Replaced above - 'out' in a comment is not working yet %typemap(cstype) int* writeLen "/*out cstype out*/ out int"
%typemap(csin) int* readLen, int* writeLen "/*csin*/ out $csinput" %typemap(csin) int* readLen, int* writeLen "/*csin*/ out $csinput"
%typemap(in) int* readLen, int* writeLen %{/*in*/ $1 = ($1_ltype)$input; %} %typemap(in) int* readLen, int* writeLen %{/*in*/ $1 = ($1_ltype)$input; %}
%typemap(out) int* readLen, int* writeLen %{/*out*/ $result = (void *)$1; %} %typemap(out) int* readLen, int* writeLen %{/*out*/ $result = (void *)$1; %}

View File

@ -73,11 +73,17 @@ Replace(obj, orig, rep, flags) Replace occurrences of orig with rep.
Chop(obj) Remove trailing whitespace Chop(obj) Remove trailing whitespace
flags is one of the following: flags is one of the following:
DOH_REPLACE_ANY DOH_REPLACE_ID
DOH_REPLACE_NOQUOTE DOH_REPLACE_ID_BEGIN
DOH_REPLACE_ID DOH_REPLACE_ID_END
DOH_REPLACE_FIRST DOH_REPLACE_NUMBER_END
and can be combined with one or more of the following:
DOH_REPLACE_ANY
DOH_REPLACE_NOQUOTE
DOH_REPLACE_NOCOMMENT
DOH_REPLACE_FIRST
Callable Operations Callable Operations
------------------- -------------------
Call(obj, args) Perform a function call with arguments args. Call(obj, args) Perform a function call with arguments args.

View File

@ -289,11 +289,12 @@ extern char *DohStrchr(const DOHString_or_char *s1, int ch);
#define DOH_REPLACE_ANY 0x01 #define DOH_REPLACE_ANY 0x01
#define DOH_REPLACE_NOQUOTE 0x02 #define DOH_REPLACE_NOQUOTE 0x02
#define DOH_REPLACE_ID 0x04 #define DOH_REPLACE_NOCOMMENT 0x04
#define DOH_REPLACE_FIRST 0x08 #define DOH_REPLACE_ID 0x08
#define DOH_REPLACE_ID_BEGIN 0x10 #define DOH_REPLACE_FIRST 0x10
#define DOH_REPLACE_ID_END 0x20 #define DOH_REPLACE_ID_BEGIN 0x20
#define DOH_REPLACE_NUMBER_END 0x40 #define DOH_REPLACE_ID_END 0x40
#define DOH_REPLACE_NUMBER_END 0x80
#define Replaceall(s,t,r) DohReplace(s,t,r,DOH_REPLACE_ANY) #define Replaceall(s,t,r) DohReplace(s,t,r,DOH_REPLACE_ANY)
#define Replaceid(s,t,r) DohReplace(s,t,r,DOH_REPLACE_ID) #define Replaceid(s,t,r) DohReplace(s,t,r,DOH_REPLACE_ID)

View File

@ -595,6 +595,13 @@ static char *end_quote(char *s) {
} }
} }
static char *end_comment(char *s) {
char *substring = strstr(s, "*/");
if (substring)
++substring;
return substring;
}
static char *match_simple(char *base, char *s, char *token, int tokenlen) { static char *match_simple(char *base, char *s, char *token, int tokenlen) {
(void) base; (void) base;
(void) tokenlen; (void) tokenlen;
@ -677,6 +684,7 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co
int ic; int ic;
int rcount = 0; int rcount = 0;
int noquote = 0; int noquote = 0;
int nocomment = 0;
char *c, *s, *t, *first; char *c, *s, *t, *first;
char *q, *q2; char *q, *q2;
char *base; char *base;
@ -698,6 +706,11 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co
if (flags & DOH_REPLACE_NOQUOTE) if (flags & DOH_REPLACE_NOQUOTE)
noquote = 1; noquote = 1;
if (flags & DOH_REPLACE_NOCOMMENT)
nocomment = 1;
assert(!(noquote && nocomment)); /* quote and comment combination not implemented */
/* If we are not replacing inside quotes, we need to do a little extra work */ /* If we are not replacing inside quotes, we need to do a little extra work */
if (noquote) { if (noquote) {
q = strpbrk(base, "\"\'"); q = strpbrk(base, "\"\'");
@ -723,6 +736,31 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co
} }
} }
/* If we are not replacing inside comments, we need to do a little extra work */
if (nocomment) {
q = strstr(base, "/*");
if (!q) {
nocomment = 0; /* Well, no comments to worry about. Oh well */
} else {
while (q && (q < s)) {
/* First match was found inside a comment. Try to find another match */
q2 = end_comment(q);
if (!q2) {
return 0;
}
if (q2 > s) {
/* Find next match */
s = (*match) (base, q2 + 1, token, tokenlen);
}
if (!s)
return 0; /* Oh well, no matches */
q = strstr(q2 + 1, "/*");
if (!q)
nocomment = 0; /* No more comments */
}
}
}
first = s; first = s;
replen = (int)strlen(rep); replen = (int)strlen(rep);
@ -768,6 +806,28 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co
} }
} }
} }
if (nocomment) {
q = strstr(s, "/*");
if (!q) {
nocomment = 0;
} else {
while (q && (q < c)) {
/* First match was found inside a comment. Try to find another match */
q2 = end_comment(q);
if (!q2) {
c = 0;
break;
}
if (q2 > c)
c = (*match) (base, q2 + 1, token, tokenlen);
if (!c)
break;
q = strstr(q2 + 1, "/*");
if (!q)
nocomment = 0; /* No more comments */
}
}
}
if (delta) { if (delta) {
if (c) { if (c) {
memmove(t, s, c - s); memmove(t, s, c - s);
@ -823,6 +883,29 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co
} }
} }
} }
if (nocomment) {
q = strstr(s, "/*");
if (!q) {
break;
} else {
while (q && (q < c)) {
/* First match was found inside a comment. Try to find another match */
q2 = end_comment(q);
if (!q2) {
c = 0;
break;
}
if (q2 > c) {
c = (*match) (base, q2 + 1, token, tokenlen);
if (!c)
break;
}
q = strstr(q2 + 1, "/*");
if (!q)
nocomment = 0;
}
}
}
if (c) { if (c) {
rcount++; rcount++;
ic--; ic--;
@ -875,6 +958,29 @@ static int replace_simple(String *str, char *token, char *rep, int flags, int co
} }
} }
} }
if (nocomment) {
q = strstr(s, "/*");
if (!q) {
nocomment = 0;
} else {
while (q && (q < c)) {
/* First match was found inside a comment. Try to find another match */
q2 = end_comment(q);
if (!q2) {
c = 0;
break;
}
if (q2 > c) {
c = (*match) (base, q2 + 1, token, tokenlen);
if (!c)
break;
}
q = strstr(q2 + 1, "/*");
if (!q)
nocomment = 0; /* No more comments */
}
}
}
if (i < (rcount - 1)) { if (i < (rcount - 1)) {
memcpy(t, s, c - s); memcpy(t, s, c - s);
t += (c - s); t += (c - s);

View File

@ -4064,7 +4064,7 @@ public:
/* Get the C# parameter type */ /* Get the C# parameter type */
if ((tm = Getattr(p, "tmap:cstype"))) { if ((tm = Getattr(p, "tmap:cstype"))) {
substituteClassname(pt, tm); substituteClassname(pt, tm);
int flags = DOH_REPLACE_FIRST | DOH_REPLACE_ID_BEGIN; int flags = DOH_REPLACE_FIRST | DOH_REPLACE_ID_BEGIN | DOH_REPLACE_NOCOMMENT;
if (Replace(tm, "ref ", "", flags) || Replace(tm, "ref\t", "", flags)) { if (Replace(tm, "ref ", "", flags) || Replace(tm, "ref\t", "", flags)) {
Printf(proxy_method_types, "typeof(%s).MakeByRefType()", tm); Printf(proxy_method_types, "typeof(%s).MakeByRefType()", tm);
} else if (Replace(tm, "out ", "", flags) || Replace(tm, "out\t", "", flags)) { } else if (Replace(tm, "out ", "", flags) || Replace(tm, "out\t", "", flags)) {