- fixes image region tiling bug (by Matze)
[supertux.git] / lib / utils / lispreader.cpp
index c49d34f..6076b16 100644 (file)
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
+#include <config.h>
+
 #include <iostream>
 #include <vector>
+#include <stdexcept>
 #include <string>
 #include <cctype>
 #include <cstdlib>
 #include <cstring>
+#include <cassert>
 
 #include "app/globals.h"
 #include "app/setup.h"
-#include "utils/lispreader.h"
+#include "lispreader.h"
+
+using namespace SuperTux;
 
 #define TOKEN_ERROR                   -1
 #define TOKEN_EOF                     0
@@ -66,7 +72,7 @@ static void
 _token_append (char c)
 {
   if (token_length >= MAX_TOKEN_LENGTH)
-    throw LispReaderException("_token_append()", __FILE__, __LINE__);
+    throw std::runtime_error("token too long.");
 
   token_string[token_length++] = c;
   token_string[token_length] = '\0';
@@ -96,7 +102,7 @@ _next_char (lisp_stream_t *stream)
       return stream->v.any.next_char(stream->v.any.data);
     }
 
-  throw LispReaderException("_next_char()", __FILE__, __LINE__);
+  assert(false);
   return EOF;
 }
 
@@ -118,7 +124,7 @@ _unget_char (char c, lisp_stream_t *stream)
       break;
 
     default :
-      throw LispReaderException("_unget_char()", __FILE__, __LINE__);
+      assert(false);
     }
 }
 
@@ -270,7 +276,7 @@ _scan (lisp_stream_t *stream)
         }
     }
 
-  throw LispReaderException("_scan()", __FILE__, __LINE__);
+  throw std::runtime_error("invalid token in lisp file");
   return TOKEN_ERROR;
 }
 
@@ -285,7 +291,7 @@ lisp_object_alloc (int type)
 }
 
 lisp_stream_t*
-lisp_stream_init_file (lisp_stream_t *stream, FILE *file)
+SuperTux::lisp_stream_init_file (lisp_stream_t *stream, FILE *file)
 {
   stream->type = LISP_STREAM_FILE;
   stream->v.file = file;
@@ -294,7 +300,7 @@ lisp_stream_init_file (lisp_stream_t *stream, FILE *file)
 }
 
 lisp_stream_t*
-lisp_stream_init_string (lisp_stream_t *stream, char *buf)
+SuperTux::lisp_stream_init_string (lisp_stream_t *stream, char *buf)
 {
   stream->type = LISP_STREAM_STRING;
   stream->v.string.buf = buf;
@@ -304,12 +310,12 @@ lisp_stream_init_string (lisp_stream_t *stream, char *buf)
 }
 
 lisp_stream_t*
