feat(cpp-object-oriented-modular-refactoring): step 6 - io-application-google-style

This commit is contained in:
KOKO\Mimi
2026-08-16 06:59:50 +09:00
parent bb178c9d3c
commit 83fd1d1c7e
31 changed files with 10499 additions and 11445 deletions
+68 -77
View File
@@ -1,16 +1,16 @@
#include "fesa/app/fesa_application.hpp"
#include "fesa/analysis/linear_static_analysis.h"
#include "fesa/assembly/parallel_for.h"
#include "fesa/core/diagnostic.h"
#include "fesa/io/hdf5/hdf5_results_writer.hpp"
#include "fesa/solvers/linear/mkl_pardiso_solver.h"
#include "fesa/app/fesa_application.h"
#include <filesystem>
#include <iostream>
#include <string>
#include <vector>
#include "fesa/analysis/linear_static_analysis.h"
#include "fesa/assembly/parallel_for.h"
#include "fesa/core/diagnostic.h"
#include "fesa/io/hdf5/hdf5_results_writer.h"
#include "fesa/solvers/linear/mkl_pardiso_solver.h"
namespace fesa {
namespace {
@@ -21,93 +21,84 @@ constexpr int kModelExitCode = 4;
constexpr int kSolverExitCode = 5;
constexpr int kOutputExitCode = 6;
bool startsWithOption(const std::string& argument) {
return !argument.empty() && argument.front() == '-';
bool StartsWithOption(const std::string& argument) {
return !argument.empty() && argument.front() == '-';
}
Diagnostic usageDiagnostic() {
return {
Severity::kError,
"cli-usage",
{{}, 0U},
"",
"",
"Usage: fesa.exe <model.inp> [--output <results.h5>]."};
Diagnostic UsageDiagnostic() {
return {Severity::kError,
"cli-usage",
{{}, 0U},
"",
"",
"Usage: fesa.exe <model.inp> [--output <results.h5>]."};
}
const char* severityName(const Severity severity) {
return severity == Severity::kWarning ? "warning" : "error";
const char* SeverityName(const Severity severity) {
return severity == Severity::kWarning ? "warning" : "error";
}
void writeDiagnostics(std::vector<Diagnostic> diagnostics) {
SortDiagnostics(diagnostics);
for (const auto& diagnostic : diagnostics) {
// Stable field labels and tab separators keep empty source fields
// explicit without depending on locale-specific formatting.
std::cerr
<< "severity=" << severityName(diagnostic.severity)
<< '\t' << "code=" << diagnostic.code
<< '\t' << "file="
<< diagnostic.location.file.generic_u8string()
<< '\t' << "line=" << diagnostic.location.line
<< '\t' << "keyword=" << diagnostic.keyword
<< '\t' << "entity_identity=" << diagnostic.entity_identity
<< '\t' << "message=" << diagnostic.message
<< '\n';
}
void WriteDiagnostics(std::vector<Diagnostic> diagnostics) {
SortDiagnostics(diagnostics);
for (const auto& diagnostic : diagnostics) {
// Stable field labels and tab separators keep empty source fields
// explicit without depending on locale-specific formatting.
std::cerr << "severity=" << SeverityName(diagnostic.severity) << '\t'
<< "code=" << diagnostic.code << '\t'
<< "file=" << diagnostic.location.file.generic_u8string() << '\t'
<< "line=" << diagnostic.location.line << '\t'
<< "keyword=" << diagnostic.keyword << '\t'
<< "entity_identity=" << diagnostic.entity_identity << '\t'
<< "message=" << diagnostic.message << '\n';
}
}
int exitCodeFor(const Status& status) {
switch (status.Category().value_or(FailureCategory::kInput)) {
int ExitCodeFor(const Status& status) {
switch (status.Category().value_or(FailureCategory::kInput)) {
case FailureCategory::kInput:
return kInputExitCode;
return kInputExitCode;
case FailureCategory::kModel:
return kModelExitCode;
return kModelExitCode;
case FailureCategory::kSolver:
return kSolverExitCode;
return kSolverExitCode;
case FailureCategory::kOutput:
return kOutputExitCode;
}
return kInputExitCode;
return kOutputExitCode;
}
return kInputExitCode;
}
} // namespace
} // namespace
int FesaApplication::run(const std::vector<std::string>& arguments) {
const bool defaultOutputForm =
arguments.size() == 1U &&
!arguments[0U].empty() &&
!startsWithOption(arguments[0U]);
const bool explicitOutputForm =
arguments.size() == 3U &&
!arguments[0U].empty() &&
!startsWithOption(arguments[0U]) &&
arguments[1U] == "--output" &&
!arguments[2U].empty() &&
!startsWithOption(arguments[2U]);
if (!defaultOutputForm && !explicitOutputForm) {
writeDiagnostics({usageDiagnostic()});
return kUsageExitCode;
}
int FesaApplication::Run(const std::vector<std::string>& arguments) {
const bool default_output_form = arguments.size() == 1U &&
!arguments[0U].empty() &&
!StartsWithOption(arguments[0U]);
const bool explicit_output_form =
arguments.size() == 3U && !arguments[0U].empty() &&
!StartsWithOption(arguments[0U]) && arguments[1U] == "--output" &&
!arguments[2U].empty() && !StartsWithOption(arguments[2U]);
if (!default_output_form && !explicit_output_form) {
WriteDiagnostics({UsageDiagnostic()});
return kUsageExitCode;
}
AnalysisRequest request;
request.input_path = arguments[0U];
request.output_path = explicitOutputForm
? std::filesystem::path{arguments[2U]}
: std::filesystem::current_path() / "results.h5";
AnalysisRequest request;
request.input_path = arguments[0U];
request.output_path = explicit_output_form
? std::filesystem::path{arguments[2U]}
: std::filesystem::current_path() / "results.h5";
TbbParallelFor parallelFor;
MklPardisoSolver linearSolver;
Hdf5ResultsWriter resultsWriter;
LinearStaticAnalysis analysis{
parallelFor, linearSolver, resultsWriter};
const Status status = analysis.Run(request);
if (status.IsOk()) {
return kSuccessExitCode;
}
TbbParallelFor parallel_for;
MklPardisoSolver linear_solver;
Hdf5ResultsWriter results_writer;
LinearStaticAnalysis analysis{parallel_for, linear_solver, results_writer};
const Status status = analysis.Run(request);
if (status.IsOk()) {
return kSuccessExitCode;
}
writeDiagnostics(status.Diagnostics());
return exitCodeFor(status);
WriteDiagnostics(status.Diagnostics());
return ExitCodeFor(status);
}
} // namespace fesa
} // namespace fesa
+11 -11
View File
@@ -1,17 +1,17 @@
#include "fesa/app/fesa_application.hpp"
#include <cstddef>
#include <string>
#include <vector>
#include "fesa/app/fesa_application.h"
int main(const int argc, char* argv[]) {
std::vector<std::string> arguments;
if (argc > 1) {
arguments.reserve(static_cast<std::size_t>(argc - 1));
}
// The application boundary receives only operands and options, not argv[0].
for (int index = 1; index < argc; ++index) {
arguments.emplace_back(argv[index]);
}
return fesa::FesaApplication{}.run(arguments);
std::vector<std::string> arguments;
if (argc > 1) {
arguments.reserve(static_cast<std::size_t>(argc - 1));
}
// The application boundary receives only operands and options, not argv[0].
for (int index = 1; index < argc; ++index) {
arguments.emplace_back(argv[index]);
}
return fesa::FesaApplication{}.Run(arguments);
}