X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Flispreader.cpp;h=9074633f9886f277bd6d961d3a61e1bbdf2593e3;hb=6074972382238a94397b649650738daf0d869775;hp=8f8bbed913ac133fbe43608ced9722fbbab386a5;hpb=bc731f8cf00de3312dc3ba76e0f5d6c4a4e6ad9d;p=supertux.git diff --git a/src/lispreader.cpp b/src/lispreader.cpp index 8f8bbed91..9074633f9 100644 --- a/src/lispreader.cpp +++ b/src/lispreader.cpp @@ -21,12 +21,14 @@ * Boston, MA 02111-1307, USA. */ +#include +#include #include #include #include #include - -#include +#include "setup.h" +#include "lispreader.h" #define TOKEN_ERROR -1 #define TOKEN_EOF 0 @@ -47,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) @@ -567,7 +569,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 +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; } @@ -1046,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; } @@ -1058,11 +1078,79 @@ 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); + 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* 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 +1237,101 @@ 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(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) +{ + 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()); + } + 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 //