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_file_pair(symbol const & k, file_path const & v)
101{
102 push_str_pair(k, v.as_internal());
103}
104
105void basic_io::stanza::push_str_multi(symbol const & k,
106 vector<string> const & v)
107{
108 string val;
109 bool first = true;
110 for (vector<string>::const_iterator i = v.begin();
111 i != v.end(); ++i)
112 {
113 if (!first)
114 val += " ";
115 val += escape(*i);
116 first = false;
117 }
118 entries.push_back(make_pair(k, val));
119 if (k().size() > indent)
120 indent = k().size();
121}
122
123void basic_io::stanza::push_str_triple(symbol const & k,
124 string const & n,
125 string const & v)
126{
127 entries.push_back(make_pair(k, escape(n) + " " + escape(v)));
128 if (k().size() > indent)
129 indent = k().size();
130}
131
132
133string basic_io::printer::buf;
134int basic_io::printer::count;
135
136basic_io::printer::printer()
137{
138 I(count == 0);
139 count++;
140 buf.clear();
141}
142
143basic_io::printer::~printer()
144{
145 count--;
146}
147
148void basic_io::printer::print_stanza(stanza const & st)
149{
150 if (LIKELY(!buf.empty()))
151 buf += '\n';
152
153 for (vector<pair<symbol, string> >::const_iterator i = st.entries.begin();
154 i != st.entries.end(); ++i)
155 {
156 for (size_t k = i->first().size(); k < st.indent; ++k)
157 buf += ' ';
158 buf.append(i->first());
159 buf += ' ';
160 buf.append(i->second);
161 buf += '\n';
162 }
163}
164
165void basic_io::parser::err(string const & s)
166{
167 tok.err(s);
168}
169
170string basic_io::parser::tt2str(token_type tt)
171{
172 switch (tt)
173 {
174 case basic_io::TOK_STRING:
175 return "TOK_STRING";
176 case basic_io::TOK_SYMBOL:
177 return "TOK_SYMBOL";
178 case basic_io::TOK_HEX:
179 return "TOK_HEX";
180 case basic_io::TOK_NONE:
181 return "TOK_NONE";
182 }
183 return "TOK_UNKNOWN";
184}
185
186#ifdef BUILD_UNIT_TESTS
187#include "unit_tests.hh"
188
189UNIT_TEST(basic_io, binary_transparency)
190{
191 std::string testpattern;
192 for (unsigned i=0; i<256; ++i) testpattern+=char(i);
193
194 static symbol test("test");
195
196 basic_io::printer printer;
197 basic_io::stanza st;
198 st.push_str_pair(test, testpattern);
199 printer.print_stanza(st);
200
201 basic_io::input_source source(printer.buf, "unit test string");
202 basic_io::tokenizer tokenizer(source);
203 basic_io::parser parser(tokenizer);
204 std::string t1;
205 parser.esym(test);
206 parser.str(t1);
207 I(testpattern==t1);
208}
209
210#endif // BUILD_UNIT_TESTS
211
212// Local Variables:
213// mode: C++
214// fill-column: 76
215// c-file-style: "gnu"
216// indent-tabs-mode: nil
217// End:
218// 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