/* file: xmlproc.h G. Moody 20 August 2010
Last revised: 22 August 2010
-------------------------------------------------------------------------------
xmlproc: generic functions for processing XML files
Copyright (C) 2010 George B. Moody
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, see .
You may contact the author by e-mail (wfdb@physionet.org) or postal mail
(MIT Room E25-505A, Cambridge, MA 02139 USA). For updates to this software,
please visit PhysioNet (http://www.physionet.org/).
_______________________________________________________________________________
This code should be compiled together with one of xmlhea.c, xmlann.c, or
xmldat.c, which provide implementations of the callback functions start(),
middle(), and end() for processing WFDB-XML header, annotation, and signal
files respectively, as well as the functions cleanup() and help().
*/
#include
/* functions including callbacks defined in xmlhea.c, xmlann.c, xmldat.c */
void XMLCALL start(void *data, const char *el, const char **attr);
void XMLCALL middle(void *data, const char *el, int len);
void XMLCALL end(void *data, const char *el);
void cleanup(void);
void help(void);
#define DATALEN 1024 /* max length of *data passed among callbacks,
in characters */
char *pname;
int qflag, vflag;
int main(int argc, char **argv)
{
FILE *ifile;
int i;
void process(FILE *ifile);
pname = argv[0];
if (argc < 2) help();
for (i = 1; i < argc; i++) {
if (argv[i][0] == '-') {
switch (argv[i][1]) {
case '\0': process(stdin); break;
case 'h': help(); break;
case 'q': qflag = 1; break;
case 'v': vflag = 1; break;
default: fprintf(stderr, "%s: unrecognized option %s\n",
argv[0], argv[i]);
exit(1);
break;
}
}
else {
ifile = fopen(argv[i], "rt");
if (ifile) {
process(ifile);
fclose(ifile);
}
else {
fprintf(stderr, "%s: can't open %s\n", argv[0], argv[i]);
exit(1);
}
}
}
exit(0);
}
/* Definitions needed by process(). XML_LARGE_SIZE and XML_USE_MSC_EXTENSIONS
may be defined in . */
#ifdef XML_LARGE_SIZE
#if defined(XML_USE_MSC_EXTENSIONS) && _MSC_VER < 1400
#define XML_FMT_INT_MOD "I64"
#else
#define XML_FMT_INT_MOD "ll"
#endif
#else
#define XML_FMT_INT_MOD "l"
#endif
#define BUFLEN 8192
void process(FILE *ifile)
{
int done = 0, len;
static char buf[BUFLEN], userdata[DATALEN];
XML_Parser p = XML_ParserCreate(NULL);
if (! p) {
fprintf(stderr, "Couldn't allocate memory for parser\n");
exit(2);
}
XML_SetUserData(p, userdata);
XML_SetElementHandler(p, start, end);
XML_SetCharacterDataHandler(p, middle);
do {
len = (int)fread(buf, 1, BUFLEN, ifile);
if (ferror(ifile)) {
fprintf(stderr, "Read error\n");
exit(-1);
}
done = feof(ifile);
if (XML_Parse(p, buf, len, done) == XML_STATUS_ERROR) {
fprintf(stderr, "Parse error at line %" XML_FMT_INT_MOD "u:\n%s\n",
XML_GetCurrentLineNumber(p),
XML_ErrorString(XML_GetErrorCode(p)));
exit(-1);
}
} while (!done);
XML_ParserFree(p);
cleanup();
userdata[0] = '\0';
if (vflag) printf("\n");
}