Template
feat(detect): define feature-check registry schema
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* check_registry.h - declarative feature-check kinds for stupidtools
|
||||
* (todo 10).
|
||||
*
|
||||
* A `feature "name" { check* }` block's children are CHECK nodes. Each
|
||||
* check node's NAME is one of eight fixed keywords - the check KINDS -
|
||||
* and its FIRST (and only) positional argument is the TARGET the check
|
||||
* is about:
|
||||
*
|
||||
* check := <name> <arg> props*
|
||||
*
|
||||
* The eight kinds mirror GNU Autoconf's "Existing Tests" (manual §5) and
|
||||
* pkg-config's PKG_CHECK_MODULES:
|
||||
*
|
||||
* header arg = header name -> #include <arg> probe
|
||||
* e.g. header "pthread.h"
|
||||
* function arg = function name -> link probe for the symbol
|
||||
* e.g. function "strdup"
|
||||
* library arg = library name -> -l<arg> link probe
|
||||
* e.g. library "pthread"
|
||||
* type arg = type name -> compile probe for the type
|
||||
* e.g. type "size_t"
|
||||
* sizeof arg = type name -> sizeof(<arg>) probe
|
||||
* e.g. sizeof "long"
|
||||
* program arg = program name -> command -v <arg> probe
|
||||
* e.g. program "pkg-config"
|
||||
* compiler_flag arg = flag -> compile probe with <arg> added
|
||||
* e.g. compiler_flag "-fsanitize=address"
|
||||
* pkg_config arg = package name -> pkg-config --cflags --libs <arg>
|
||||
* e.g. pkg_config "openssl"
|
||||
*
|
||||
* WHAT THIS TODO OWNS
|
||||
* -------------------
|
||||
* Only the DECLARATIVE SHAPE: the kind enumeration, the kind<->keyword
|
||||
* mapping, and per-kind argument/property shape as DATA (the table
|
||||
* below). It deliberately does NOT implement probe generation (todo 11)
|
||||
* or probe execution/caching (todo 12). src/kdl/schema.c consumes the
|
||||
* mapping + table to enforce the DSL (see its todo-10 HOOK); todos 11
|
||||
* and 16 consume the same table to generate probes and substitute
|
||||
* results - THIS HEADER IS THE CONTRACT for them.
|
||||
*
|
||||
* OPTIONAL `version` CONSTRAINT (library and pkg_config)
|
||||
* ------------------------------------------------------
|
||||
* `library` and `pkg_config` may carry an optional version constraint,
|
||||
* spelled EXACTLY like the project node's version (pinned by todo 9):
|
||||
* the literal keyword `version` followed by a constraint string, as two
|
||||
* further positional arguments:
|
||||
*
|
||||
* library "curl" version ">=7.0"
|
||||
* pkg_config "openssl" version ">=1.1"
|
||||
*
|
||||
* The constraint is "<op><version>": <op> one of >= <= = > <, <version>
|
||||
* a dotted numeric version. Todo 10 pins only the SHAPE (the keyword +
|
||||
* a non-empty unannotated string); the OPERATOR SEMANTICS are
|
||||
* interpreted by todo 11 (probe generation) and todo 16 (result
|
||||
* substitution). The spelling is an argument pair, not a KDL property,
|
||||
* because this parser classifies `version "..."` as two positional
|
||||
* arguments - the same reason the project node spells it that way. The
|
||||
* property form `version="..."` is NOT part of the DSL and is rejected
|
||||
* (see PROPERTIES below).
|
||||
*
|
||||
* PROPERTIES
|
||||
* ----------
|
||||
* No check kind accepts properties in this todo (the grammar's `props*`
|
||||
* is always empty for now); the schema validator rejects them with a
|
||||
* spanned error. The shape table carries no props column for the same
|
||||
* reason - todos 11/16 derive everything from the argument counts.
|
||||
*
|
||||
* ERRORS
|
||||
* ------
|
||||
* st_check_kind_from_node() reports unknown/empty check names as owned
|
||||
* ST_ERR_KDL_SCHEMA errors whose span is heap-allocated IN THE SAME
|
||||
* BLOCK as the error (the parser.c pattern), so err->span stays valid
|
||||
* until st_error_free(err). The span points at the node's name token.
|
||||
*
|
||||
* Copyright (c) 2026 huntedbytheirs
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef ST_DETECT_CHECK_REGISTRY_H
|
||||
#define ST_DETECT_CHECK_REGISTRY_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
struct st_error;
|
||||
struct st_kdl_node;
|
||||
|
||||
/* The eight declarative check kinds, in canonical order. */
|
||||
enum st_check_kind {
|
||||
ST_CHECK_HEADER = 0, /* header "pthread.h" */
|
||||
ST_CHECK_FUNCTION, /* function "strdup" */
|
||||
ST_CHECK_LIBRARY, /* library "pthread" -> -lpthread */
|
||||
ST_CHECK_TYPE, /* type "size_t" */
|
||||
ST_CHECK_SIZEOF, /* sizeof "long" */
|
||||
ST_CHECK_PROGRAM, /* program "pkg-config" -> command -v */
|
||||
ST_CHECK_COMPILER_FLAG, /* compiler_flag "-fsanitize=address" */
|
||||
ST_CHECK_PKG_CONFIG, /* pkg_config "openssl" */
|
||||
ST_CHECK_KIND_COUNT, /* sentinel: number of real kinds above */
|
||||
};
|
||||
|
||||
/* The DSL shape of one check kind, as DATA (consumed by the schema
|
||||
* validator and by todos 11/16). */
|
||||
struct st_check_shape {
|
||||
enum st_check_kind kind; /* the kind this row describes */
|
||||
const char *name; /* DSL keyword spelling, e.g. "header" */
|
||||
const char *arg_meaning; /* what the required argument names, e.g.
|
||||
"header name" */
|
||||
size_t required_args; /* positional args the node MUST carry */
|
||||
size_t optional_args; /* further positional args tolerated; 2
|
||||
for library/pkg_config = the literal
|
||||
`version` keyword followed by the
|
||||
version constraint string (see the
|
||||
header comment); 0 elsewhere */
|
||||
};
|
||||
|
||||
/* The registry table: one row per kind, indexed by the ST_CHECK_*
|
||||
* values (st_check_shapes[k].kind == k). */
|
||||
extern const struct st_check_shape st_check_shapes[ST_CHECK_KIND_COUNT];
|
||||
|
||||
/* Map a feature's check child node to its kind by the node NAME. The
|
||||
* name may be any KDL string form (bare identifier or quoted). Returns
|
||||
* the kind and leaves *err untouched on success. On failure returns
|
||||
* ST_CHECK_KIND_COUNT and sets *err to an owned ST_ERR_KDL_SCHEMA error
|
||||
* whose span points at the node's name: an unknown keyword, an empty
|
||||
* name, or (defensively) a NULL node. */
|
||||
enum st_check_kind st_check_kind_from_node(const struct st_kdl_node *node,
|
||||
struct st_error **err);
|
||||
|
||||
/* Stable DSL keyword for a kind (e.g. "header"). Kinds outside the
|
||||
* table yield "?" rather than indexing out of range. */
|
||||
const char *st_check_kind_name(enum st_check_kind kind);
|
||||
|
||||
/* The shape-table row for a kind, or NULL when `kind` is not a real
|
||||
* kind. */
|
||||
const struct st_check_shape *st_check_kind_shape(enum st_check_kind kind);
|
||||
|
||||
/* Number of real kinds (ST_CHECK_KIND_COUNT). */
|
||||
size_t st_check_kind_count(void);
|
||||
|
||||
#endif /* ST_DETECT_CHECK_REGISTRY_H */
|
||||
Reference in New Issue
Block a user