Template
feat(gen): emit config.status/config.log/config.h
This commit is contained in:
+79
-9
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user