monotone

monotone Mtn Source Tree

Root/basic_io.cc

1// Copyright (C) 2004 Graydon Hoare <graydon@pobox.com>
2//
3// This program is made available under the GNU GPL version 2.0 or
4// greater. See the accompanying file COPYING for details.
5//
6// This program is distributed WITHOUT ANY WARRANTY; without even the
7// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8// PURPOSE.
9
10#include "base.hh"
11#include "basic_io.hh"
12#include "sanity.hh"
13#include "transforms.hh"
14#include "vocab.hh"
15
16using std::logic_error;
17using std::make_pair;
18using std::pair;
19using std::string;
20using std::vector;
21
22// This file provides parsing and printing primitives used by the
23// higher level parser and printer routines for the datatypes cset,
24// roster/marking_map and revision.
25
26void basic_io::input_source::err(string const & s)
27{
28 E(false,
29 F("parsing a %s at %d:%d:E: %s") % name % line % col % s);
30}
31
32
33void basic_io::tokenizer::err(string const & s)
34{
35 in.err(s);
36}
37
38string
39basic_io::escape(string const & s)
40{
41 string escaped;
42 escaped.reserve(s.size() + 8);
43
44 escaped += "\"";
45
46 for (string::const_iterator i = s.begin(); i != s.end(); ++i)
47 {
48 switch (*i)
49 {
50 case '\\':
51 case '"':
52 escaped += '\\';
53 default:
54 escaped += *i;
55 }
56 }
57
58 escaped += "\"";
59
60 return escaped;
61}
62
63basic_io::stanza::stanza() : indent(0)
64{}
65
66void basic_io::stanza::push_binary_pair(symbol const & k, id const & v)
67{
68 push_hex_pair(k, hexenc<id>(encode_hexenc(v())));
69}
70
71void basic_io::stanza::push_hex_pair(symbol const & k, hexenc<id> const & v)
72{
73 entries.push_back(make_pair(k, ""));
74 string const & s(v());
75 entries.back().second.reserve(s.size()+2);
76 entries.back().second.push_back('[');
77 entries.back().second.append(s);
78 entries.back().second.push_back(']');
79 if (k().size() > indent)
80 indent = k().size();
81}
82
83void basic_io::stanza::push_binary_triple(symbol const & k,
84 string const & n,
85 id const & v)
86{
87 string const & s(encode_hexenc(v()));
88 entries.push_back(make_pair(k, escape(n) + " " + "[" + s + "]"));
89 if (k().size() > indent)
90 indent = k().size();
91}
92
93void basic_io::stanza::push_str_pair(symbol const & k, string const & v)
94{
95 entries.push_back(make_pair(k, escape(v)));
96 if (k().size() > indent)
97 indent = k().size();
98}
99
100void basic_io::stanza::push_str_pair(symbol const & k, symbol const & v)
101{
102 // Note that this value is a symbol, not a string; the Lua basic_io parser
103 // will return this pair as two lines with no values.
104 entries.push_back(make_pair(k, v()));
105 if (k().size() > indent)
106 indent = k().size();
107}
108
109void basic_io::stanza::push_file_pair(symbol const & k, file_path const & v)
110{
111 push_str_pair(k, v.as_internal());
112}
113
114void basic_io::stanza::push_str_multi(symbol const & k,
115 vector<string> const & v)
116{
117 string val;
118 bool first = true;
119 for (vector<string>::const_iterator i = v.begin();
120 i != v.end(); ++i)
121 {
122 if (!first)
123 val += " ";
124 val += escape(*i);
125 first = false;
126 }
127 entries.push_back(make_pair(k, val));
128 if (k().size() > indent)
129 indent = k().size();
130}
131
132void basic_io::stanza::push_str_triple(symbol const & k,
133 string const & n,
134 string const & v)
135{
136 entries.push_back(make_pair(k, escape(n) + " " + escape(v)));
137 if (k().size() > indent)
138 indent = k().size();
139}
140
141
142string basic_io::printer::buf;
143int basic_io::printer::count;
144
145basic_io::printer::printer()
146{
147 I(count == 0);
148 count++;
149 buf.clear();
150}
151
152basic_io::printer::~printer()
153{
154 count--;
155}
156
157void basic_io::printer::print_stanza(stanza const & st)
158{
159 if (LIKELY(!buf.empty()))
160 buf += '\n';
161
162 for (vector<pair<symbol, string> >::const_iterator i = st.entries.begin();
163 i != st.entries.end(); ++i)
164 {
165 for (size_t k = i->first().size(); k < st.indent; ++k)
166 buf += ' ';
167 buf.append(i->first());
168 buf += ' ';
169 buf.append(i->second);
170 buf += '\n';
171 }
172}
173
174void basic_io::parser::err(string const & s)
175{
176 tok.err(s);
177}
178
179string basic_io::parser::tt2str(token_type tt)
180{
181 switch (tt)
182 {
183 case basic_io::TOK_STRING:
184 return "TOK_STRING";
185 case basic_io::TOK_SYMBOL:
186 return "TOK_SYMBOL";
187 case basic_io::TOK_HEX:
188 return "TOK_HEX";
189 case basic_io::TOK_NONE:
190 return "TOK_NONE";
191 }
192 return "TOK_UNKNOWN";
193}
194
195#ifdef BUILD_UNIT_TESTS
196#include "unit_tests.hh"
197
198UNIT_TEST(basic_io, binary_transparency)
199{
200 std::string testpattern;
201 for (unsigned i=0; i<256; ++i) testpattern+=char(i);
202
203 static symbol test("test");
204
205 basic_io::printer printer;
206 basic_io::stanza st;
207 st.push_str_pair(test, testpattern);
208 printer.print_stanza(st);
209
210 basic_io::input_source source(printer.buf, "unit test string");
211 basic_io::tokenizer tokenizer(source);
212 basic_io::parser parser(tokenizer);
213 std::string t1;
214 parser.esym(test);
215 parser.str(t1);
216 I(testpattern==t1);
217}
218
219#endif // BUILD_UNIT_TESTS
220
221// Local Variables:
222// mode: C++
223// fill-column: 76
224// c-file-style: "gnu"
225// indent-tabs-mode: nil
226// End:
227// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status