| #!/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 `.rst` format for the website. |
| |
| 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 subprocess |
| import sys |
| |
| 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.settings import ( |
| COMPILE_TIME_SETTINGS, |
| DEPRECATED_SETTINGS, |
| EXPERIMENTAL_SETTINGS, |
| LEGACY_SETTINGS, |
| ) |
| from tools.utils import exit_with_error, 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', |
| } |
| |
| deprecated_header = ''' |
| .. _deprecated-settings: |
| |
| =================== |
| Deprecated Settings |
| =================== |
| |
| The following settings have been proposed for removal from emscripten. These settings |
| still function but may be removed in a future version. If your project is using one of |
| these settings please open a bug (or reply to one of the existing bugs). |
| |
| ''' |
| |
| legacy_header = ''' |
| .. _legacy-settings: |
| |
| =============== |
| Legacy Settings |
| =============== |
| |
| The following settings no longer have any effect but are still accepted by emscripten |
| for backwards compatibility with older versions: |
| |
| ''' |
| |
| output_file = path_from_root('site/source/docs/tools_reference/settings_reference.rst') |
| |
| |
| def check_tags(setting_name, tags): |
| if setting_name in COMPILE_TIME_SETTINGS and 'compile' not in tags and 'compile+link' not in tags: |
| print(tags) |
| exit_with_error(f'setting {setting_name} in COMPILE_TIME_SETTINGS but missing [compile] tag') |
| if setting_name in DEPRECATED_SETTINGS and 'deprecated' not in tags: |
| exit_with_error(f'setting {setting_name} in DEPRECATED_SETTINGS but missing [deprecated] tag') |
| if setting_name in EXPERIMENTAL_SETTINGS and 'experimental' not in tags: |
| exit_with_error(f'setting {setting_name} in EXPERIMENTAL_SETTINGS but missing [experimental] tag') |
| |
| |
| 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 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(None, 3) |
| comment = '\n'.join(current_comment).strip() |
| check_tags(setting_name, current_tags) |
| write_setting(f, setting_name, setting_default, comment, current_tags) |
| current_comment = [] |
| current_tags = [] |
| |
| f.write(deprecated_header) |
| |
| for name, desc in DEPRECATED_SETTINGS.items(): |
| f.write(f' - ``{name}``: {desc}\n') |
| |
| f.write(legacy_header) |
| |
| for name, values, *extra_fields in LEGACY_SETTINGS: |
| desc = f'Valid values: {values}' |
| if extra_fields: |
| desc = f'{extra_fields[0]} ({desc})' |
| f.write(f' - ``{name}``: {desc}\n') |
| |
| |
| 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', encoding='utf-8') 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', encoding='utf-8') as f: |
| write_file(f) |
| |
| return 0 |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main(sys.argv[1:])) |