From 8b4cba6afa4b0d80acf3e3b3d81a3a562a461486 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Mon, 12 Feb 2024 15:51:53 +0200 Subject: [PATCH] Add support for #cmakedefine01 (GH issue #63) --- README.md | 4 +- libbuild2-autoconf-tests/module/testscript | 21 +++++++ .../libbuild2/autoconf/rule.cxx | 62 +++++++++++++++++-- 3 files changed, 80 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 3be743d..a214738 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,8 @@ GNU Autoconf emulation build system module for `build2`. Specifically, this module provides an [`in`][module-in]-based rule for processing `config.h.in` files. Besides the Autoconf special line flavor -(`#undef`), it also supports the CMake (`#cmakedefine`) and Meson -(`#mesondefine`) variants. +(`#undef`), it also supports the CMake (`#cmakedefine`, `#cmakedefine01`) and +Meson (`#mesondefine`) variants. Similar to Autoconf, this module provides built-in support for a number of common `HAVE_*` configuration options. However, the values of these options diff --git a/libbuild2-autoconf-tests/module/testscript b/libbuild2-autoconf-tests/module/testscript index f7f0ea3..0f2611d 100644 --- a/libbuild2-autoconf-tests/module/testscript +++ b/libbuild2-autoconf-tests/module/testscript @@ -102,6 +102,14 @@ ln -s ../../bootstrap.build ../../root.build build/; cat <=config.h.cmake; #define VERSION "@version@" + #cmakedefine01 TRUE01 + #cmakedefine01 FALSE01 + #cmakedefine01 ONE01 + #cmakedefine01 ZERO01 + + #cmakedefine TRUE01 + #cmakedefine FALSE01 + #cmakedefine TRUE #cmakedefine FALSE #cmakedefine ONE @@ -131,6 +139,11 @@ cat <=config.h.cmake; $* <>EOO #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 #undef FALSE #define ONE 1 diff --git a/libbuild2-autoconf/libbuild2/autoconf/rule.cxx b/libbuild2-autoconf/libbuild2/autoconf/rule.cxx index 620a8ba..7904869 100644 --- a/libbuild2-autoconf/libbuild2/autoconf/rule.cxx +++ b/libbuild2-autoconf/libbuild2/autoconf/rule.cxx @@ -177,7 +177,7 @@ namespace build2 flavor f (t.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. // // Return true if it was substituted with #define, false if with #undef, @@ -291,6 +291,41 @@ namespace build2 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 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 // been handled and fall through to use the normal substitution logic. // @@ -378,9 +413,7 @@ namespace build2 // #cmakedefine size_t @SIZE_T@ // // The #cmakedefine01 variant is always replaced with #define, - // either with value 1 if NAME is true and 0 otherwise. It's doesn't - // appear to be used much in practice so we are not going to bother - // with it. + // either with value 1 if NAME is true and 0 otherwise. // skip_ws (s, i); @@ -423,7 +456,26 @@ namespace build2 s += *value; } 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; }