X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Flispreader.cpp;h=9074633f9886f277bd6d961d3a61e1bbdf2593e3;hb=6074972382238a94397b649650738daf0d869775;hp=add98b2c630b946bc1663acbec14009e4752204d;hpb=3181262386659262786395df341544a24c667caf;p=supertux.git diff --git a/src/lispreader.cpp b/src/lispreader.cpp index add98b2c6..9074633f9 100644 --- a/src/lispreader.cpp +++ b/src/lispreader.cpp @@ -21,12 +21,13 @@ * Boston, MA 02111-1307, USA. */ +#include #include #include #include #include #include - +#include "setup.h" #include "lispreader.h" #define TOKEN_ERROR -1 @@ -48,10 +49,10 @@ 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) @@ -1041,6 +1042,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; } @@ -1048,11 +1051,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; } @@ -1060,6 +1078,24 @@ LispReader::read_float (const char* name, float* f) } bool +LispReader::read_string_vector (const char* name, std::vector* 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* vec) { lisp_object_t* obj = search_for (name); @@ -1067,6 +1103,8 @@ LispReader::read_int_vector (const char* name, std::vector* vec) { 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); } @@ -1097,7 +1135,8 @@ 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; } @@ -1110,6 +1149,8 @@ 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; } @@ -1196,6 +1237,7 @@ LispWriter::create_lisp () return lisp_obj; } +#if 0 void mygzungetc(char c, void* file) { gzungetc(c, file); @@ -1205,6 +1247,51 @@ 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(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(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) { @@ -1223,28 +1310,18 @@ bool has_suffix(const char* data, const char* suffix) } } -lisp_object_t* lisp_read_from_file(const char* filename) +lisp_object_t* lisp_read_from_file(const std::string& filename) { lisp_stream_t stream; - if (has_suffix(filename, ".gz")) + if (has_suffix(filename.c_str(), ".gz")) { - 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; + return lisp_read_from_gzfile(filename.c_str()); } else { lisp_object_t* obj = 0; - FILE* in = fopen(filename, "r"); + FILE* in = fopen(filename.c_str(), "r"); if (in) {