Revert "Possible fix for coverity #29375"
[supertux.git] / src / lisp / writer.cpp
1 //  SuperTux
2 //  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
3 //
4 //  This program is free software: you can redistribute it and/or modify
5 //  it under the terms of the GNU General Public License as published by
6 //  the Free Software Foundation, either version 3 of the License, or
7 //  (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17 #include "lisp/writer.hpp"
18
19 #include "physfs/ofile_stream.hpp"
20 #include "util/log.hpp"
21
22 namespace lisp {
23
24 Writer::Writer(const std::string& filename) :
25   out(),
26   out_owned(),
27   indent_depth(),
28   lists()
29 {
30   out = new OFileStream(filename);
31   out_owned = true;
32   indent_depth = 0;
33   out->precision(10);
34 }
35
36 Writer::Writer(std::ostream* newout) :
37   out(),
38   out_owned(),
39   indent_depth(),
40   lists()
41 {
42   out = newout;
43   out_owned = false;
44   indent_depth = 0;
45   out->precision(10);
46 }
47
48 Writer::~Writer()
49 {
50   if(lists.size() > 0) {
51     log_warning << "Not all sections closed in lispwriter" << std::endl;
52   }
53   if(out_owned)
54     delete out;
55 }
56
57 void
58 Writer::write_comment(const std::string& comment)
59 {
60   *out << "; " << comment << "\n";
61 }
62
63 void
64 Writer::start_list(const std::string& listname, bool string)
65 {
66   indent();
67   *out << '(';
68   if(string)
69     write_escaped_string(listname);
70   else
71     *out << listname;
72   *out << '\n';
73   indent_depth += 2;
74
75   lists.push_back(listname);
76 }
77
78 void
79 Writer::end_list(const std::string& listname)
80 {
81   if(lists.size() == 0) {
82     log_warning << "Trying to close list '" << listname << "', which is not open" << std::endl;
83     return;
84   }
85   if(lists.back() != listname) {
86     log_warning << "trying to close list '" << listname << "' while list '" << lists.back() << "' is open" << std::endl;
87     return;
88   }
89   lists.pop_back();
90
91   indent_depth -= 2;
92   indent();
93   *out << ")\n";
94 }
95
96 void
97 Writer::write(const std::string& name, int value)
98 {
99   indent();
100   *out << '(' << name << ' ' << value << ")\n";
101 }
102
103 void
104 Writer::write(const std::string& name, float value)
105 {
106   indent();
107   *out << '(' << name << ' ' << value << ")\n";
108 }
109
110 void
111 Writer::write(const std::string& name, const std::string& value,
112               bool translatable)
113 {
114   indent();
115   *out << '(' << name;
116   if(translatable) {
117     *out << " (_ ";
118     write_escaped_string(value);
119     *out << "))\n";
120   } else {
121     *out << " ";
122     write_escaped_string(value);
123     *out << ")\n";
124   }
125 }
126
127 void
128 Writer::write(const std::string& name, bool value)
129 {
130   indent();
131   *out << '(' << name << ' ' << (value ? "#t" : "#f") << ")\n";
132 }
133
134 void
135 Writer::write(const std::string& name,
136               const std::vector<int>& value)
137 {
138   indent();
139   *out << '(' << name;
140   for(std::vector<int>::const_iterator i = value.begin(); i != value.end(); ++i)
141     *out << " " << *i;
142   *out << ")\n";
143 }
144
145 void
146 Writer::write(const std::string& name,
147               const std::vector<unsigned int>& value)
148 {
149   indent();
150   *out << '(' << name;
151   for(std::vector<unsigned int>::const_iterator i = value.begin(); i != value.end(); ++i)
152     *out << " " << *i;
153   *out << ")\n";
154 }
155
156 void
157 Writer::write(const std::string& name,
158               const std::vector<float>& value)
159 {
160   indent();
161   *out << '(' << name;
162   for(std::vector<float>::const_iterator i = value.begin(); i != value.end(); ++i)
163     *out << " " << *i;
164   *out << ")\n";
165 }
166
167 void
168 Writer::write(const std::string& name,
169               const std::vector<std::string>& value)
170 {
171   indent();
172   *out << '(' << name;
173   for(std::vector<std::string>::const_iterator i = value.begin(); i != value.end(); ++i) {
174     *out << " ";
175     write_escaped_string(*i);
176   }
177   *out << ")\n";
178 }
179
180 void
181 Writer::write_escaped_string(const std::string& str)
182 {
183   *out << '"';
184   for(const char* c = str.c_str(); *c != 0; ++c) {
185     if(*c == '\"')
186       *out << "\\\"";
187     else if(*c == '\\')
188       *out << "\\\\";
189     else
190       *out << *c;
191   }
192   *out << '"';
193 }
194
195 void
196 Writer::indent()
197 {
198   for(int i = 0; i<indent_depth; ++i)
199     *out << ' ';
200 }
201
202 } // end of namespace lisp
203
204 /* EOF */