1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
// file : bbot/bootstrap-manifest.cxx -*- C++ -*-
// license : MIT; see accompanying LICENSE file
#include <bbot/bootstrap-manifest.hxx>
#include <libbutl/manifest-parser.hxx>
#include <libbutl/manifest-serializer.hxx>
using namespace butl;
namespace bbot
{
using parser = manifest_parser;
using parsing = manifest_parsing;
using serializer = manifest_serializer;
using serialization = manifest_serialization;
using name_value = manifest_name_value;
// bootstrap_manifest
//
bootstrap_manifest::
bootstrap_manifest (parser& p, bool iu)
: bootstrap_manifest (p, p.next (), iu)
{
// Make sure this is the end.
//
name_value nv (p.next ());
if (!nv.empty ())
throw parsing (p.name (), nv.name_line, nv.name_column,
"single bootstrap manifest expected");
}
bootstrap_manifest::
bootstrap_manifest (parser& p, name_value nv, bool iu)
{
auto bad_name = [&p, &nv] (const string& d)
{
throw parsing (p.name (), nv.name_line, nv.name_column, d);
};
auto bad_value = [&p, &nv] (const string& d)
{
throw parsing (p.name (), nv.value_line, nv.value_column, d);
};
// Make sure this is the start and we support the version.
//
if (!nv.name.empty ())
bad_name ("start of bootstrap manifest expected");
if (nv.value != "1")
bad_value ("unsupported format version");
// Parse the bootstrap manifest.
//
for (nv = p.next (); !nv.empty (); nv = p.next ())
{
string& n (nv.name);
string& v (nv.value);
size_t nn (n.size ()); // Name length.
// Note: returns false if nothing preceeds a suffix.
//
auto suffix = [&n, nn] (const char* s, size_t sn) -> bool
{
return nn > sn && n.compare (nn - sn, sn, s) == 0;
};
size_t sn;
if (suffix ("-version", sn = 8))
{
string pn (n, 0, nn - sn); // Package name.
// Package version.
//
try
{
// Make sure the package version is not redefined.
//
if (!versions.emplace (move (pn), standard_version (v)).second)
bad_name (n + " redefinition");
}
catch (const invalid_argument& e)
{
bad_value (string ("invalid package version: ") + e.what ());
}
}
else if (!iu)
bad_name ("unknown name '" + n + "' in bootstrap manifest");
}
// Verify all non-optional values were specified.
//
if (versions.empty ())
bad_value ("no package versions specified");
}
void bootstrap_manifest::
serialize (serializer& s) const
{
// @@ Should we check that all non-optional values are specified?
//
s.next ("", "1"); // Start of manifest.
// Serialize *-version values.
//
for (const auto& v: versions)
s.next (v.first + "-version", v.second.string_project ());
s.next ("", ""); // End of manifest.
}
}
|