ClassicCPP scanner fails with UTF-8 BOM on non-UTF8 file
Damjan Jovanovic <[email protected]>
| Newsgroups | gmane.comp.programming.tools.scons.user |
|---|---|
| Message-ID | <CAJm2B-kCsdUh8Vq6d-O2gwv65hQrgxR6dpY2brvqiHtGQW63qA@mail.gmail.com> |
Hi
I am trying to port Apache OpenOffice to build with SCons, and while it's
still early, so far it's been a fantastic replacement for its current
"gbuild" system based on GNU make with unmaintainable custom eval()-based
logic. It has all the advanced build features we need usable in such a
clear and simple way.
When it comes to dependency scanning however, I've found a potential
problem. Our custom l10n translation system generates .res files from .src
files in 4 steps:
source/newerverwarn.src
| transex3
v
SrsPartMergeTarget/newerverwarn.src
| rsc
v
SrsPartTarget/newerverwarn.src
| cat files together
v
SrsTarget/uui.srs
| rsc
v
ResTarget/uuien-US.res
All that already works (and is half the code and 1000 times more readable
than GNU make). The problem is that .src files can #include other files.
When I add a dependency scanner for .src files:
env.Append(SCANNERS=ClassicCPP("AOOSRCScanner", '.src', "CPPPATH", '^[
\t]*#[ \t]*(?:include|import)[ \t]*(<|")([^>"]+)(>|")'))
which I want to scan the first file (source/newerverwarn.src), it also
scans the 2nd and 3rd .src files. With translation off it works perfectly.
However with translation on, the 2nd/3rd files are unusual, in that they
start with a UTF-8 BOM but the remainder of the file isn't UTF-8 but rather
latin-1 (a sample file is attached). This causes scons to exit with an
exception:
scons: ***
[solver/450/unxfbsdx/workdir/scons/uui/Res/SrsTarget/uui/res.srs]
UnicodeDecodeError : 'utf-8' codec can't decode byte 0xc3 in position 3552:
invalid continuation byte
I could hack File.get_text_contents() in engine/SCons/Node/FS.py to catch
exceptions when parsing in utf-8 with the BOM removed and retry in latin-1.
But an even better solution would be to limit the ClassicCPP scanner to
only scan the .src files under the source/ directory and ignore the
generated files in other directories. Is there some way to do that?
Thank you
Damjan
P.S. Standalone test with the sample file:
import sys
import codecs
contents = open(sys.argv[1], 'rb').read()
if contents[:len(codecs.BOM_UTF8)] == codecs.BOM_UTF8:
print(sys.argv[1] + " starts with UTF-8 BOM")
else:
print(sys.argv[1] + " does not start with UTF-8 BOM")
try:
contents.decode('utf-8')
print('Decoded in utf-8')
except UnicodeDecodeError as e:
try:
contents.decode('latin-1')
print('Decoded in latin-1')
except UnicodeDecodeError as e:
contents.decode('utf-8', error='backslashreplace')
print('Decoded in utf-8 with backslashreplace')
_______________________________________________
Scons-users mailing list
[email protected]
https://pairlist4.pair.net/mailman/listinfo/scons-users
newerverwarn.zip
(application/zip, 16.8 KB) - not displayed