Skip to content

Commit

Permalink
Per #2690, reimplement the vx_config library to read config elements …
Browse files Browse the repository at this point in the history
…into a stringstream stream rather than reading/writing/deleting temp files each time a config file or config string is read.
  • Loading branch information
JohnHalleyGotway committed Sep 28, 2023
1 parent a65edcf commit feea653
Show file tree
Hide file tree
Showing 5 changed files with 112 additions and 91 deletions.
2 changes: 1 addition & 1 deletion src/basic/vx_config/config.tab.cc
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ extern "C" int configwrap();

char * configtext;

FILE * configin;
stringstream configbuf;

int LineNumber = 1;

Expand Down
2 changes: 1 addition & 1 deletion src/basic/vx_config/config.tab.yy
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ extern "C" int configwrap();

char * configtext;

FILE * configin;
stringstream configbuf;

int LineNumber = 1;

Expand Down
171 changes: 93 additions & 78 deletions src/basic/vx_config/config_file.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ using namespace std;

extern int configparse();

extern FILE * configin;
extern stringstream configbuf;

extern int configdebug;

Expand Down Expand Up @@ -298,156 +298,171 @@ return n;
////////////////////////////////////////////////////////////////////////


bool MetConfig::read(const char * name)
bool MetConfig::read(const char * filename)

