add arg-parser

This commit is contained in:
Syoyo Fujita
2025-07-03 04:10:26 +09:00
parent 81f42e6969
commit c99b12fd97
7 changed files with 192 additions and 0 deletions

View File

@@ -370,6 +370,7 @@ if(TINYUSDZ_WITH_PYTHON)
endif()
set(TINYUSDZ_SOURCES
${PROJECT_SOURCE_DIR}/src/arg-parser.cc
${PROJECT_SOURCE_DIR}/src/asset-resolution.cc
${PROJECT_SOURCE_DIR}/src/tinyusdz.cc
${PROJECT_SOURCE_DIR}/src/xform.cc
@@ -1257,6 +1258,10 @@ if(TINYUSDZ_BUILD_EXAMPLES)
if (TINYUSDZ_WITH_TYDRA)
add_subdirectory(examples/tydra_api)
add_subdirectory(examples/tydra_to_renderscene)
if (TINYUSDZ_WITH_MCP_SERVER)
add_subdirectory(examples/mcp_server)
endif()
endif ()
add_subdirectory(examples/api_tutorial)

View File

@@ -0,0 +1,14 @@
# Assume this cmake is called from tinyusdz root(../../)
set(EXAMPLE_TARGET "mcp_server")
set(EXAMPLE_SOURCES
example-mcp-server.cc
)
add_executable(${EXAMPLE_TARGET} ${EXAMPLE_SOURCES})
add_sanitizers(${EXAMPLE_TARGET})
target_include_directories(${EXAMPLE_TARGET} PRIVATE ${PROJECT_SOURCE_DIR}/src)
target_link_libraries(${EXAMPLE_TARGET} tinyusdz_static)
set_target_properties(${EXAMPLE_TARGET} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}")

View File

@@ -0,0 +1,14 @@
#include <iostream>
#include "tydra/mcp-server.hh"
#include "arg-parser.hh"
int main(int argc, char **argv) {
#if !defined(TINYUSDZ_WITH_MCP_SERVER)
std::cerr << "TinyUSDZ is not built with `TINYUSDZ_WITH_MCP_SERVER` cmake option)" << "\n";
#endif
return 0;
}

91
src/arg-parser.cc Normal file
View File

@@ -0,0 +1,91 @@
// SPDX-License-Identifier: MIT
// Copyright 2025 - Present, Light Transport Entertainment, Inc.
//
#include "arg-parser.hh"
#include "str-util.hh"
namespace tinyusdz {
namespace argparser {
ArgParser::ArgParser() {}
void ArgParser::add_option(const std::string& name, bool has_value, const std::string& help) {
Option opt;
opt.name = name;
opt.has_value = has_value;
opt.is_set = false;
opt.value = "";
opt.help = help;
options_[name] = opt;
}
bool ArgParser::parse(int argc, char** argv) {
positional_args_.clear();
for (int i = 1; i < argc; ++i) {
std::string arg = argv[i];
if (arg.size() > 0 && arg[0] == '-') {
// Option
auto it = options_.find(arg);
if (it == options_.end()) {
// Unknown option
return false;
}
it->second.is_set = true;
if (it->second.has_value) {
if (i + 1 < argc) {
it->second.value = argv[i + 1];
++i;
} else {
// Missing value
return false;
}
}
} else {
// Positional argument
positional_args_.push_back(arg);
}
}
return true;
}
bool ArgParser::is_set(const std::string& name) const {
auto it = options_.find(name);
if (it != options_.end()) {
return it->second.is_set;
}
return false;
}
bool ArgParser::get(const std::string& name, std::string& value) const {
auto it = options_.find(name);
if (it != options_.end() && it->second.is_set && it->second.has_value) {
value = it->second.value;
return true;
}
return false;
}
bool ArgParser::get(const std::string& name, double& value) const {
auto it = options_.find(name);
if (it != options_.end() && it->second.is_set && it->second.has_value) {
double d = tinyusdz::atof(it->second.value.c_str());
value = d;
return true;
}
return false;
}
const std::vector<std::string>& ArgParser::positional() const {
return positional_args_;
}
void ArgParser::print_help() const {
for (const auto& kv : options_) {
const auto& opt = kv.second;
std::string value_hint = opt.has_value ? " <value>" : "";
printf(" %s%s\n %s\n", opt.name.c_str(), value_hint.c_str(), opt.help.c_str());
}
}
} // namespace argparser
} // namespace tinyusdz

53
src/arg-parser.hh Normal file
View File

@@ -0,0 +1,53 @@
// SPDX-License-Identifier: MIT
// Copyright 2025 - Present, Light Transport Entertainment, Inc.
//
// Simple arg parser.
//
#pragma once
#include <string>
#include <vector>
#include <map>
namespace tinyusdz {
namespace argparser {
struct Option {
std::string name;
std::string value;
bool has_value;
bool is_set;
std::string help; // Help string for the option
};
class ArgParser {
public:
ArgParser();
// Register an option (e.g., "--input") with help string
void add_option(const std::string& name, bool has_value, const std::string& help = "");
// Parse argc/argv. Returns true on success, false on error.
bool parse(int argc, char** argv);
// Check if option is set
bool is_set(const std::string& name) const;
// Get value for option. Returns true if found, false otherwise.
bool get(const std::string& name, std::string& value) const;
// Get value for option as double. Returns true if found and conversion succeeds, false otherwise.
bool get(const std::string& name, double& value) const;
// Get positional arguments (non-option arguments)
const std::vector<std::string>& positional() const;
// Print help for all options
void print_help() const;
private:
std::map<std::string, Option> options_;
std::vector<std::string> positional_args_;
};
} // namespace argparser
} // namespace tinyusdz

View File

@@ -707,4 +707,14 @@ std::string makeIdentifierValid(const std::string &str, bool is_utf8) {
return s;
}
double atof(const char *p) {
// TODO: Use from_chars
return std::atof(p);
}
double atof(const std::string &s) {
return atof(s.c_str());
}
} // namespace tinyusdz

View File

@@ -395,4 +395,9 @@ inline std::string join(const std::string& sep, It& v)
}
#endif
// Simple atof replacement
// Returns qNaN for invalid input.
double atof(const char *s);
double atof(const std::string &s);
} // namespace tinyusdz