diff options
author | Karl Wette <karl.wette@ligo.org> | 2013-02-19 11:46:27 +0100 |
---|---|---|
committer | William S Fulton <wsf@fultondesigns.co.uk> | 2013-02-19 20:05:45 +0000 |
commit | 9d330a99703f079bdff5a8d7945cc1d2d7c56f53 (patch) | |
tree | 304d45e9034e5e2bcba9f2c0238c28a35ab6a452 | |
parent | d1b40b468b607c4c71f424a1a2d36c5b240ca975 (diff) | |
download | swig-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.c | 78 |
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; |