summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Wette <karl.wette@ligo.org>2013-02-19 11:46:27 +0100
committerWilliam S Fulton <wsf@fultondesigns.co.uk>2013-02-19 20:05:45 +0000
commit9d330a99703f079bdff5a8d7945cc1d2d7c56f53 (patch)
tree304d45e9034e5e2bcba9f2c0238c28a35ab6a452
parentd1b40b468b607c4c71f424a1a2d36c5b240ca975 (diff)
downloadswig-9d330a99703f079bdff5a8d7945cc1d2d7c56f53.tar.gz
Fix qualifier parsing in SwigType_add_qualifier()
- use list to ensure qualifiers are unique and sorted - now allows 'qual' to contain multiple qualifiers
-rw-r--r--Source/Swig/typeobj.c78
1 files changed, 42 insertions, 36 deletions
diff --git a/Source/Swig/typeobj.c b/Source/Swig/typeobj.c
index 20caa9ec9..cb9327dc7 100644
--- a/Source/Swig/typeobj.c
+++ b/Source/Swig/typeobj.c
@@ -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);
+
+ /* create list of all qualifiers from string */
+ qlist = Split(allq, ' ', INT_MAX);
+ Delete(allq);
- /* Add the qualifier to the existing list. */
+ /* 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;