1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
#!/usr/bin/env python
# $Id: convert_hardwareconfig2.py,v 1.1 2004/10/23 23:22:21 mthuurne Exp $
#
# Script for updating openMSX 0.5.0 configurations (hardwareconfig.xml)
# to the new format used by CVS HEAD. Even though CVS HEAD is compatible
# with the 0.5.0 format (msxconfig2), the new format is preferred.
# If you run this script and see "NOTE:" in the output, please verify the
# created XML files manually.
import os, os.path, sys
from StringIO import StringIO
from xml.dom.minidom import parse
def convertDoc(dom, checksums):
assert dom.nodeType == dom.DOCUMENT_NODE
if dom.doctype.systemId == 'msxconfig.dtd':
print ' old unsupported format, skipping'
return
elif dom.doctype.systemId != 'msxconfig2.dtd':
print ' NOTE: unknown format, skipping'
return
sawCVSid = False
for child in dom.childNodes:
if child.nodeType == dom.COMMENT_NODE:
if child.nodeValue.startswith(' $Id') \
and child.nodeValue.endswith('$ '):
sawCVSid = True
elif child.nodeType == dom.DOCUMENT_TYPE_NODE:
if child.nodeName != 'msxconfig':
print ' NOTE: unknown document type "%s", skipping' % \
child.nodeName
return
elif child.nodeType == dom.ELEMENT_NODE:
if child.nodeName == 'msxconfig':
convertRoot(child, checksums)
else:
print ' NOTE: wrong root node "%s", skipping' % child.nodeName
return
if not sawCVSid:
print ' NOTE: no CVS id'
def convertRoot(node, checksums):
def removeSlowDrainOnReset(memNode):
for child in memNode.childNodes:
if child.nodeType == node.ELEMENT_NODE \
and child.nodeName == 'slow_drain_on_reset':
print ' remove slow_drain_on_reset'
memNode.removeChild(child)
child.unlink()
return
for child in node.getElementsByTagName('RAM') \
+ node.getElementsByTagName('MemoryMapper') \
+ node.getElementsByTagName('PanasonicRAM'):
removeSlowDrainOnReset(child)
def stripSpaces(node):
if node.nodeType == node.TEXT_NODE:
if node.nodeValue.isspace():
node.parentNode.removeChild(node)
node.unlink()
else:
for child in list(node.childNodes):
stripSpaces(child)
def layoutDocument(dom):
for child in dom.childNodes:
if child.nodeType == dom.ELEMENT_NODE:
layoutNode(child)
def layoutNode(node, indent = '', lineSpacing = 2):
hasElements = False
for child in list(node.childNodes):
if child.nodeType == node.ELEMENT_NODE:
if child.tagName == 'secondary': lineSpacing = 2
hasElements = True
node.insertBefore(
child.ownerDocument.createTextNode(
'\n' * lineSpacing + ' ' + indent
),
child
)
layoutNode(
child,
indent + ' ',
1 + int(child.tagName in ['devices'])
)
elif child.nodeType == node.COMMENT_NODE:
node.insertBefore(
child.ownerDocument.createTextNode(
'\n' * lineSpacing + ' ' + indent
),
child
)
if hasElements:
node.appendChild(node.ownerDocument.createTextNode(
'\n' * lineSpacing + indent
))
if len(sys.argv) != 3:
print 'Usage: convert_hardwareconfig.py <indir> <outdir>'
sys.exit(2)
indir = sys.argv[1]
outdir = sys.argv[2]
if outdir[-1] != '/': outdir += '/'
for root, dirs, files in os.walk(indir):
if 'hardwareconfig.xml' in files:
print 'Converting ' + root.split('/')[-1] + '...'
assert root.startswith(indir)
outpath = outdir + root[len(indir) : ]
checksums = {}
if os.path.isdir(root + '/roms') \
and os.path.isfile(root + '/roms/SHA1SUMS'):
for line in open(root + '/roms/SHA1SUMS'):
checksum, empty, fileName = line[ : -1].split(' ')
assert empty == ''
checksums[fileName] = checksum
dom = parse(root + '/hardwareconfig.xml')
dom.normalize()
stripSpaces(dom)
convertDoc(dom, checksums)
layoutDocument(dom)
if not os.path.isdir(outpath):
os.makedirs(outpath)
out = StringIO()
dom.writexml(out)
out.seek(0)
outFile = open(outpath + '/hardwareconfig.xml', 'w')
# Minidom doesn't seem to allow text nodes at document level,
# so do some postprocessing using string manipulation.
afterDoctype = False
for line in out.readlines():
if line.startswith('<!--'):
index = 0
while True:
start = index
index = line.find('-->', start)
if index == -1:
line = line[start : ]
break
index += 3
outFile.write(line[start : index] + '\n')
if line.startswith('<!DOCTYPE'):
outFile.write(line[ : -1])
afterDoctype = True
elif afterDoctype:
index = 0
while line[index].isspace(): index += 1
outFile.write(' ' + line[index : ])
afterDoctype = False
else:
outFile.write(line)
outFile.write('\n')
outFile.close()
out.close()
dom.unlink()
|