Ejemplo n.º 1
0
def test_svg_file(tester, fileName):
    """ Run the basic tests for a single input file """

    basename = os.path.basename(fileName)
    parse = XmlRfcParser("Tests/" + fileName,
                         quiet=True,
                         cache_path=None,
                         no_network=True,
                         preserve_all_white=True)
    tree = parse.parse(remove_comments=False,
                       remove_pis=True,
                       strip_cdata=False)

    log.write_out = io.StringIO()
    log.write_err = log.write_out
    checkTree(tree.tree)

    (result, errors) = tree.validate(
        rng_path=parse.default_rng_path.replace("rfc7991", "svg"))

    returnValue = check_results(log.write_out,
                                "Results/" + basename.replace(".svg", ".out"))
    tester.assertFalse(returnValue, "Output to console is different")

    result = io.StringIO(
        lxml.etree.tostring(tree.tree,
                            xml_declaration=True,
                            encoding='utf-8',
                            pretty_print=True).decode('utf-8'))
    returnValue = check_results(result, "Results/" + basename)
    tester.assertFalse(returnValue,
                       "Result from editing the tree is different")
    tester.assertTrue(result, "Fails to validate againist the RNG")
Ejemplo n.º 2
0
 def test_entity(self):
     """ Test that an entity is loaded."""
     parser = XmlRfcParser("Tests/entity.xml", quiet=False,
                           cache_path=None, no_network=True)
     tree = parser.parse()
     self.assertEqual(len(tree.tree.xpath('good')), 1,
                      "Must be exactly one node named good")
Ejemplo n.º 3
0
 def test_include2(self):
     """ Test that a two level xi:include is loaded"""
     parser = XmlRfcParser("Tests/include2.xml", quiet=False,
                           cache_path=None, no_network=True)
     tree = parser.parse()
     self.assertEqual(len(tree.tree.xpath('good')), 1,
                      "Must be exactly one node named good")
Ejemplo n.º 4
0
 def test_remote_xinclude(self):
     """ Test that a remote https entity can be loaded """
     parser = XmlRfcParser("Tests/include-http.xml", quiet=False,
                           cache_path=None, no_network=False)
     tree = parser.parse()
     self.assertEqual(len(tree.tree.xpath('reference')), 1,
                      "Must be exactly one reference node")
     parser.cachingResolver.close_all()
Ejemplo n.º 5
0
 def test_remote_cache_xinclude(self):
     """ Test that a remote https entity can be cached """
     parser = XmlRfcParser("Tests/include-http.xml", quiet=False,
                           cache_path='Tests/cache', no_network=False)
     clear_cache(parser)
     tree = parser.parse()
     parser.cachingResolver.close_all()
     self.assertEqual(len(tree.tree.xpath('reference')), 1,
                      "Must be exactly one reference node")
     self.assertTrue(os.path.exists('Tests/cache/reference.RFC.1847.xml'))
Ejemplo n.º 6
0
 def test_local_nocache_entity(self):
     """ See that we have a failure if we try to get an uncached item """
     restore = GetCache()
     SetCache([])
     parser = XmlRfcParser("Tests/entity-http.xml", quiet=False,
                           cache_path='Tests/cache', no_network=True)
     clear_cache(parser)
     with self.assertRaises(XmlRfcError):
         parser.parse()
     SetCache(restore)
Ejemplo n.º 7
0
 def test_network_dtd(self):
     """ Find a dtd using the network """
     old = GetCache()
     # CACHES = []
     SetCache([])
     parser = XmlRfcParser("Tests/network-dtd.xml", quiet=False,
                           cache_path='Tests/cache')
     clear_cache(parser)
     parser.parse()
     SetCache(old)
     parser.cachingResolver.close_all()
Ejemplo n.º 8
0
 def test_remote(self):
     """ Test that a remote https entity can be loaded """
     parser = XmlRfcParser("Tests/entity-http.xml", quiet=False,
                           cache_path=None, no_network=False)
     try:
         tree = parser.parse()
         self.assertEqual(len(tree.tree.xpath('reference')), 1,
                          "Must be exactly one reference node")
     except XmlRfcError as e:
         # print('Unable to parse the XML Document: ' + source)
         print(e)
         self.assertFalse()
     parser.cachingResolver.close_all()
Ejemplo n.º 9
0
 def test_local_cache_entity(self):
     """ Test that an entity in the cache can be used w/o a network """
     old = GetCache()
     SetCache([])
     parser = XmlRfcParser("Tests/entity-http.xml", quiet=False,
                           cache_path='Tests/cache', no_network=True)
     clear_cache(parser)
     if not os.path.exists('Tests/cache'):
         os.mkdir('Tests/cache')
     shutil.copy('Tests/cache_saved/reference.RFC.1847.xml',
                 'Tests/cache/reference.RFC.1847.xml')
     tree = parser.parse()
     self.assertEqual(len(tree.tree.xpath('reference')), 1,
                      "Must be exactly one reference node")
     parser.cachingResolver.close_all()
     SetCache(old)