-lisp_stream_init_any (lisp_stream_t *stream, void *data,
+SuperTux::lisp_stream_init_any (lisp_stream_t *stream, void *data,
                       int (*next_char) (void *data),
                       void (*unget_char) (char c, void *data))
 {
   if (next_char == 0 || unget_char == 0)
-    throw LispReaderException("lisp_stream_init_any()", __FILE__, __LINE__);
+    throw std::runtime_error("no data");
 
   stream->type = LISP_STREAM_ANY;
   stream->v.any.data = data;
@@ -320,7 +326,7 @@ lisp_stream_init_any (lisp_stream_t *stream, void *data,
 }
 
 lisp_object_t*
-lisp_make_integer (int value)
+SuperTux::lisp_make_integer (int value)
 {
   lisp_object_t *obj = lisp_object_alloc(LISP_TYPE_INTEGER);
 
@@ -330,7 +336,7 @@ lisp_make_integer (int value)
 }
 
 lisp_object_t*
-lisp_make_real (float value)
+SuperTux::lisp_make_real (float value)
 {
   lisp_object_t *obj = lisp_object_alloc(LISP_TYPE_REAL);
 
@@ -340,7 +346,7 @@ lisp_make_real (float value)
 }
 
 lisp_object_t*
-lisp_make_symbol (const char *value)
+SuperTux::lisp_make_symbol (const char *value)
 {
   lisp_object_t *obj = lisp_object_alloc(LISP_TYPE_SYMBOL);
 
@@ -350,7 +356,7 @@ lisp_make_symbol (const char *value)
 }
 
 lisp_object_t*
-lisp_make_string (const char *value)
+SuperTux::lisp_make_string (const char *value)
 {
   lisp_object_t *obj = lisp_object_alloc(LISP_TYPE_STRING);
 
@@ -360,7 +366,7 @@ lisp_make_string (const char *value)
 }
 
 lisp_object_t*
-lisp_make_cons (lisp_object_t *car, lisp_object_t *cdr)
+SuperTux::lisp_make_cons (lisp_object_t *car, lisp_object_t *cdr)
 {
   lisp_object_t *obj = lisp_object_alloc(LISP_TYPE_CONS);
 
@@ -371,7 +377,7 @@ lisp_make_cons (lisp_object_t *car, lisp_object_t *cdr)
 }
 
 lisp_object_t*
-lisp_make_boolean (int value)
+SuperTux::lisp_make_boolean (int value)
 {
   lisp_object_t *obj = lisp_object_alloc(LISP_TYPE_BOOLEAN);
 
@@ -404,7 +410,7 @@ lisp_make_pattern_var (int type, int index, lisp_object_t *sub)
 }
 
 lisp_object_t*
-lisp_read (lisp_stream_t *in)
+SuperTux::lisp_read (lisp_stream_t *in)
 {
   int token = _scan(in);
   lisp_object_t *obj = lisp_nil();
@@ -497,12 +503,12 @@ lisp_read (lisp_stream_t *in)
       return lisp_make_boolean(0);
     }
 
-  throw LispReaderException("lisp_read()", __FILE__, __LINE__);
+  throw std::runtime_error("syntax error in lisp file");
   return &error_object;
 }
 
 void
-lisp_free (lisp_object_t *obj)
+SuperTux::lisp_free (lisp_object_t *obj)
 {
   if (obj == 0)
     return;
@@ -547,7 +553,7 @@ lisp_free (lisp_object_t *obj)
 }
 
 lisp_object_t*
-lisp_read_from_string (const char *buf)
+SuperTux::lisp_read_from_string (const char *buf)
 {
   lisp_stream_t stream;
 
@@ -642,7 +648,7 @@ _compile_pattern (lisp_object_t **obj, int *index)
 }
 
 int
-lisp_compile_pattern (lisp_object_t **obj, int *num_subs)
+SuperTux::lisp_compile_pattern (lisp_object_t **obj, int *num_subs)
 {
   int index = 0;
   int result;
@@ -661,7 +667,7 @@ static int
 _match_pattern_var (lisp_object_t *pattern, lisp_object_t *obj, lisp_object_t **vars)
 {
   if (lisp_type(pattern) != LISP_TYPE_PATTERN_VAR)
-    throw LispReaderException("_match_pattern_var", __FILE__, __LINE__);
+    throw std::runtime_error("type is not a var");
 
   switch (pattern->v.pattern.type)
     {
@@ -706,7 +712,7 @@ _match_pattern_var (lisp_object_t *pattern, lisp_object_t *obj, lisp_object_t **
         for (sub = pattern->v.pattern.sub; sub != 0; sub = lisp_cdr(sub))
           {
             if (lisp_type(sub) != LISP_TYPE_CONS)
-              throw LispReaderException("_match_pattern_var()", __FILE__, __LINE__);
+              throw std::runtime_error("type isn't a car/cons");
 
             if (_match_pattern(lisp_car(sub), obj, vars))
               matched = 1;
@@ -718,7 +724,7 @@ _match_pattern_var (lisp_object_t *pattern, lisp_object_t *obj, lisp_object_t **
       break;
 
     default :
-      throw LispReaderException("_match_pattern_var()", __FILE__, __LINE__);
+      assert(false);
     }
 
   if (vars != 0)
@@ -768,14 +774,14 @@ _match_pattern (lisp_object_t *pattern, lisp_object_t *obj, lisp_object_t **vars
       break;
 
     default :
-      throw LispReaderException("_match_pattern()", __FILE__, __LINE__);
+      assert(false);
     }
 
   return 0;
 }
 
 int
-lisp_match_pattern (lisp_object_t *pattern, lisp_object_t *obj, lisp_object_t **vars, int num_subs)
+SuperTux::lisp_match_pattern (lisp_object_t *pattern, lisp_object_t *obj, lisp_object_t **vars, int num_subs)
 {
   int i;
 
@@ -787,7 +793,7 @@ lisp_match_pattern (lisp_object_t *pattern, lisp_object_t *obj, lisp_object_t **
 }
 
 int
-lisp_match_string (const char *pattern_string, lisp_object_t *obj, lisp_object_t **vars)
+SuperTux::lisp_match_string (const char *pattern_string, lisp_object_t *obj, lisp_object_t **vars)
 {
   lisp_object_t *pattern;
   int result;
@@ -813,7 +819,7 @@ lisp_match_string (const char *pattern_string, lisp_object_t *obj, lisp_object_t
 }
 
 int
-lisp_type (lisp_object_t *obj)
+SuperTux::lisp_type (lisp_object_t *obj)
 {
   if (obj == 0)
     return LISP_TYPE_NIL;
@@ -821,46 +827,46 @@ lisp_type (lisp_object_t *obj)
 }
 
 int
-lisp_integer (lisp_object_t *obj)
+SuperTux::lisp_integer (lisp_object_t *obj)
 {
   if (obj->type != LISP_TYPE_INTEGER)
-    throw LispReaderException("lisp_integer()", __FILE__, __LINE__);
+    throw std::runtime_error("expected integer");
 
   return obj->v.integer;
 }
 
 char*
-lisp_symbol (lisp_object_t *obj)
+SuperTux::lisp_symbol (lisp_object_t *obj)
 {
   if (obj->type != LISP_TYPE_SYMBOL)
-    throw LispReaderException("lisp_symbol()", __FILE__, __LINE__);
+    throw std::runtime_error("expected symbol");
 
   return obj->v.string;
 }
 
 char*
-lisp_string (lisp_object_t *obj)
+SuperTux::lisp_string (lisp_object_t *obj)
 {
   if (obj->type != LISP_TYPE_STRING)
-    throw LispReaderException("lisp_string()", __FILE__, __LINE__);
+    throw std::runtime_error("expected string");
 
   return obj->v.string;
 }
 
 int
-lisp_boolean (lisp_object_t *obj)
+SuperTux::lisp_boolean (lisp_object_t *obj)
 {
   if (obj->type != LISP_TYPE_BOOLEAN)
-    throw LispReaderException("lisp_boolean()", __FILE__, __LINE__);
+    throw std::runtime_error("expected boolean");
 
   return obj->v.integer;
 }
 
 float
-lisp_real (lisp_object_t *obj)
+SuperTux::lisp_real (lisp_object_t *obj)
 {
   if (obj->type != LISP_TYPE_REAL && obj->type != LISP_TYPE_INTEGER)
-    throw LispReaderException("lisp_real()", __FILE__, __LINE__);
+    throw std::runtime_error("expected real");
 
   if (obj->type == LISP_TYPE_INTEGER)
     return obj->v.integer;
@@ -868,25 +874,25 @@ lisp_real (lisp_object_t *obj)
 }
 
 lisp_object_t*
-lisp_car (lisp_object_t *obj)
+SuperTux::lisp_car (lisp_object_t *obj)
 {
   if (obj->type != LISP_TYPE_CONS && obj->type != LISP_TYPE_PATTERN_CONS)
-    throw LispReaderException("lisp_car()", __FILE__, __LINE__);
+    throw std::runtime_error("expected car");
 
   return obj->v.cons.car;
 }
 
 lisp_object_t*
-lisp_cdr (lisp_object_t *obj)
+SuperTux::lisp_cdr (lisp_object_t *obj)
 {
   if (obj->type != LISP_TYPE_CONS && obj->type != LISP_TYPE_PATTERN_CONS)
-    throw LispReaderException("lisp_cdr()", __FILE__, __LINE__);
+    throw std::runtime_error("expected cons");
 
   return obj->v.cons.cdr;
 }
 
 lisp_object_t*
-lisp_cxr (lisp_object_t *obj, const char *x)
+SuperTux::lisp_cxr (lisp_object_t *obj, const char *x)
 {
   int i;
 
@@ -896,20 +902,20 @@ lisp_cxr (lisp_object_t *obj, const char *x)
     else if (x[i] == 'd')
       obj = lisp_cdr(obj);
     else
-      throw LispReaderException("lisp_cxr()", __FILE__, __LINE__);
+      throw std::runtime_error("couldn't parse cxr");
 
   return obj;
 }
 
 int
-lisp_list_length (lisp_object_t *obj)
+SuperTux::lisp_list_length (lisp_object_t *obj)
 {
   int length = 0;
 
   while (obj != 0)
     {
       if (obj->type != LISP_TYPE_CONS && obj->type != LISP_TYPE_PATTERN_CONS)
-        throw LispReaderException("lisp_list_length()", __FILE__, __LINE__);
+        throw std::runtime_error("expected cons");
 
       ++length;
       obj = obj->v.cons.cdr;
@@ -919,14 +925,14 @@ lisp_list_length (lisp_object_t *obj)
 }
 
 lisp_object_t*
-lisp_list_nth_cdr (lisp_object_t *obj, int index)
+SuperTux::lisp_list_nth_cdr (lisp_object_t *obj, int index)
 {
   while (index > 0)
     {
       if (obj == 0)
-        throw LispReaderException("lisp_list_nth_cdr()", __FILE__, __LINE__);
+        throw std::runtime_error("list too short");
       if (obj->type != LISP_TYPE_CONS && obj->type != LISP_TYPE_PATTERN_CONS)
-        throw LispReaderException("lisp_list_nth_cdr()", __FILE__, __LINE__);
+        throw std::runtime_error("expected cons");
 
       --index;
       obj = obj->v.cons.cdr;
@@ -936,18 +942,18 @@ lisp_list_nth_cdr (lisp_object_t *obj, int index)
 }
 
 lisp_object_t*
-lisp_list_nth (lisp_object_t *obj, int index)
+SuperTux::lisp_list_nth (lisp_object_t *obj, int index)
 {
   obj = lisp_list_nth_cdr(obj, index);
 
   if (obj == 0)
-    throw LispReaderException("lisp_list_nth()", __FILE__, __LINE__);
+    throw std::runtime_error("list too short");
 
   return obj->v.cons.car;
 }
 
 void
-lisp_dump (lisp_object_t *obj, FILE *out)
+SuperTux::lisp_dump (lisp_object_t *obj, FILE *out)
 {
   if (obj == 0)
     {
@@ -1023,7 +1029,7 @@ lisp_dump (lisp_object_t *obj, FILE *out)
       break;
 
     default :
-      throw LispReaderException("lisp_dump()", __FILE__, __LINE__);
+      throw std::runtime_error("unknown list type");
     }
 }
 
@@ -1047,13 +1053,12 @@ LispReader::load(const std::string& filename, const std::string& toplevellist)
 
   if(obj->type == LISP_TYPE_EOF || obj->type == LISP_TYPE_PARSE_ERROR) {
     lisp_free(obj);
-    throw LispReaderException("LispReader::load", __FILE__, __LINE__);
+    throw std::runtime_error("Error while parsing lispfile");
   }
 
   if(toplevellist != lisp_symbol(lisp_car(obj))) {
     lisp_car(obj);
-    throw LispReaderException("LispReader::load wrong toplevel symbol",
-        __FILE__, __LINE__);
+    throw std::runtime_error("Worng toplevel symbol in lisp file");
   }
   
   LispReader* reader = new LispReader(lisp_cdr(obj));  
@@ -1075,7 +1080,6 @@ LispReader::search_for(const char* name)
       if (!lisp_cons_p(cur) || !lisp_symbol_p (lisp_car(cur)))
         {
           lisp_dump(cur, stdout);
-          //throw ConstruoError (std::string("LispReader: Read error in search_for ") + name);
          printf("LispReader: Read error in search\n");
         }
       else
@@ -1106,6 +1110,20 @@ LispReader::read_int (const char* name, int& i)
 }
 
 bool
+LispReader::read_uint (const char* name, unsigned int& i)
+{
+  lisp_object_t* obj = search_for (name);
+  if(!obj)
+    return false;
+      
+  if (!lisp_integer_p(lisp_car(obj)))
+    return false;
+  
+  i = (unsigned int) lisp_integer(lisp_car(obj));
+  return true;
+}
+
+bool
 LispReader::read_lisp(const char* name, lisp_object_t*& b)
 {
   lisp_object_t* obj = search_for (name);
@@ -1130,7 +1148,7 @@ LispReader::read_float (const char* name, float& f)
     return false;
   
   if (!lisp_real_p(lisp_car(obj)) && !lisp_integer_p(lisp_car(obj)))
-    st_abort("LispReader expected type real at token: ", name);
+    Termination::abort("LispReader expected type real at token: ", name);
   
   f = lisp_real(lisp_car(obj));
   return true;
@@ -1147,7 +1165,7 @@ LispReader::read_string_vector (const char* name, std::vector<std::string>& vec)
   while(!lisp_nil_p(obj))
   {
     if (!lisp_string_p(lisp_car(obj)))
-      st_abort("LispReader expected type string at token: ", name);
+      Termination::abort("LispReader expected type string at token: ", name);
     vec.push_back(lisp_string(lisp_car(obj)));
     obj = lisp_cdr(obj);
   }
@@ -1165,7 +1183,7 @@ LispReader::read_int_vector (const char* name, std::vector<int>& vec)
   while(!lisp_nil_p(obj))
   {
     if (!lisp_integer_p(lisp_car(obj)))
-      st_abort("LispReader expected type integer at token: ", name);
+      Termination::abort("LispReader expected type integer at token: ", name);
     vec.push_back(lisp_integer(lisp_car(obj)));
     obj = lisp_cdr(obj);
   }
@@ -1183,7 +1201,7 @@ LispReader::read_int_vector (const char* name, std::vector<unsigned int>& vec)
   while(!lisp_nil_p(obj))
   {
     if (!lisp_integer_p(lisp_car(obj)))
-      st_abort("LispReader expected type integer at token: ", name);
+      Termination::abort("LispReader expected type integer at token: ", name);
     vec.push_back(lisp_integer(lisp_car(obj)));
     obj = lisp_cdr(obj);
   }
@@ -1251,7 +1269,7 @@ LispReader::read_string (const char* name, std::string& str, bool translatable)
     return false;
 
   if (!lisp_string_p(lisp_car(obj)))
-    st_abort("LispReader expected type string at token: ", name);
+    Termination::abort("LispReader expected type string at token: ", name);
   str = lisp_string(lisp_car(obj));
   return true;
 }
@@ -1264,7 +1282,7 @@ LispReader::read_bool (const char* name, bool& b)
     return false;
   
   if (!lisp_boolean_p(lisp_car(obj)))
-    st_abort("LispReader expected type bool at token: ", name);
+    Termination::abort("LispReader expected type bool at token: ", name);
   b = lisp_boolean(lisp_car(obj));
   return true;
 }
@@ -1275,7 +1293,7 @@ LispReader::get_lisp()
   return lst;
 }
 
-lisp_object_t* lisp_read_from_file(const std::string& filename)
+lisp_object_t* SuperTux::lisp_read_from_file(const std::string& filename)
 {
   FILE* in = fopen(filename.c_str(), "r");
 
@@ -1289,5 +1307,3 @@ lisp_object_t* lisp_read_from_file(const std::string& filename)
 
   return obj;
 }
-
-// EOF //