this shouldn't be in svn
[supertux.git] / src / lisp / writer.cpp
index e4a810a..4126b7f 100644 (file)
@@ -1,7 +1,7 @@
 //  $Id$
 //
-//  SuperTux -  A Jump'n Run
-//  Copyright (C) 2004 Matthias Braun <matze@braunis.de
+//  SuperTux
+//  Copyright (C) 2006 Matthias Braun <matze@braunis.de>
 //
 //  This program is free software; you can redistribute it and/or
 //  modify it under the terms of the GNU General Public License
 
 #include <iostream>
 
-#include "writer.h"
+#include "writer.hpp"
+#include "physfs/physfs_stream.hpp"
+#include "log.hpp"
 
 namespace lisp
 {
 
-Writer::Writer(std::ostream& newout)
-  : out(newout), indent_depth(0)
+Writer::Writer(const std::string& filename)
 {
+  out = new OFileStream(filename);
+  out_owned = true;
+  indent_depth = 0;
+}
+  
+Writer::Writer(std::ostream* newout)
+{
+  out = newout;
+  out_owned = false;
+  indent_depth = 0;
 }
 
 Writer::~Writer()
 {
   if(lists.size() > 0) {
-    std::cerr << "Warning: Not all sections closed in lispwriter!\n";
+    log_warning << "Not all sections closed in lispwriter" << std::endl;
   }
+  if(out_owned)
+    delete out;
 }
 
 void
 Writer::write_comment(const std::string& comment)
 {
-  out << "; " << comment << "\n";
+  *out << "; " << comment << "\n";
 }
 
 void
-Writer::start_list(const std::string& listname)
+Writer::start_list(const std::string& listname, bool string)
 {
   indent();
-  out << '(' << listname << '\n';
+  *out << '(';
+  if(string)
+    write_escaped_string(listname);
+  else
+    *out << listname;
+  *out << '\n';
   indent_depth += 2;
 
   lists.push_back(listname);
@@ -58,34 +76,32 @@ void
 Writer::end_list(const std::string& listname)
 {
   if(lists.size() == 0) {
-    std::cerr << "Trying to close list '" << listname 
-              << "', which is not open.\n";
+    log_warning << "Trying to close list '" << listname << "', which is not open" << std::endl;
     return;
   }
   if(lists.back() != listname) {
-    std::cerr << "Warning: trying to close list '" << listname 
-              << "' while list '" << lists.back() << "' is open.\n";
+    log_warning << "trying to close list '" << listname << "' while list '" << lists.back() << "' is open" << std::endl;
     return;
   }
   lists.pop_back();
   
   indent_depth -= 2;
   indent();
-  out << ")\n";
+  *out << ")\n";
 }
 
 void
 Writer::write_int(const std::string& name, int value)
 {
   indent();
-  out << '(' << name << ' ' << value << ")\n";
+  *out << '(' << name << ' ' << value << ")\n";
 }
 
 void
 Writer::write_float(const std::string& name, float value)
 {
   indent();
-  out << '(' << name << ' ' << value << ")\n";
+  *out << '(' << name << ' ' << value << ")\n";
 }
 
 void
@@ -93,11 +109,15 @@ Writer::write_string(const std::string& name, const std::string& value,
     bool translatable)
 {
   indent();
-  out << '(' << name;
+  *out << '(' << name;
   if(translatable) {
-    out << " (_ \"" << value << "\"))\n";
+    *out << " (_ ";
+    write_escaped_string(value);
+    *out << "))\n";
   } else {
-    out << " \"" << value << "\")\n";
+    *out << " ";
+    write_escaped_string(value);
+    *out << ")\n";
   }
 }
 
@@ -105,7 +125,7 @@ void
 Writer::write_bool(const std::string& name, bool value)
 {
   indent();
-  out << '(' << name << ' ' << (value ? "#t" : "#f") << ")\n";
+  *out << '(' << name << ' ' << (value ? "#t" : "#f") << ")\n";
 }
 
 void
@@ -113,10 +133,10 @@ Writer::write_int_vector(const std::string& name,
     const std::vector<int>& value)
 {
   indent();
-  out << '(' << name;
+  *out << '(' << name;
   for(std::vector<int>::const_iterator i = value.begin(); i != value.end(); ++i)
-    out << " " << *i;
-  out << ")\n";
+    *out << " " << *i;
+  *out << ")\n";
 }
 
 void
@@ -124,17 +144,43 @@ Writer::write_int_vector(const std::string& name,
     const std::vector<unsigned int>& value)
 {
   indent();
-  out << '(' << name;
+  *out << '(' << name;
   for(std::vector<unsigned int>::const_iterator i = value.begin(); i != value.end(); ++i)
-    out << " " << *i;
-  out << ")\n";
+    *out << " " << *i;
+  *out << ")\n";
+}
+
+void
+Writer::write_float_vector(const std::string& name,
+                           const std::vector<float>& value)
+{
+  indent();
+  *out << '(' << name;
+  for(std::vector<float>::const_iterator i = value.begin(); i != value.end(); ++i)
+    *out << " " << *i;
+  *out << ")\n";
+}
+
+void
+Writer::write_escaped_string(const std::string& str)
+{
+  *out << '"';
+  for(const char* c = str.c_str(); *c != 0; ++c) {
+    if(*c == '\"')
+      *out << "\\\"";
+    else if(*c == '\\')
+      *out << "\\\\";
+    else
+      *out << *c;
+  }
+  *out << '"';
 }
 
 void
 Writer::indent()
 {
   for(int i = 0; i<indent_depth; ++i)
-    out << ' ';
+    *out << ' ';
 }
 
 } // end of namespace lisp