aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2023-03-29 09:17:57 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2023-03-29 09:17:57 +0200
commit47d5ba0863811f7657653458b4497437d1d317ac (patch)
treec91fe93ca28dbc2772a79b5b3f5ab539739561f5
parent699d0dfe6769ca949808bf78606a689aeff117df (diff)
Use new next_expect*() JSON parser API in install manifest parsing
Also handle potential future extensions to install manifest format.
-rw-r--r--bpkg/system-package-manager.cxx105
1 files changed, 29 insertions, 76 deletions
diff --git a/bpkg/system-package-manager.cxx b/bpkg/system-package-manager.cxx
index 977b000..373e8ff 100644
--- a/bpkg/system-package-manager.cxx
+++ b/bpkg/system-package-manager.cxx
@@ -787,94 +787,38 @@ namespace bpkg
//
auto parse_entry = [&r, &p] (const auto& parse_entry) -> void
{
- optional<event> e (p.next ());
+ // enter: after begin_object
+ // leave: after end_object
- // @@ This is really ugly, need to add next_expect() helpers to JSON
- // parser (similar to libstudxml).
-
- if (*e != event::begin_object)
- fail << "entry object expected";
-
- // type
- //
- if (!(e = p.next ()) || *e != event::name || p.name () != "type")
- fail << "type member expected";
-
- if (!(e = p.next ()) || *e != event::string)
- fail << "type member string value expected";
-
- string t (p.value ()); // Note: value invalidated after p.next().
+ string t (p.next_expect_member_string ("type"));
if (t == "target")
{
- // name
- //
- if (!(e = p.next ()) || *e != event::name || p.name () != "name")
- fail << "name member expected";
-
- if (!(e = p.next ()) || *e != event::string)
- fail << "name member string value expected";
+ p.next_expect_member_string ("name");
- // entries
- //
- if (!(e = p.next ()) || *e != event::name || p.name () != "entries")
- fail << "entries member expected";
-
- if (!(e = p.next ()) || *e != event::begin_array)
- fail << "entries member array value expected";
-
- while ((e = p.peek ()) && *e != event::end_array)
+ p.next_expect_member_array ("entries");
+ while (p.next_expect (event::begin_object, event::end_array))
parse_entry (parse_entry);
-
- if (!(e = p.next ()) || *e != event::end_array)
- fail << "entries member array value end expected";
}
- else if (t == "file" || t == "symlink" || t == "directory")
+ else if (t == "file" || t == "symlink")
{
- // path
- //
- if (!(e = p.next ()) || *e != event::name || p.name () != "path")
- fail << "path member expected";
-
- if (!(e = p.next ()) || *e != event::string)
- fail << "path member string value expected";
-
- path ep (p.value ());
+ path ep (p.next_expect_member_string ("path"));
assert (ep.absolute () && ep.normalized (false /* separators */));
- if (t == "file" || t == "directory")
+ if (t == "file")
{
- // mode
- //
- if (!(e = p.next ()) || *e != event::name || p.name () != "mode")
- fail << "mode member expected";
-
- if (!(e = p.next ()) || *e != event::string)
- fail << "mode member string value expected";
+ string em (p.next_expect_member_string ("mode"));
- string em (p.value ());
-
- if (t == "file")
- {
- auto p (
- r.emplace (
- move (ep), installed_entry {move (em), nullptr}));
+ auto p (
+ r.emplace (
+ move (ep), installed_entry {move (em), nullptr}));
- if (!p.second)
- fail << p.first->first << " is installed multiple times";
- }
+ if (!p.second)
+ fail << p.first->first << " is installed multiple times";
}
else
{
- // target
- //
- if (!(e = p.next ()) || *e != event::name || p.name () != "target")
- fail << "target member expected";
-
- if (!(e = p.next ()) || *e != event::string)
- fail << "target member string value expected";
-
- path et (p.value ());
+ path et (p.next_expect_member_string ("target"));
if (et.relative ())
{
et = ep.directory () / et;
@@ -893,14 +837,22 @@ namespace bpkg
}
}
else
- fail << "unknown entry type '" << t << "'";
+ {
+ // Fall through to skip all members of an unknown entry type.
+ //
+ // Note that this also covers the directory entires which we
+ // don't care about.
+ }
- if (!(e = p.next ()) || *e != event::end_object)
- fail << "entry object end expected";
+ // Skip unknown members.
+ //
+ while (p.next_expect (event::name, event::end_object))
+ p.next_expect_value_skip ();
};
while (p.peek ()) // More values.
{
+ p.next_expect (event::begin_object); // entry
parse_entry (parse_entry);
if (p.next ()) // Consume value-terminating nullopt.
@@ -912,7 +864,8 @@ namespace bpkg
catch (const json::invalid_json_input& e)
{
if (pr.wait ())
- fail << "invalid " << args[0] << " json input: " << e;
+ fail (location ("<stdin>", e.line, e.column))
+ << "invalid install manifest json input: " << e;
// Fall through.
}