- added draw_part()
[supertux.git] / src / lispreader.cpp
index 8f8bbed..0ece43d 100644 (file)
  * Boston, MA 02111-1307, USA.
  */
 
+#include <string>
 #include <assert.h>
 #include <ctype.h>
 #include <stdlib.h>
 #include <string.h>
-
-#include <lispreader.h>
+#include "setup.h"
+#include "lispreader.h"
 
 #define TOKEN_ERROR                   -1
 #define TOKEN_EOF                     0
 static char token_string[MAX_TOKEN_LENGTH + 1] = "";
 static int token_length = 0;
 
-static lisp_object_t end_marker = { LISP_TYPE_EOF };
-static lisp_object_t error_object = { LISP_TYPE_PARSE_ERROR };
-static lisp_object_t close_paren_marker = { LISP_TYPE_PARSE_ERROR };
-static lisp_object_t dot_marker = { LISP_TYPE_PARSE_ERROR };
+static lisp_object_t end_marker = { LISP_TYPE_EOF , {0,0}  };
+static lisp_object_t error_object = { LISP_TYPE_PARSE_ERROR , {0,0}  };
+static lisp_object_t close_paren_marker = { LISP_TYPE_PARSE_ERROR , {0,0}  };
+static lisp_object_t dot_marker = { LISP_TYPE_PARSE_ERROR , {0,0} };
 
 static void
 _token_clear (void)
@@ -567,7 +568,8 @@ _compile_pattern (lisp_object_t **obj, int *index)
         int type;
         int i;
         lisp_object_t *pattern;
-
+        type = -1;
+       
         if (lisp_type(lisp_car(*obj)) != LISP_TYPE_SYMBOL)
           return 0;
 
@@ -1039,6 +1041,8 @@ LispReader::read_int (const char* name, int* i)
   lisp_object_t* obj = search_for (name);
   if (obj)
     {
+      if (!lisp_integer_p(lisp_car(obj)))
+        st_abort("LispReader expected type integer at token: ", name);
       *i = lisp_integer(lisp_car(obj));
       return true;
     }
@@ -1046,11 +1050,26 @@ LispReader::read_int (const char* name, int* i)
 }
 
 bool
+LispReader::read_lisp(const char* name, lisp_object_t** b)
+{
+  lisp_object_t* obj = search_for (name);
+  if (obj)
+    {
+      *b = obj;
+      return true;
+    }
+  else
+    return false;
+}
+
+bool
 LispReader::read_float (const char* name, float* f)
 {
   lisp_object_t* obj = search_for (name);
   if (obj)
     {
+      if (!lisp_real_p(lisp_car(obj)) && !lisp_integer_p(lisp_car(obj)))
+        st_abort("LispReader expected type real at token: ", name);
       *f = lisp_real(lisp_car(obj));
       return true;
     }
@@ -1058,11 +1077,79 @@ LispReader::read_float (const char* name, float* f)
 }
 
 bool
