feat(gen): emit config.status/config.log/config.h

This commit is contained in:
2026-08-29 00:15:46 -04:00
parent 03497e2c38
commit 08e1ea93dd
5 changed files with 847 additions and 17 deletions
+79 -9
View File
@@ -20,6 +20,7 @@
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "gen/config.h"
#include "gen/configure.h"
#include "cli.h" /* STUPIDTOOLS_VERSION (the generated-by version string) */
@@ -327,9 +328,7 @@ static const char SUBST_LOOKUP_TAIL[] =
" done < ./Makefile.in\n"
"}\n"
"\n"
"st_subst\n"
"\n"
"exit 0\n";
"st_subst\n";
/* ---- section emitters -------------------------------------------------- */
@@ -570,6 +569,27 @@ done:
return err;
}
/* Append `name` (owned) to the feature-name list, growing it as needed.
* Used by the probe-section loop to collect the names the todo-17 results
* summary + config.h defines are emitted from. */
static struct st_error *
collect_feature_name(char ***names, size_t *count, size_t *cap, char *name)
{
if (*count == *cap) {
size_t ncap = *cap == 0 ? 8 : *cap * 2;
char **nn = realloc(*names, ncap * sizeof(*nn));
if (nn == NULL) {
return st_error_internal("out of memory collecting feature "
"names");
}
*names = nn;
*cap = ncap;
}
(*names)[(*count)++] = name;
return NULL;
}
/* ---- the public API ---------------------------------------------------- */
struct st_error *
@@ -583,6 +603,9 @@ st_gen_configure_emit(FILE *out, const struct st_kdl_document *doc,
const struct st_kdl_node *node;
char **subst_names = NULL;
size_t n_subst = 0;
char **feat_names = NULL;
size_t n_feat = 0;
size_t feat_cap = 0;
if (out == NULL || doc == NULL || ctx == NULL) {
return st_error_usage("st_gen_configure_emit: NULL argument");
@@ -634,7 +657,13 @@ st_gen_configure_emit(FILE *out, const struct st_kdl_document *doc,
goto done;
}
/* 3. host detection */
/* 3. config.log init + original-args capture (todo 17) */
err = st_gen_config_log_init_emit(out);
if (err != NULL) {
goto done;
}
/* 4. host detection */
if (st_sh_emit_str(out, HOST_DETECT_PRE) < 0) {
err = st_error_io("I/O error emitting host detection");
goto done;
@@ -648,7 +677,7 @@ st_gen_configure_emit(FILE *out, const struct st_kdl_document *doc,
goto done;
}
/* 4. toolchain defaults (before the cache boilerplate; see the header) */
/* 5. toolchain defaults (before the cache boilerplate; see the header) */
if (st_sh_emit_str(out, TOOLCHAIN_DEFAULTS_PRE) < 0) {
err = st_error_io("I/O error emitting toolchain defaults");
goto done;
@@ -681,15 +710,18 @@ st_gen_configure_emit(FILE *out, const struct st_kdl_document *doc,
goto done;
}
/* 5. cache boilerplate (todo 12) */
/* 6. cache boilerplate (todo 12) */
err = st_probe_emit_cache_functions(out);
if (err != NULL) {
goto done;
}
/* 6. probe section: each top-level `feature` node in document order */
/* 7. probe section: each top-level `feature` node in document order.
* The resolved feature names are collected here for the todo-17
* results summary + config.h defines, emitted right after the loop. */
for (node = doc->nodes; node != NULL; node = node->next) {
bool is_feature = false;
char *fname = NULL;
err = name_equals(&node->name, "feature", &is_feature);
if (err != NULL) {
@@ -702,21 +734,59 @@ st_gen_configure_emit(FILE *out, const struct st_kdl_document *doc,
if (err != NULL) {
goto done;
}
/* a successful emit_feature guarantees the name is a valid shell
* identifier (it errors otherwise), so the have_<name> /
* HAVE_<NAME> interpolation below is safe */
err = extract_string(&node->args->value, "feature name", &fname);
if (err != NULL) {
goto done;
}
err = collect_feature_name(&feat_names, &n_feat, &feat_cap, fname);
if (err != NULL) {
free(fname);
goto done;
}
}
/* 7. substitution section */
/* 8. probe-results summary + config.h (todo 17) */
err = st_gen_config_results_emit(out, (const char *const *)feat_names,
n_feat);
if (err != NULL) {
goto done;
}
err = st_gen_config_h_emit(out, (const char *const *)feat_names, n_feat);
if (err != NULL) {
goto done;
}
/* 9. substitution section */
err = emit_subst_lookup(out, (const char *const *)subst_names, n_subst);
if (err != NULL) {
goto done;
}
/* 8. exit 0 is already the last line of the substitution tail */
/* 10. config.status (todo 17): written after substitution, before the
* final exit 0 */
err = st_gen_config_status_emit(out);
if (err != NULL) {
goto done;
}
if (st_sh_emit_str(out, "\nexit 0\n") < 0) {
err = st_error_io("I/O error emitting configure");
goto done;
}
/* 11. final stream check */
if (ferror(out)) {
err = st_error_io("I/O error emitting configure");
goto done;
}
done:
for (i = 0; i < n_feat; i++) {
free(feat_names[i]);
}
free(feat_names);
free(subst_names);
return err;
}