diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2023-03-29 09:17:57 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2023-03-29 09:17:57 +0200 |
commit | 47d5ba0863811f7657653458b4497437d1d317ac (patch) | |
tree | c91fe93ca28dbc2772a79b5b3f5ab539739561f5 | |
parent | 699d0dfe6769ca949808bf78606a689aeff117df (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.cxx | 105 |
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. } |