diff --git a/.github/workflows/verify-data.yml b/.github/workflows/verify-data.yml index 7ec4f81..6354ba0 100644 --- a/.github/workflows/verify-data.yml +++ b/.github/workflows/verify-data.yml @@ -20,3 +20,19 @@ jobs: yamllint_file_or_dir: "*.yaml" yamllint_strict: false yamllint_comment: false + + - name: "Set up Python" + uses: actions/setup-python@v5 + with: + python-version: "3.x" + + - name: "Install dependencies" + run: | + python3 -m pip install --upgrade pip + python3 -m pip install PyYAML jsonschema + + - name: "Verify features" + run: | + for file in features_c*.yaml; do + python3 verify_features.py "$file" + done diff --git a/features.schema.yaml b/features.schema.yaml new file mode 100644 index 0000000..d685585 --- /dev/null +++ b/features.schema.yaml @@ -0,0 +1,83 @@ +--- +$schema: "http://json-schema.org/draft-07/schema#" +title: Feature List Schema +type: object +required: + - features +properties: + features: + type: array + items: + $ref: "#/definitions/feature" +definitions: + feature: + type: object + required: + - desc + additionalProperties: false + properties: + desc: + type: string + description: "The title and / or description of the feature. Supports Markdown." + paper: + description: "One or multiple paper numbers that belong to the feature." + oneOf: + - type: string + - type: array + items: + type: string + lib: + type: boolean + default: false + description: "If true, the feature counts as a standard library feature." + support: + type: array + description: "A list of toolchains that support the feature." + items: + type: string + pattern: "^(GCC|Clang|MSVC|Xcode)( [0-9]+(\\.[0-9]+)*)?( \\((partial|hint)\\))?$" + hints: + type: array + description: "A list of hints targeting toolchains in the support list." + items: + type: object + required: + - target + - msg + additionalProperties: false + properties: + target: + type: string + description: "The toolchain that this hint targets." + msg: + type: string + description: "The reason for partial support, or the hint. Supports Markdown." + ftm: + type: array + description: "A list of feature-testing macros (FTM) for the feature." + items: + type: object + required: + - name + - value + additionalProperties: false + properties: + name: + type: string + description: "The name of the FTM." + value: + oneOf: + - type: string + - type: integer + description: "The value of the FTM." + desc: + type: string + description: "Optional description of what this FTM specifically refers to." + content: + type: string + description: "Information about the feature (e.g. a filename)." + keywords: + type: array + description: "A list of keywords to categorize the feature." + items: + type: string diff --git a/features_c23.yaml b/features_c23.yaml index 6a003c1..c0ee85d 100644 --- a/features_c23.yaml +++ b/features_c23.yaml @@ -1,3 +1,4 @@ +--- features: - desc: "`static_assert` with no message" paper: N3020 diff --git a/features_c99.yaml b/features_c99.yaml index c852de2..f21a6c1 100644 --- a/features_c99.yaml +++ b/features_c99.yaml @@ -1,3 +1,4 @@ +--- features: - desc: "Universal-character-names in [identifiers](https://en.cppreference.com/w/c/language/identifiers.html)" support: diff --git a/verify_features.py b/verify_features.py new file mode 100644 index 0000000..c58825f --- /dev/null +++ b/verify_features.py @@ -0,0 +1,35 @@ +import yaml +import jsonschema +import sys + +def validate_yaml(schema_file, data_file): + try: + with open(schema_file, 'r') as f: + schema = yaml.safe_load(f) + + with open(data_file, 'r') as f: + data = yaml.safe_load(f) + + jsonschema.validate(instance=data, schema=schema) + print(f"Verification successful: {data_file}") + return True + except jsonschema.exceptions.ValidationError as e: + print(f"Verification failed: {data_file}") + print(f"Error: {e.message}") + print(f"Path: {' -> '.join(map(str, e.path))}") + return False + except Exception as e: + print(f"An error occurred: {e}") + return False + +if __name__ == "__main__": + schema_path = "features.schema.yaml" + + if len(sys.argv) < 2: + print("Usage: python3 verify_features.py ") + sys.exit(1) + + data_path = sys.argv[1] + success = validate_yaml(schema_path, data_path) + if not success: + sys.exit(1)