{

if ( empty(name) ) {
set_buffer_from_file(filename);

mlog << Error << "\nMetConfig::read(const char *) -> "
<< "empty filename!\n\n";

exit ( 1 );
return parse_buffer();

}

DictionaryStack DS(*this);
ConcatString temp_filename = get_tmp_dir();

temp_filename << "/" << "met_config";
temp_filename = make_temp_file_name(temp_filename.c_str(), nullptr);

recursive_envs(name, temp_filename.c_str());

bison_input_filename = temp_filename.c_str();
////////////////////////////////////////////////////////////////////////

dict_stack = &DS;

LineNumber = 1;
bool MetConfig::read_string(const char * config_string)

Column = 1;
{

is_lhs = true;
set_buffer_from_string(config_string);

Filename.add(bison_input_filename);
return parse_buffer();

configdebug = (Debug ? 1 : 0);
}

if ( (configin = met_fopen(bison_input_filename, "r")) == nullptr ) {

mlog << Error << "\nMetConfig::read(const char *) -> "
<< "unable to open input file \"" << bison_input_filename << "\"\n\n";
////////////////////////////////////////////////////////////////////////


void MetConfig::set_buffer_from_file(const char * filename)

{

if ( empty(filename) ) {

mlog << Error << "\nMetConfig::set_buffer_from_file(const char *) -> "
<< "empty filename!\n\n";

exit ( 1 );

}

int parse_status;
// Open input config file

parse_status = configparse();
ifstream configfilein;

if ( configin ) {
met_open(configfilein, filename);

fclose(configin);
configin = (FILE *) nullptr;
if ( ! configfilein ) {

mlog << Error << "\nMetConfig::read(const char *) -> "
<< "unable to open input file \"" << filename << "\"\n\n";

exit ( 1 );

}

if ( parse_status != 0 ) {
// Read contents into buffer

return false;
string line;

}
while ( getline(configfilein, line) ) {

if ( DS.n_elements() != 1 ) {
recursive_envs(line);

mlog << Error << "\nMetConfig::read(const char *) -> "
<< "should be only one dictionary left after parsing! ...("
<< DS.n_elements() << ")\n\n";
configbuf << line << "\n";

DS.dump(cout);
DS.dump_config_format(cout);
}

mlog << Error << "\n"
<< "parse failed!\n\n";
// Close the input file

configfilein.close();

exit ( 1 );
bison_input_filename = filename;

Filename.add(filename);

return;

}

//
// done
//

patch_parents();
////////////////////////////////////////////////////////////////////////

bison_input_filename = (const char *) nullptr;

dict_stack = (DictionaryStack *) nullptr;
void MetConfig::set_buffer_from_string(const char * config_string)

LineNumber = 1;
{

Column = 1;
string line(config_string);

is_lhs = true;
recursive_envs(line);

set_exit_on_warning();
configbuf << line << "\n";

unlink(temp_filename.c_str());
bison_input_filename = "config_string";

return true;
Filename.add("config_string");

return;

}


////////////////////////////////////////////////////////////////////////


bool MetConfig::read_string(const char * s)
bool MetConfig::parse_buffer()

{

if ( empty(s) ) {
DictionaryStack DS(*this);

mlog << Error << "\nMetConfig::read_string(const char *) -> "
<< "empty input string!\n\n";
dict_stack = &DS;

exit ( 1 );
LineNumber = 1;

}
Column = 1;

//
// write temporary config file
// default to the current directory
//
is_lhs = true;

ofstream out;
ConcatString temp_filename = get_tmp_dir();
configdebug = (Debug ? 1 : 0);

temp_filename << "/" << "met_config";
temp_filename = make_temp_file_name(temp_filename.c_str(), nullptr);

out.open(temp_filename.c_str());
int parse_status = configparse();

if ( ! out ) {
if ( parse_status != 0 ) {

return false;

mlog << Error << "\nMetConfig::read_string(const char *) -> "
<< "unable to open temp file \"" << temp_filename << "\".\n"
<< "Set MET_TMP_DIR to specify a temporary directory.\n\n";
}

if ( DS.n_elements() != 1 ) {

mlog << Error << "\nMetConfig::parse_buffer(const char *) -> "
<< "should be only one dictionary left after parsing! ...("
<< DS.n_elements() << ")\n\n";

DS.dump(cout);
DS.dump_config_format(cout);

mlog << Error << "\n"
<< "parse failed!\n\n";

exit ( 1 );

}

out << s << '\n';
//
// done
//

patch_parents();

out.close();
bison_input_filename = (const char *) nullptr;

bool status = read(temp_filename.c_str());
dict_stack = (DictionaryStack *) nullptr;

remove_temp_file(temp_filename);
LineNumber = 1;

return status;
Column = 1;

is_lhs = true;

set_exit_on_warning();

return true;

}

Expand Down
8 changes: 7 additions & 1 deletion src/basic/vx_config/config_file.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ class MetConfig : public Dictionary {

void assign(const MetConfig &);

void set_buffer_from_file(const char *);

void set_buffer_from_string(const char *);

bool parse_buffer();

StringArray Filename;

bool Debug;
Expand Down Expand Up @@ -78,7 +84,7 @@ class MetConfig : public Dictionary {

bool read(const char * filename);

bool read_string(const char *);
bool read_string(const char * config_string);

const DictionaryEntry * lookup(const char * name);

Expand Down
20 changes: 10 additions & 10 deletions src/basic/vx_config/my_config_scanner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ extern int LineNumber;

extern int Column;

extern FILE * configin;
extern stringstream configbuf;

extern char * configtext;

Expand Down Expand Up @@ -732,15 +732,15 @@ n = 0;

while ( n < max_id_length ) {

c = fgetc(configin);
c = configbuf.get();

if ( c == EOF ) break;

if ( c == '\"' ) break;

if ( c == '\\' ) {

c = fgetc(configin);
c = configbuf.get();

if ( c == EOF ) break;

Expand Down Expand Up @@ -848,7 +848,7 @@ while ( 1 ) {

c1 = c2;

c2 = fgetc(configin);
c2 = configbuf.get();

}

Expand All @@ -873,9 +873,9 @@ reading_comment = true;

while ( 1 ) {

if ( feof (configin) ) break;
if ( configbuf.eof() ) break;

c = fgetc(configin);
c = configbuf.get();

if ( (c == eof) || (c == '\n') ) break;

Expand Down Expand Up @@ -999,15 +999,15 @@ if ( reading_env ) {
// not reading env
//

if ( feof(configin) ) return eof;
if ( configbuf.eof() ) return eof;

c = fgetc(configin);
c = configbuf.get();

if ( c == '\n' ) { ++LineNumber; Column = 0; }

if ( c == '$' ) {

cc = fgetc(configin);
cc = configbuf.get();

++Column;

Expand All @@ -1029,7 +1029,7 @@ if ( c == '$' ) {

// SonarQube: to avoid side effect by || operator
while (env_pos < max_id_length) {
if ((c = fgetc(configin)) == R_curly) break;
if ((c = configbuf.get()) == R_curly) break;
env_name[env_pos++] = (char) c;
}

Expand Down

0 comments on commit feea653

Please sign in to comment.