aboutsummaryrefslogtreecommitdiff
path: root/libbuild2/parser.cxx
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2024-02-06 05:22:12 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2024-02-07 15:02:38 +0200
commit36d6b4e5549dc45baf890105de5ef487211f0144 (patch)
tree762f9eba621026e9bb7d8fd69107a4447783a45a /libbuild2/parser.cxx
parenta5acaba537dab8e06be1197916acff86699aa5a3 (diff)
Add experimental support for JSON value types
New types: json json_array json_object New functions: $json.value_type(<json>) $json.value_size(<json>) $json.member_{name,value}(<json-member>) $json.object_names(<json-object>) $json.array_size(<json-array>) $json.array_find(<json-array>, <json>) $json.array_find_index(<json-array>, <json>) $json.load(<path>) $json.parse(<text>) $json.serialize(<json>[, <indentation>]) For example, to load a JSON value from a file: j = $json.load($src_base/board.json) Or to construct it in a buildfile: j = [json] one@1 two@([json] 2 3 4) three@([json] x@1 y@-1) This can also be done incrementally with append/prepend: j = [json_object] j += one@1 j += two@([json] 2 3 4) j += three@([json] x@1 y@-1) Instead of using this JSON-like syntax, one can also specify valid JSON input text: j = [json] '{"one":1, "two":[2, 3, 4], "three":{"x":1, "y":-1}' Besides the above set of functions, other handy ways to access components in a JSON value are iteration and subscript. For example: for m: $j print $member_name($m) $member_value($m) print ($j[three]) A subscript can be nested: print ($j[two][1]) print ($j[three][x]) While a JSON value can be printed directly like any other value, the representation will not be pretty-printed. As a result, for complex JSON values, printing a serialized representation might be a more readable option: info $serialize($j)
Diffstat (limited to 'libbuild2/parser.cxx')
-rw-r--r--libbuild2/parser.cxx124
1 files changed, 100 insertions, 24 deletions
diff --git a/libbuild2/parser.cxx b/libbuild2/parser.cxx
index 043cd10..1ac159b 100644
--- a/libbuild2/parser.cxx
+++ b/libbuild2/parser.cxx
@@ -5761,30 +5761,106 @@ namespace build2
const value_type* parser::
find_value_type (const scope*, const string& n)
{
- auto ptr = [] (const value_type& vt) {return &vt;};
-
- return
- n == "bool" ? ptr (value_traits<bool>::value_type) :
- n == "int64" ? ptr (value_traits<int64_t>::value_type) :
- n == "uint64" ? ptr (value_traits<uint64_t>::value_type) :
- n == "string" ? ptr (value_traits<string>::value_type) :
- n == "path" ? ptr (value_traits<path>::value_type) :
- n == "dir_path" ? ptr (value_traits<dir_path>::value_type) :
- n == "abs_dir_path" ? ptr (value_traits<abs_dir_path>::value_type) :
- n == "name" ? ptr (value_traits<name>::value_type) :
- n == "name_pair" ? ptr (value_traits<name_pair>::value_type) :
- n == "target_triplet" ? ptr (value_traits<target_triplet>::value_type) :
- n == "project_name" ? ptr (value_traits<project_name>::value_type) :
-
- n == "int64s" ? ptr (value_traits<int64s>::value_type) :
- n == "uint64s" ? ptr (value_traits<uint64s>::value_type) :
- n == "strings" ? ptr (value_traits<strings>::value_type) :
- n == "paths" ? ptr (value_traits<paths>::value_type) :
- n == "dir_paths" ? ptr (value_traits<dir_paths>::value_type) :
- n == "names" ? ptr (value_traits<vector<name>>::value_type) :
- n == "cmdline" ? ptr (value_traits<cmdline>::value_type) :
-
- nullptr;
+ switch (n[0])
+ {
+ case 'a':
+ {
+ if (n == "abs_dir_path") return &value_traits<abs_dir_path>::value_type;
+ break;
+ }
+ case 'b':
+ {
+ if (n == "bool") return &value_traits<bool>::value_type;
+ break;
+ }
+ case 'c':
+ {
+ if (n == "cmdline") return &value_traits<cmdline>::value_type;
+ break;
+ }
+ case 'd':
+ {
+ if (n.compare (0, 8, "dir_path") == 0)
+ {
+ if (n[8] == '\0') return &value_traits<dir_path>::value_type;
+ if (n[8] == 's' &&
+ n[9] == '\0') return &value_traits<dir_paths>::value_type;
+ }
+ break;
+ }
+ case 'i':
+ {
+ if (n.compare (0, 5, "int64") == 0)
+ {
+ if (n[5] == '\0') return &value_traits<int64_t>::value_type;
+ if (n[5] == 's' &&
+ n[6] == '\0') return &value_traits<int64s>::value_type;
+ }
+ break;
+ }
+ case 'j':
+ {
+ if (n.compare (0, 4, "json") == 0)
+ {
+ if (n[4] == '\0') return &value_traits<json_value>::value_type;
+ if (n == "json_array") return &value_traits<json_array>::value_type;
+ if (n == "json_object") return &value_traits<json_object>::value_type;
+ }
+ break;
+ }
+ case 'n':
+ {
+ if (n.compare (0, 4, "name") == 0)
+ {
+ if (n[4] == '\0') return &value_traits<name>::value_type;
+ if (n[4] == 's' &&
+ n[5] == '\0') return &value_traits<vector<name>>::value_type;
+ if (n == "name_pair") return &value_traits<name_pair>::value_type;
+ }
+ break;
+ }
+
+ case 'p':
+ {
+ if (n.compare (0, 4, "path") == 0)
+ {
+ if (n[4] == '\0') return &value_traits<path>::value_type;
+ if (n[4] == 's' &&
+ n[5] == '\0') return &value_traits<paths>::value_type;
+ }
+ else if (n == "project_name") return &value_traits<project_name>::value_type;
+ break;
+ }
+ case 's':
+ {
+ if (n.compare (0, 6, "string") == 0)
+ {
+ if (n[6] == '\0') return &value_traits<string>::value_type;
+ if (n[6] == 's' &&
+ n[7] == '\0') return &value_traits<strings>::value_type;
+ }
+ break;
+ }
+ case 't':
+ {
+ if (n == "target_triplet") return &value_traits<target_triplet>::value_type;
+ break;
+ }
+ case 'u':
+ {
+ if (n.compare (0, 6, "uint64") == 0)
+ {
+ if (n[6] == '\0') return &value_traits<uint64_t>::value_type;
+ if (n[6] == 's' &&
+ n[7] == '\0') return &value_traits<uint64s>::value_type;
+ }
+ break;
+ }
+ default:
+ break;
+ }
+
+ return nullptr;
}
void parser::