⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xml.c

📁 linux subdivision ying gai ke yi le ba
💻 C
字号:
/*    neon test suite   Copyright (C) 2002-2003, Joe Orton <joe@manyfish.co.uk>   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.     This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.     You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include "config.h"#include <sys/types.h>#ifdef HAVE_STDLIB_H#include <stdlib.h>#endif#ifdef HAVE_UNISTD_H#include <unistd.h>#endif#include "ne_xml.h"#include "tests.h"#include "child.h"#include "utils.h"/* A set of SAX handlers which serialize SAX events back into a  * pseudo-XML-like string. */static int startelm(void *userdata, int state,                    const char *nspace, const char *name,		    const char **atts){    ne_buffer *buf = userdata;    int n;    if (strcmp(name, "decline") == 0)        return NE_XML_DECLINE;    ne_buffer_concat(buf, "<", "{", nspace, "}", name, NULL);    for (n = 0; atts && atts[n] != NULL; n+=2) {	ne_buffer_concat(buf, " ", atts[n], "='", atts[n+1], "'", NULL);    }    ne_buffer_zappend(buf, ">");    return state + 1;}static int chardata(void *userdata, int state, const char *cdata, size_t len){    ne_buffer *buf = userdata;    ne_buffer_append(buf, cdata, len);    return !strncmp(cdata, "!ABORT!", len);}static int endelm(void *userdata, int state,                  const char *nspace, const char *name){    ne_buffer *buf = userdata;    ne_buffer_concat(buf, "</{", nspace, "}", name, ">", NULL);    return 0;}/* A set of SAX handlers which do as above, but change some element * names; used to check nested SAX handling is working properly.  */static int startelm_xform(void *userdata, int state,                          const char *nspace, const char *name,                          const char **atts){    if (strcmp(nspace, "two") == 0)        return startelm(userdata, state, nspace, "xform", atts);    else        return NE_XML_DECLINE;}static int endelm_xform(void *userdata, int state,                        const char *nspace, const char *name){    if (strcmp(nspace, "two") == 0)        return endelm(userdata, state, nspace, "xform");    else        return NE_XML_DECLINE;}/* A set of SAX handlers which verify that state handling is working * correctly. */static int startelm_state(void *userdata, int parent,                          const char *nspace, const char *name,                          const char **atts){    int n;    if (strcmp(nspace, "state") != 0)        return NE_XML_DECLINE;    for (n = 0; atts[n]; n += 2) {        if (strcmp(atts[n], "parent") == 0) {            int expected = atoi(atts[n+1]);                        if (expected != parent) {                char err[50];                sprintf(err, "parent state of %s was %d not %d", name, parent,                     expected);                ne_buffer_zappend(userdata, err);            }        }    }    return atoi(name+1);    }static int endelm_state(void *userdata, int state,                        const char *nspace, const char *name){    int expected = atoi(name + 1);    ne_buffer *buf = userdata;        if (state != expected)        ne_buffer_concat(buf, "wrong state in endelm of ", name, NULL);        return 0;}/* A set of SAX handlers which verify that abort handling is working * correctly. */static int startelm_abort(void *buf, int parent,                          const char *nspace, const char *name,                          const char **atts){    if (strcmp(name, "abort-start") == 0) {        ne_buffer_zappend(buf, "ABORT");        return NE_XML_ABORT;    } else        return startelm(buf, parent, nspace, name, atts);}static int endelm_abort(void *buf, int state,                        const char *nspace, const char *name){    if (strcmp(name, "abort-end") == 0) {        ne_buffer_zappend(buf, "ABORT");        return -1;    } else        return 0;}enum match_type {    match_valid = 0,    match_invalid,    match_nohands,    match_encoding};static int parse_match(const char *doc, const char *result, enum match_type t){    ne_xml_parser *p = ne_xml_create();    ne_buffer *buf = ne_buffer_create();    if (t == match_invalid)        ne_xml_push_handler(p, startelm_abort, chardata, endelm_abort, buf);    if (t != match_encoding && t != match_nohands) {        ne_xml_push_handler(p, startelm_state, NULL, endelm_state, buf);        ne_xml_push_handler(p, startelm, chardata, endelm, buf);        ne_xml_push_handler(p, startelm_xform, chardata, endelm_xform, buf);    }    ne_xml_parse(p, doc, strlen(doc));    ne_xml_parse(p, "", 0);        if (t == match_invalid)        ONV(ne_xml_valid(p), ("parse did not fail: %s", buf->data));    else        ONV(!ne_xml_valid(p), ("parse failed: %s", ne_xml_get_error(p)));        if (t == match_encoding) {        const char *enc = ne_xml_doc_encoding(p);        ONV(strcmp(enc, result), ("encoding was `%s' not `%s'", enc, result));    } else if (t == match_valid)        ONV(strcmp(result, buf->data),            ("result mismatch: %s not %s", buf->data, result));            ne_xml_destroy(p);    ne_buffer_destroy(buf);    return OK;}static int matches(void){#define PFX "<?xml version='1.0' encoding='utf-8'?>\r\n"#define E(ns, n) "<{" ns "}" n "></{" ns "}" n ">"    static const struct {	const char *in, *out;        enum match_type invalid;    } ms[] = {                /*** Simplest tests ***/	{ PFX "<hello/>", "<{}hello></{}hello>"},	{ PFX "<hello foo='bar'/>",	  "<{}hello foo='bar'></{}hello>"},	/*** Tests for character data handling. ***/	{ PFX "<hello> world</hello>", "<{}hello> world</{}hello>"},	/* test for cdata between elements. */	{ PFX "<hello>\r\n<wide>  world</wide></hello>",	  "<{}hello>\n<{}wide>  world</{}wide></{}hello>"},	/*** Tests for namespace handling. ***/#define NSA "xmlns:foo='bar'"	{ PFX "<foo:widget " NSA "/>", 	  "<{bar}widget " NSA ">"	  "</{bar}widget>" },	/* inherited namespace expansion. */	{ PFX "<widget " NSA "><foo:norman/></widget>",	  "<{}widget " NSA ">" E("bar", "norman") "</{}widget>"},	{ PFX "<widget " NSA " xmlns:abc='def' xmlns:g='z'>"          "<foo:norman/></widget>",	  "<{}widget " NSA " xmlns:abc='def' xmlns:g='z'>"           E("bar", "norman") "</{}widget>"},	/* empty namespace default takes precedence. */	{ PFX "<widget xmlns='foo'><smidgen xmlns=''><norman/>"	  "</smidgen></widget>",	  "<{foo}widget xmlns='foo'><{}smidgen xmlns=''>" 	  E("", "norman") 	  "</{}smidgen></{foo}widget>" },        /* inherited empty namespace default */        { PFX "<bar xmlns='foo'><grok xmlns=''><fish/></grok></bar>",          "<{foo}bar xmlns='foo'><{}grok xmlns=''>"           E("", "fish") "</{}grok></{foo}bar>" },	/* regression test for neon <= 0.23.5 with libxml2, where the	 * "dereference entities" flag was not set by default. */	{ PFX "<widget foo=\"no&amp;body\"/>",	  "<{}widget foo='no&body'></{}widget>" },	{ PFX "<widget foo=\"no&#x20;body\"/>",	  "<{}widget foo='no body'></{}widget>" },        /* tests for declined branches */        { PFX "<hello><decline>fish</decline>"          "<world><decline/>yes</world>goodbye<decline/></hello>",          "<{}hello><{}world>yes</{}world>goodbye</{}hello>" },        { PFX           "<hello><decline><nested>fish</nested>bar</decline><fish/></hello>",          "<{}hello>" E("", "fish") "</{}hello>" },        /* tests for nested SAX handlers */        { PFX "<hello xmlns='two'><decline/></hello>",          "<{two}hello xmlns='two'>" E("two", "xform") "</{two}hello>"},        /* tests for state handling */        { PFX "<a55 xmlns='state'/>", "" },        { PFX "<a777 xmlns='state' parent='0'/>", "" },        { PFX "<a99 xmlns='state'><f77 parent='99'/>blah</a99>", "" },        /* tests for abort handling */        { PFX "<hello><merry><abort-start/></merry></hello>",          "<{}hello><{}merry>ABORT", match_invalid },        { PFX "<hello><merry><abort-end/>fish</merry></hello>",          "<{}hello><{}merry><{}abort-end>ABORT", match_invalid },        { PFX "<hello>!ABORT!</hello>", "<{}hello>!ABORT!", match_invalid },        { PFX "<hello>!ABORT!<foo/></hello>", "<{}hello>!ABORT!", match_invalid },        { PFX "<hello>!ABORT!</fish>", "<{}hello>!ABORT!", match_invalid },        /* tests for encodings */        { "<?xml version='1.0' encoding='ISO-8859-1'?><hello/>",          "ISO-8859-1", match_encoding },        { "<?xml version='1.0' encoding='UTF-8'?><hello/>",          "UTF-8", match_encoding },        /* test that parse is valid even with no handlers registered. */        { PFX "<hello><old>world</old></hello>", "", match_nohands },        /* regression test for prefix matching bug fixed in 0.18.0 */#define THENS "xmlns:d='foo' xmlns:dd='bar'"        { PFX "<d:hello " THENS "/>",          "<{foo}hello " THENS "></{foo}hello>" },        /**** end of list ****/ { NULL, NULL }    };    int n;    for (n = 0; ms[n].in != NULL; n++) {	CALL(parse_match(ms[n].in, ms[n].out, ms[n].invalid));    }    return OK;}static int mapping(void){    static const struct ne_xml_idmap map[] = {        { "fee", "bar", 1 },        { "foo", "bar", 2 },        { "bar", "foo", 3 },        { "", "bob", 4 },        { "balloon", "buffoon", 5},        { NULL, NULL, 0}    };    int n;    for (n = 0; map[n].id; n++) {        int id = ne_xml_mapid(map, NE_XML_MAPLEN(map) - 1,                              map[n].nspace, map[n].name);        ONV(id != map[n].id, ("mapped to id %d not %d", id, map[n].id));    }    n = ne_xml_mapid(map, NE_XML_MAPLEN(map) - 1, "no-such", "element");    ONV(n != 0, ("unknown element got id %d not zero", n));    return OK;}/* Test for some parse failures */static int fail_parse(void){    static const char *docs[] = {        "foo",        PFX "<bar:foo/>",        /* malformed namespace declarations */        PFX "<foo xmlns:D=''/>",        PFX "<foo xmlns:='fish'/>",        PFX "<foo: xmlns:foo='bar'/>",#if 0        /* 2-byte encoding of '.': */        PFX "<foo>" "\x2F\xC0\xAE\x2E\x2F" "</foo>",        /* 3-byte encoding of '.': */        PFX "<foo>" "\x2F\xE0\x80\xAE\x2E\x2F" "</foo>",        /* 4-byte encoding of '.': */        PFX "<foo>" "\x2F\xF0\x80\x80\xAE\x2E\x2F" "</foo>",        /* 5-byte encoding of '.': */        PFX "<foo>" "\x2F\xF8\x80\x80\x80\xAE\x2E\x2F" "</foo>",        /* 6-byte encoding of '.': */        PFX "<foo>" "\x2F\xFC\x80\x80\x80\x80\xAE\x2E\x2F" "</foo>",        /* two-byte encoding of '<' must not be parsed as a '<': */        PFX "\xC0\xBC" "foo></foo>",#endif        NULL    };    int n;    for (n = 0; docs[n]; n++) {        ne_xml_parser *p = ne_xml_create();        const char *err;        ne_xml_parse(p, docs[n], strlen(docs[n]));        ne_xml_parse(p, "", 0);        ONV(ne_xml_valid(p), ("`%s' was valid", docs[n]));        err = ne_xml_get_error(p);        ONV(strstr(err, "parse error") == NULL,            ("bad error %s", err));                ne_xml_destroy(p);    }    return OK;}static int check_attrib(ne_xml_parser *p, const char **atts,                         const char *nspace, const char *name,                        const char *value){    const char *act = ne_xml_get_attr(p, atts, nspace, name);    char err[50];    int ret = 0;    if (value == NULL) {        if (act != NULL) {            sprintf(err, "attribute %s was set to %s", name, act);            ret = NE_XML_ABORT;        }    } else {        if (act == NULL) {            sprintf(err, "attribute %s not found", name);            ret = NE_XML_ABORT;        } else if (strcmp(act, value) != 0) {            sprintf(err, "attribute %s was %s not %s", name, act, value);            ret = NE_XML_ABORT;        }    }    if (ret == NE_XML_ABORT) ne_xml_set_error(p, err);    return ret;}static int startelm_attrib(void *userdata, int state,                           const char *nspace, const char *name,                           const char **atts){    ne_xml_parser *p = userdata;        if (strcmp(name, "hello") == 0) {        CALL(check_attrib(p, atts, NULL, "first", "second"));        CALL(check_attrib(p, atts, NULL, "third", ""));        CALL(check_attrib(p, atts, "garth", "bar", "asda"));        CALL(check_attrib(p, atts, "giraffe", "bar", NULL));        CALL(check_attrib(p, atts, "hot", "dog", NULL));        CALL(check_attrib(p, atts, NULL, "nonesuch", NULL));    } else if (strcmp(name, "goodbye") == 0) {        if (atts[0] != NULL) {            ne_xml_set_error(p, "non-empty attrib array");            return 1;        }    }    return 1;}static int attributes(void){    ne_xml_parser *p = ne_xml_create();    static const char doc[] = PFX        "<hello xmlns:foo='garth' first='second' third='' "        "foo:bar='asda' goof:bar='jar'><goodbye/></hello>";    ne_xml_push_handler(p, startelm_attrib, NULL, NULL, p);    ne_xml_parse_v(p, doc, strlen(doc));    ONV(!ne_xml_valid(p), ("parse error: %s", ne_xml_get_error(p)));    ne_xml_destroy(p);    return OK;}/* Test for the get/set error interface */static int errors(void){    ne_xml_parser *p = ne_xml_create();    const char *err;        ONV(strcmp(ne_xml_get_error(p), "Unknown error") != 0,        ("initial error string unspecified"));    ne_xml_set_error(p, "Fish food");    err = ne_xml_get_error(p);        ONV(strcmp(err, "Fish food"), ("wrong error %s!", err));    ne_xml_destroy(p);    return 0;        }ne_test tests[] = {    T(matches),    T(mapping),    T(fail_parse),    T(attributes),    T(errors),    T(NULL)};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -