void Skeleton::emit_prolog (OutputFile & o)
{
o << "\n" << "#include <stdio.h>";
- o << "\n" << "#include <stdlib.h> // malloc, free";
- o << "\n" << "#include <string.h> // memset";
+ o << "\n" << "#include <stdlib.h> /* malloc, free */";
o << "\n";
- o << "\n" << "static size_t filesize (FILE * f)";
+ o << "\n" << "static void * read_file";
+ o << "\n" << indString << "( const char * fname";
+ o << "\n" << indString << ", size_t unit";
+ o << "\n" << indString << ", size_t padding";
+ o << "\n" << indString << ", size_t * pfsize";
+ o << "\n" << indString << ")";
o << "\n" << "{";
- o << "\n" << indString << "const long pos = ftell (f);";
+ o << "\n" << indString << "void * buffer = NULL;";
+ o << "\n" << indString << "size_t fsize = 0;";
+ o << "\n";
+ o << "\n" << indString << "/* open file */";
+ o << "\n" << indString << "FILE * f = fopen (fname, \"rb\");";
+ o << "\n" << indString << "if (f == NULL)";
+ o << "\n" << indString << "{";
+ o << "\n" << indString << indString << "goto error;";
+ o << "\n" << indString << "}";
+ o << "\n";
+ o << "\n" << indString << "/* get file size */";
o << "\n" << indString << "fseek (f, 0, SEEK_END);";
- o << "\n" << indString << "const long size = ftell (f);";
- o << "\n" << indString << "fseek (f, pos, SEEK_SET);";
- o << "\n" << indString << "return (size_t) size;";
+ o << "\n" << indString << "fsize = (size_t) ftell (f) / unit;";
+ o << "\n" << indString << "fseek (f, 0, SEEK_SET);";
+ o << "\n";
+ o << "\n" << indString << "/* allocate memory for file and padding */";
+ o << "\n" << indString << "buffer = malloc (unit * (fsize + padding));";
+ o << "\n" << indString << "if (buffer == NULL)";
+ o << "\n" << indString << "{";
+ o << "\n" << indString << indString << "goto error;";
+ o << "\n" << indString << "}";
+ o << "\n";
+ o << "\n" << indString << "/* read the whole file in memory */";
+ o << "\n" << indString << "if (fread (buffer, unit, fsize, f) != fsize)";
+ o << "\n" << indString << "{";
+ o << "\n" << indString << indString << "goto error;";
+ o << "\n" << indString << "}";
+ o << "\n";
+ o << "\n" << indString << "fclose (f);";
+ o << "\n" << indString << "*pfsize = fsize;";
+ o << "\n" << indString << "return buffer;";
+ o << "\n";
+ o << "\n" << "error:";
+ o << "\n" << indString << "fprintf (stderr, \"error: cannot read file '%s'\\n\", fname);";
+ o << "\n" << indString << "free (buffer);";
+ o << "\n" << indString << "if (f != NULL)";
+ o << "\n" << indString << "{";
+ o << "\n" << indString << indString << "fclose (f);";
+ o << "\n" << indString << "}";
+ o << "\n" << indString << "return NULL;";
o << "\n" << "}";
o << "\n";
}
o << "\n";
o << "\n" << "int lex_" << name << " ()";
o << "\n" << "{";
- o << "\n" << indString << "const char * finput_name = \"" << o.file_name << "." << name << ".input\";";
- o << "\n" << indString << "FILE * finput = fopen (finput_name, \"rb\");";
- o << "\n" << indString << "if (!finput)";
- o << "\n" << indString << "{";
- o << "\n" << indString << indString << "fprintf (stderr, \"cannot open file '%s'\\n\", finput_name);";
- o << "\n" << indString << indString << "return 1;";
- o << "\n" << indString << "}";
- o << "\n" << indString << "const size_t input_len = filesize (finput) / sizeof (YYCTYPE);";
- o << "\n" << indString << "const size_t padding = " << maxfill << "; // YYMAXFILL";
- o << "\n" << indString << "YYCTYPE * input = (YYCTYPE *) malloc ((input_len + padding) * sizeof (YYCTYPE));";
- o << "\n" << indString << "if (fread (input, sizeof (YYCTYPE), input_len, finput) != input_len)";
- o << "\n" << indString << "{";
- o << "\n" << indString << indString << "fprintf (stderr, \"cannot read file '%s'\\n\", finput_name);";
- o << "\n" << indString << indString << "return 1;";
- o << "\n" << indString << "}";
- o << "\n" << indString << "fclose (finput);";
- o << "\n" << indString << "memset (input + input_len, 0, padding * sizeof (YYCTYPE));";
+ o << "\n" << indString << "const size_t padding = " << maxfill << "; /* YYMAXFILL */";
+ o << "\n" << indString << "int status = 0;";
+ o << "\n" << indString << "size_t input_len = 0;";
+ o << "\n" << indString << "size_t keys_count = 0;";
+ o << "\n" << indString << "YYCTYPE * input = NULL;";
+ o << "\n" << indString << "YYKEYTYPE * keys = NULL;";
+ o << "\n" << indString << "const YYCTYPE * cursor = NULL;";
+ o << "\n" << indString << "const YYCTYPE * marker = NULL;";
+ o << "\n" << indString << "const YYCTYPE * ctxmarker = NULL;";
+ o << "\n" << indString << "const YYCTYPE * limit = NULL;";
+ o << "\n" << indString << "const YYCTYPE * eof = NULL;";
+ o << "\n" << indString << "unsigned int i = 0;";
o << "\n";
- o << "\n" << indString << "const char * fkeys_name = \"" << o.file_name << "." << name << ".keys\";";
- o << "\n" << indString << "FILE * fkeys = fopen (fkeys_name, \"rb\");";
- o << "\n" << indString << "if (!fkeys)";
+ o << "\n" << indString << "input = (YYCTYPE *) read_file";
+ o << "\n" << indString << indString << "(\"" << o.file_name << "." << name << ".input\"";
+ o << "\n" << indString << indString << ", sizeof (YYCTYPE)";
+ o << "\n" << indString << indString << ", padding";
+ o << "\n" << indString << indString << ", &input_len";
+ o << "\n" << indString << indString << ");";
+ o << "\n" << indString << "if (input == NULL)";
o << "\n" << indString << "{";
- o << "\n" << indString << indString << "fprintf (stderr, \"cannot open file '%s'\\n\", fkeys_name);";
- o << "\n" << indString << indString << "return 1;";
+ o << "\n" << indString << indString << "status = 1;";
+ o << "\n" << indString << indString << "goto end;";
o << "\n" << indString << "}";
- o << "\n" << indString << "const size_t keys_size = filesize (fkeys);";
- o << "\n" << indString << "YYKEYTYPE * keys = (YYKEYTYPE *) malloc (keys_size);";
- o << "\n" << indString << "if (fread (keys, 1, keys_size, fkeys) != keys_size)";
+ o << "\n";
+ o << "\n" << indString << "keys = (YYKEYTYPE *) read_file";
+ o << "\n" << indString << indString << "(\"" << o.file_name << "." << name << ".keys\"";
+ o << "\n" << indString << indString << ", 3 * sizeof (YYKEYTYPE)";
+ o << "\n" << indString << indString << ", 0";
+ o << "\n" << indString << indString << ", &keys_count";
+ o << "\n" << indString << indString << ");";
+ o << "\n" << indString << "if (keys == NULL)";
o << "\n" << indString << "{";
- o << "\n" << indString << indString << "fprintf (stderr, \"cannot read file '%s'\\n\", fkeys_name);";
- o << "\n" << indString << indString << "return 1;";
+ o << "\n" << indString << indString << "status = 1;";
+ o << "\n" << indString << indString << "goto end;";
o << "\n" << indString << "}";
- o << "\n" << indString << "fclose (fkeys);";
- o << "\n" << indString << "const size_t keys_count = keys_size / (3 * sizeof (YYKEYTYPE));";
o << "\n";
- o << "\n" << indString << "const YYCTYPE * cursor = input;";
- o << "\n" << indString << "const YYCTYPE * marker = input;";
- o << "\n" << indString << "const YYCTYPE * ctxmarker = input;";
- o << "\n" << indString << "const YYCTYPE * const limit = input + input_len + padding;";
- o << "\n" << indString << "const YYCTYPE * const eof = input + input_len;";
+ o << "\n" << indString << "cursor = input;";
+ o << "\n" << indString << "marker = input;";
+ o << "\n" << indString << "ctxmarker = input;";
+ o << "\n" << indString << "limit = input + input_len + padding;";
+ o << "\n" << indString << "eof = input + input_len;";
o << "\n";
- o << "\n" << indString << "int status = 0;";
- o << "\n" << indString << "unsigned int i;";
o << "\n" << indString << "for (i = 0; status == 0 && cursor < eof && i < keys_count; ++i)";
o << "\n" << indString << "{";
o << "\n" << indString << indString << "const YYCTYPE * token = cursor;";
o << "\n" << indString << indString << indString << "fprintf (stderr, \"error: " << incond (cond) << "unused keys left\\n\");";
o << "\n" << indString << indString << "}";
o << "\n" << indString << "}";
+ o << "\n";
+ o << "\n" << "end:";
o << "\n" << indString << "free (input);";
o << "\n" << indString << "free (keys);";
o << "\n";