Skip to content

Commit

Permalink
Merge pull request #10148 from NREL/9825_CLI_2
Browse files Browse the repository at this point in the history
#9825 - Handle non ASCII command line parameters such as path
  • Loading branch information
Myoldmopar authored Aug 24, 2023
2 parents bf2e96d + fdc89ba commit c854ba6
Show file tree
Hide file tree
Showing 18 changed files with 11,246 additions and 2,731 deletions.
1 change: 1 addition & 0 deletions cmake/CompilerFlags.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ if(MSVC AND NOT ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")) # Visual C++ (VS
target_compile_options(project_options INTERFACE /EHsc)
target_compile_options(project_options INTERFACE /MP) # Enables multi-processor compilation of source within a single project
target_compile_options(project_options INTERFACE /Zc:externConstexpr) # allows constexpr to be extern'd in headers, which is part of the standard, and supported by default on non-vs compilers
target_compile_options(project_options INTERFACE /utf-8) # Specifies both the source character set and the execution character set as UTF-8

# string(REGEX REPLACE "/W3" "/W1" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}"
# )# Increase to /W2 then /W3 as more serious warnings are addressed (using regex to avoid VC override warnings)
Expand Down
342 changes: 142 additions & 200 deletions src/ConvertInputFormat/main.cpp

Large diffs are not rendered by default.

40 changes: 40 additions & 0 deletions src/EnergyPlus/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1071,6 +1071,46 @@ if(BUILD_TESTING)
set_tests_properties("API.test_SysExit" PROPERTIES ENVIRONMENT PYTHONPATH=${DIR_WITH_PY_ENERGYPLUS})
add_test(NAME "API.test_OutputFiles" COMMAND "${Python_EXECUTABLE}" "${PROJECT_SOURCE_DIR}/tst/EnergyPlus/api/test_OutputFiles.py")
set_tests_properties("API.test_OutputFiles" PROPERTIES ENVIRONMENT PYTHONPATH=${DIR_WITH_PY_ENERGYPLUS})

# 9825 - Test some non-ASCII directories
set(CLI_TEST_DIR "${PROJECT_BINARY_DIR}/tst/cli")
set(EXAMPLES_FILES_DIR "${PROJECT_SOURCE_DIR}/testfiles")

# This has some accented chars, and also the nice thing about it is that in `C:\path\dir\térmica`, you do have something that could be a `\t` escape sequence
set(NON_ASCII_DIRNAME "térmicà")
set(INPUT_TEST_DIR "${CLI_TEST_DIR}/${NON_ASCII_DIRNAME}")
file(MAKE_DIRECTORY ${INPUT_TEST_DIR})

set(TEST_CASE "1ZoneUncontrolled")
set(IDF_FILE "${EXAMPLES_FILES_DIR}/${TEST_CASE}.idf")
configure_file(${IDF_FILE} "${INPUT_TEST_DIR}/${TEST_CASE}.idf" COPYONLY)

add_test(NAME energyplus.TestNonASCIIDirsAndFiles.NoPlugin.FromWithin
COMMAND energyplus -D -d "${CLI_TEST_DIR}/NoPlugin.FromWithin/out-${NON_ASCII_DIRNAME}" ${TEST_CASE}.idf
WORKING_DIRECTORY "${CLI_TEST_DIR}/${NON_ASCII_DIRNAME}"
)

add_test(NAME energyplus.TestNonASCIIDirsAndFiles.NoPlugin.FromOutside
COMMAND energyplus -D -d "${CLI_TEST_DIR}/NoPlugin.FromOutside/out-${NON_ASCII_DIRNAME}" ${NON_ASCII_DIRNAME}/${TEST_CASE}.idf
WORKING_DIRECTORY "${CLI_TEST_DIR}"
)

set(TEST_CASE "PythonPlugin1ZoneUncontrolledCondFD")
set(IDF_FILE "${EXAMPLES_FILES_DIR}/${TEST_CASE}.idf")
configure_file(${IDF_FILE} "${INPUT_TEST_DIR}/${TEST_CASE}.idf" COPYONLY)
set(PY_FILE "${EXAMPLES_FILES_DIR}/${TEST_CASE}.py")
configure_file(${PY_FILE} "${INPUT_TEST_DIR}/${TEST_CASE}.py" COPYONLY)

add_test(NAME energyplus.TestNonASCIIDirsAndFiles.PythonPlugin.FromWithin
COMMAND energyplus -D -d "${CLI_TEST_DIR}/PythonPlugin.FromWithin/out-${NON_ASCII_DIRNAME}" ${TEST_CASE}.idf
WORKING_DIRECTORY "${CLI_TEST_DIR}/${NON_ASCII_DIRNAME}"
)

add_test(NAME energyplus.TestNonASCIIDirsAndFiles.PythonPlugin.FromOutside
COMMAND energyplus -D -d "${CLI_TEST_DIR}/PythonPlugin.FromOutside/out-${NON_ASCII_DIRNAME}" ${NON_ASCII_DIRNAME}/${TEST_CASE}.idf
WORKING_DIRECTORY "${CLI_TEST_DIR}"
)

endif()

if(UNIX AND NOT APPLE)
Expand Down
431 changes: 174 additions & 257 deletions src/EnergyPlus/CommandLineInterface.cc

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion src/EnergyPlus/CommandLineInterface.hh
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@

// C++ Headers
#include <string>
#include <vector>

// EnergyPlus Headers
#include <EnergyPlus/api/EnergyPlusAPI.h>
Expand All @@ -72,7 +73,7 @@ namespace CommandLineInterface {
};

// Process command line arguments
int ENERGYPLUSLIB_API ProcessArgs(EnergyPlusData &state, int argc, const char *argv[]);
int ENERGYPLUSLIB_API ProcessArgs(EnergyPlusData &state, const std::vector<std::string> &args);

void ReadINIFile(InputFile &inputFile, // Unit number of the opened INI file
std::string const &Heading, // Heading for the parameters ('[heading]')
Expand Down
186 changes: 98 additions & 88 deletions src/EnergyPlus/PluginManager.cc

Large diffs are not rendered by default.

6 changes: 4 additions & 2 deletions src/EnergyPlus/PluginManager.hh
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,7 @@ namespace PluginManagement {
~PluginManager();

static int numActiveCallbacks(EnergyPlusData &state);
static void addToPythonPath(EnergyPlusData &state, const fs::path &path, bool userDefinedPath);
static fs::path sanitizedPath(fs::path const &path);
static void addToPythonPath(EnergyPlusData &state, const fs::path &includePath, bool userDefinedPath);
static void setupOutputVariables(EnergyPlusData &state);

int maxGlobalVariableIndex = -1;
Expand All @@ -211,6 +210,9 @@ namespace PluginManagement {
static bool anyUnexpectedPluginObjects(EnergyPlusData &state);

bool eplusRunningViaPythonAPI = false;

// For debugging purposes / issuing better error messages
static std::vector<std::string> currentPythonPath();
};

struct PluginTrendVariable
Expand Down
19 changes: 11 additions & 8 deletions src/EnergyPlus/api/EnergyPlusPgm.cc
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,9 @@
// C++ Headers
#include <exception>
#include <iostream>
#include <string>
#include <vector>

#ifndef NDEBUG
#ifdef __unix__
#include <cfenv>
Expand Down Expand Up @@ -219,7 +222,7 @@
#include <unistd.h>
#endif

int EnergyPlusPgm(int argc, const char *argv[], std::string const &filepath)
int EnergyPlusPgm(const std::vector<std::string> &args, std::string const &filepath)
{
EnergyPlus::EnergyPlusData state;
//// these need to be set early to be used in help and version output messaging
Expand All @@ -233,7 +236,7 @@ int EnergyPlusPgm(int argc, const char *argv[], std::string const &filepath)
}
state.dataStrGlobals->VerStringVar = EnergyPlus::DataStringGlobals::VerString + "," + state.dataStrGlobals->CurrentDateTime;

EnergyPlus::CommandLineInterface::ProcessArgs(state, argc, argv);
EnergyPlus::CommandLineInterface::ProcessArgs(state, args);
return RunEnergyPlus(state, filepath);
}

Expand Down Expand Up @@ -333,9 +336,7 @@ int initializeEnergyPlus(EnergyPlus::EnergyPlusData &state, std::string const &f
return EXIT_FAILURE;
}
state.dataStrGlobals->ProgramPath = filepath + DataStringGlobals::pathChar;
int dummy_argc = 1;
const char *dummy_argv[1] = {"energyplus"};
CommandLineInterface::ProcessArgs(state, dummy_argc, dummy_argv);
CommandLineInterface::ProcessArgs(state, {"energyplus"});
}

return commonRun(state);
Expand Down Expand Up @@ -418,7 +419,7 @@ int RunEnergyPlus(EnergyPlus::EnergyPlusData &state, std::string const &filepath
return wrapUpEnergyPlus(state);
}

int runEnergyPlusAsLibrary(EnergyPlus::EnergyPlusData &state, int argc, const char *argv[])
int runEnergyPlusAsLibrary(EnergyPlus::EnergyPlusData &state, const std::vector<std::string> &args)
{
// PROGRAM INFORMATION:
// AUTHOR Linda K. Lawrie, et al
Expand All @@ -441,7 +442,7 @@ int runEnergyPlusAsLibrary(EnergyPlus::EnergyPlusData &state, int argc, const ch
if (!std::cerr.good()) std::cerr.clear();
if (!std::cout.good()) std::cout.clear();

int return_code = EnergyPlus::CommandLineInterface::ProcessArgs(state, argc, argv);
int return_code = EnergyPlus::CommandLineInterface::ProcessArgs(state, args);
if (return_code == static_cast<int>(EnergyPlus::CommandLineInterface::ReturnCodes::Failure)) {
return return_code;
} else if (return_code == static_cast<int>(EnergyPlus::CommandLineInterface::ReturnCodes::SuccessButHelper)) {
Expand All @@ -450,7 +451,9 @@ int runEnergyPlusAsLibrary(EnergyPlus::EnergyPlusData &state, int argc, const ch
}

int status = initializeAsLibrary(state);
if (status || state.dataGlobal->outputEpJSONConversionOnly) return status;
if (status || state.dataGlobal->outputEpJSONConversionOnly) {
return status;
}
try {
EnergyPlus::SimulationManager::ManageSimulation(state);
} catch (const EnergyPlus::FatalError &e) {
Expand Down
5 changes: 3 additions & 2 deletions src/EnergyPlus/api/EnergyPlusPgm.hh
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@

// C++ Headers
#include <string>
#include <vector>

namespace EnergyPlus {
struct EnergyPlusData;
Expand All @@ -65,11 +66,11 @@ int initializeEnergyPlus(EnergyPlus::EnergyPlusData &state, std::string const &f

int wrapUpEnergyPlus(EnergyPlus::EnergyPlusData &state);

int ENERGYPLUSLIB_API EnergyPlusPgm(int argc, const char *argv[], std::string const &filepath = std::string());
int ENERGYPLUSLIB_API EnergyPlusPgm(const std::vector<std::string> &args, std::string const &filepath = std::string());

int ENERGYPLUSLIB_API RunEnergyPlus(EnergyPlus::EnergyPlusData &state, std::string const &filepath = std::string());

int runEnergyPlusAsLibrary(EnergyPlus::EnergyPlusData &state, int argc, const char *argv[]);
int runEnergyPlusAsLibrary(EnergyPlus::EnergyPlusData &state, const std::vector<std::string> &args);

void ENERGYPLUSLIB_API StoreProgressCallback(EnergyPlus::EnergyPlusData &state, void (*f)(int const));

Expand Down
3 changes: 2 additions & 1 deletion src/EnergyPlus/api/runtime.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ int energyplus(EnergyPlusState state, int argc, const char *argv[])
return 1;
}
thisState->ready = false;
return runEnergyPlusAsLibrary(*thisState, argc, argv);
std::vector<std::string> args(argv, std::next(argv, static_cast<std::ptrdiff_t>(argc)));
return runEnergyPlusAsLibrary(*thisState, args);
}

void stopSimulation(EnergyPlusState state)
Expand Down
11 changes: 9 additions & 2 deletions src/EnergyPlus/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,24 @@
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.

// EnergyPlus Headers
#include <EnergyPlus/api/EnergyPlusPgm.hh>

#include <CLI/CLI11.hpp>

#ifdef DEBUG_ARITHM_GCC_OR_CLANG
#include <EnergyPlus/fenv_missing.h>
#endif

int main(int argc, const char *argv[])
int main()
{
#ifdef DEBUG_ARITHM_GCC_OR_CLANG
feenableexcept(FE_DIVBYZERO | FE_INVALID | FE_OVERFLOW);
#endif

return EnergyPlusPgm(argc, argv);
int const argc = CLI::argc();
const char *const *argv = CLI::argv(); // This is going to use CommandLineToArgvW on Windows and **narrow** from wchar_t to char

const std::vector<std::string> args(argv, std::next(argv, static_cast<std::ptrdiff_t>(argc)));
return EnergyPlusPgm(args);
}
Loading

5 comments on commit c854ba6

@nrel-bot
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

develop (Myoldmopar) - Win64-Windows-10-VisualStudio-16: OK (2713 of 2713 tests passed, 0 test warnings)

Build Badge Test Badge

@nrel-bot-2c
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

develop (Myoldmopar) - x86_64-Linux-Ubuntu-22.04-gcc-11.4: OK (2735 of 2735 tests passed, 0 test warnings)

Build Badge Test Badge

@nrel-bot-2c
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

develop (Myoldmopar) - x86_64-Linux-Ubuntu-22.04-gcc-11.4-UnitTestsCoverage-Debug: OK (1929 of 1929 tests passed, 0 test warnings)

Build Badge Test Badge Coverage Badge

@nrel-bot-2b
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

develop (Myoldmopar) - x86_64-Linux-Ubuntu-22.04-gcc-11.4-IntegrationCoverage-Debug: OK (787 of 787 tests passed, 0 test warnings)

Build Badge Test Badge Coverage Badge

@nrel-bot-3
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

develop (Myoldmopar) - x86_64-MacOS-10.17-clang-14.0.0: OK (2714 of 2714 tests passed, 0 test warnings)

Build Badge Test Badge

Please sign in to comment.