Ejemplo n.º 10
0
def DistanceTest(tester, leftFile, rightFile, diffFile, htmlFile, markParagraphs):
    """ General distance test function """
    options = OOO()
    SourceFiles.Clear()
    left = XmlRfcParser(leftFile, quiet=True, cache_path=None, no_network=True). \
        parse(strip_cdata=False, remove_comments=False)
    left = BuildDiffTree(left.tree, options)
    if markParagraphs:
        left = AddParagraphs(left)
    SourceFiles.LeftDone()
    right = XmlRfcParser(rightFile, quiet=True, cache_path=None, no_network=True). \
        parse(strip_cdata=False, remove_comments=False)
    right = BuildDiffTree(right.tree, options)
    if markParagraphs:
        right = AddParagraphs(right)

    editSet = distance(left, right, DiffRoot.get_children,
                       DiffRoot.InsertCost, DiffRoot.DeleteCost, DiffRoot.UpdateCost)
    with open(diffFile, 'r') as f:
        lines2 = f.readlines()

    d = difflib.Differ()

    # check that the edit set is the same
    lines2 = [line.strip() for line in lines2]
    lines1 = [edit.toString() for edit in editSet]
    result = list(d.compare(lines1, lines2))

    hasError = False
    for ll in result:
        if ll[0:2] == '+ ' or ll[0:2] == '- ':
            hasError = True
            break
    if hasError:
        print("\n".join(result))
        tester.assertFalse(hasError, "edit map differs")

    # check that the HTML output is the same
    left.applyEdits(editSet)
    x = left.ToString()
    x = x.splitlines()
    x = [line.rstrip() for line in x]
    with open(htmlFile, 'rb') as f:
        lines2 = f.read().decode('utf-8').splitlines()
    lines2 = [line.rstrip() for line in lines2]

    result = list(d.compare(x, lines2))

    hasError = False
    for l in result:
        if l[0:2] == '+ ' or l[0:2] == '- ':
            hasError = True
            break
    if hasError:
        print("\n".join(result))
        tester.assertFalse(hasError, "html differs")
Ejemplo n.º 11
0
def DistanceTest(tester, leftFile, rightFile, diffFile, htmlFile):
    """ General distance test function """
    options = OOO()
    diffCount = 0
    left = XmlRfcParser(leftFile, quiet=True, cache_path=None,
                        no_network=True).parse()
    left = BuildDiffTree(left.tree, options)
    right = XmlRfcParser(rightFile,
                         quiet=True,
                         cache_path=None,
                         no_network=True).parse()
    right = BuildDiffTree(right.tree, options)

    editSet = distance(left, right, DiffRoot.get_children, DiffRoot.InsertCost,
                       DiffRoot.DeleteCost, DiffRoot.UpdateCost)
    with open(diffFile, 'r') as f:
        lines2 = f.readlines()

    d = difflib.Differ()

    # check that the edit set is the same
    lines2 = [line.strip() for line in lines2]
    lines1 = [edit.toString() for edit in editSet]
    result = list(d.compare(lines1, lines2))

    hasError = False
    for ll in result:
        if ll[0:2] == '+ ' or ll[0:2] == '- ':
            hasError = True
            break
    if hasError:
        print("\n".join(result))
        tester.assertFalse(hasError, "edit map differs")

    # check that the HTML output is the same
    left.applyEdits(editSet)
    x = left.ToString()
    x = x.splitlines()
    with open(htmlFile, 'r') as f:
        lines2 = f.readlines()
    lines2 = [line.strip() for line in lines2]

    result = list(d.compare(x, lines2))

    hasError = False
    for l in result:
        if l[0:2] == '+ ' or l[0:2] == '- ':
            hasError = True
            break
    if hasError:
        print("\n".join(result))
        tester.assertFalse(hasError, "html differs")
Ejemplo n.º 12
0
def DistanceTest(leftFile, rightFile, options):
    try:
        left = XmlRfcParser(leftFile, quiet=True).parse()
        left = BuildDiffTree(left.tree, options)
        left = AddParagraphs(left)
        right = XmlRfcParser(rightFile, quiet=True).parse()
        right = BuildDiffTree(right.tree, options)
        right = AddParagraphs(right)

        editSet = distance(left, right, DiffRoot.get_children,
                           DiffRoot.InsertCost, DiffRoot.DeleteCost,
                           DiffRoot.UpdateCost)

        c = left.applyEdits(editSet)

        if c > 0:
            log.error("Fail applying edits for '{0}' and '{1}', # edits = {2}".
                      format(leftFile, rightFile, c))
    except Exception as e:
        log.exception(
            "Fail applying edits for '{0}' and '{1}'".format(
                leftFile, rightFile), e)
