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