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