Ejemplo n.º 13
0
def main():
    # Populate options
    formatter = optparse.IndentedHelpFormatter(max_help_position=40)
    optionparser = optparse.OptionParser(usage='rfclint SOURCE [OPTIONS] '
                                         '...\nExample: rfclint '
                                         'draft.xml',
                                         formatter=formatter)

    parser_options = optparse.OptionGroup(optionparser, "Parser Options")
    parser_options.add_option('-C',
                              '--clear-cache',
                              action='store_true',
                              dest='clear_cache',
                              default=False,
                              help='purge the cache and exit')
    parser_options.add_option('-c',
                              '--cache',
                              dest='cache',
                              help='specify a primary cache directory to'
                              ' write to; default: try [ %s ]' %
                              ', '.join(CACHES))
    parser_options.add_option(
        '-N',
        '--no-network',
        action='store_true',
        default=False,
        help='don\'t use the network to resolve references')
    parser_options.add_option('-n',
                              '--no-rng',
                              action='store_true',
                              help='disable RNG validation step')
    parser_options.add_option('-r',
                              '--rng',
                              action='store_true',
                              help='Specify an alternate RNG file')
    parser_options.add_option('-X',
                              '--no-xinclude',
                              action='store_true',
                              dest='no_xinclude',
                              help='don\'t resolve any xi:include elements')

    optionparser.add_option_group(parser_options)

    general_options = optparse.OptionGroup(optionparser, "General Options")
    general_options.add_option('-o',
                               '--out',
                               dest='output_filename',
                               metavar='FILE',
                               help='specify an explicit output filename')
    parser_options.add_option('--no-xml',
                              dest='no_xml',
                              action='store_true',
                              help='Don\'t perform XML well-formness checking')
    parser_options.add_option('--bcp14',
                              dest='bcp14',
                              action='store_true',
                              help='Perform bcp14 checking')
    optionparser.add_option_group(general_options)

    plain_options = optparse.OptionGroup(optionparser, 'Plain Options')

    plain_options.add_option('-q',
                             '--quiet',
                             action='store_true',
                             help='dont print anything')
    plain_options.add_option('-v',
                             '--verbose',
                             action='store_true',
                             help='print extra information')
    plain_options.add_option('-V',
                             '--version',
                             action='callback',
                             callback=display_version,
                             help='display the version number and exit')
    plain_options.add_option('--debug',
                             action='store_true',
                             help='Show debugging output')
    plain_options.add_option('--extract',
                             dest='extract',
                             help='Extract all items of the given type')
    plain_options.add_option('--no-svgcheck',
                             action='store_true',
                             dest='no_svgcheck',
                             help='Don\'t run svgcheck')
    optionparser.add_option_group(plain_options)

    spell_options = optparse.OptionGroup(optionparser, 'Spell Options')
    spell_options.add_option('--no-spell',
                             dest='no_spell',
                             default=False,
                             action='store_true',
                             help='Don\'t run the spell checking')
    spell_options.add_option(
        '--dictionary',
        dest='dict_list',
        action='append',
        help='Use this addition dictionary when spell checking')
    spell_options.add_option(
        '--personal',
        dest='dict_personal',
        help='use this dictionary as the personal dictionary')
    spell_options.add_option(
        '--spell-window',
        dest='spell_window',
        action='store',
        type='int',
        help='Set the number of words to appear around spelling errors')
    spell_options.add_option('--no-dup-detection',
                             dest='no_dups',
                             action='store_true',
                             help='Don\'t do duplication detection.')
    spell_options.add_option('--spell-program',
                             dest='spell_program',
                             metavar='NAME',
                             help='Name of spelling program to use')
    spell_options.add_option('--no-suggest',
                             dest='spell_suggest',
                             action='store_false',
                             help='Do not provide suggestions')
    spell_options.add_option('--suggest',
                             dest='spell_suggest',
                             action='store_true',
                             help='provide suggestions (default)')
    spell_options.add_option('--color',
                             dest='spell_color',
                             action='callback',
                             callback=check_color,
                             type='string',
                             help='color incorrect words in supplied context')
    spell_options.add_option(
        '--no-curses',
        dest='no_curses',
        action='store_true',
        help='disable curses when doing spell checking and dup detection')
    spell_options.add_option(
        '--skip-code',
        dest='skip_code',
        action='store_true',
        help='skip all code elements when doing spell and duplicate checking')
    spell_options.add_option(
        '--skip-artwork',
        dest='skip_artwork',
        action='store_true',
        help='skip all artwork elements when doing spell and '
        'duplicate checking')
    optionparser.add_option_group(spell_options)

    abnf_options = optparse.OptionGroup(optionparser, 'ABNF Options')
    abnf_options.add_option('--abnf-program',
                            dest='abnf_program',
                            metavar='NAME',
                            help='Name of ABNF checker program to use')
    abnf_options.add_option('--no-abnf',
                            dest='no_abnf',
                            action='store_true',
                            help='Don\'t perform ABNF checking')
    abnf_options.add_option('--abnf-add-rules',
                            dest='abnf_add',
                            help='ABNF file to append during evaluation.')

    config_options = optparse.OptionGroup(optionparser,
                                          'Configuration Options')
    config_options.add_option(
        '--configfile',
        dest='config_file',
        metavar='NAME',
        help="Specify the name of the configuration file.")
    config_options.add_option('--save-config',
                              dest='save_config',
                              default=False,
                              action='store_true',
                              help='Save configuration back to file')

    # --- Parse and validate arguments ---------------------------------

    (options, args) = optionparser.parse_args()

    # --- Setup and parse the input file

    if options.cache:
        if not os.path.exists(options.cache):
            try:
                os.makedirs(options.cache)
                if options.verbose:
                    log.write('Created cache directory at', options.cache)
            except OSError as e:
                print('Unable to make cache directory: %s ' % options.cache)
                print(e)
                sys.exit(1)
        else:
            if not os.access(options.cache, os.W_OK):
                print('Cache directory is not writable: %s' % options.cache)
                sys.exit(1)

    if options.clear_cache:
        clear_cache(options.cache)

    # --- Locate the configuration file if it exists and import it ----

    config = ConfigFile(options)

    if options.save_config:
        config.save()
        sys.exit(0)

    # make things quiet if output goes to stdout
    if options.output_filename is None and not options.quiet and (
            options.extract):
        options.quiet = True

    # --- Get the file to be processed --------------------------------

    if len(args) < 1:
        optionparser.print_help()
        sys.exit(2)
    source = args[0]
    if not os.path.exists(source):
        sys.exit('No such file: ' + source)

    # Setup warnings module
    # rfclint.log.warn_error = options.warn_error and True or False
    log.quiet = options.quiet and True or False
    log.verbose = options.verbose

    # Parse the document into an xmlrfc tree instance
    log.note("Checking for well-formness of '{0}'".format(source))
    parser = XmlRfcParser(source,
                          verbose=options.verbose,
                          preserve_all_white=True,
                          quiet=True,
                          cache_path=options.cache,
                          no_network=options.no_network,
                          no_xinclude=options.no_xinclude,
                          templates_path=globals().get('_TEMPLATESPATH', None))
    try:
        xmlrfc = parser.parse(remove_comments=False, strip_cdata=False)
    except XmlRfcError as e:
        log.exception('Unable to parse the XML document: ' + source, e)
        sys.exit(1)
    except lxml.etree.XMLSyntaxError as e:
        # Give the lxml.etree.XmlSyntaxError exception a line attribute which
        # matches lxml.etree._LogEntry, so we can use the same logging function
        log.error("Unable to parse the XML document: " +
                  os.path.normpath(source))
        log.exception_lines("dummy", e.error_log)
        sys.exit(1)
    log.note("Well-formness passes")

    # Validate the document unless disabled
    if not options.no_rng:
        log.note("Checking for schema validation...")
        if not options.rng:
            options.rng = parser.default_rng_path
        ok, errors = xmlrfc.validate(rng_path=options.rng)
        if not ok:
            log.error('Unable to validate the XML document: ' +
                      os.path.normpath(source))
            log.exception_lines("dummy", errors)
            sys.exit(1)
        log.info("Schema validation passes")
    else:
        log.note("Skipping schema validation")

    # Do Extracts

    if options.extract:
        codeItems = xmlrfc.tree.getroot().xpath(
            "//sourcecode[@type='{0}']".format(options.extract))

        if len(codeItems) == 0:
            log.error("No sourcecode elements with type = '{0}' found.".format(
                options.extract))
            exit(1)

        if options.output_filename:
            file = open(options.output_filename, 'w')
        else:
            file = sys.stdout

        needEOL = True
        for item in codeItems:
            if "name" in item.attrib:
                with open(item.attrib["name"], 'w') as f:
                    f.write(item.text)
                    if len(item.text) > 0 and item.text[-1] != '\n':
                        f.write('\n')
            else:
                file.write(item.text)
                if len(item.text) > 0:
                    needEOL = item.text[-1] != '\n'

        if needEOL:
            file.write('\n')

        if options.output_filename:
            file.close()
        exit(0)

    #  Validate any embedded XML

    if not options.no_xml:
        codeItems = xmlrfc.tree.getroot().xpath("//sourcecode[@type='xml']")
        if len(codeItems) > 0:
            log.note("Validating XML fragments in sourcecode elements")
            # resolver without knowledge of rfc_number:
            caching_resolver = CachingResolver(no_network=True,
                                               verbose=options.verbose,
                                               quiet=options.quiet)

            for item in codeItems:
                parser = lxml.etree.XMLParser(dtd_validation=False,
                                              load_dtd=False,
                                              no_network=True,
                                              resolve_entities=False,
                                              recover=False)
                parser.resolvers.add(caching_resolver)
                try:
                    text = re.sub(u'^\s+<\?xml ', '<?xml ', item.text)
                    file = six.BytesIO(text.encode('utf-8'))

                    lxml.etree.parse(file, parser)
                    log.info(
                        "XML fragment in source code found and is well defined.",
                        where=item)
                except (lxml.etree.XMLSyntaxError) as e:
                    log.warn(u'XML in sourcecode not well formed: ',
                             e.msg,
                             where=item)
                except Exception as e:
                    log.exception(u'Error occured processing XML: ', e)
        else:
            log.info("No XML fragments in sourcecode elements found.")

    #  Validate any embedded ABNF
    if not options.no_abnf:
        try:
            checker = AbnfChecker(config)

            checker.validate(xmlrfc.tree)
        except RfcLintError as e:
            log.error("Skipping ABNF checking because")
            log.error(e.message, additional=2)

    # Validate any SVG items
    if not options.no_svgcheck:
        checkTree(xmlrfc.tree)

    # do the Spelling checking
    if not options.no_spell:
        speller = None
        try:
            speller = Speller(config)
            if options.no_curses:
                speller.no_curses = True
            speller.initscr()
            speller.processTree(xmlrfc.tree.getroot())
            speller.sendCommand("#")  # save personal dictionary
            speller.endwin()
        except RfcLintError as e:
            log.error("Skipping spell checking because")
            log.error(e.message, additional=2)
            if speller:
                speller.endwin()
        except Exception:
            if speller:
                speller.endwin()
            raise

    # do the Duplicate checking
    if not options.no_dups:
        try:
            dups = Dups(config)
            if options.no_curses:
                dups.no_curses = True
            dups.initscr()
            dups.processTree(xmlrfc.tree.getroot())
            dups.endwin()
        except RfcLintError as e:
            dups.endwin()
            log.error("Skipping duplicate checking because")
            log.error(e.message, additional=2)
        except Exception:
            dups.endwin()
            raise

    # do the 2119 Language tag checking
    if options.bcp14:
        try:
            lang2119 = Lang2119(config)
            if options.no_curses:
                lang2119.no_curses = True
            lang2119.initscr()
            lang2119.processTree(xmlrfc.tree.getroot())
            lang2119.endwin()
        except RfcLintError as e:
            log.error("Skipping RFC 2119 language tag checking because")
            log.error(e.message, additoin=2)
        except Exception:
            lang2119.endwin()
            raise

    if options.output_filename is not None:
        if six.PY2:
            file = open(options.output_filename, 'w')
        else:
            file = open(options.output_filename, 'w', encoding='utf8')
        text = lxml.etree.tostring(xmlrfc.tree.getroot(),
                                   xml_declaration=True,
                                   encoding='utf-8',
                                   doctype=xmlrfc.tree.docinfo.doctype)
        if six.PY3:
            text = text.decode('utf8')
        file.write(text)
        if len(text) > 0 and text[-1] != '\n':
            file.write('\n')
