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/buffered_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   BufferedOFileStream* filestream = new BufferedOFileStream(filename);
31   out = filestream->get_stream();
32   out_owned = true;
33   indent_depth = 0;
34   out->precision(10);
35 }
36
37 Writer::Writer(std::ostream* newout) :
38   out(),
39   out_owned(),
40   indent_depth(),
41   lists()
42 {
43   out = newout;
44   out_owned = false;
45   indent_depth = 0;
46   out->precision(10);
47 }
48
49 Writer::~Writer()
50 {
51   if(lists.size() > 0) {
52     log_warning << "Not all sections closed in lispwriter" << std::endl;
53   }
54   if(out_owned)
55     delete out;
56 }
57
58 void
59 Writer::write_comment(const std::string& comment)
60 {
61   *out << "; " << comment << "\n";
62 }
63
64 void
65 Writer::start_list(const std::string& listname, bool string)
66 {
67   indent();
68   *out << '(';
69   if(string)
70     write_escaped_string(listname);
71   else
72     *out << listname;
73   *out << '\n';
74   indent_depth += 2;
75
76   lists.push_back(listname);
77 }
78
79 void
80 Writer::end_list(const std::string& listname)
81 {
82   if(lists.size() == 0) {
83     log_warning << "Trying to close list '" << listname << "', which is not open" << std::endl;
84     return;
85   }
86   if(lists.back() != listname) {
87     log_warning << "trying to close list '" << listname << "' while list '" << lists.back() << "' is open" << std::endl;
88     return;
89   }
90   lists.pop_back();
91
92   indent_depth -= 2;
93   indent();
94   *out << ")\n";
95 }
96
97 void
98 Writer::write(const std::string& name, int value)
99 {
100   indent();
101   *out << '(' << name << ' ' << value << ")\n";
102 }
103
104 void
105 Writer::write(const std::string& name, float value)
106 {
107   indent();
108   *out << '(' << name << ' ' << value << ")\n";
109 }
110
111 void
112 Writer::write(const std::string& name, const std::string& value,
113               bool translatable)
114 {
115   indent();
116   *out << '(' << name;
117   if(translatable) {
118     *out << " (_ ";
119     write_escaped_string(value);
120     *out << "))\n";
121   } else {
122     *out << " ";
123     write_escaped_string(value);
124     *out << ")\n";
125   }
126 }
127
128 void
129 Writer::write(const std::string& name, bool value)
130 {
131   indent();
132   *out << '(' << name << ' ' << (value ? "#t" : "#f") << ")\n";
133 }
134
135 void
136 Writer::write(const std::string& name,
137               const std::vector<int>& value)
138 {
139   indent();
140   *out << '(' << name;
141   for(std::vector<int>::const_iterator i = value.begin(); i != value.end(); ++i)
142     *out << " " << *i;
143   *out << ")\n";
144 }
145
146 void
147 Writer::write(const std::string& name,
148               const std::vector<unsigned int>& value)
149 {
150   indent();
151   *out << '(' << name;
152   for(std::vector<unsigned int>::const_iterator i = value.begin(); i != value.end(); ++i)
153     *out << " " << *i;
154   *out << ")\n";
155 }
156
157 void
158 Writer::write(const std::string& name,
159               const std::vector<float>& value)
160 {
161   indent();
162   *out << '(' << name;
163   for(std::vector<float>::const_iterator i = value.begin(); i != value.end(); ++i)
164     *out << " " << *i;
165   *out << ")\n";
166 }
167
168 void
169 Writer::write(const std::string& name,
170               const std::vector<std::string>& value)
171 {
172   indent();
173   *out << '(' << name;
174   for(std::vector<std::string>::const_iterator i = value.begin(); i != value.end(); ++i) {
175     *out << " ";
176     write_escaped_string(*i);
177   }
178   *out << ")\n";
179 }
180
181 void
182 Writer::write_escaped_string(const std::string& str)
183 {
184   *out << '"';
185   for(const char* c = str.c_str(); *c != 0; ++c) {
186     if(*c == '\"')
187       *out << "\\\"";
188     else if(*c == '\\')
189       *out << "\\\\";
190     else
191       *out << *c;
192   }
193   *out << '"';
194 }
195
196 void
197 Writer::indent()
198 {
199   for(int i = 0; i<indent_depth; ++i)
200     *out << ' ';
201 }
202
203 } // end of namespace lisp
204
205 /* EOF */