aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bbot/build-config4
-rw-r--r--bbot/build-config.cxx18
-rw-r--r--bbot/buildfile1
-rw-r--r--bbot/manifest17
-rw-r--r--bbot/manifest.cxx38
-rw-r--r--bbot/variable46
-rw-r--r--bbot/variable.cxx94
-rw-r--r--tests/buildtab/testscript22
-rw-r--r--tests/manifest/task.test21
-rw-r--r--tests/variable/buildfile9
-rw-r--r--tests/variable/driver.cxx61
-rw-r--r--tests/variable/testscript55
12 files changed, 93 insertions, 293 deletions
diff --git a/bbot/build-config b/bbot/build-config
index 0a3ecb3..0f92eb8 100644
--- a/bbot/build-config
+++ b/bbot/build-config
@@ -16,8 +16,6 @@
#include <bbot/export>
-#include <bbot/variable>
-
namespace bbot
{
// Build configuration matching specific machine names. Used by bbot
@@ -30,7 +28,7 @@ namespace bbot
butl::optional<butl::target_triplet> target;
- variables vars;
+ std::vector<std::string> vars;
};
using build_configs = std::vector<build_config>;
diff --git a/bbot/build-config.cxx b/bbot/build-config.cxx
index 226ead3..0ee00e9 100644
--- a/bbot/build-config.cxx
+++ b/bbot/build-config.cxx
@@ -13,6 +13,8 @@
#include <butl/fdstream>
#include <butl/tab-parser>
+#include <bbot/manifest> // task_manifest::check_config()
+
using namespace std;
using namespace butl;
@@ -34,17 +36,17 @@ namespace bbot
// then we refer to the end-of-line column (presumably reporting a missed
// field).
//
- auto bad_line = [&name, &tl, &i, n] (const string& d, size_t offset = 0)
+ auto bad_line = [&name, &tl, &i, n] (const string& d)
{
// Offset beyond the end-of-line is meaningless.
//
- assert (i < n || (i == n && offset == 0));
+ assert (i <= n);
throw tab_parsing (name,
tl.line,
i == n
? tl.end_column
- : tl[i].column + offset,
+ : tl[i].column,
d);
};
@@ -93,12 +95,14 @@ namespace bbot
try
{
for (; i < n; ++i)
- config.vars.emplace_back (variable (move (tl[i].value)));
+ {
+ task_manifest::check_config (tl[i].value);
+ config.vars.emplace_back (move (tl[i].value));
+ }
}
- catch (const invalid_variable& e)
+ catch (const invalid_argument& e)
{
- bad_line (e.what (), e.pos); // Note that tl[i].value is moved from,
- // but happily we don't use it
+ bad_line (e.what ());
}
// Save the configuration.
diff --git a/bbot/buildfile b/bbot/buildfile
index 1bb608f..27bde1a 100644
--- a/bbot/buildfile
+++ b/bbot/buildfile
@@ -8,7 +8,6 @@ lib{bbot}: \
{hxx cxx}{ build-config } \
{hxx }{ export } \
{hxx cxx}{ manifest } \
-{hxx cxx}{ variable } \
{hxx }{ version } \
$int_libs
diff --git a/bbot/manifest b/bbot/manifest
index 3022535..087fd25 100644
--- a/bbot/manifest
+++ b/bbot/manifest
@@ -17,8 +17,6 @@
#include <bbot/export>
-#include <bbot/variable>
-
namespace bbot
{
using strings = std::vector<std::string>;
@@ -105,8 +103,12 @@ namespace bbot
// Build system configuration variables (in addition to build environment
// configuration variables).
+ // Note: could be quoted.
//
- variables config;
+ strings config;
+
+ strings
+ unquoted_config ();
task_manifest (std::string nm,
bpkg::version vr,
@@ -114,7 +116,7 @@ namespace bbot
strings tr,
std::string mn,
butl::optional<butl::target_triplet> tg,
- variables cf)
+ strings cf)
: name (std::move (nm)),
version (std::move (vr)),
repository (std::move (rl)),
@@ -132,6 +134,13 @@ namespace bbot
void
serialize (butl::manifest_serializer&) const;
+
+ // Check that a string has the name=value format. The name must not
+ // contain spaces. Throw invalid_argument if the string doesn't conform to
+ // these rules.
+ //
+ static void
+ check_config (const std::string&);
};
class LIBBBOT_EXPORT task_response_manifest
diff --git a/bbot/manifest.cxx b/bbot/manifest.cxx
index 0f7a053..1d164db 100644
--- a/bbot/manifest.cxx
+++ b/bbot/manifest.cxx
@@ -16,6 +16,7 @@
#include <butl/utility> // digit()
#include <butl/tab-parser>
+#include <butl/string-parser>
#include <butl/manifest-parser>
#include <butl/manifest-serializer>
@@ -442,14 +443,16 @@ namespace bbot
{
try
{
- config.emplace_back (variable (move (tf.value)));
+ check_config (tf.value);
}
- catch (const invalid_variable& e)
+ catch (const invalid_argument& e)
{
bad_value (string ("invalid task configuration: ") + e.what (),
- tf.column - 1 + e.pos,
+ tf.column - 1,
tl.line - 1);
}
+
+ config.emplace_back (move (tf.value));
}
}
}
@@ -520,6 +523,35 @@ namespace bbot
s.next ("", ""); // End of manifest.
}
+ strings task_manifest::
+ unquoted_config ()
+ {
+ return string_parser::unquote (config);
+ }
+
+ void task_manifest::
+ check_config (const string& s)
+ {
+ auto i (s.begin ());
+ auto e (s.end ());
+
+ // Iterate until the variable name end and check that it contains no
+ // whitespaces.
+ //
+ for (; i != e; ++i)
+ {
+ char c (*i);
+
+ if (c == ' ' || c == '\t') // Whitespace in name.
+ throw invalid_argument ("expected variable assignment");
+ else if (c == '=')
+ break;
+ }
+
+ if (i == e)
+ throw invalid_argument ("no variable value");
+ }
+
// task_response_manifest
//
task_response_manifest::
diff --git a/bbot/variable b/bbot/variable
deleted file mode 100644
index 11e84ec..0000000
--- a/bbot/variable
+++ /dev/null
@@ -1,46 +0,0 @@
-// file : bbot/variable -*- C++ -*-
-// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#ifndef BBOT_VARIABLE
-#define BBOT_VARIABLE
-
-#include <string>
-#include <vector>
-#include <cstdint> // uint64_t
-#include <stdexcept> // invalid_argument
-
-#include <bbot/export>
-
-namespace bbot
-{
- class LIBBBOT_EXPORT invalid_variable: public std::invalid_argument
- {
- public:
- invalid_variable (std::uint64_t p, const std::string& d)
- : invalid_argument (d), pos (p) {}
-
- std::uint64_t pos; // Zero-based.
- };
-
- // String in the name=value format. Can contain single or double quoted
- // substrings. No escaping is supported. The name must not contain spaces.
- // Throw variable_error if the string doesn't conform to these rules.
- //
- struct LIBBBOT_EXPORT variable: std::string
- {
- variable (std::string);
-
- // Remove a single level of quotes. Don't validate the format or the
- // correctness of the quotation. Note that the variable can potentially be
- // modified through the std::string interface in a way that breaks
- // format/quoting.
- //
- std::string
- unquoted () const;
- };
-
- using variables = std::vector<variable>;
-}
-
-#endif // BBOT_VARIABLE
diff --git a/bbot/variable.cxx b/bbot/variable.cxx
deleted file mode 100644
index a25b007..0000000
--- a/bbot/variable.cxx
+++ /dev/null
@@ -1,94 +0,0 @@
-// file : bbot/variable.cxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#include <bbot/variable>
-
-#include <utility> // move()
-
-using namespace std;
-
-namespace bbot
-{
- variable::
- variable (string v): string (move (v))
- {
- // Scan the string untill the end to check that the quoting is terminated.
- // We will also make sure that the name doesn't contain spaces and the
- // value is provided.
- //
- char quoting ('\0'); // Current quoting mode, can be used as bool.
- bool name (true); // True while we are parsing the variable name.
-
- auto b (cbegin ());
- auto i (b);
-
- auto bad_variable = [&b, &i] (const string& d)
- {
- throw invalid_variable (i - b, d);
- };
-
- for (auto e (cend ()); i != e; ++i)
- {
- char c (*i);
-
- if (!quoting)
- {
- if (c == '"' || c == '\'') // Begin of quoted string,
- {
- quoting = c;
- continue;
- }
- }
- else if (c == quoting) // End of quoted string,
- {
- quoting = '\0';
- continue;
- }
-
- if (name)
- {
- if (c == ' ' || c == '\t')
- bad_variable ("expected variable assignment");
- else if (c == '=')
- name = false;
- }
- }
-
- if (quoting)
- bad_variable ("unterminated quoted string");
-
- if (name)
- bad_variable ("no variable value");
- }
-
- string variable::
- unquoted () const
- {
- string r;
- char quoting ('\0'); // Current quoting mode, can be used as bool.
-
- for (auto i (cbegin ()), e (cend ()); i != e; ++i)
- {
- char c (*i);
-
- if (!quoting)
- {
- if (c == '"' || c == '\'') // Begin of quoted string.
- {
- quoting = c;
- continue;
- }
- }
- else if (c == quoting) // End of quoted string.
- {
- quoting = '\0';
- continue;
- }
-
- r += c;
- }
-
- return r;
- }
-}
diff --git a/tests/buildtab/testscript b/tests/buildtab/testscript
index 5bf6b24..6bf76bc 100644
--- a/tests/buildtab/testscript
+++ b/tests/buildtab/testscript
@@ -48,11 +48,23 @@
: invalid-var
:
- $* <<EOI 2>>EOE == 1
- windows*-vc_14* windows-vc_14-32 config.cc.coptions="/Z7
- EOI
- cin:1:57: error: unterminated quoted string
- EOE
+ {
+ : unquoted
+ :
+ $* <<EOI 2>>EOE == 1
+ windows*-vc_14* windows-vc_14-32 config.cc.coptions="/Z7
+ EOI
+ cin:1:57: error: unterminated quoted string
+ EOE
+
+ : no-value
+ :
+ $* <<EOI 2>>EOE == 1
+ windows*-vc_14* windows-vc_14-32 i686-microsoft-win32-msvc14.0 config.cc.coptions
+ EOI
+ cin:1:64: error: no variable value
+ EOE
+ }
: dup-config-name
:
diff --git a/tests/manifest/task.test b/tests/manifest/task.test
index cbb4598..f2afd9c 100644
--- a/tests/manifest/task.test
+++ b/tests/manifest/task.test
@@ -198,10 +198,21 @@ test.options += -t
: bad-var
:
- $* <<EOI 2>'stdin:2:12: error: invalid task configuration: no variable value' == 1
- : 1
- config: abc xyz=1
- EOI
+ {
+ : no-value
+ :
+ $* <<EOI 2>'stdin:2:9: error: invalid task configuration: no variable value' == 1
+ : 1
+ config: abc xyz=1
+ EOI
+
+ : no-assignment
+ :
+ $* <<EOI 2>'stdin:2:9: error: invalid task configuration: expected variable assignment' == 1
+ : 1
+ config: 'abc xyz'=1
+ EOI
+ }
: multiline
:
@@ -217,7 +228,7 @@ test.options += -t
: bad-var
:
- $* <<EOI 2>'stdin:3:4: error: invalid task configuration: no variable value' == 1
+ $* <<EOI 2>'stdin:3:1: error: invalid task configuration: no variable value' == 1
: 1
config: \
abc xyz=1
diff --git a/tests/variable/buildfile b/tests/variable/buildfile
deleted file mode 100644
index e9c0cf2..0000000
--- a/tests/variable/buildfile
+++ /dev/null
@@ -1,9 +0,0 @@
-# file : tests/variable/buildfile
-# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
-# license : MIT; see accompanying LICENSE file
-
-import libs = libbutl%lib{butl}
-
-exe{driver}: cxx{driver} ../../bbot/lib{bbot} $libs test{testscript}
-
-include ../../bbot/
diff --git a/tests/variable/driver.cxx b/tests/variable/driver.cxx
deleted file mode 100644
index 88167ad..0000000
--- a/tests/variable/driver.cxx
+++ /dev/null
@@ -1,61 +0,0 @@
-// file : tests/variable/driver.cxx -*- C++ -*-
-// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
-// license : MIT; see accompanying LICENSE file
-
-#include <ios> // ios_base::failbit, ios_base::badbit
-#include <string>
-#include <cassert>
-#include <cstddef> // size_t
-#include <iostream>
-
-#include <butl/utility> // operator<<(ostream,exception)
-
-#include <bbot/variable>
-
-using namespace std;
-using namespace butl;
-using namespace bbot;
-
-// Usage: argv[0] [-u]
-//
-// Read variables from STDIN (one per line) and serialize them to STDOUT (also
-// one per line).
-//
-// -u output variables being unquoted beforehand
-//
-int
-main (int argc, char* argv[])
-{
- assert (argc <= 2);
- bool unquote (false);
-
- if (argc == 2)
- {
- assert (argv[1] == string ("-u"));
- unquote = true;
- }
-
- cin.exceptions (ios_base::badbit);
- cout.exceptions (ios_base::failbit | ios_base::badbit);
-
- string s;
- for (size_t l (1); getline (cin, s); ++l)
- {
- try
- {
- variable v (move (s));
-
- cout << (unquote
- ? v.unquoted ()
- : static_cast<const string&> (v))
- << '\n';
- }
- catch (const invalid_variable& e)
- {
- cerr << l << ':' << 1 + e.pos << ": error: " << e << endl;
- return 1;
- }
- }
-
- return 0;
-}
diff --git a/tests/variable/testscript b/tests/variable/testscript
deleted file mode 100644
index 3269a37..0000000
--- a/tests/variable/testscript
+++ /dev/null
@@ -1,55 +0,0 @@
-# file : tests/variable/testscript
-# copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
-# license : MIT; see accompanying LICENSE file
-
-test.options += -u
-
-: valid
-:
-{
- $* <<EOI >>EOO
- config.cc.coptions="-O3 -stdlib='libc++'"
- ab'c="x y"'
- var=xy
- var=
- EOI
- config.cc.coptions=-O3 -stdlib='libc++'
- abc="x y"
- var=xy
- var=
- EOO
-}
-
-: invalid
-:
-{
- : expected-assignment
- :
- $* <'v"a r=abc"' 2>'1:4: error: expected variable assignment' == 1
-
- : unterminated-quoted-string
- :
- $* <'var="a b' 2>'1:9: error: unterminated quoted string' == 1
-
- : no-value
- :
- $* <'var' 2>'1:4: error: no variable value' == 1
-}
-
-: unquoting
-:
-{
- : single
- :
- $* <"var='a \" b'" >'var=a " b'
-
- : double
- :
- $* <'var="a '"'"' b"' >"var=a ' b"
-
- : mixed
- :
- $* <<EOI >'var=a bc e'
- var='a b'"c e"
- EOI
-}