+LispReader::read_string_vector (const char* name, std::vector<std::string>* vec)
+{
+  lisp_object_t* obj = search_for (name);
+  if (obj)
+    {
+      while(!lisp_nil_p(obj))
+        {
+          if (!lisp_string_p(lisp_car(obj)))
+            st_abort("LispReader expected type string at token: ", name);
+          vec->push_back(lisp_string(lisp_car(obj)));
+          obj = lisp_cdr(obj);
+        }
+      return true;
+    }
+  return false;    
+}
+
+bool
+LispReader::read_int_vector (const char* name, std::vector<int>* vec)
+{
+  lisp_object_t* obj = search_for (name);
+  if (obj)
+    {
+      while(!lisp_nil_p(obj))
+        {
+          if (!lisp_integer_p(lisp_car(obj)))
+            st_abort("LispReader expected type integer at token: ", name);
+          vec->push_back(lisp_integer(lisp_car(obj)));
+          obj = lisp_cdr(obj);
+        }
+      return true;
+    }
+  return false;    
+}
+
+bool
+LispReader::read_char_vector (const char* name, std::vector<char>* vec)
+{
+  lisp_object_t* obj = search_for (name);
+  if (obj)
+    {
+      while(!lisp_nil_p(obj))
+        {
+          vec->push_back(*lisp_string(lisp_car(obj)));
+          obj = lisp_cdr(obj);
+        }
+      return true;
+    }
+  return false;    
+}
+
+bool
+LispReader::read_string (const char* name, std::string* str)
+{
+  lisp_object_t* obj = search_for (name);
+  if (obj)
+    {
+      if (!lisp_string_p(lisp_car(obj)))
+        st_abort("LispReader expected type string at token: ", name);
+     *str = lisp_string(lisp_car(obj));
+      return true;
+    }
+  return false;  
+}
+
+bool
 LispReader::read_bool (const char* name, bool* b)
 {
   lisp_object_t* obj = search_for (name);
   if (obj)
     {
+      if (!lisp_boolean_p(lisp_car(obj)))
+        st_abort("LispReader expected type bool at token: ", name);
       *b = lisp_boolean(lisp_car(obj));
       return true;
     }
@@ -1149,3 +1236,113 @@ LispWriter::create_lisp ()
   return lisp_obj;
 }
 
+#if 0
+void mygzungetc(char c, void* file)
+{
+  gzungetc(c, file);
+}
+
+lisp_stream_t* lisp_stream_init_gzfile (lisp_stream_t *stream, gzFile file)
+{
+  return lisp_stream_init_any (stream, file, gzgetc, mygzungetc);
+}
+#endif
+
+lisp_object_t* lisp_read_from_gzfile(const char* filename)
+{
+  bool done = false;
+  lisp_object_t* root_obj = 0;
+  int chunk_size = 128 * 1024;
+  int buf_pos = 0;
+  int try_number = 1;
+  char* buf = static_cast<char*>(malloc(chunk_size));
+  assert(buf);
+
+  gzFile in = gzopen(filename, "r");
+
+  while (!done)
+    {
+      int ret = gzread(in, buf + buf_pos, chunk_size);
+      if (ret == -1)
+        {
+          free (buf);
+          assert(!"Error while reading from file");
+        }
+      else if (ret == chunk_size) // buffer got full, eof not yet there so resize
+        {
+          buf_pos = chunk_size * try_number;
+          try_number += 1;
+          buf = static_cast<char*>(realloc(buf, chunk_size * try_number));
+          assert(buf);
+        }
+      else 
+        {
+          // everything fine, encountered EOF 
+          done = true;
+        }
+    }
+      
+  lisp_stream_t stream;
+  lisp_stream_init_string (&stream, buf);
+  root_obj = lisp_read (&stream);
+      
+  free(buf);
+  gzclose(in);
+
+  return root_obj;
+}
+
+bool has_suffix(const char* data, const char* suffix)
+{
+  int suffix_len = strlen(suffix);
+  int data_len   = strlen(data);
+  
+  const char* data_suffix = (data + data_len - suffix_len);
+
+  if (data_suffix >= data)
+    {
+      return (strcmp(data_suffix, suffix) == 0);
+    }
+  else
+    {
+      return false;
+    }
+}
+
+lisp_object_t* lisp_read_from_file(const std::string& filename)
+{
+  lisp_stream_t stream;
+
+  if (has_suffix(filename.c_str(), ".gz"))
+    {
+      return lisp_read_from_gzfile(filename.c_str());
+#if 0
+      lisp_object_t* obj = 0;
+      gzFile in = gzopen(filename, "r");
+
+      if (in)
+        {
+          lisp_stream_init_gzfile(&stream, in);
+          obj = lisp_read(&stream);
+          gzclose(in);
+        }
+        return obj;
+#endif
+    }
+  else
+    {
+      lisp_object_t* obj = 0;
+      FILE* in = fopen(filename.c_str(), "r");
+
+      if (in)
+        {
+          lisp_stream_init_file(&stream, in);
+          obj = lisp_read(&stream);
+          fclose(in);
+        }
+
+      return obj;
+    }
+}
+
+// EOF //