diff --git a/dataobj/tabfile.cc b/dataobj/tabfile.cc
index 828955297..028b24ea5 100644
--- a/dataobj/tabfile.cc
+++ b/dataobj/tabfile.cc
@@ -24,6 +24,7 @@
bool tabfile_t::open(const char *filename)
{
close();
+ sublines.clear();
file = dr_fopen(filename, "r");
current_line_number = 0;
return file != NULL;
@@ -36,6 +37,7 @@ void tabfile_t::close()
fclose(file);
file = NULL;
}
+ sublines.clear();
}
@@ -291,181 +293,279 @@ void tabfileobj_t::unused( const char *exclude_start_chars )
}
+// if-tree for directives
+int tabfile_t::directive(char *dir)
+{
+ const char *STARTSUB = "";
+ const char *ENDSUB = "";
+ const char *MARKER = "";
+ const char *DELSUB = "";
+ if(!strcmp(dir, STARTSUB)){
+ return 1;
+ }
+ if(!strcmp(dir, ENDSUB)){
+ return 2;
+ }
+ if(!strcmp(dir, MARKER)){
+ return 3;
+ }
+ if(!strcmp(dir, DELSUB)){
+ return 4;
+ }
+ return -1;
+}
+
bool tabfile_t::read(tabfileobj_t &objinfo, FILE *fp)
{
bool lines = false;
char line[LINEBUFFER_SIZE];
-
char line_expand[LINEBUFFER_SIZE];
char delim_expand[LINEBUFFER_SIZE];
char buffer[LINEBUFFER_SIZE];
char *param[10];
char *expansion[10];
-
+
+ bool in_sub_block = false;
+ bool line_to_obj = false;
+ const char *DEFAULT = "#";
+ char subname[LINEBUFFER_SIZE];
current_line_number = 0;
-
objinfo.clear();
-
do {
while(read_line(line, sizeof(line)) && *line != '-') {
- char *delim = strchr(line, '=');
-
- if(delim) {
- *delim++ = '\0';
- format_key(line);
- if (line[0] == 0) {
- return false;
+ // This part of the code handles substitution blocks. Lines get stored in the substitution_map, unless it's the end of the block.
+ if(in_sub_block) {
+ if(line[0] == '<') { // lines in substitution blocks cannot start with '<' except for ending the block.
+ if(directive(line)==2){ //End-Substitution
+ in_sub_block=false;
+ }
+ else {
+ dbg->warning( "tabfile_t::read", "Line %d in substitution block ignored. \"%s\"", current_line_number, line);
+ }
}
-
- int parameters = 0;
- int expansions = 0;
- /*
- @line, the whole parameter text (everything before =)
- @delim, the whole value text (everything after =)
- @parameters, number of fields enclosed by square brackets []
- @expansions, number of expansions included in the value (text inside angle brackets <>)
- @param, array containing the text inside each [] field
- @expansion, array containing the text inside each <> field
- */
- if(find_parameter_expansion(line, delim, ¶meters, &expansions, param, expansion) > 0) {
- int parameter_value[10][256];
- int parameter_length[10];
- int parameter_values[10]; // number of possible 'values' inside each [] field | e.g. [0-4]=5 / [n,s,w]=3
- char parameter_name[256][6]; // non-numeric ribis strings for all parameter fields consecutively
- bool parameter_ribi[10]; // true if parameters are ribi strings
-
- int combinations=1;
- int names = 0; // total number of ribi parameters
-
- // analyse and obtain all parameter expansions
- for(int i=0; ipush_back(helper);
+ }
+ }
+ // this part handles directives starting with '<'
+ else if(line[0] == '<') {
+ // since directives can be key-value-pairs, they may need to be seperated
+ char *delim = strchr(line, '=');
+ if(delim) {
+ *delim++ = '\0';
+ format_key(line);
+ }
+ // then, the code depends on the preprocessor command:
+ switch (directive(line)){
+ case 1: //Beginning of a substitution block
+ if(delim) {
+ strcpy(subname, delim);
+ sublines.put(subname, std::vector(0));
+ in_sub_block = true;
+ }
+ else{
+ dbg->warning( "tabfile_t::read", "Line %d ignored. Start of substitution block without name.", current_line_number);
+ }
+ break;
+ case 2: //End of a substitution block -> Warning
+ dbg->warning( "tabfile_t::read", "End of substitution block outside of substitution block in line %d ignored.", current_line_number);
+ break;
+ case 3: //Insertion marker
+ if(delim) {
+ strcpy(subname, delim);
+ line_to_obj = true;
+ }
+ else{
+ dbg->warning( "tabfile_t::read", "Line %d ignored. Insertion of substitution without name.", current_line_number);
+ }
+ break;
+ case 4: //forget substitution block
+ if(delim) {
+ sublines.remove(delim);
+ }
+ else{
+ sublines.clear();
+ }
+ break;
+ default: //Unknown command
+ dbg->warning( "tabfile_t::read", "Unknown command in line %d ignored. \"%s\"", current_line_number, line);
+ }
+ }
+ // if we deal with a regular line, just guide it through
+ else {
+ strcpy(subname, DEFAULT);
+ line_to_obj = true;
+ }
+ if(line_to_obj){
+ for(size_t i=0; i < (strcmp(subname, DEFAULT) ? (sublines.access(subname) ? sublines.access(subname)->size() : 0) : 1); i++) {
+ // Replace line in case we need to.
+ if(strcmp(subname, DEFAULT)){
+ strcpy(line, sublines.access(subname)->at(i));
+ }
+ // from here, it's mostly the old code. Just the lines fed to this code are sometimes substituted.
+ char *delim = strchr(line, '=');
+
+ if(delim) {
+ *delim++ = '\0';
+ format_key(line);
+ if (line[0] == 0) {
+ return false;
}
- parameter_value[i][parameter_values[i]++] = value;
-
- token_ptr = strtok(buffer,"-,");
- while (token_ptr != NULL && parameter_values[i]<256) {
- switch(param[i][token_ptr-buffer-1]) {
- case ',':
- value = atoi(token_ptr);
- if (parameter_ribi[i]) {
- value = parameter_values[i];
- sprintf(parameter_name[ names++ ], "%.*s", (int)strcspn(buffer+name_length+1,","), buffer+name_length+1);
- name_length += strcspn(buffer+name_length+1,",") + 1;
- }
- parameter_value[i][parameter_values[i]++] = value;
- break;
- case '-':
- if (parameter_ribi[i]) {
- value = parameter_values[i];
- sprintf(parameter_name[value], "%.*s", (int)strcspn(buffer+name_length+1,","), buffer+name_length+1);
- name_length += strcspn(buffer+name_length+1,",") + 1;
- parameter_value[i][parameter_values[i]++] = value;
+
+ int parameters = 0;
+ int expansions = 0;
+ /*
+ @line, the whole parameter text (everything before =)
+ @delim, the whole value text (everything after =)
+ @parameters, number of fields enclosed by square brackets []
+ @expansions, number of expansions included in the value (text inside angle brackets <>)
+ @param, array containing the text inside each [] field
+ @expansion, array containing the text inside each <> field
+ */
+ if(find_parameter_expansion(line, delim, ¶meters, &expansions, param, expansion) > 0) {
+ int parameter_value[10][256];
+ int parameter_length[10];
+ int parameter_values[10]; // number of possible 'values' inside each [] field | e.g. [0-4]=5 / [n,s,w]=3
+ char parameter_name[256][6]; // non-numeric ribis strings for all parameter fields consecutively
+ bool parameter_ribi[10]; // true if parameters are ribi strings
+
+ int combinations=1;
+ int names = 0; // total number of ribi parameters
+
+ // analyse and obtain all parameter expansions
+ for(int i=0; i= 256) {
+ dbg->fatal("tabfile_t::read", "Invalid number range %d-%d (Max range %d values) in line %d", start_range, end_range, 256 - parameter_values[i], current_line_number);
+ }
+
+ for(int range=start_range; range= 256) {
- dbg->fatal("tabfile_t::read", "Invalid number range %d-%d (Max range %d values) in line %d", start_range, end_range, 256 - parameter_values[i], current_line_number);
+ // start expansion of the parameter
+ for(int c=0; c0) {
+ // warp values around the number of parameters the expansion has
+ for(int j=0; j0) {
- // warp values around the number of parameters the expansion has
- for(int j=0; j0) {
- int expansion_length[10];
- int expansion_value[10];
+ // expand the value
+ if(expansions>0) {
+ int expansion_length[10];
+ int expansion_value[10];
- for(int i=0; i")-1;
- sprintf(buffer, "%.*s", expansion_length[i]+1, expansion[i]);
+ for(int i=0; i")-1;
+ sprintf(buffer, "%.*s", expansion_length[i]+1, expansion[i]);
- expansion_value[i] = calculate(buffer, parameter_value, parameters, combination);
- }
+ expansion_value[i] = calculate(buffer, parameter_value, parameters, combination);
+ }
+
+ sprintf(delim_expand, "%.*s%d", (int)(expansion[0]-delim), delim, expansion_value[0]);
+ for(int i=1; iwarning( "tabfile_t::read", "No data in \"%s\"", line );
}
}
- lines = true;
- }
- else if( *line ) {
- dbg->warning( "tabfile_t::read", "No data in \"%s\"", line );
+ line_to_obj=false;
}
}
} while(!lines && !feof(file)); // skip empty objects
diff --git a/dataobj/tabfile.h b/dataobj/tabfile.h
index 83239a566..c1a81a26c 100644
--- a/dataobj/tabfile.h
+++ b/dataobj/tabfile.h
@@ -8,6 +8,7 @@
#include
+#include
#include "../simcolor.h"
#include "../tpl/stringhashtable_tpl.h"
@@ -47,7 +48,7 @@ class tabfile_t
public:
tabfile_t() : file(NULL) {}
~tabfile_t() { close(); }
-
+ stringhashtable_tpl> sublines;
public:
bool open(const char *filename);
@@ -98,6 +99,11 @@ private:
* Format the key string (trimright and lowercase)
*/
void format_key(char *key);
+
+ /**
+ * Turns directives into integer values.
+ */
+ int directive(char *dir);
private:
FILE *file;