summaryrefslogtreecommitdiff
path: root/src/xml_pyx.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xml_pyx.c')
-rw-r--r--src/xml_pyx.c293
1 files changed, 293 insertions, 0 deletions
diff --git a/src/xml_pyx.c b/src/xml_pyx.c
new file mode 100644
index 0000000..e97dbd2
--- /dev/null
+++ b/src/xml_pyx.c
@@ -0,0 +1,293 @@
+/* $Id: xml_pyx.c,v 1.9 2005/03/12 03:24:23 mgrouch Exp $ */
+
+/**
+ * Based on xmln from pyxie project
+ *
+ * The PYX format is a line-oriented representation of
+ * XML documents that is derived from the SGML ESIS format.
+ * (see ESIS - ISO 8879 Element Structure Information Set spec,
+ * ISO/IEC JTC1/SC18/WG8 N931 (ESIS))
+ *
+ * A non-validating, ESIS generating tool
+ * ESIS Generation by Sean Mc Grath http://www.digitome.com/sean.html
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <libxml/parser.h>
+#include <libxml/parserInternals.h>
+
+#include "xmlstar.h"
+
+/**
+ * Output newline and tab characters as escapes
+ * Required both for attribute values and character data (#PCDATA)
+ */
+static void
+SanitizeData(const xmlChar *s, int len)
+{
+ while (len--)
+ {
+ switch (*s)
+ {
+ case 10:
+ printf("\\n");
+ break;
+ case 13:
+ break;
+ case 9:
+ printf ("\\t");
+ break;
+ case '\\':
+ printf ("\\\\");
+ break;
+ default:
+ putchar (*s);
+ }
+ s++;
+ }
+}
+
+static void
+print_qname(const xmlChar *prefix, const xmlChar *localname)
+{
+ if (prefix)
+ printf("%s:", prefix);
+ printf("%s", localname);
+}
+
+int
+CompareAttributes(const void *a1,const void *a2)
+{
+ typedef xmlChar const *const xmlCStr;
+ xmlCStr *attr1 = a1, *attr2 = a2;
+ return xmlStrcmp(*attr1, *attr2);
+}
+
+void
+pyxStartElement (void * ctx,
+ const xmlChar * localname,
+ const xmlChar * prefix,
+ const xmlChar * URI,
+ int nb_namespaces,
+ const xmlChar ** namespaces,
+ int nb_attributes,
+ int nb_defaulted,
+ const xmlChar ** attributes)
+{
+ int i;
+ fprintf(stdout,"(");
+ print_qname(prefix, localname);
+ fprintf(stdout, "\n");
+
+
+ if (nb_attributes > 1)
+ /* Sort the pairs based on the name part of the pair */
+ qsort ((void *)attributes,
+ nb_attributes,
+ sizeof(xmlChar *)*5,
+ CompareAttributes);
+
+ for (i = 0; i < nb_namespaces; i++) {
+ int aidx = i * 2;
+ const xmlChar
+ *prefix = namespaces[aidx],
+ *uri = namespaces[aidx+1];
+ /* namespace definitions take the form xmlns:prefix=uri*/
+ putchar('A');
+ if (xmlStrlen(prefix) > 0)
+ print_qname(BAD_CAST "xmlns", prefix);
+ else
+ fputs("xmlns", stdout);
+ putchar(' ');
+ SanitizeData(uri, xmlStrlen(uri));
+ putchar('\n');
+ }
+
+ for (i = 0; i < nb_attributes; i++) {
+ int aidx = i * 5;
+ const xmlChar *localname = attributes[aidx],
+ *prefix = attributes[aidx+1],
+ /* *nsURI = attributes[aidx+2], */
+ *valueBegin = attributes[aidx+3],
+ *valueEnd = attributes[aidx+4];
+ int valueLen = valueEnd - valueBegin;
+
+ /* Attribute Name */
+ putchar('A');
+ print_qname(prefix, localname);
+ putchar(' ');
+ /* value - can contain literal "\n" so escape */
+ SanitizeData(valueBegin, valueLen);
+ putchar('\n');
+ }
+}
+
+void
+pyxEndElement(void *userData, const xmlChar *localname, const xmlChar *prefix,
+ const xmlChar *URI)
+{
+ fprintf(stdout,")");
+ print_qname(prefix, localname);
+ putchar('\n');
+}
+
+void
+pyxCharacterData(void *userData, const xmlChar *s, int len)
+{
+ fprintf(stdout, "-");
+ SanitizeData(s, len);
+ putchar('\n');
+}
+
+void
+pyxProcessingInstruction(void *userData,
+ const xmlChar *target,
+ const xmlChar *data)
+{
+ fprintf(stdout,"?%s ",target);
+ SanitizeData(data, xmlStrlen(data));
+ fprintf(stdout,"\n");
+}
+
+void
+pyxUnparsedEntityDeclHandler(void *userData,
+ const xmlChar *entityName,
+ const xmlChar *publicId,
+ const xmlChar *systemId,
+ const xmlChar *notationName)
+{
+ fprintf(stdout, "U%s %s %s%s%s\n",
+ (char *)entityName, (char *)notationName, (char *)systemId,
+ (publicId == NULL? "": " "),
+ (publicId == NULL? "": (char *) publicId));
+}
+
+void
+pyxNotationDeclHandler(void *userData,
+ const xmlChar *notationName,
+ const xmlChar *publicId,
+ const xmlChar *systemId)
+{
+ fprintf(stdout, "N%s %s%s%s\n", (char*) notationName, (char*) systemId,
+ (publicId == NULL? "": " "),
+ (publicId == NULL? "": (const char*) publicId));
+}
+
+void
+pyxExternalEntityReferenceHandler(void* userData,
+ const xmlChar *name)
+{
+ const xmlChar *p = name;
+ fprintf (stdout, "&");
+ /* Up to space is the name of the referenced entity */
+ while (*p && (*p != ' ')) {
+ putchar (*p);
+ p++;
+ }
+}
+
+static void
+pyxExternalSubsetHandler(void *ctx ATTRIBUTE_UNUSED, const xmlChar *name,
+ const xmlChar *ExternalID, const xmlChar *SystemID)
+{
+ fprintf(stdout, "D %s PUBLIC", name); /* TODO: re-check */
+ if (ExternalID == NULL)
+ fprintf(stdout, " ");
+ else
+ fprintf(stdout, " \"%s\"", ExternalID);
+ if (SystemID == NULL)
+ fprintf(stdout, "\n");
+ else
+ fprintf(stdout, " \"%s\"\n", SystemID);
+}
+
+static void
+pyxCommentHandler(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value)
+{
+ fprintf(stdout,"C");
+ SanitizeData(value, xmlStrlen(value));
+ fprintf(stdout,"\n");
+}
+
+static void
+pyxCdataBlockHandler(void *ctx ATTRIBUTE_UNUSED, const xmlChar *value, int len)
+{
+ fprintf(stdout,"[");
+ SanitizeData(value, len);
+ fprintf(stdout,"\n");
+}
+
+static void
+pyxUsage(const char *argv0, exit_status status)
+{
+ extern void fprint_pyx_usage(FILE* o, const char* argv0);
+ extern const char more_info[];
+ FILE *o = (status == EXIT_SUCCESS)? stdout : stderr;
+ fprint_pyx_usage(o, argv0);
+ fprintf(o, "%s", more_info);
+ exit(status);
+}
+
+int
+pyx_process_file(const char *filename)
+{
+ int ret;
+ xmlParserCtxtPtr ctxt;
+
+ xmlInitParser();
+ ctxt = xmlCreateFileParserCtxt(filename);
+
+ memset(ctxt->sax, 0, sizeof(*ctxt->sax));
+
+ /* Establish Event Handlers */
+ ctxt->sax->initialized = XML_SAX2_MAGIC;
+ ctxt->sax->startElementNs = pyxStartElement;
+ ctxt->sax->endElementNs = pyxEndElement;
+ ctxt->sax->processingInstruction = pyxProcessingInstruction;
+ ctxt->sax->characters = pyxCharacterData;
+ ctxt->sax->notationDecl = pyxNotationDeclHandler;
+ ctxt->sax->reference = pyxExternalEntityReferenceHandler;
+ ctxt->sax->unparsedEntityDecl = pyxUnparsedEntityDeclHandler;
+ ctxt->sax->externalSubset = pyxExternalSubsetHandler;
+ ctxt->sax->comment = pyxCommentHandler;
+ ctxt->sax->cdataBlock = pyxCdataBlockHandler;
+
+ ret = xmlParseDocument(ctxt);
+ xmlFreeParserCtxt(ctxt);
+ xmlCleanupParser();
+
+ return ret;
+}
+
+int
+pyxMain(int argc,const char *argv[])
+{
+ int status = 0;
+
+ if ((argc > 2) &&
+ (
+ (strcmp(argv[2],"-h") == 0) ||
+ (strcmp(argv[2],"-H") == 0) ||
+ (strcmp(argv[2],"-Z") == 0) ||
+ (strcmp(argv[2],"-?") == 0) ||
+ (strcmp(argv[2],"--help") == 0)
+ ))
+ {
+ pyxUsage(argv[0], EXIT_SUCCESS);
+ }
+ if (argc == 2) {
+ status = pyx_process_file("-");
+ }
+ else {
+ argv++;
+ argc--;
+ for (++argv; argc>1; argc--,argv++) {
+ int ret = pyx_process_file(*argv);
+ if (ret != 0) status = ret;
+ }
+ }
+ return status;
+}