| #!/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:])) |