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 <sstream>
12#include <cctype>
13#include <cstdlib>
14
15#include "basic_io.hh"
16#include "sanity.hh"
17#include "vocab.hh"
18
19using std::logic_error;
20using std::make_pair;
21using std::pair;
22using std::string;
23using std::vector;
24
25// This file provides parsing and printing primitives used by the
26// higher level parser and printer routines for the datatypes cset,
27// roster/marking_map and revision.
28
29void basic_io::input_source::err(string const & s)
30{
31 E(false,
32 F("parsing a %s at %d:%d:E: %s") % name % line % col % s);
33}
34
35
36void basic_io::tokenizer::err(string const & s)
37{
38 in.err(s);
39}
40
41string
42basic_io::escape(string const & s)
43{
44 string escaped;
45 escaped.reserve(s.size() + 8);
46
47 escaped += "\"";
48
49 for (string::const_iterator i = s.begin(); i != s.end(); ++i)
50 {
51 switch (*i)
52 {
53 case '\\':
54 case '"':
55 escaped += '\\';
56 default:
57 escaped += *i;
58 }
59 }
60
61 escaped += "\"";
62
63 return escaped;
64}
65
66basic_io::stanza::stanza() : indent(0)
67{}
68
69void basic_io::stanza::push_hex_pair(symbol const & k, hexenc<id> const & v)
70{
71 entries.push_back(make_pair(k, ""));
72 string const & s(v());
73 entries.back().second.reserve(s.size()+2);
74 entries.back().second.push_back('[');
75 entries.back().second.append(s);
76 entries.back().second.push_back(']');
77 if (k().size() > indent)
78 indent = k().size();
79}
80
81void basic_io::stanza::push_hex_triple(symbol const & k,
82 string const & n,
83 hexenc<id> const & v)
84{
85 entries.push_back(make_pair(k, escape(n) + " " + "[" + v() + "]"));
86 if (k().size() > indent)
87 indent = k().size();
88}
89
90void basic_io::stanza::push_str_pair(symbol const & k, string const & v)
91{
92 entries.push_back(make_pair(k, escape(v)));
93 if (k().size() > indent)
94 indent = k().size();
95}
96
97void basic_io::stanza::push_file_pair(symbol const & k, file_path const & v)
98{
99 push_str_pair(k, v.as_internal());
100}
101
102void basic_io::stanza::push_str_multi(symbol const & k,
103 vector<string> const & v)
104{
105 string val;
106 bool first = true;
107 for (vector<string>::const_iterator i = v.begin();
108 i != v.end(); ++i)
109 {
110 if (!first)
111 val += " ";
112 val += escape(*i);
113 first = false;
114 }
115 entries.push_back(make_pair(k, val));
116 if (k().size() > indent)
117 indent = k().size();
118}
119
120void basic_io::stanza::push_str_triple(symbol const & k,
121 string const & n,
122 string const & v)
123{
124 entries.push_back(make_pair(k, escape(n) + " " + escape(v)));
125 if (k().size() > indent)
126 indent = k().size();
127}
128
129
130string basic_io::printer::buf;
131int basic_io::printer::count;
132
133basic_io::printer::printer()
134{
135 I(count == 0);
136 count++;
137 buf.clear();
138}
139
140basic_io::printer::~printer()
141{
142 count--;
143}
144
145void basic_io::printer::print_stanza(stanza const & st)
146{
147 if (LIKELY(!buf.empty()))
148 buf += '\n';
149
150 for (vector<pair<symbol, string> >::const_iterator i = st.entries.begin();
151 i != st.entries.end(); ++i)
152 {
153 for (size_t k = i->first().size(); k < st.indent; ++k)
154 buf += ' ';
155 buf.append(i->first());
156 buf += ' ';
157 buf.append(i->second);
158 buf += '\n';
159 }
160}
161
162void basic_io::parser::err(string const & s)
163{
164 tok.err(s);
165}
166
167string basic_io::parser::tt2str(token_type tt)
168{
169 switch (tt)
170 {
171 case basic_io::TOK_STRING:
172 return "TOK_STRING";
173 case basic_io::TOK_SYMBOL:
174 return "TOK_SYMBOL";
175 case basic_io::TOK_HEX:
176 return "TOK_HEX";
177 case basic_io::TOK_NONE:
178 return "TOK_NONE";
179 }
180 return "TOK_UNKNOWN";
181}
182
183#ifdef BUILD_UNIT_TESTS
184#include "unit_tests.hh"
185
186UNIT_TEST(basic_io, binary_transparency)
187{
188 std::string testpattern;
189 for (unsigned i=0; i<256; ++i) testpattern+=char(i);
190
191 static symbol test("test");
192
193 basic_io::printer printer;
194 basic_io::stanza st;
195 st.push_str_pair(test, testpattern);
196 printer.print_stanza(st);
197
198 basic_io::input_source source(printer.buf, "unit test string");
199 basic_io::tokenizer tokenizer(source);
200 basic_io::parser parser(tokenizer);
201 std::string t1;
202 parser.esym(test);
203 parser.str(t1);
204 I(testpattern==t1);
205}
206
207#endif // BUILD_UNIT_TESTS
208
209// Local Variables:
210// mode: C++
211// fill-column: 76
212// c-file-style: "gnu"
213// indent-tabs-mode: nil
214// End:
215// 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