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