From: Rhodri James Date: Wed, 5 Jul 2017 14:56:10 +0000 (+0100) Subject: Sort notations by name in xmlwf for conformance tests X-Git-Tag: R_2_2_5~39^2~8 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=688ecaa7ab52bc6e7124b345c08193e03b435ead;p=libexpat Sort notations by name in xmlwf for conformance tests --- diff --git a/expat/xmlwf/xmlwf.c b/expat/xmlwf/xmlwf.c index 1f63b341..93a22f57 100644 --- a/expat/xmlwf/xmlwf.c +++ b/expat/xmlwf/xmlwf.c @@ -307,49 +307,108 @@ startDoctypeDecl(void *UNUSED_P(userData), currentDoctypeName = xmlCharDup(doctypeName); } +static void +freeNotations(void) +{ + while (notationListHead != NULL) { + NotationList *next = notationListHead->next; + free((void *)notationListHead->notationName); + free((void *)notationListHead->systemId); + free((void *)notationListHead->publicId); + free(notationListHead); + notationListHead = next; + } +} + +static int xcscmp(const XML_Char *xs, const XML_Char *xt) +{ + while (*xs != 0 && *xt != 0) { + if (*xs < *xt) + return -1; + if (*xs > *xt) + return 1; + xs++; + xt++; + } + if (*xs < *xt) + return -1; + if (*xs > *xt) + return 1; + return 0; +} + +static int +notationCmp(const void *a, const void *b) +{ + const NotationList * const n1 = *(NotationList **)a; + const NotationList * const n2 = *(NotationList **)b; + + return xcscmp(n1->notationName, n2->notationName); +} + static void XMLCALL endDoctypeDecl(void *userData) { FILE *fp = (FILE *)userData; + NotationList **notations; + int notationCount = 0; + NotationList *p; + int i; - if (notationListHead != NULL) { - /* Output the DOCTYPE header */ - fputts(T("next; - fputts(T("notationName, fp); - if (notationListHead->publicId != NULL) { - fputts(T(" PUBLIC '"), fp); - fputts(notationListHead->publicId, fp); + /* How many notations do we have? */ + for (p = notationListHead; p != NULL; p = p->next) + notationCount++; + if (notationCount == 0) + return; /* Nothing to report */ + + notations = malloc(notationCount * sizeof(NotationList *)); + if (notations == NULL) { + fprintf(stderr, "Unable to sort notations"); + freeNotations(); + return; + } + + for (p = notationListHead, i = 0; + i < notationCount; + p = p->next, i++) { + notations[i] = p; + } + qsort(notations, notationCount, sizeof(NotationList *), notationCmp); + + /* Output the DOCTYPE header */ + fputts(T("notationName, fp); + if (notations[i]->publicId != NULL) { + fputts(T(" PUBLIC '"), fp); + fputts(notations[i]->publicId, fp); + puttc(T('\''), fp); + if (notations[i]->systemId != NULL) { + puttc(T(' '), fp); puttc(T('\''), fp); - if (notationListHead->systemId != NULL) { - puttc(T(' '), fp); - puttc(T('\''), fp); - fputts(notationListHead->systemId, fp); - puttc(T('\''), fp); - } - } - else if (notationListHead->systemId != NULL) { - fputts(T(" SYSTEM '"), fp); - fputts(notationListHead->systemId, fp); + fputts(notations[i]->systemId, fp); puttc(T('\''), fp); } - puttc(T('>'), fp); - puttc(T('\n'), fp); - free((void *)notationListHead->notationName); - free((void *)notationListHead->systemId); - free((void *)notationListHead->publicId); - free(notationListHead); - notationListHead = next; } - /* Finally end the DOCTYPE */ - fputts(T("]>\n"), fp); + else if (notations[i]->systemId != NULL) { + fputts(T(" SYSTEM '"), fp); + fputts(notations[i]->systemId, fp); + puttc(T('\''), fp); + } + puttc(T('>'), fp); + puttc(T('\n'), fp); } + + /* Finally end the DOCTYPE */ + fputts(T("]>\n"), fp); + + free(notations); + freeNotations(); free((void *)currentDoctypeName); currentDoctypeName = NULL; }