tom_som_c_v0 — typed TomSpecs object model for C
> Cross-references. > tom_specs_model/doc/som_multiplatform_spec_model.md
> is the SOM authority: SOM §6 decides the split between this > typed access path and the generic one,
SOM §8 decides what > this generated surface contains, SOM §4.2 decides the model > version stamp and the editing rules it enforces, and >
SOM §17 decides how the package is built and published. > tom_specs_model/doc/index.md
catalogues every > TomSpecs subject-matter document and owns the § citation > convention. This README says how to
use this package's code; > those documents own the model, the formats and the rules, and > nothing here restates them.
Generated typed TomSpecs object-model facade (C).
Where this fits
tom_som_c_v0 is the generated typed face of the TomSpecs object model for C: one type per document section, so a specification is read and written through named members rather than through string paths. It exists because a string path is checked only at run time — a mistyped one reads as an absent value instead of an error — and a specification is exactly the kind of document where that failure is silent and expensive. It is one half of a pair: the hand-written
tom_som_c_runtime
holds everything identical in every language (the sparse document store, the codecs, the validator) and this half holds only what changes when the model changes, so a regeneration rewrites the typed types and touches nothing else. The same pair exists for all nine SOM languages, generated from one model, so a document written through any of them reads identically through the other eight. There is no registry: both halves build to a static and a shared library with a pkg-config
.pc file, so make install and pkg-config --cflags --libs are the integration surface.
Overview
A TomSpecs document is sparse and path-keyed: a value lives under the globally-unique section-id path it belongs to, and an absent key means "no value" rather than an empty one. This package holds none of those values —
SpecDocument, in the runtime, does. What it holds is a typed view: each generated type wraps a document together with the path prefix it is rooted at, and its members resolve to the paths beneath that prefix. Constructing a document root also runs the model-version check (SOM §4.2), so a document stamped by a different model version is refused rather than silently misread.
Everything generated here is derived from the tom_specs_model Dart model and rewritten wholesale on every run of
tom_specs_clitool/bin/generate_som.dart. Beside the typed types the package ships the lossless meta-data file (meta/spec_model.meta.json,
SOM §5.3), the generated DocSpecs schemas (schemas/, SOM §13), and the metadata trees that drive the dot-notation and id-tree access surfaces (SOM §8). The hand-written trees beside them —
examples/, the tests, doc/ — are preserved across regeneration; the generator writes files, it never wipes the output root.
Installation
C has no package registry. Install the facade and the runtime (runtime first — the facade links against it), then let
pkg-config supply the compile and link flags:
make -C ../tom_som_c_runtime install
make install
cc myapp.c $(pkg-config --cflags --libs tom_som_c_v0) -o myapp
The facade .pc declares Requires: tom_som_c_runtime, so a single pkg-config tom_som_c_v0
pulls in the runtime flags too. Both .pc files report Version 1.3.2.
tom_som_c_v0 and tom_som_c_runtime both carry version 1.3.2, taken from the TomSpecs model version — pin them together. Every other dependency route (git, path, vendored, build-from-source) is in
readme_howtointegrate.md.
Features
Document roots
Each root is a whole TomSpecs document, and the first segment of every path beneath it is its section id. Construct the root you need over a
SpecDocument; the 1254 model classes are reached through it.
| Section id | Document | Generated root type |
|---|---|---|
SBP | Solution Blueprint | D00SolutionBlueprint |
CLA |
Current Landscape Assessment | D01CurrentLandscapeAssessment |
TOM |
Target Operating Model | D02TargetOperatingModel |
IFM | Information Model | D03InformationModel |
RSP |
Requirements Specification | D04RequirementsSpecification |
ISC | Interaction Scenarios | D05InteractionScenarios |
ATS |
Architecture & Technology Specification | D06ArchitectureTechnologySpecification |
IIS |
Integration & Interface Specification | D07IntegrationInterfaceSpecification |
SAS |
Security & Access Specification | D08SecurityAccessSpecification |
XDS |
Experience Design Specification | D09ExperienceDesignSpecification |
QAP |
Quality & Acceptance Plan | D10QualityAcceptancePlan |
DRM | Delivery Roadmap | D11DeliveryRoadmap |
TRP |
Transition & Rollout Plan | D12TransitionRolloutPlan |
CGP |
CodeSpecs Generation Projection | D13CodeSpecsProjection |
Quick start
Build and install tom_som_c_v0 (and tom_som_c_runtime), then compile against it with
pkg-config:
#include "tom_som_c_v0.h"
int main(void) {
// A typed Solution Blueprint over a fresh document. The constructor also runs
// the instantiation-time model-version check (an empty stamp is editable).
SpecDocument doc;
spec_document_init(&doc);
D00SolutionBlueprint bp;
d00_solution_blueprint_new(&bp, &doc, "", NULL);
d00_solution_blueprint_set_content(
&bp, "A platform that unifies our fragmented order systems.");
CurrentLandscape cl = d00_solution_blueprint_current_landscape(&bp);
current_landscape_set_content(
&cl, "Three legacy systems with no shared customer record.");
char *content = d00_solution_blueprint_content(&bp);
printf("%s\n", content);
free(content);
current_landscape_free(&cl);
d00_solution_blueprint_free(&bp);
spec_document_free(&doc);
return 0;
}
Prints A platform that unifies our fragmented order systems. — the value just written, read back through the typed getter.
Examples
| Sample | Demonstrates |
|---|---|
a_typed_access.c
|
The generated typed facade — named members, nested-section navigation, and the typed
SomList
collection.
|
b_generic_document.c
|
The generic runtime underneath — string paths into a sparse store, plus JSON and YAML serialization. |
c_reflection_metadata.c
|
The value-free reflection surface — load
meta/spec_model.meta.json
, enumerate roots and fields, resolve a path to the model node it lands on.
|
examples/README.md
gives the run command for each.
For complete, runnable sample projects — a whole task carried end to end across several packages rather than one package's API — see
tom_specs_samples/.
Usage
The generic store underneath
A facade is a view; the document is the value. Reach past the typed types whenever a path is computed rather than known — both sides address exactly the same store.
#include "tom_som_c_runtime.h"
#include "tom_som_c_v0_meta.h"
SpecDocument doc;
spec_document_init(&doc);
spec_document_set_content(
&doc, "SBP/content",
"A platform that unifies our fragmented order systems.");
/* A repeated section: each append returns the new item's OWNED path. */
char *item = spec_document_add_list_item(
&doc, "SBP/currentLandscape/CUOPME-OPER-LST");
char *leaf = spec_path_join(item, "content");
spec_document_set_content(&doc, leaf, "Average order turnaround: 4.2 days.");
free(leaf);
free(item);
/* encode_yaml also returns an owned buffer the caller frees. */
char *err = NULL;
char *yaml = encode_yaml(&doc, d00_solution_blueprint_meta_tree(), "1.0", &err);
printf("%s", yaml);
free(yaml);
spec_document_free(&doc);
Metadata and reflection
The exported class graph answers "what can the model hold?" with no document values involved — enumerate roots and fields, or resolve a concrete path to the model node it lands on (SOM §7).
#include "tom_som_c_runtime.h"
char *err = NULL;
SpecModel *model = spec_model_from_json_str(data, &err);
SpecReflection ref = spec_reflection_make(model);
/* The roots are model data; the reflection resolves paths against them. */
for (size_t i = 0; i < model->roots_len; i++) {
const SpecRoot *root = &model->roots[i];
printf("%s %s
", spec_reflection_root_segment(root), root->title);
}
SpecResolution res;
if (spec_reflection_resolve(&ref, "SBP/currentLandscape/content", &res)) {
printf("kind=%s value_leaf=%d
", res.kind,
spec_resolution_is_value_leaf(&res));
spec_resolution_free(&res);
}
spec_model_free(model);
Regenerating
This package is output. When the model changes, regenerate it rather than editing it — every file carrying the
GENERATED … do not edit by hand banner is overwritten:
dart run tom_specs_clitool/bin/generate_som.dart
Architecture
tom_som_c_v0 the typed path — this package
D00SolutionBlueprint … one type per document root
│ extends
▼
SomNode / SomScalar / SomList editing-facade bases
│ bound to
▼
SpecDocument sparse, path-keyed value store
│ (tom_som_c_runtime)
▼
SpecReflection · SpecValidator · YAML + Markdown codecs
▲
│ described by
SomMetaTree ◀── meta/spec_model.meta.json
| Type | Responsibility |
|---|---|
D00SolutionBlueprint … |
The generated document roots — one per row of the table above, each the typed entry point to a whole document. |
SomNode |
The base every generated section type extends: a document plus the path prefix this section is rooted at. |
SomScalar |
A typed leaf — parse and format at the store boundary, so
int
/
bool
/ enum members read as themselves.
|
SomList |
A typed repeated section — append, index and enumerate items whose paths the store generates. |
SomMetaTree / SomMetaNode |
The generated metadata trees (
SOM §7
): the model's shape as data, behind the dot-notation and id-tree access surfaces.
|
SomEditability |
The
SOM §4.2
version-check outcome — whether a stamped document may be edited by this facade.
|
SpecDocument |
The value store itself. Lives in tom_som_c_runtime; every type above is a view onto it. |
Ecosystem
tom_specs_model the Dart model — the source of truth
│
▼ generate_som
tom_specs_clitool the generator
│
▼ emits
tom_som_c_v0 ← this package (typed)
│
▼ depends on
tom_som_c_runtime (generic, hand-written)
│
▼ validated against
tom_som_conformance the shared cross-language corpus
The same shape repeats for all nine languages; the corpus at the bottom is shared, which is what makes "identical in every language" a measured claim rather than an intention (SOM §19).
Further documentation
TomSpecs subject matter — the authorities this package implements:
| Document | Authority for |
|---|---|
| index.md | The catalogue of every TomSpecs subject-matter document, and the § citation convention. |
| som_multiplatform_spec_model.md |
The two access paths, what this generated surface contains, the version stamp and editing rules, the
*.md
and
*.docspecs.yaml
formats, and the conformance corpus.
|
| som_toolchains.md | This language plane's build and verify toolchain, and the reference host. |
| tom_specs_model_meta_schema.md | The on-disk schema of meta/spec_model.meta.json. |
This package — its own guides:
| Guide | Covers |
|---|---|
| doc/tutorial.md |
A C walkthrough end to end — install, open a document, read and edit a section, validate it, and serialize to
*.docspecs.yaml
and Markdown.
|
| readme_howtointegrate.md | Every dependency route, how to pin the version, and building from source. |
| examples/README.md | The runnable samples and how to run each. |
Siblings — packages you will reach for next:
| Package | What it is |
|---|---|
| tom_som_c_runtime | The generic runtime this facade is a view over — reach for it directly to drive a document by path. |
| tom_som_conformance | The shared corpus and the cross-language drivers that run every port against it. |
| tom_specs_clitool | The generator that writes this package. |
Status
Version 1.3.2, tracking the TomSpecs model version and matching tom_som_c_runtime. Generated surface: 14 document roots, 1254 model classes. Verify the package with:
make -C ../tom_som_c_runtime
make
./run_tests.sh # the behavioural suites + the three samples
A generated README states no fixed test count: the count moves with the model, and a number this file could not update would go stale the first time the model did. The command above is the standing answer — it runs this package against the shared cross-language corpus (SOM §19).