From 2cf8f3baec88ba30d84baca331bcdd685c399488 Mon Sep 17 00:00:00 2001 From: gereon Date: Wed, 21 Nov 2012 20:32:15 +0100 Subject: [PATCH] more work on refactoring / rewriting parsers --- src/parser/readLabFile.cpp | 123 ++++++++++++ src/parser/readLabFile.h | 19 ++ .../{read_tra_file.cpp => readTraFile.cpp} | 107 ++++++----- src/parser/readTraFile.h | 19 ++ src/parser/read_lab_file.cpp | 181 ------------------ src/parser/read_lab_file.h | 24 --- src/parser/read_tra_file.h | 20 -- 7 files changed, 220 insertions(+), 273 deletions(-) create mode 100644 src/parser/readLabFile.cpp create mode 100644 src/parser/readLabFile.h rename src/parser/{read_tra_file.cpp => readTraFile.cpp} (70%) create mode 100644 src/parser/readTraFile.h delete mode 100644 src/parser/read_lab_file.cpp delete mode 100644 src/parser/read_lab_file.h delete mode 100644 src/parser/read_tra_file.h diff --git a/src/parser/readLabFile.cpp b/src/parser/readLabFile.cpp new file mode 100644 index 000000000..c09fd2db5 --- /dev/null +++ b/src/parser/readLabFile.cpp @@ -0,0 +1,123 @@ +/* + * readLabFile.cpp + * + * Created on: 21.11.2012 + * Author: Gereon Kremer + */ + +#include "parser.h" + +#include "readLabFile.h" + +#include "src/exceptions/wrong_file_format.h" +#include "src/exceptions/file_IO_exception.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace mrmc { + +namespace parser { + + +/*! + * Reads a .lab file and puts the result in a labeling structure. + * + * Labelings created with this method have to be freed with the delete operator. + * @param node_count the number of states. + * @param filename input .lab file's name. + * @return The pointer to the created labeling object. + */ +mrmc::models::AtomicPropositionsLabeling * readLabFile(int node_count, const char * filename) +{ + /*! + * open file and map to memory + */ + struct stat st; + int f = open(filename, O_RDONLY); + if ((f < 0) || (stat(filename, &st) != 0)) { + /*! + * + */ + pantheios::log_ERROR("File could not be opened."); + throw mrmc::exceptions::file_IO_exception(); + return NULL; + } + + char* data = (char*) mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, f, 0); + if (data == (char*)-1) + { + pantheios::log_ERROR("File could not be mapped. Something went wrong with mmap."); + close(f); + throw mrmc::exceptions::file_IO_exception(); + return NULL; + } + + char* buf = data; + char sep[] = " \n\t"; + uint_fast32_t proposition_count = 0; + size_t cnt = 0; + + do { + buf += cnt; + cnt = strcspn(buf, sep); + if (cnt > 0) { + if (strncmp(buf, "#DECLARATION", cnt) == 0) continue; + if (strncmp(buf, "#END", cnt) == 0) break; + proposition_count++; + } + else cnt = 1; + } while (cnt > 0); + + mrmc::models::AtomicPropositionsLabeling* result = new mrmc::models::AtomicPropositionsLabeling(node_count, proposition_count); + char proposition[128]; + buf = data; + cnt = 0; + do { + buf += cnt; + cnt = strcspn(buf, sep); + if (cnt > 0) { + if (strncmp(buf, "#DECLARATION", cnt) == 0) continue; + if (strncmp(buf, "#END", cnt) == 0) break; + strncpy(proposition, buf, cnt); + proposition[cnt] = '\0'; + result->addAtomicProposition(proposition); + } + else cnt = 1; + } while (cnt > 0); + buf += 4; + + uint_fast32_t node; + while (1) { + node = strtol(buf, &buf, 10); + while (*buf != '\0') { + cnt = strcspn(buf, sep); + if (cnt == 0) buf++; + else break; + } + strncpy(proposition, buf, cnt); + proposition[cnt] = '\0'; + result->addAtomicPropositionToState(proposition, node); + buf += cnt; + } + + munmap(data, st.st_size); + close(f); + return result; +} + +} //namespace parser + +} //namespace mrmc diff --git a/src/parser/readLabFile.h b/src/parser/readLabFile.h new file mode 100644 index 000000000..4019864e0 --- /dev/null +++ b/src/parser/readLabFile.h @@ -0,0 +1,19 @@ +/* + * read_lab_file.h + * + */ + +#pragma once + +#include "src/models/atomic_propositions_labeling.h" + + +namespace mrmc { + +namespace parser { + +mrmc::models::AtomicPropositionsLabeling * readLabFile(int node_count, const char * filename); + +} + +} diff --git a/src/parser/read_tra_file.cpp b/src/parser/readTraFile.cpp similarity index 70% rename from src/parser/read_tra_file.cpp rename to src/parser/readTraFile.cpp index 842f1a697..af5350693 100644 --- a/src/parser/read_tra_file.cpp +++ b/src/parser/readTraFile.cpp @@ -3,15 +3,13 @@ * system of a Markov chain (DTMC) and saving it into a corresponding * matrix. * - * Reuses code from the file "read_tra_file.c" from the old MRMC project. - * * Created on: 20.11.2012 * Author: Gereon Kremer */ #include "parser.h" -#include "src/parser/read_tra_file.h" +#include "src/parser/readTraFile.h" #include "src/exceptions/file_IO_exception.h" #include "src/exceptions/wrong_file_format.h" #include "boost/integer/integer_mask.hpp" @@ -44,26 +42,23 @@ char* skipWS(char* buf) } } -// Disable C4996 - This function or variable may be unsafe. -#pragma warning(disable:4996) - /*! -* This method does the first pass through the .tra file and computes -* the number of non-zero elements that are not diagonal elements, -* which correspondents to the number of transitions that are not -* self-loops. -* (Diagonal elements are treated in a special way). -* -* @return The number of non-zero elements that are not on the diagonal -* @param buf Data to scan. Is expected to be some char array. -*/ -static uint_fast32_t make_first_pass(char* buf) + * This method does the first pass through the .tra file and computes + * the number of non-zero elements that are not diagonal elements, + * which correspondents to the number of transitions that are not + * self-loops. + * (Diagonal elements are treated in a special way). + * + * @return The number of non-zero elements that are not on the diagonal + * @param buf Data to scan. Is expected to be some char array. + */ +static uint_fast32_t makeFirstPass(char* buf) { uint_fast32_t non_zero = 0; - /* - check file header and extract number of transitions - */ + /*! + * check file header and extract number of transitions + */ if (strncmp(buf, "STATES ", 7) != 0) return 0; buf += 7; // skip "STATES " if (strtol(buf, &buf, 10) == 0) return 0; @@ -72,9 +67,9 @@ static uint_fast32_t make_first_pass(char* buf) buf += 12; // skip "TRANSITIONS " if ((non_zero = strtol(buf, &buf, 10)) == 0) return 0; - /* - check all transitions for non-zero diagonal entrys - */ + /*! + * check all transitions for non-zero diagonal entrys + */ unsigned int row, col; double val; while (1) @@ -98,17 +93,21 @@ static uint_fast32_t make_first_pass(char* buf) * @return a pointer to the created sparse matrix. */ -sparse::StaticSparseMatrix * read_tra_file(const char * filename) { - if (setlocale( LC_NUMERIC, "de_DE" ) == 0) - { - fprintf(stderr, "could not set locale\n"); - } - /* - open file and map to memory +sparse::StaticSparseMatrix * readTraFile(const char * filename) { + /*! + * enforce locale where decimal point is '.' */ + setlocale( LC_NUMERIC, "C" ); + + /*! + * open file and map to memory + */ struct stat st; int f = open(filename, O_RDONLY); if((f < 0) || (stat(filename, &st) != 0)) { + /*! + * stat() or open() failed + */ pantheios::log_ERROR("File ", filename, " was not readable (Does it exist?)"); throw exceptions::file_IO_exception("mrmc::read_tra_file: Error opening file! (Does it exist?)"); return NULL; @@ -116,36 +115,42 @@ sparse::StaticSparseMatrix * read_tra_file(const char * filename) { char *data = (char*)mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE|MAP_DENYWRITE, f, 0); if (data == (char*)-1) { + /*! + * mmap() failed + */ pantheios::log_ERROR("Could not map the file to memory. Something went wrong with mmap."); throw exceptions::file_IO_exception("mrmc::read_tra_file: Error mapping file to memory"); close(f); return NULL; } - /* - perform first pass - */ - uint_fast32_t non_zero = make_first_pass(data); + /*! + * perform first pass, i.e. count entries that are not zero and not on the diagonal + */ + uint_fast32_t non_zero = makeFirstPass(data); if (non_zero == 0) { + /*! + * first pass returned zero, this means the file format was wrong + */ close(f); munmap(data, st.st_size); throw mrmc::exceptions::wrong_file_format(); return NULL; } - /* - perform second pass - - from here on, we already know that the file header is correct - */ + /*! + * perform second pass + * + * from here on, we already know that the file header is correct + */ char* buf = data; uint_fast32_t rows; sparse::StaticSparseMatrix *sp = NULL; - /* - read file header, extract number of states - */ + /*! + * read file header, extract number of states + */ buf += 7; // skip "STATES " rows = strtol(buf, &buf, 10); buf = skipWS(buf); @@ -156,13 +161,17 @@ sparse::StaticSparseMatrix * read_tra_file(const char * filename) { pantheios::integer(rows), " rows and ", pantheios::integer(non_zero), " Non-Zero-Elements"); - /* Creating matrix - * Memory for diagonal elements is automatically allocated, hence only the number of non-diagonal - * non-zero elements has to be specified (which is non_zero, computed by make_first_pass) + /*! + * Creating matrix + * Memory for diagonal elements is automatically allocated, hence only the number of non-diagonal + * non-zero elements has to be specified (which is non_zero, computed by make_first_pass) */ sp = new sparse::StaticSparseMatrix(rows); if (sp == NULL) { + /*! + * creating the matrix failed + */ close(f); munmap(data, st.st_size); throw std::bad_alloc(); @@ -172,9 +181,9 @@ sparse::StaticSparseMatrix * read_tra_file(const char * filename) { uint_fast64_t row, col; double val; - /* - read all transitions from file - */ + /*! + * read all transitions from file + */ while (1) { row = strtol(buf, &buf, 10); @@ -189,7 +198,9 @@ sparse::StaticSparseMatrix * read_tra_file(const char * filename) { sp->addNextValue(row,col,val); } - // clean up + /*! + * clean up + */ close(f); munmap(data, st.st_size); diff --git a/src/parser/readTraFile.h b/src/parser/readTraFile.h new file mode 100644 index 000000000..c4b025a64 --- /dev/null +++ b/src/parser/readTraFile.h @@ -0,0 +1,19 @@ +/* + * read_tra_file.h + * + * Created on: 15.08.2012 + * Author: Thomas Heinemann + */ + +#pragma once + +#include "src/sparse/static_sparse_matrix.h" + +namespace mrmc { + namespace parser { + + mrmc::sparse::StaticSparseMatrix * readTraFile(const char * filename); + + } +} + diff --git a/src/parser/read_lab_file.cpp b/src/parser/read_lab_file.cpp deleted file mode 100644 index 2a3742afe..000000000 --- a/src/parser/read_lab_file.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* - * read_lab_file.cpp - * - * Created on: 10.09.2012 - * Author: Thomas Heinemann - */ - -#include "parser.h" - -#include "read_lab_file.h" - -#include "src/exceptions/wrong_file_format.h" -#include "src/exceptions/file_IO_exception.h" - -#include -#include -#include - -#include -#include - -#ifdef WIN32 -# define STRTOK_FUNC strtok_s -#else -# define STRTOK_FUNC strtok_r -#endif - -// Disable C4996 - This function or variable may be unsafe. -#pragma warning(disable:4996) - - -namespace mrmc { - -namespace parser { - - -/*! - * Reads a .lab file and puts the result in a labeling structure. - * - * Labelings created with this method have to be freed with the delete operator. - * @param node_count the number of states. - * @param filename input .lab file's name. - * @return The pointer to the created labeling object. - */ -mrmc::models::AtomicPropositionsLabeling * read_lab_file(int node_count, const char * filename) -{ - /* Note that this function uses strtok_r on char-array s. - * This function will modify this string. - * However, as only the result of its tokenization is used, this is not a problem. - * - * Thread-safety is ensured by using strtok_r instead of strtok. - */ - FILE *P; - - //TODO (Thomas Heinemann): handle files with lines that are longer than BUFFER_SIZE - //TODO (Thomas Heinemann): Throw errors if fgets return NULL in the declaration. (fixed by Philipp. Or?) - - char s[BUFFER_SIZE]; //String buffer - char *saveptr = NULL; //Buffer for strtok_r - char sep[] = " \n\t"; //Separators for the tokens - - P = fopen(filename, "r"); - - if (P == NULL) { - pantheios::log_ERROR("File could not be opened."); - throw mrmc::exceptions::file_IO_exception(); - return NULL; - } - - if (!fgets(s, BUFFER_SIZE, P) || strcmp(s, "#DECLARATION\n")) { - fclose(P); - pantheios::log_ERROR("Wrong declaration section (\"#DECLARATION\" missing)."); - throw mrmc::exceptions::wrong_file_format(); - return NULL; - } - - - - uint_fast32_t buffer_size_count = 1; - uint_fast32_t buffer_start = 0; - char* decl_buffer = new char[buffer_size_count*BUFFER_SIZE]; - bool need_next_iteration = true; - - do { - decl_buffer[buffer_size_count*BUFFER_SIZE - 1] = '\xff'; - if (fgets(decl_buffer + buffer_start, buffer_size_count*BUFFER_SIZE - buffer_start, P)) { - if ((decl_buffer[buffer_size_count*BUFFER_SIZE - 1] != '\xff') && - (decl_buffer[buffer_size_count*BUFFER_SIZE - 2] != '\n')) { - //fgets changed the last bit -> read string has maximum length - //AND line is longer than size of decl_buffer - char* temp_buffer = decl_buffer; - decl_buffer = NULL; - - buffer_size_count++; - decl_buffer = new char[buffer_size_count*BUFFER_SIZE]; - - buffer_start = (buffer_size_count - 1) * BUFFER_SIZE; - - memcpy(decl_buffer, temp_buffer, buffer_start - 1); - delete[] temp_buffer; - } else { - need_next_iteration = false; - } - } else { - pantheios::log_ERROR("EOF in the declaration section"); - throw mrmc::exceptions::wrong_file_format(); - delete[] decl_buffer; - return NULL; - } - } while (need_next_iteration); - - uint_fast32_t proposition_count = 0; - char * proposition; - int pos = 0; - - if (decl_buffer[pos] != ' ' && decl_buffer[pos] != '\t' && decl_buffer[pos] != '\0') { - proposition_count++; - } - - while (decl_buffer[pos] != '\0') { - if ((decl_buffer[pos] == ' ' || decl_buffer[pos] == '\t') && - (decl_buffer[pos + 1] != ' ' && decl_buffer[pos + 1] != '\t' && decl_buffer[pos + 1] != '\0')) { - proposition_count++; - } - pos++; - } - - mrmc::models::AtomicPropositionsLabeling* result = new mrmc::models::AtomicPropositionsLabeling(node_count, proposition_count); - - //Here, all propositions are to be declared... - for (proposition = STRTOK_FUNC(decl_buffer, sep, &saveptr); - proposition != NULL; - proposition = STRTOK_FUNC(NULL, sep, &saveptr)) { - result -> addAtomicProposition(proposition); - } - - // Free decl_buffer - delete[] decl_buffer; - - - saveptr = NULL; //resetting save pointer for strtok_r - - if (!fgets(s, BUFFER_SIZE, P) || strcmp(s, "#END\n")) { - fclose(P); - delete result; - pantheios::log_ERROR("Wrong declaration section (\"#END\" missing)."); - throw mrmc::exceptions::wrong_file_format(); - return NULL; - } - - while (fgets(s, BUFFER_SIZE, P)) { - char * token = NULL; - uint_fast32_t node = 0; - /* First token has to be a number identifying the node, - * hence it is treated differently from the other tokens. - */ - token = STRTOK_FUNC(s, sep, &saveptr); - if (sscanf(token, "%u", &node) == 0) { - fclose(P); - delete result; - pantheios::log_ERROR("Line assigning propositions does not start with a node number."); - throw mrmc::exceptions::wrong_file_format(); - return NULL; - } - do { - token = STRTOK_FUNC(NULL, sep, &saveptr); - if (token == NULL) { - break; - } - result->addAtomicPropositionToState(token, node); - } while (token != NULL); - - } - - fclose(P); - return result; -} - -} //namespace parser - -} //namespace mrmc diff --git a/src/parser/read_lab_file.h b/src/parser/read_lab_file.h deleted file mode 100644 index ddbb7f82a..000000000 --- a/src/parser/read_lab_file.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * read_lab_file.h - * - * Created on: 10.09.2012 - * Author: thomas - */ - -#ifndef READ_LAB_FILE_H_ -#define READ_LAB_FILE_H_ - -#include "src/models/atomic_propositions_labeling.h" - - -namespace mrmc { - -namespace parser { - -mrmc::models::AtomicPropositionsLabeling * read_lab_file(int node_count, const char * filename); - -} - -} - -#endif /* READ_LAB_FILE_H_ */ diff --git a/src/parser/read_tra_file.h b/src/parser/read_tra_file.h deleted file mode 100644 index 20886d2f6..000000000 --- a/src/parser/read_tra_file.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * read_tra_file.h - * - * Created on: 15.08.2012 - * Author: Thomas Heinemann - */ - -#ifndef READ_TRA_FILE_H_ -#define READ_TRA_FILE_H_ -#include "src/sparse/static_sparse_matrix.h" -namespace mrmc{ -namespace parser { - -mrmc::sparse::StaticSparseMatrix * read_tra_file(const char * filename); - -} -} - - -#endif /* READ_TRA_FILE_H_ */