From b475bb6f360c379fb689325d0dd97f8ad4c6a858 Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Mon, 3 Aug 2026 04:21:16 -0700 Subject: [PATCH] Move schema related generated files into their own directory PiperOrigin-RevId: 958296165 Change-Id: I48cacc72c7df5994f5f816489ba069a5813845a1 --- doc/generate/generate_default_table.py | 9 +++++---- doc/generate/generate_mjcf_map.py | 7 ++++--- doc/generate/generate_mjcf_table.py | 2 +- doc/generate/generate_read_table.py | 8 ++++---- doc/generate/generate_schema.py | 2 +- src/xml/{ => generated}/mjcf_default_table.inc | 0 src/xml/{ => generated}/mjcf_map.h | 6 +++--- src/xml/{ => generated}/mjcf_read_table.inc | 0 src/xml/{ => generated}/mjcf_table.inc | 0 src/xml/xml_base.h | 2 +- src/xml/xml_native_reader.cc | 4 ++-- src/xml/xml_native_writer.cc | 2 +- test/doc/doc_test.py | 11 +++++++---- test/xml/schema_defaults_test.cc | 2 +- 14 files changed, 30 insertions(+), 25 deletions(-) rename src/xml/{ => generated}/mjcf_default_table.inc (100%) rename src/xml/{ => generated}/mjcf_map.h (98%) rename src/xml/{ => generated}/mjcf_read_table.inc (100%) rename src/xml/{ => generated}/mjcf_table.inc (100%) diff --git a/doc/generate/generate_default_table.py b/doc/generate/generate_default_table.py index aa5a919e..0c718ad4 100644 --- a/doc/generate/generate_default_table.py +++ b/doc/generate/generate_default_table.py @@ -16,7 +16,7 @@ The schema declares attribute defaults, but the defaults that act live in the C default-constructors (mjs_default*, mj_defaultOption, ...). This -emits src/xml/mjcf_default_table.inc: one row per defaulted attribute, +emits src/xml/generated/mjcf_default_table.inc: one row per defaulted attribute, binding the declared values to the field they describe, consumed by SchemaDefaultsTest, which compares every row against a freshly-constructed spec -- so a schema default that disagrees with the C defaults is a test @@ -24,7 +24,7 @@ failure, not documentation drift. Checked in and gated by test/doc/doc_test.py. """ -import os +import os # pylint: disable=unused-import import sys _SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) @@ -83,7 +83,7 @@ struct mjXDefaultTable { ''' -def _values(schema, attr, ctype): +def _values(schema, attr): """(ndecl, [C value expressions]) for an attribute's declared default.""" default = attr.default if attr.type == 'enum': @@ -125,7 +125,7 @@ def collect(schema, structs): f'field {field} ({ctype})') kind = KIND_BY_CTYPE.get(ctype, 2) # other mjt enums are int-sized length = dim if dim is not None else '1' - ndecl, values = _values(schema, attr, ctype) + ndecl, values = _values(schema, attr) if ndecl > 8: raise ValueError(f'{element.name}.{attr.name}: {ndecl} default ' 'values exceed the row capacity') @@ -143,6 +143,7 @@ def collect(schema, structs): def generate() -> str: + """Generates the mjcf_default_table.inc content as a string.""" schema = mjcf_schema.parse_file(SCHEMA_PATH) structs = generate_read_table.parse_spec_structs( generate_read_table.SPEC_H_PATH, generate_read_table.MODEL_H_PATH) diff --git a/doc/generate/generate_mjcf_map.py b/doc/generate/generate_mjcf_map.py index 5740507a..c757ca6b 100644 --- a/doc/generate/generate_mjcf_map.py +++ b/doc/generate/generate_mjcf_map.py @@ -14,14 +14,14 @@ # ============================================================================== """Generates the keyword-map header from src/xml/mjcf.schema. -Emits src/xml/mjcf_map.h: one mjMap array and size constant per schema +Emits src/xml/generated/mjcf_map.h: one mjMap array and size constant per schema enum, as C++17 inline variables, so the reader, the writer and the generated tables share one definition with no extern declarations to maintain. It is checked in and gated by test/doc/doc_test.py, which regenerates it from the schema and diffs. """ -import os +import os # pylint: disable=unused-import import sys _SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) @@ -29,7 +29,7 @@ sys.path.insert(0, _SCRIPT_DIR) import mjcf_schema _REPO_ROOT = os.path.dirname(os.path.dirname(_SCRIPT_DIR)) SCHEMA_PATH = os.path.join(_REPO_ROOT, 'src', 'xml', 'mjcf.schema') -_GUARD = 'MUJOCO_SRC_XML_MJCF_MAP_H_' +_GUARD = 'MUJOCO_SRC_XML_GENERATED_MJCF_MAP_H_' _INCLUDES = '''\ #include @@ -83,6 +83,7 @@ _FOOTER = '''\ def generate() -> str: + """Generates the mjcf_map.h content as a string.""" schema = mjcf_schema.parse_file(SCHEMA_PATH) out = [] for enum in schema.enums.values(): diff --git a/doc/generate/generate_mjcf_table.py b/doc/generate/generate_mjcf_table.py index b2f5e537..15b42b76 100644 --- a/doc/generate/generate_mjcf_table.py +++ b/doc/generate/generate_mjcf_table.py @@ -14,7 +14,7 @@ # ============================================================================== """Generates the MJCF[] grammar table from src/xml/mjcf.schema. -The table (src/xml/mjcf_table.inc) is the element tree consumed by the +The table (src/xml/generated/mjcf_table.inc) is the element tree consumed by the mjXSchema validator: rows of {name, cardinality, attributes...} with {"<"}/{">"} nesting markers. It is checked in and gated by test/doc/doc_test.py, which regenerates it from the schema and diffs. diff --git a/doc/generate/generate_read_table.py b/doc/generate/generate_read_table.py index c21fc5c1..ed183f01 100644 --- a/doc/generate/generate_read_table.py +++ b/doc/generate/generate_read_table.py @@ -14,9 +14,9 @@ # ============================================================================== """Generates keyword maps and typed attribute-read rows from mjcf.schema. -Emits src/xml/mjcf_read_table.inc: per-element mjXAttr row arrays consumed by -mjXReader::ReadAttrTable, plus the kSensorDispatch tag table and shared group -arrays. +Emits src/xml/generated/mjcf_read_table.inc: per-element mjXAttr row arrays +consumed by mjXReader::ReadAttrTable, plus the kSensorDispatch tag table and +shared group arrays. Which elements get rows is determined automatically: every schema element with a bound spec struct and at least one table-drivable attribute is included, @@ -29,7 +29,7 @@ compile errors, and the field's C type (parsed from mjspec.h) selects the row kind, so mjtNum vs double is decided by the struct, not by the schema. """ -import os +import os # pylint: disable=unused-import import re import sys diff --git a/doc/generate/generate_schema.py b/doc/generate/generate_schema.py index ba213cc7..48b6810d 100644 --- a/doc/generate/generate_schema.py +++ b/doc/generate/generate_schema.py @@ -124,7 +124,7 @@ def generate() -> str: """ script_dir = os.path.dirname(os.path.abspath(__file__)) repo_root = os.path.dirname(os.path.dirname(script_dir)) - filepath = os.path.join(repo_root, 'src', 'xml', 'mjcf_table.inc') + filepath = os.path.join(repo_root, 'src', 'xml', 'generated', 'mjcf_table.inc') xmlfile = os.path.join(repo_root, 'doc', 'XMLreference.rst') # Collect all link targets from XMLreference.rst for validation. diff --git a/src/xml/mjcf_default_table.inc b/src/xml/generated/mjcf_default_table.inc similarity index 100% rename from src/xml/mjcf_default_table.inc rename to src/xml/generated/mjcf_default_table.inc diff --git a/src/xml/mjcf_map.h b/src/xml/generated/mjcf_map.h similarity index 98% rename from src/xml/mjcf_map.h rename to src/xml/generated/mjcf_map.h index bff5bb6a..25be5c4e 100644 --- a/src/xml/mjcf_map.h +++ b/src/xml/generated/mjcf_map.h @@ -19,8 +19,8 @@ // the generated tables. Inline variables: including this header is all a // translation unit needs. -#ifndef MUJOCO_SRC_XML_MJCF_MAP_H_ -#define MUJOCO_SRC_XML_MJCF_MAP_H_ +#ifndef MUJOCO_SRC_XML_GENERATED_MJCF_MAP_H_ +#define MUJOCO_SRC_XML_GENERATED_MJCF_MAP_H_ #include #include @@ -486,4 +486,4 @@ inline constexpr mjMap flexeq_map[] = { inline constexpr int flexeq_sz = 4; // clang-format on -#endif // MUJOCO_SRC_XML_MJCF_MAP_H_ +#endif // MUJOCO_SRC_XML_GENERATED_MJCF_MAP_H_ diff --git a/src/xml/mjcf_read_table.inc b/src/xml/generated/mjcf_read_table.inc similarity index 100% rename from src/xml/mjcf_read_table.inc rename to src/xml/generated/mjcf_read_table.inc diff --git a/src/xml/mjcf_table.inc b/src/xml/generated/mjcf_table.inc similarity index 100% rename from src/xml/mjcf_table.inc rename to src/xml/generated/mjcf_table.inc diff --git a/src/xml/xml_base.h b/src/xml/xml_base.h index a6bd8e52..2c7902fe 100644 --- a/src/xml/xml_base.h +++ b/src/xml/xml_base.h @@ -25,7 +25,7 @@ // keyword maps, one per schema enum, generated into mjcf_map.h -#include "xml/mjcf_map.h" // IWYU pragma: export +#include "xml/generated/mjcf_map.h" // IWYU pragma: export //---------------------------------- Base XML class ------------------------------------------------ diff --git a/src/xml/xml_native_reader.cc b/src/xml/xml_native_reader.cc index d4bfab06..43ceb411 100644 --- a/src/xml/xml_native_reader.cc +++ b/src/xml/xml_native_reader.cc @@ -165,13 +165,13 @@ static void UpdateString(string& psuffix, int count, int i) { //---------------------------------- MJCF schema --------------------------------------------------- -#include "mjcf_table.inc" +#include "xml/generated/mjcf_table.inc" //---------------------------------- class mjXReader implementation -------------------------------- // typed attribute rows, generated from mjcf.schema; the keyword maps the // rows reference are generated into mjcf_map.h -#include "mjcf_read_table.inc" +#include "xml/generated/mjcf_read_table.inc" mjXReader::mjXReader() diff --git a/src/xml/xml_native_writer.cc b/src/xml/xml_native_writer.cc index e2c23b5e..64b27fa6 100644 --- a/src/xml/xml_native_writer.cc +++ b/src/xml/xml_native_writer.cc @@ -39,7 +39,7 @@ #include "tinyxml2.h" // typed attribute rows, generated from mjcf.schema; shared with the reader -#include "mjcf_read_table.inc" +#include "xml/generated/mjcf_read_table.inc" namespace { diff --git a/test/doc/doc_test.py b/test/doc/doc_test.py index 00644785..af9a532b 100644 --- a/test/doc/doc_test.py +++ b/test/doc/doc_test.py @@ -88,7 +88,8 @@ class DocTest(googletest.TestCase): def test_mjcf_table(self): """Checks that mjcf_table.inc matches the schema-generated output.""" - table_file = os.path.join(_REPO_ROOT, 'src', 'xml', 'mjcf_table.inc') + table_file = os.path.join(_REPO_ROOT, 'src', 'xml', 'generated', + 'mjcf_table.inc') source = generate_mjcf_table.generate() with open(table_file, 'r', encoding='utf-8') as file: if source != file.read(): @@ -96,7 +97,7 @@ class DocTest(googletest.TestCase): def test_default_table(self): """Checks that mjcf_default_table.inc matches the schema-generated output.""" - table_file = os.path.join(_REPO_ROOT, 'src', 'xml', + table_file = os.path.join(_REPO_ROOT, 'src', 'xml', 'generated', 'mjcf_default_table.inc') source = generate_default_table.generate() with open(table_file, 'r', encoding='utf-8') as file: @@ -105,7 +106,8 @@ class DocTest(googletest.TestCase): def test_mjcf_map(self): """Checks that mjcf_map.h matches the schema-generated output.""" - map_file = os.path.join(_REPO_ROOT, 'src', 'xml', 'mjcf_map.h') + map_file = os.path.join(_REPO_ROOT, 'src', 'xml', 'generated', + 'mjcf_map.h') source = generate_mjcf_map.generate() with open(map_file, 'r', encoding='utf-8') as file: if source != file.read(): @@ -113,7 +115,8 @@ class DocTest(googletest.TestCase): def test_read_table(self): """Checks that mjcf_read_table.inc matches the schema-generated output.""" - table_file = os.path.join(_REPO_ROOT, 'src', 'xml', 'mjcf_read_table.inc') + table_file = os.path.join(_REPO_ROOT, 'src', 'xml', 'generated', + 'mjcf_read_table.inc') source = generate_read_table.generate() with open(table_file, 'r', encoding='utf-8') as file: if source != file.read(): diff --git a/test/xml/schema_defaults_test.cc b/test/xml/schema_defaults_test.cc index f07e7c38..a77a25a5 100644 --- a/test/xml/schema_defaults_test.cc +++ b/test/xml/schema_defaults_test.cc @@ -24,7 +24,7 @@ #include #include "test/fixture.h" -#include "src/xml/mjcf_default_table.inc" +#include "src/xml/generated/mjcf_default_table.inc" namespace mujoco { namespace {