Skip to content
Snippets Groups Projects
Commit 3bf2eb72 authored by Frank Winklmeier's avatar Frank Winklmeier
Browse files

JobOptionSvc: use stringstream to read job options file

The current method of reading the input file leads to undefined behavior
errors in the ATLAS debug build. Use `std::stringstream` instead, which
is also supposedly faster.

Also rewrite `GetLastLineAndColumn` to not read the file twice.
parent a8e9986c
No related branches found
No related tags found
1 merge request!1509JobOptionSvc: use stringstream to read job options file
/***********************************************************************************\ /***********************************************************************************\
* (c) Copyright 1998-2020 CERN for the benefit of the LHCb and ATLAS collaborations * * (c) Copyright 1998-2023 CERN for the benefit of the LHCb and ATLAS collaborations *
* * * *
* This software is distributed under the terms of the Apache version 2 licence, * * This software is distributed under the terms of the Apache version 2 licence, *
* copied verbatim in the file "LICENSE". * * copied verbatim in the file "LICENSE". *
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <fmt/format.h> #include <fmt/format.h>
#include <fstream> #include <fstream>
#include <sstream>
// ============================================================================ // ============================================================================
namespace classic = boost::spirit::classic; namespace classic = boost::spirit::classic;
...@@ -28,28 +29,23 @@ namespace gpu = Gaudi::Parsers::Utils; ...@@ -28,28 +29,23 @@ namespace gpu = Gaudi::Parsers::Utils;
namespace qi = boost::spirit::qi; namespace qi = boost::spirit::qi;
// ============================================================================ // ============================================================================
namespace { namespace {
// ============================================================================
void GetLastLineAndColumn( std::ifstream& ifs, int& line, int& column ) { // Return last line and column number of text in `s` with newline delimiter `delim`
int n = 0; std::pair<int, int> GetLastLineAndColumn( std::string_view s, const char delim = '\n' ) {
std::string str; size_t line = 1;
while ( !ifs.eof() ) { for ( size_t p = s.find( delim ); p != s.npos; p = s.find( delim ) ) {
getline( ifs, str ); s.remove_prefix( p + 1 );
++n; ++line;
} }
line = n; return { line, s.size() + 1 };
column = str.length() + 1;
ifs.clear();
ifs.seekg( 0, ifs.beg );
} }
template <typename Grammar> template <typename Grammar>
bool ParseStream( std::ifstream& stream, const std::string& stream_name, gp::Messages* messages, gp::Node* root ) { bool ParseStream( std::ifstream& stream, const std::string& stream_name, gp::Messages* messages, gp::Node* root ) {
// Load input stream
const std::string input = ( std::ostringstream{} << stream.rdbuf() ).str();
int last_line, last_column; auto [last_line, last_column] = GetLastLineAndColumn( input );
GetLastLineAndColumn( stream, last_line, last_column );
std::string input( ( std::istreambuf_iterator<char>( stream ) ), std::istreambuf_iterator<char>() );
BaseIterator in_begin( input.begin() ); BaseIterator in_begin( input.begin() );
// convert input iterator to forward iterator, usable by spirit parser // convert input iterator to forward iterator, usable by spirit parser
...@@ -57,7 +53,6 @@ namespace { ...@@ -57,7 +53,6 @@ namespace {
ForwardIterator fwd_end; ForwardIterator fwd_end;
// wrap forward iterator with position iterator, to record the position // wrap forward iterator with position iterator, to record the position
Iterator position_begin( fwd_begin, fwd_end, stream_name ); Iterator position_begin( fwd_begin, fwd_end, stream_name );
Iterator position_end; Iterator position_end;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment