Add support for #cmakedefine01 (GH issue #63)

This commit is contained in:
Boris Kolpackov 2024-02-12 15:51:53 +02:00
parent e894e792e6
commit 8b4cba6afa
3 changed files with 80 additions and 7 deletions

View File

@ -4,8 +4,8 @@ GNU Autoconf emulation build system module for `build2`.
Specifically, this module provides an [`in`][module-in]-based rule for Specifically, this module provides an [`in`][module-in]-based rule for
processing `config.h.in` files. Besides the Autoconf special line flavor processing `config.h.in` files. Besides the Autoconf special line flavor
(`#undef`), it also supports the CMake (`#cmakedefine`) and Meson (`#undef`), it also supports the CMake (`#cmakedefine`, `#cmakedefine01`) and
(`#mesondefine`) variants. Meson (`#mesondefine`) variants.
Similar to Autoconf, this module provides built-in support for a number of Similar to Autoconf, this module provides built-in support for a number of
common `HAVE_*` configuration options. However, the values of these options common `HAVE_*` configuration options. However, the values of these options

View File

@ -102,6 +102,14 @@ ln -s ../../bootstrap.build ../../root.build build/;
cat <<EOI >=config.h.cmake; cat <<EOI >=config.h.cmake;
#define VERSION "@version@" #define VERSION "@version@"
#cmakedefine01 TRUE01
#cmakedefine01 FALSE01
#cmakedefine01 ONE01
#cmakedefine01 ZERO01
#cmakedefine TRUE01
#cmakedefine FALSE01
#cmakedefine TRUE #cmakedefine TRUE
#cmakedefine FALSE #cmakedefine FALSE
#cmakedefine ONE #cmakedefine ONE
@ -131,6 +139,11 @@ cat <<EOI >=config.h.cmake;
$* <<EOI &config.h &config.h.d; $* <<EOI &config.h &config.h.d;
./: h{config}: in{config.h.cmake} ./: h{config}: in{config.h.cmake}
{ {
TRUE01 = true
FALSE01 = [bool] false
ONE01 = 1
ZERO01 = [uint64] 000
TRUE = true TRUE = true
FALSE = [bool] false FALSE = [bool] false
ONE = 1 ONE = 1
@ -165,6 +178,14 @@ $* <<EOI &config.h &config.h.d;
cat config.h >>EOO cat config.h >>EOO
#define VERSION "1.2.3" #define VERSION "1.2.3"
#define TRUE01 1
#define FALSE01 0
#define ONE01 1
#define ZERO01 0
/* TRUE01 already defined. */
/* FALSE01 already defined. */
#define TRUE 1 #define TRUE 1
#undef FALSE #undef FALSE
#define ONE 1 #define ONE 1

View File

@ -177,7 +177,7 @@ namespace build2
flavor f (t.data<match_data> (a).flavor); flavor f (t.data<match_data> (a).flavor);
// Substitute special #undef/#cmakedfine/#mesondefine line. If value is // Substitute special #undef/#cmakedefine/#mesondefine line. If value is
// false, then do not append the value to #define. // false, then do not append the value to #define.
// //
// Return true if it was substituted with #define, false if with #undef, // Return true if it was substituted with #define, false if with #undef,
@ -291,6 +291,41 @@ namespace build2
return r; return r;
}; };
// Substitute special #cmakedefine01 line with #define 0 or 1.
//
auto substitute_special01 = [this,
&l,
a, &t,
&dd, &dd_skip,
strict, smap, &null,
&s] (const string& name)
{
// Essentially a simplified version of substitute_special() above.
//
optional<string> ov (substitute (l,
a, t,
dd, dd_skip,
name, 1 /* flags */,
strict, smap, null));
assert (ov);
string& v (*ov);
if (v == "0" || v == "1")
;
else if (v == "false")
v = "0";
else if (v == "true")
v = "1";
else
fail (l) << "variable " << name << " should be false/0 or true/1";
s = "#define ";
s += name;
s += ' ';
s += v;
};
// Deal with special lines of each flavor. Return if the line has has // Deal with special lines of each flavor. Return if the line has has
// been handled and fall through to use the normal substitution logic. // been handled and fall through to use the normal substitution logic.
// //
@ -378,9 +413,7 @@ namespace build2
// #cmakedefine size_t @SIZE_T@ // #cmakedefine size_t @SIZE_T@
// //
// The #cmakedefine01 variant is always replaced with #define, // The #cmakedefine01 variant is always replaced with #define,
// either with value 1 if NAME is true and 0 otherwise. It's doesn't // either with value 1 if NAME is true and 0 otherwise.
// appear to be used much in practice so we are not going to bother
// with it.
// //
skip_ws (s, i); skip_ws (s, i);
@ -423,7 +456,26 @@ namespace build2
s += *value; s += *value;
} }
else if (s.compare (i, 13, "cmakedefine01") == 0 && ws (s[i + 13])) else if (s.compare (i, 13, "cmakedefine01") == 0 && ws (s[i + 13]))
fail(l) << "#cmakedefine01 is not yet supported"; {
i += 13;
skip_ws (s, i);
size_t n (read_id (s, i));
if (n == 0)
fail (l) << "expected identifier after #cmakedefine01";
string name (s, i, n);
i += n;
skip_ws (s, i);
if (s[i] != '\0')
fail (l) << "junk after variable name in #cmakedefine01";
substitute_special01 (name);
return;
}
} }
break; break;
} }