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
|
#!/usr/bin/env python3
# Copyright 2021 The Emscripten Authors. All rights reserved.
# Emscripten is available under two separate licenses, the MIT license and the
# University of Illinois/NCSA Open Source License. Both these licenses can be
# found in the LICENSE file.
"""Convert src/settings.js into ReSt docs that get published as
part of the emscripten docs.
This parser for src/settings.js is somewhat fragile, and
comments need to be written in a ReSt friendly way. This
means, for example, using double backticks for keywords and
leaving a blank line before and after list blocks.
The parser does understand several "tags" which we use
settings.js. For example [compile] and [link].
"""
import os
import sys
import subprocess
script_dir = os.path.dirname(os.path.abspath(__file__))
root_dir = os.path.dirname(os.path.dirname(script_dir))
sys.path.insert(0, root_dir)
from tools.utils import path_from_root, read_file, safe_ensure_dirs
header = '''\
.. _settings-reference:
============================
Emscripten Compiler Settings
============================
The following is a complete list of settings that can be passed
to emscripten via ``-s`` on the command line. For example
``-sASSERTIONS`` or ``-sASSERTIONS=0``. For more details see the
:ref:`emcc <emcc-s-option-value>` documentation.
Unless otherwise noted these settings only apply when linking
and have no effect during compilation.
.. Auto-generated by update_settings_docs.py. **DO NOT EDIT**
'''
all_tags = {
'link': '',
'compile+link': 'Applicable during both linking and compilation',
'compile': 'Only applicable during compilation',
'experimental': 'This is an experimental setting',
'deprecated': 'This setting is deprecated',
}
output_file = path_from_root('site/source/docs/tools_reference/settings_reference.rst')
def write_setting(f, setting_name, setting_default, comment, tags):
# Convert markdown backticks to rst double backticks
f.write('\n.. _' + setting_name.lower() + ':\n')
f.write('\n' + setting_name + '\n')
f.write('=' * len(setting_name) + '\n\n')
f.write(comment + '\n')
for tag in tags:
for t in tag.split():
if all_tags[t]:
f.write('\n.. note:: ' + all_tags[t] + '\n')
# TODO: Properly handle multi-line values, like for INCOMING_MODULE_JS_API,
# which is [, newline, and then lines of content. For now print a
# placeholder.
if setting_default == '[':
setting_default = '(multi-line value, see settings.js)'
f.write('\nDefault value: ' + setting_default + '\n')
def write_file(f):
f.write(header)
current_comment = []
current_tags = []
for line in read_file(path_from_root('src/settings.js')).splitlines():
if 'Internal, used for testing only, from here' in line:
break
if not line:
current_comment = []
current_tags = []
if line.startswith('//'):
line = line[2:]
# Strip at most one leading space
if line and line[0] == ' ':
line = line[1:]
if line.startswith('[') and line.endswith(']'):
tag = line.strip('[')
tag = tag.rstrip(']')
if tag in all_tags:
current_tags.append(tag)
continue
current_comment.append(line)
elif line.startswith('var'):
# Format:
# var NAME = DEFAULT;
# Split it and strip the final ';'.
_, setting_name, _, setting_default = line.strip(';').split()
comment = '\n'.join(current_comment).strip()
write_setting(f, setting_name, setting_default, comment, current_tags)
current_comment = []
current_tags = []
def main(args):
if '--check' in args:
safe_ensure_dirs(path_from_root('out'))
tmp_output = path_from_root('out/settings_reference.rst')
with open(tmp_output, 'w') as f:
write_file(f)
if read_file(tmp_output) != read_file(output_file):
print(f'{output_file} is out-of-date. Please run tools/maint/update_settings_docs.py')
subprocess.call(['diff', '-u', output_file, tmp_output])
return 1
else:
with open(output_file, 'w') as f:
write_file(f)
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))
|