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 <ctype.h>
#include <limits.h>
/* -----------------------------------------------------------------------------
* Synopsis
@ -425,61 +426,66 @@ int SwigType_isreference(const SwigType *t) {
* Repeated qualifications have no effect. Moreover, the order of qualifications
* is alphabetical---meaning that "const volatile" and "volatile const" are
* 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) {
String *newq;
int sz, added = 0;
char *q, *cqual;
/* Helper function to sort the mangled list */
static int SwigType_compare_qualifiers(const DOH *a, const DOH *b) {
return strcmp(Char(a), Char(b));
}
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);
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);
Insert(t, 0, temp);
Delete(temp);
return t;
}
/* The type already has a qualifier on it. In this case, we first check to
see if the qualifier is already specified. In that case do nothing.
If it is a new qualifier, we add it to the qualifier list in alphabetical
order */
sz = element_size(c);
if (strstr(c, cqual)) {
/* Qualifier already added */
return t;
/* create string of all qualifiers */
if (strncmp(c, "q(", 2) == 0) {
allq = SwigType_parm(t);
Append(allq, " ");
SwigType_del_element(t); /* delete old qualifier list from 't' */
} else {
allq = NewStringEmpty();
}
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(");
q = c + 2;
q = strtok(q, " ).");
while (q) {
if (strcmp(cqual, q) < 0) {
/* New qualifier is less that current qualifier. We need to insert it */
Append(newq, cqual);
Append(newq, " ");
Append(newq, q);
added = 1;
} else {
cqprev = NULL;
for (i = 0; i < sz; ++i) {
q = Getitem(qlist, i);
cq = Char(q);
if (cqprev == NULL || strcmp(cqprev, cq) != 0) {
if (i > 0) {
Append(newq, " ");
}
Append(newq, q);
cqprev = cq;
}
q = strtok(NULL, " ).");
if (q) {
Append(newq, " ");
}
}
if (!added) {
Append(newq, " ");
Append(newq, cqual);
}
Append(newq, ").");
Delslice(t, 0, sz);
Delete(qlist);
/* replace qualifier string with new one */
Insert(t, 0, newq);
Delete(newq);
return t;