Ejemplo n.º 14
0
 def test_local_dtd(self):
     """ Find a dtd in the templates directory """
     parser = XmlRfcParser("Tests/dtd.xml", quiet=False)
     parser.parse()
Ejemplo n.º 15
0
 def test_pi_include(self):
     parser = XmlRfcParser("Tests/pi_include.xml", quiet=False)
     parser.parse()
Ejemplo n.º 16
0
 def test_utf8_xml(self):
     """ Parse file w/ encoding UTF-8 """
     parser = XmlRfcParser("Tests/doc_utf8.xml", quiet=False)
     parser.parse()
Ejemplo n.º 17
0
 def test_french_xml(self):
     """ Parse file w/ encoding ISO-8859-1 """
     parser = XmlRfcParser("Tests/doc_fr_latin1.xml", quiet=False)
     parser.parse()
     """ self.assertEqual(len(tree.tree.xpath('doc')), 1,
Ejemplo n.º 18
0
def main():
    """ Main function for xmldiff """

    formatter = optparse.IndentedHelpFormatter(max_help_position=40)
    optionparser = optparse.OptionParser(usage='xmldiff LEFT RIGHT [OPTIONS] '
                                         '...\nExample: rfc-xmldiff '
                                         'draft1.xml draft2.xml',
                                         formatter=formatter)

    value_options = optparse.OptionGroup(optionparser, 'Other Options')
    value_options.add_option('-o',
                             '--out',
                             dest='output_filename',
                             metavar='FILE',
                             help='specify an explicit output filename',
                             default=None)
    value_options.add_option('--debug',
                             action="store_true",
                             help='Show debugging output')
    value_options.add_option('--raw',
                             action="store_true",
                             help='Diff using the raw tree')
    value_options.add_option('-t',
                             '--template',
                             dest='template',
                             metavar='FILE',
                             help='specify the HTML template filename',
                             default='base.html')
    value_options.add_option('-V',
                             '--version',
                             action='callback',
                             callback=display_version,
                             help='display the version number and exit')
    value_options.add_option('-C',
                             '--clear-cache',
                             action='store_true',
                             dest='clear_cache',
                             default=False,
                             help='purge the cache and exit')
    value_options.add_option(
        '-c',
        '--cache',
        dest='cache',
        help='specify a primary cache directory to write to; '
        'default: try [ %s ]' % ', '.join(CACHES))
    value_options.add_option('-q',
                             '--quiet',
                             action='store_true',
                             help='dont print anything')
    value_options.add_option('-v',
                             '--verbose',
                             action='store_true',
                             help='print extra information')
    value_options.add_option('--no-resolve-entities',
                             dest='noEntity',
                             action="store_true",
                             help="Don't resolve entities in the XML")
    value_options.add_option(
        '-N',
        '--no-network',
        action='store_true',
        default=False,
        help='don\'t use the network to resolve references')
    value_options.add_option('-X',
                             '--no-xinclude',
                             action='store_true',
                             dest='no_xinclude',
                             help='don\'t resolve any xi:include elements')
    value_options.add_option('-D',
                             '--no-defaults',
                             action='store_false',
                             default=True,
                             help="don't add default attributes")

    optionparser.add_option_group(value_options)

    # --- Parse and validate arguments ----------------------------

    (options, args) = optionparser.parse_args()

    if options.clear_cache:
        clear_cache(options.cache)

    if len(args) < 1:
        optionparser.print_help()
        sys.exit(2)

    # Setup warnings module
    # rfclint.log.warn_error = options.warn_error and True or False
    log.quiet = options.quiet and True or False
    log.verbose = options.verbose

    # Load the left file
    leftSource = args[0]
    if not os.path.exists(leftSource):
        sys.exit('No such file: ' + leftSource)

    log.note("Parse input files")
    parser = XmlRfcParser(leftSource,
                          verbose=log.verbose,
                          quiet=log.quiet,
                          no_network=options.no_network,
                          no_xinclude=options.no_xinclude,
                          resolve_entities=not options.noEntity,
                          attribute_defaults=options.no_defaults)
    try:
        ll = parser.parse(remove_pis=False,
                          strip_cdata=False,
                          remove_comments=False).tree
        leftXml = BuildDiffTree(ll, options)
        if not options.raw:
            leftXml = AddParagraphs(leftXml)
        leftFile_base = os.path.basename(leftSource)
        SourceFiles.LeftDone()
    except XmlRfcError as e:
        log.exception('Unable to parse the XML document: ' + leftSource, e)
        sys.exit(1)

    rightSource = args[1]
    if not os.path.exists(rightSource):
        sys.exit('No such file: ' + rightSource)

    parser = XmlRfcParser(rightSource,
                          verbose=log.verbose,
                          quiet=log.quiet,
                          no_network=options.no_network,
                          no_xinclude=options.no_xinclude,
                          resolve_entities=not options.noEntity,
                          attribute_defaults=options.no_defaults)
    try:
        rightXml = parser.parse(remove_pis=False,
                                strip_cdata=False,
                                remove_comments=False)
        rightXml = BuildDiffTree(rightXml.tree, options)
        if not options.raw:
            rightXml = AddParagraphs(rightXml)
        rightFile_base = os.path.basename(rightSource)
    except XmlRfcError as e:
        log.exception('Unable to parse the XML document: ' + rightSource, e)
        sys.exit(1)

    log.note("Read files for source display")
    cache = CachingResolver(library_dirs=[])

    leftSources = ""
    leftSourceNames = ""
    for i in range(len(SourceFiles.leftFiles)):
        file = SourceFiles.leftFiles[i]
        if file[:5] == 'file:':
            file = urlparse(file)
            file = file[2]
            if file[2] == ':':
                file = file[1:]
        else:
            file = cache.getReferenceRequest(file)[0]

        if six.PY2:
            with open(file, "rb") as f:
                leftLines = f.read()
                leftLines = leftLines.decode('utf8').splitlines(1)
        else:
            with open(file, "rU", encoding="utf8") as f:
                leftLines = f.readlines()

        leftSources += u'<div id="L_File{0}" class="tabcontent">\n'.format(i)
        leftLines = [
            escape(x).replace(' ', '&nbsp;').replace('"', '&quot;')
            for x in leftLines
        ]
        leftSources += formatLines(leftLines, 'L', i)
        leftSources += u'</div>\n'

        leftSourceNames += u'<option label="{0}" value="L_File{1}">{2}</option>\n'. \
                           format(file, i, file)

    rightSources = ""
    rightSourceNames = ""

    for i in range(len(SourceFiles.rightFiles)):
        file = SourceFiles.rightFiles[i]
        if file[:5] == 'file:':
            file = urlparse(file)
            file = file[2]
            if file[2] == ':':
                file = file[1:]
        else:
            file = cache.getReferenceRequest(file)[0]

        if six.PY2:
            with open(file, "rb") as f:
                rightLines = f.read().decode('utf8').splitlines(1)
        else:
            with open(file, "rU", encoding="utf8") as f:
                rightLines = f.readlines()

        rightSources += u'<div id="R_File{0}" class="tabcontent">\n'.format(i)
        rightLines = [
            escape(x).replace(' ', '&nbsp;').replace('"', '&quot;')
            for x in rightLines
        ]
        rightSources += formatLines(rightLines, 'R', i)
        rightSources += u'</div>\n'

        rightSourceNames += '<option label="{0}" value="R_File{1}">{2}</option>\n'. \
                            format(file, i, file)

    log.note("Start computing tree edit distance")
    editSet = distance(leftXml, rightXml, DiffRoot.get_children,
                       DiffRoot.InsertCost, DiffRoot.DeleteCost,
                       DiffRoot.UpdateCost)

    if options.debug:
        print("edit count = " + str(len(editSet)))
        for edit in editSet:
            print(edit.toString())

    log.note("Apply copmuted tree edits")
    if len(editSet) == 0:
        log.info("Files are identical")

    leftXml.applyEdits(editSet)

    log.note("Setup to write html file")
    templates_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)),
                                 'Templates')
    log.note("   template directory = " + templates_dir)

    if six.PY2:
        with open(os.path.join(templates_dir, "resize.js"), "rb") as f:
            allScript = f.read()
    else:
        with open(os.path.join(templates_dir, "resize.js"),
                  "rU",
                  encoding="utf8") as f:
            allScript = f.read()

    template_file = options.template
    if not os.path.exists(options.template):
        template_file = os.path.join(templates_dir, options.template)
        if not os.path.exists(template_file):
            sys.exit('No template file: ' + template_file)

    log.note('   template source file: ' + template_file)
    with open(template_file, 'rb') as file:
        html_template = string.Template(file.read().decode('utf8'))

    rightLines = [x.replace(' ', '&nbsp;') for x in rightLines]

    buffers = {}
    buffers['leftFile'] = leftSources
    buffers['rightFile'] = rightSources
    buffers['body'] = leftXml.ToString()

    subs = {
        'background': '',
        # HTML-escaped values
        'title': 'rfc-xmldiff {0} {1}'.format(leftFile_base, rightFile_base),
        'body': ''.join(buffers['body']),
        'leftFile': buffers['leftFile'],
        'leftSourceNames': leftSourceNames,
        'rightFile': buffers['rightFile'],
        'rightSourceNames': rightSourceNames,
        'allScript': allScript
    }
    output = html_template.substitute(subs)

    if options.output_filename is None:
        write_to(sys.stdout, output)
    else:
        log.note('Write out html file: ' + options.output_filename)
        file = open(options.output_filename, "wb")
        file.write(output.encode('utf8'))
        file.close()
Ejemplo n.º 19
0
def clear_cache(cache_path):
    XmlRfcParser('', cache_path=cache_path).delete_cache()
    sys.exit()
Ejemplo n.º 20
0
def main():
    # Populate the options
    formatter = optparse.IndentedHelpFormatter(max_help_position=40)
    optionparser = optparse.OptionParser(usage='svgcheck SOURCE [OPTIONS] '
                                         '...\nExample: svgcheck draft.xml',
                                         formatter=formatter)

    parser_options = optparse.OptionGroup(optionparser, 'Parser Options')
    parser_options.add_option(
        '-N',
        '--no-network',
        action='store_true',
        default=False,
        help='don\'t use the network to resolve references')
    parser_options.add_option('-X',
                              "--no-xinclude",
                              action='store_true',
                              default=False,
                              help='don\'t resolve xi:include elements')

    parser_options.add_option('-C',
                              '--clear-cache',
                              action='store_true',
                              dest='clear_cache',
                              default=False,
                              help='purge the cache and exit')
    parser_options.add_option(
        '-c',
        '--cache',
        dest='cache',
        help='specify a primary cache directory to write to;'
        'default: try [ %s ]' % ', '.join(CACHES))

    parser_options.add_option('-d',
                              '--rng',
                              dest='rng',
                              help='specify an alternate RNG file')
    optionparser.add_option_group(parser_options)

    other_options = optparse.OptionGroup(optionparser, 'Other options')
    other_options.add_option('-q',
                             '--quiet',
                             action='store_true',
                             help='don\'t print anything')
    other_options.add_option('-o',
                             '--out',
                             dest='output_filename',
                             metavar='FILE',
                             help='specify an explicit output filename')
    other_options.add_option('-v',
                             '--verbose',
                             action='store_true',
                             help='print extra information')
    other_options.add_option('-V',
                             '--version',
                             action='callback',
                             callback=display_version,
                             help='display the version number and exit')
    optionparser.add_option_group(other_options)

    svg_options = optparse.OptionGroup(optionparser, 'SVG options')
    svg_options.add_option('-r',
                           '--repair',
                           action='store_true',
                           default=False,
                           help='Repair the SVG so it meets RFC 7966')
    svg_options.add_option(
        '-a',
        '--always-emit',
        action='store_true',
        default=False,
        help='Emit the SVG file even if does not need repairing.  Implies -r')
    svg_options.add_option(
        '-g',
        '--grey-scale',
        action='store_true',
        help='Use grey scaling hieristic to determine what is white')
    svg_options.add_option(
        '--grey-level',
        default=381,
        help='Level to use for grey scaling, defaults to 381')
    optionparser.add_option_group(svg_options)

    # --- Parse and validate arguments --------------

    (options, args) = optionparser.parse_args()

    # Setup warnings module
    # rfclint.log.warn_error = options.warn_error and True or False
    log.quiet = options.quiet and True or False
    log.verbose = options.verbose

    if options.cache:
        if not os.path.exists(options.cache):
            try:
                os.makedirs(options.cache)
                if options.verbose:
                    log.write('Created cache directory at', options.cache)
            except OSError as e:
                print('Unable to make cache directory: %s ' % options.cache)
                print(e)
                sys.exit(1)
        else:
            if not os.access(options.cache, os.W_OK):
                print('Cache directory is not writable: %s' % options.cache)
                sys.exit(1)

    if options.clear_cache:
        clear_cache(options.cache)

    if options.grey_scale:
        wp.color_threshold = options.grey_level

    sourceText = None
    if len(args) < 1:
        sourceText = sys.stdin.read()
        source = os.getcwd() + "/stdin"
    else:
        source = args[0]
        if not os.path.exists(source):
            sys.exit('No such file: ' + source)

    # Setup warnings module
    # rfclint.log.warn_error = options.warn_error and True or False
    log.quiet = options.quiet and True or False
    log.verbose = options.verbose

    # Parse the document into an xmlrfc tree instance
    parser = XmlRfcParser(source,
                          verbose=options.verbose,
                          preserve_all_white=True,
                          quiet=options.quiet,
                          cache_path=options.cache,
                          no_network=options.no_network,
                          no_xinclude=options.no_xinclude)
    try:
        xmlrfc = parser.parse(remove_pis=True,
                              remove_comments=False,
                              strip_cdata=False,
                              textIn=sourceText)
    except XmlRfcError as e:
        log.exception('Unable to parse the XML document: ' + source, e)
        sys.exit(1)
    except lxml.etree.XMLSyntaxError as e:
        # Give the lxml.etree.XmlSyntaxError exception a line attribute which
        # matches lxml.etree._LogEntry, so we can use the same logging function
        log.exception('Unable to parse the XML document: ' + source,
                      e.error_log)
        sys.exit(1)

    # Check that

    ok = checkTree(xmlrfc.tree)
    if (not ok and options.repair) or options.always_emit:
        encodedBytes = lxml.etree.tostring(xmlrfc.tree.getroot(),
                                           xml_declaration=True,
                                           encoding='utf-8',
                                           pretty_print=True).decode('utf-8')
        if options.output_filename is None:
            file = sys.stdout
        else:
            file = open(options.output_filename, 'w')
        log.write_to(file, encodedBytes)

    if ok:
        log.info("File conforms to SVG requirements.")
        sys.exit(0)

    log.error("File does not conform to SVG requirements")
    sys.exit(1)
Ejemplo n.º 21
0
 def test_simple(self):
     """ Test a simple xml file will load."""
     parse = XmlRfcParser("Tests/simple.xml", quiet=False,
                          cache_path=None, no_network=True)
     parse = parse.parse()