Fix qualifier parsing in SwigType_add_qualifier()

- use list to ensure qualifiers are unique and sorted
- now allows 'qual' to contain multiple qualifiers
This commit is contained in:
Karl Wette 2013-02-19 11:46:27 +01:00 • committed by William S Fulton
commit 9d330a9970

View file

@ -16,6 +16,7 @@
#include "swig.h" #include "swig.h"
#include <ctype.h> #include <ctype.h>
#include <limits.h>
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* Synopsis * Synopsis
@ -425,61 +426,66 @@ int SwigType_isreference(const SwigType *t) {
* Repeated qualifications have no effect. Moreover, the order of qualifications * Repeated qualifications have no effect. Moreover, the order of qualifications
* is alphabetical---meaning that "const volatile" and "volatile const" are * is alphabetical---meaning that "const volatile" and "volatile const" are
* stored in exactly the same way as "q(const volatile)". * stored in exactly the same way as "q(const volatile)".
* 'qual' can be a list of multiple qualifiers in any order, separated by spaces.
* ----------------------------------------------------------------------------- */ * ----------------------------------------------------------------------------- */
SwigType *SwigType_add_qualifier(SwigType *t, const_String_or_char_ptr qual) { /* Helper function to sort the mangled list */
String *newq; static int SwigType_compare_qualifiers(const DOH *a, const DOH *b) {
int sz, added = 0; return strcmp(Char(a), Char(b));
char *q, *cqual; }
char *c = Char(t); SwigType *SwigType_add_qualifier(SwigType *t, const_String_or_char_ptr qual) {
List *qlist;
String *allq, *newq, *q;
int i, sz;
char *c, *cqual, *cq, *cqprev;
c = Char(t);
cqual = Char(qual); cqual = Char(qual);
if (!(strncmp(c, "q(", 2) == 0)) { /* if 't' has no qualifiers and 'qual' is a single qualifier, simply add it */
if ((strncmp(c, "q(", 2) != 0) && (strstr(cqual, " ") == NULL)) {
String *temp = NewStringf("q(%s).", cqual); String *temp = NewStringf("q(%s).", cqual);
Insert(t, 0, temp); Insert(t, 0, temp);
Delete(temp); Delete(temp);
return t; return t;
} }
/* The type already has a qualifier on it. In this case, we first check to /* create string of all qualifiers */
see if the qualifier is already specified. In that case do nothing. if (strncmp(c, "q(", 2) == 0) {
If it is a new qualifier, we add it to the qualifier list in alphabetical allq = SwigType_parm(t);
order */ Append(allq, " ");
SwigType_del_element(t); /* delete old qualifier list from 't' */
sz = element_size(c); } else {
allq = NewStringEmpty();
if (strstr(c, cqual)) {
/* Qualifier already added */
return t;
} }
Append(allq, qual);
/* Add the qualifier to the existing list. */ /* create list of all qualifiers from string */
qlist = Split(allq, ' ', INT_MAX);
Delete(allq);
/* sort list */
SortList(qlist, SwigType_compare_qualifiers);
/* create new qualifier string from unique elements of list */
sz = Len(qlist);
newq = NewString("q("); newq = NewString("q(");
q = c + 2; cqprev = NULL;
q = strtok(q, " )."); for (i = 0; i < sz; ++i) {
while (q) { q = Getitem(qlist, i);
if (strcmp(cqual, q) < 0) { cq = Char(q);
/* New qualifier is less that current qualifier. We need to insert it */ if (cqprev == NULL || strcmp(cqprev, cq) != 0) {
Append(newq, cqual); if (i > 0) {
Append(newq, " "); Append(newq, " ");
Append(newq, q); }
added = 1;
} else {
Append(newq, q); Append(newq, q);
cqprev = cq;
} }
q = strtok(NULL, " ).");
if (q) {
Append(newq, " ");
}
}
if (!added) {
Append(newq, " ");
Append(newq, cqual);
} }
Append(newq, ")."); Append(newq, ").");
Delslice(t, 0, sz); Delete(qlist);
/* replace qualifier string with new one */
Insert(t, 0, newq); Insert(t, 0, newq);
Delete(newq); Delete(newq);
return t; return t;