Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
191 changes: 93 additions & 98 deletions src/ifc-printer/main.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -29,98 +29,90 @@ auto& std_error = std::cerr;
using namespace ifc::util;
using namespace std::literals;

struct Arguments {
PrintOptions options = PrintOptions::None;
namespace {
struct Arguments {
PrintOptions options = PrintOptions::None;

// Files to process.
std::vector<ifc::fs::path> files;
};
// Files to process.
std::vector<ifc::fs::path> files;
};


void print_help(const ifc::fs::path& path)
{
auto name = path.stem().string();
std::cout << "Usage:\n\n";
std::cout << name << " ifc-file1 [ifc-file2 ...] [--color/-c]\n";
std::cout << name << " --help/-h\n";
}
void print_help(const ifc::fs::path& path)
{
auto name = path.stem().string();
std::cout << "Usage:\n\n";
std::cout << name << " ifc-file1 [ifc-file2 ...] [--color/-c]\n";
std::cout << name << " --help/-h\n";
}

Arguments process_args(int argc, ifc::tool::NativeChar* argv[])
{
Arguments result;
for (int i = 1; i < argc; ++i)
Arguments process_args(int argc, ifc::tool::NativeChar* argv[])
{
if (argv[i] == NSV("--help"))
Arguments result;
for (int i = 1; i < argc; ++i)
{
print_help(argv[0]);
exit(0);
}
else if (argv[i] == NSV("--color"))
{
result.options |= PrintOptions::Use_color;
if (argv[i] == NSV("--help"))
{
print_help(argv[0]);
exit(0);
}
else if (argv[i] == NSV("--color"))
{
result.options |= PrintOptions::Use_color;
}
// Future flags to add as needed
// --location: print locations
// --header: print module header
// etc.

else if (argv[i][0] != '-')
{
result.files.emplace_back(argv[i]);
}
else
{
std_error << NSV("Unknown command line argument '") << argv[i] << NSV("'\n");
print_help(argv[0]);
std::exit(1);
}
}
// Future flags to add as needed
// --location: print locations
// --header: print module header
// etc.

else if (argv[i][0] != '-')
{
result.files.emplace_back(argv[i]);
}
else
if (result.files.empty())
{
std_error << NSV("Unknown command line argument '") << argv[i] << NSV("'\n");
std_error << NSV("Specify filepath of an ifc file\n");
print_help(argv[0]);
std::exit(1);
}
}

if (result.files.empty())
{
std_error << NSV("Specify filepath of an ifc file\n");
print_help(argv[0]);
std::exit(1);
return result;
}

return result;
}

std::vector<std::byte> load_file(const ifc::fs::path& path)
{
auto size = std::filesystem::file_size(path);
std::vector<std::byte> v;
v.resize(size);
std::ifstream file(path.string(), std::ios::binary);
file.read(reinterpret_cast<char*>(v.data()), static_cast<std::streamsize>(v.size()));
return v;
}

void process_ifc(const ifc::fs::path& path, PrintOptions options)
{
auto contents = load_file(path);

ifc::InputIfc file{gsl::span(contents)};
ifc::Pathname name{path.u8string().c_str()};
file.validate<ifc::UnitSort::Primary>(name, ifc::Architecture::Unknown, ifc::Pathname{},
ifc::IfcOptions::IntegrityCheck);

ifc::Reader reader(file);
ifc::util::Loader loader(reader);
auto& gs = loader.get(reader.ifc.header()->global_scope);
print(gs, std::cout, options);

// Make sure that we resolve and print all
// referenced nodes.
options |= PrintOptions::Top_level_index;
while (not loader.referenced_nodes.empty())
void process_ifc(const ifc::fs::path& path, PrintOptions options)
{
auto it = loader.referenced_nodes.begin();
const auto node_key = *it;
loader.referenced_nodes.erase(it);
ifc::tool::InputFile container { path };

ifc::InputIfc file { container.contents() };
ifc::Pathname name{path.u8string().c_str()};
file.validate<ifc::UnitSort::Primary>(name, ifc::Architecture::Unknown, ifc::Pathname{},
ifc::IfcOptions::IntegrityCheck);

ifc::Reader reader(file);
ifc::util::Loader loader(reader);
auto& gs = loader.get(reader.ifc.header()->global_scope);
print(gs, std::cout, options);

// Make sure that we resolve and print all
// referenced nodes.
options |= PrintOptions::Top_level_index;
while (not loader.referenced_nodes.empty())
{
auto it = loader.referenced_nodes.begin();
const auto node_key = *it;
loader.referenced_nodes.erase(it);

auto& item = loader.get(node_key);
print(item, std::cout, options);
auto& item = loader.get(node_key);
print(item, std::cout, options);
}
}
}

Expand All @@ -130,32 +122,35 @@ int wmain(int argc, wchar_t* argv[])
int main(int argc, char* argv[])
#endif
{
Arguments arguments = process_args(argc, argv);
std::size_t error_count = 0;

try
Arguments arguments = process_args(argc, argv);
for (const auto& file : arguments.files)
{
for (const auto& file : arguments.files)
try {
process_ifc(file, arguments.options);

return EXIT_SUCCESS;
}
catch (const ifc::IfcArchMismatch&)
{
std::cerr << "ifc architecture mismatch\n";
}
catch(ifc::error_condition::UnexpectedVisitor& e)
{
std::cerr << "visit unexpected " << e.category << ": "
<< e.sort << '\n';
}
catch(const ifc::InputIfc::MissingIfcHeader&)
{
std::cerr << "Missing ifc binary file header\n";
}
catch (...)
{
std::cerr << "unknown exception caught\n";
continue;
}
catch (const ifc::IfcArchMismatch&)
{
std::cerr << file.string() << ": ifc architecture mismatch\n";
}
catch(const ifc::error_condition::UnexpectedVisitor& e)
{
std::cerr << file.string()
<< ": visit unexpected " << e.category << ", "
<< e.sort << "\n";
}
catch(const ifc::InputIfc::MissingIfcHeader&)
{
std::cerr << file.string() << ": Missing ifc binary file header\n";
}
catch (...)
{
std::cerr << file.string() << ": unknown exception caught\n";
}
++error_count;
}

return EXIT_FAILURE;
return error_count == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}