00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "lisp/writer.hpp"
00018
00019 #include "physfs/ofile_stream.hpp"
00020 #include "util/log.hpp"
00021
00022 namespace lisp {
00023
00024 Writer::Writer(const std::string& filename) :
00025 out(),
00026 out_owned(),
00027 indent_depth(),
00028 lists()
00029 {
00030 out = new OFileStream(filename);
00031 out_owned = true;
00032 indent_depth = 0;
00033 out->precision(10);
00034 }
00035
00036 Writer::Writer(std::ostream* newout) :
00037 out(),
00038 out_owned(),
00039 indent_depth(),
00040 lists()
00041 {
00042 out = newout;
00043 out_owned = false;
00044 indent_depth = 0;
00045 out->precision(10);
00046 }
00047
00048 Writer::~Writer()
00049 {
00050 if(lists.size() > 0) {
00051 log_warning << "Not all sections closed in lispwriter" << std::endl;
00052 }
00053 if(out_owned)
00054 delete out;
00055 }
00056
00057 void
00058 Writer::write_comment(const std::string& comment)
00059 {
00060 *out << "; " << comment << "\n";
00061 }
00062
00063 void
00064 Writer::start_list(const std::string& listname, bool string)
00065 {
00066 indent();
00067 *out << '(';
00068 if(string)
00069 write_escaped_string(listname);
00070 else
00071 *out << listname;
00072 *out << '\n';
00073 indent_depth += 2;
00074
00075 lists.push_back(listname);
00076 }
00077
00078 void
00079 Writer::end_list(const std::string& listname)
00080 {
00081 if(lists.size() == 0) {
00082 log_warning << "Trying to close list '" << listname << "', which is not open" << std::endl;
00083 return;
00084 }
00085 if(lists.back() != listname) {
00086 log_warning << "trying to close list '" << listname << "' while list '" << lists.back() << "' is open" << std::endl;
00087 return;
00088 }
00089 lists.pop_back();
00090
00091 indent_depth -= 2;
00092 indent();
00093 *out << ")\n";
00094 }
00095
00096 void
00097 Writer::write(const std::string& name, int value)
00098 {
00099 indent();
00100 *out << '(' << name << ' ' << value << ")\n";
00101 }
00102
00103 void
00104 Writer::write(const std::string& name, float value)
00105 {
00106 indent();
00107 *out << '(' << name << ' ' << value << ")\n";
00108 }
00109
00110 void
00111 Writer::write(const std::string& name, const std::string& value,
00112 bool translatable)
00113 {
00114 indent();
00115 *out << '(' << name;
00116 if(translatable) {
00117 *out << " (_ ";
00118 write_escaped_string(value);
00119 *out << "))\n";
00120 } else {
00121 *out << " ";
00122 write_escaped_string(value);
00123 *out << ")\n";
00124 }
00125 }
00126
00127 void
00128 Writer::write(const std::string& name, bool value)
00129 {
00130 indent();
00131 *out << '(' << name << ' ' << (value ? "#t" : "#f") << ")\n";
00132 }
00133
00134 void
00135 Writer::write(const std::string& name,
00136 const std::vector<int>& value)
00137 {
00138 indent();
00139 *out << '(' << name;
00140 for(std::vector<int>::const_iterator i = value.begin(); i != value.end(); ++i)
00141 *out << " " << *i;
00142 *out << ")\n";
00143 }
00144
00145 void
00146 Writer::write(const std::string& name,
00147 const std::vector<unsigned int>& value)
00148 {
00149 indent();
00150 *out << '(' << name;
00151 for(std::vector<unsigned int>::const_iterator i = value.begin(); i != value.end(); ++i)
00152 *out << " " << *i;
00153 *out << ")\n";
00154 }
00155
00156 void
00157 Writer::write(const std::string& name,
00158 const std::vector<float>& value)
00159 {
00160 indent();
00161 *out << '(' << name;
00162 for(std::vector<float>::const_iterator i = value.begin(); i != value.end(); ++i)
00163 *out << " " << *i;
00164 *out << ")\n";
00165 }
00166
00167 void
00168 Writer::write(const std::string& name,
00169 const std::vector<std::string>& value)
00170 {
00171 indent();
00172 *out << '(' << name;
00173 for(std::vector<std::string>::const_iterator i = value.begin(); i != value.end(); ++i) {
00174 *out << " ";
00175 write_escaped_string(*i);
00176 }
00177 *out << ")\n";
00178 }
00179
00180 void
00181 Writer::write_escaped_string(const std::string& str)
00182 {
00183 *out << '"';
00184 for(const char* c = str.c_str(); *c != 0; ++c) {
00185 if(*c == '\"')
00186 *out << "\\\"";
00187 else if(*c == '\\')
00188 *out << "\\\\";
00189 else
00190 *out << *c;
00191 }
00192 *out << '"';
00193 }
00194
00195 void
00196 Writer::indent()
00197 {
00198 for(int i = 0; i<indent_depth; ++i)
00199 *out << ' ';
00200 }
00201
00202 }
00203
00204