/* ***************************************************************************** * * $RCSfile: xmlparse.c,v $ * $Date: 1999/05/18 18:36:20 $ * $Source: /home/richard/Xml/RCS/xmlparse.c,v $ * $Revision: 1.24 $ * $Author: richard $ * ***************************************************************************** * * Copyright 1998, Brown University and Richard Goerwitz * ***************************************************************************** * * Master xmlparse source file. For help, see the README and INSTALL * files. For syntax and usage information, see the man page. For a * brief usage summary, invoke xmlparse with the -h (help) option. * * Summary: * * This file houses the main entry point for a simple validating XML * parser called Xmlparse. It does the following: * * 1) initializes the xmlparse_env structure that is used throughout * nearly all modules (it contains the default lib directory; the * locations of the message catalog and SGML catalog files; the * list of XML files being processed, etc.); most initialization * is actually done by readcfg() (in readcfg.c) * * 2) checks whether the user supplied -h on the command line (the * help option), and if so exits (status 1) with a help message * * 3) finds all the file arguments, and tries to open and validate * the XML they contain by running them through parse_xml_file() * (in parsutil.y); note that parse_xml_file() will print out any * errors it finds; note also that if a given file argument does * not correspond to any local file, xmlparse tries to interpret * it as a URI * * 4) frees up the memory used by the parser, and by xmlparse_env * (this is done as a memory integrity check) * * 5) if there were no errors found in any of the XML files, exits * with status = 0; otherwise, exits with status = 4 and emits * a simple error message * ***************************************************************************** */ #include "general.h" #include "dtdutil.h" #include "errabort.h" #include "fileutil.h" #include "parsutil.h" #include "readcfg.h" #include "sigstuff.h" #include "strutil.h" #include "utfutil.h" #include "version.h" xmlparse_environment xmlparse_env; int main (int argc, char **argv) { my_wchar_t *sysid; int c, i, were_errors; char *format, *usage, *helpmsg; /* zero out the xmlparse_env structure */ memset (&xmlparse_env, 0, sizeof (xmlparse_env)); /* Set up xmlparse_env; parse command-line opts; read/parse config file */ readcfg (argc, argv); /* keep the parse tree around if the debug level is over zero */ if (xmlparse_env.debug_level > 0) xmlparse_env.keep_children = yes; /* If you change arg 3 to getopt here, change it in readcfg()! */ xwrap (errdebug (3, "re-parsing command-line arguments (third pass)\n")); while ((c = getopt (argc, argv, "c:C:d:E:fhl:m:np:su:v")) != EOF) { switch (c) { case 'h': /* emit an extensive help message */ fprintf (stderr, "%s, version %s\n", xmlparse_env.program_name, XMLPARSE_VERSION); format = strdup (getmessage (xmlparse_env.message_catalog, "1")); usage = strdup (getmessage (xmlparse_env.message_catalog, "2")); helpmsg = getmessage (xmlparse_env.message_catalog, "3"); fprintf (stderr, format, xmlparse_env.program_name, usage, helpmsg); free (format); free (usage); exit (1); break; case 'v': fprintf (stderr, "%s, version %s\n", xmlparse_env.program_name, XMLPARSE_VERSION); exit (1); case '?': case ':': errabort (10, "syntax error; invoke w/ -h option\n"); break; default: /* other command-line arguments are handled in readcfg() */ break; } } if ((xmlparse_env.filelen = argc - optind) == 0) errabort (11, "no files to process\n"); else { /* Stuff all input files supplied on the cmd line into * xml_file structures within xmlparse_env. */ xwrap (errdebug (5, "initializing %d xml_file structs\n", xmlparse_env.filelen)); xmlparse_env.xml_files = malloc (sizeof (xml_file) * xmlparse_env.filelen); if (xmlparse_env.xml_files == NULL) errabort (40, "malloc error in %s\n", "main()"); for (i = 0; xmlparse_env.filelen > i; i++) { /* argv[optind] may be treated just like a system ID; open it */ sysid = uni_strdup (utf_8_to_utf_16 (argv[optind + i])); xmlparse_env.xml_files[i] = resolve_pub_or_sysid (NULL, NULL, sysid); if (xmlparse_env.xml_files[i] == NULL) { /* abort if this is the only file we're processing */ if (xmlparse_env.filelen == 1) errabort (61, "can't resolve path, %s\n", argv[optind + i]); errwarn (61, "can't resolve path, %s\n", argv[optind + i]); } free (sysid); } } /* process xml files */ were_errors = 0; xwrap (errdebug (5, "parsing xml_file structs\n")); for (i = 0; i < xmlparse_env.filelen; i++) /* check for NULL here (indicates un-openable file) */ were_errors |= parse_xml_file (xmlparse_env.xml_files[i]); /* if debugging, free up storage as a memory integrity check */ if (xmlparse_env.debug_level >= 1) { /* free xml_file structs */ xwrap (errdebug (5, "freeing up storage used by xml_file structs\n")); for (i = 0; i < xmlparse_env.filelen; i++) if (xmlparse_env.xml_files[i]) free_xml_file (xmlparse_env.xml_files[i]); free (xmlparse_env.xml_files); xmlparse_env.filelen = 0; /* free message catalog, etc. (as a memory integrity check) */ free_message_catalog (xmlparse_env.message_catalog); xmlparse_env.message_catalog = NULL; /* free misc. strings being used */ if (xmlparse_env.config_filename) free (xmlparse_env.config_filename); xmlparse_env.config_filename = NULL; if (xmlparse_env.sgml_catalog_filenames) free (xmlparse_env.sgml_catalog_filenames); if (xmlparse_env.public_to_system_identifier_hashtable != NULL) rg_free_htable_and_data (xmlparse_env.public_to_system_identifier_hashtable); xmlparse_env.public_to_system_identifier_hashtable = NULL; xmlparse_env.sgml_catalog_filenames = NULL; if (xmlparse_env.libdir) free (xmlparse_env.libdir); xmlparse_env.libdir = NULL; xwrap (errdebug (3, "done; exiting\n")); /* free up the name of this program */ if (xmlparse_env.program_name) free (xmlparse_env.program_name); xmlparse_env.program_name = NULL; } if (were_errors) { /* one or more files triggered parsing errors */ errwarn (4, "there were errors\n"); exit (4); } /* We're done! */ return 0; }