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
|
// file : libbuild2/version/utility.cxx -*- C++ -*-
// license : MIT; see accompanying LICENSE file
#include <libbuild2/version/utility.hxx>
#include <libbutl/manifest-parser.mxx>
#include <libbutl/manifest-serializer.mxx>
#include <libbuild2/context.hxx>
#include <libbuild2/diagnostics.hxx>
using namespace butl;
namespace build2
{
namespace version
{
auto_rmfile
fixup_manifest (context& ctx,
const path& in,
path out,
const standard_version& v)
{
auto_rmfile r (move (out), !ctx.dry_run /* active */);
if (!ctx.dry_run)
{
try
{
permissions perm (path_permissions (in));
ifdstream ifs (in);
manifest_parser p (ifs, in.string ());
auto_fd ofd (fdopen (r.path,
fdopen_mode::out |
fdopen_mode::create |
fdopen_mode::exclusive |
fdopen_mode::binary,
perm));
ofdstream ofs (move (ofd));
manifest_serializer s (ofs, r.path.string ());
manifest_name_value nv (p.next ());
assert (nv.name.empty () && nv.value == "1"); // We just loaded it.
s.next (nv.name, nv.value);
for (nv = p.next (); !nv.empty (); nv = p.next ())
{
if (nv.name == "version")
nv.value = v.string ();
s.next (nv.name, nv.value);
}
s.next (nv.name, nv.value); // End of manifest.
s.next (nv.name, nv.value); // End of stream.
ofs.close ();
ifs.close ();
}
catch (const manifest_parsing& e)
{
location l (in, e.line, e.column);
fail (l) << e.description;
}
catch (const manifest_serialization& e)
{
location l (r.path);
fail (l) << e.description;
}
catch (const io_error& e)
{
fail << "io error: " << e <<
info << "while reading " << in <<
info << "while writing " << r.path;
}
}
return r;
}
}
}
|