diff --git a/.clang-lint-ignore b/.clang-lint-ignore index 73f2076..38d20db 100644 --- a/.clang-lint-ignore +++ b/.clang-lint-ignore @@ -1,2 +1,2 @@ # ignore third_party code from clang-format checks -include/uconfig/detail/* +include/uri-template/detail/* diff --git a/CMakeLists.txt b/CMakeLists.txt index 42d80b2..9480e0c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,26 +46,27 @@ endif() option(URITEMPLATE_BUILD_TESTING "Build included unit-tests" OFF) option(URITEMPLATE_BUILD_DOCS "Build sphinx generated docs" OFF) +option(URITEMPLATE_BUILD_EXAMPLE "Build example" OFF) ############################################## # Create target and set properties -set(UCONFIG_INC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) -set(UCONFIG_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) +set(URITEMPLATE_INC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include) +set(URITEMPLATE_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src) -set(UCONFIG_SOURCES ${UCONFIG_SRC_DIR}/Expander.cpp - ${UCONFIG_SRC_DIR}/Matcher.cpp - ${UCONFIG_SRC_DIR}/Modifier.cpp - ${UCONFIG_SRC_DIR}/Operator.cpp - ${UCONFIG_SRC_DIR}/Parser.cpp - ${UCONFIG_SRC_DIR}/Template.cpp - ${UCONFIG_SRC_DIR}/Variable.cpp +set(URITEMPLATE_SOURCES ${URITEMPLATE_SRC_DIR}/Expander.cpp + ${URITEMPLATE_SRC_DIR}/Matcher.cpp + ${URITEMPLATE_SRC_DIR}/Modifier.cpp + ${URITEMPLATE_SRC_DIR}/Operator.cpp + ${URITEMPLATE_SRC_DIR}/Parser.cpp + ${URITEMPLATE_SRC_DIR}/Template.cpp + ${URITEMPLATE_SRC_DIR}/Variable.cpp ) # liburi-template -add_library(${PROJECT_NAME} ${UCONFIG_SOURCES}) +add_library(${PROJECT_NAME} ${URITEMPLATE_SOURCES}) add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME}) target_include_directories(${PROJECT_NAME} @@ -94,7 +95,7 @@ install(TARGETS ${PROJECT_NAME} ) ## Install headers -install(DIRECTORY ${UCONFIG_INC_DIR}/${PROJECT_NAME} +install(DIRECTORY ${URITEMPLATE_INC_DIR}/${PROJECT_NAME} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) @@ -151,3 +152,8 @@ endif() if(URITEMPLATE_BUILD_DOCS) add_subdirectory(docs) endif() + +if(URITEMPLATE_BUILD_EXAMPLE) + add_executable("Example" example/Example.cpp) + target_link_libraries("Example" ${PROJECT_NAME}) +endif() diff --git a/README.md b/README.md index 10b19b1..4736f5a 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ Generally, to use this library you need to tell your compiler where to lookup fo Easiest way is to install this library onto your system. To do so, execute these commands from `uri-template` folder (sudo may be required): ```bash -cmake -H. -Bbuild -DUCONFIG_BUILD_TESTING=OFF -DUCONFIG_BUILD_DOCS=OFF +cmake -H. -Bbuild -DURITEMPLATE_BUILD_TESTING=OFF -DURITEMPLATE_BUILD_DOCS=OFF cmake --build ./build --target install ``` @@ -128,25 +128,26 @@ cmake --build ./build To install (sudo may be required): ```bash -cmake -H. -Bbuild -DUCONFIG_BUILD_TESTING=OFF -DUCONFIG_BUILD_DOCS=OFF +cmake -H. -Bbuild -DURITEMPLATE_BUILD_TESTING=OFF -DURITEMPLATE_BUILD_DOCS=OFF cmake --build ./build --target install ``` Or test: ```bash -cmake -H. -Bbuild -DUCONFIG_BUILD_TESTING=ON +cmake -H. -Bbuild -DURITEMPLATE_BUILD_TESTING=ON cmake --build ./build cmake -E chdir ./build ctest --output-on-failure ``` -*All these commands assume you are in uconfig root folder* +*All these commands assume you are in uri-template root folder* ### Cmake options * **CMAKE_BUILD_TYPE** – [build type](https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html). `RelWithDebInfo` by default. * **BUILD_SHARED_LIBS** – [build shared or static library](https://cmake.org/cmake/help/v3.0/variable/BUILD_SHARED_LIBS.html). `OFF` by default. -* **UCONFIG_BUILD_TESTING** – build included unit-tests. `OFF` by default. -* **UCONFIG_BUILD_DOCS** – build html (sphinx) reference docs. `OFF` by default. +* **URITEMPLATE_BUILD_TESTING** – build included unit-tests. `OFF` by default. +* **URITEMPLATE_BUILD_DOCS** – build html (sphinx) reference docs. `OFF` by default. +* **URITEMPLATE_BUILD_EXAMPLE** – build [example](./example/Example.cpp). `OFF` by default. ## License diff --git a/example/Example.cpp b/example/Example.cpp new file mode 100644 index 0000000..b58fc39 --- /dev/null +++ b/example/Example.cpp @@ -0,0 +1,33 @@ +#include +#include +// = "http://example.com/search?q=cat&lang=en"; +// "http://example.com/search{?q,lang}" + +int main() { + try{ + std::string uri; + std::string input_template; + std::cin >> uri; + std::cin >> input_template; + // Parse the template + const URI::Template::Template uri_template = URI::Template::ParseTemplate(input_template); + + // Match it to the URI + // &matched_values can be nullptr if you don't care about values. + std::unordered_map matched_values; + bool matched = URI::Template::MatchURI(uri_template, uri, &matched_values); + + // Print results + std::cout << std::boolalpha; + std::cout << "Template matched: " << matched << std::endl; + for (const auto& [name, value] : matched_values) { + std::cout << name << "=" << value << std::endl; + } + + // Expand + const std::string expanded_uri = URI::Template::ExpandTemplate(uri_template, matched_values); + std::cout << "Template expanded: " << expanded_uri << std::endl; + } catch (std::exception& exp){ + std::cout << "Error: " << exp.what() << std::endl; + } +} diff --git a/src/Parser.cpp b/src/Parser.cpp index b27c238..dd08c94 100644 --- a/src/Parser.cpp +++ b/src/Parser.cpp @@ -92,6 +92,9 @@ URI::Template::Expression URI::Template::ParseExpression(const std::string& expr if (!var_name.empty()) { variables.emplace_back(std::move(var_name), std::move(var_mod), ModLength::ToNumber(var_len)); } + if (variables.empty()) { + throw std::runtime_error("expression '" + expr_string + "' is empty"); + } return Expression(std::move(expr_oper), std::move(variables)); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 400691b..481d4ab 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,10 +2,10 @@ cmake_minimum_required(VERSION 3.4 FATAL_ERROR) set(CMAKE_MACOSX_RPATH 1) if(NOT TARGET testing) - set(TETING_TARGET_LOCAL "True") + set(TESTING_TARGET_LOCAL "True") add_custom_target(testing COMMAND ${CMAKE_CTEST_COMMAND}) else() - set(TETING_TARGET_LOCAL "False") + set(TESTING_TARGET_LOCAL "False") endif() # Download and unpack googletest at configure time @@ -37,7 +37,7 @@ function(add_unit_test name) add_executable(${name} ${ARGN}) target_link_libraries(${name} ${PROJECT_NAME}::${PROJECT_NAME} gtest_main) add_test(NAME ${name} COMMAND $) - if (TETING_TARGET_LOCAL) + if (TESTING_TARGET_LOCAL) add_dependencies(testing ${name}) endif () endfunction() diff --git a/tests/parsing.cpp b/tests/parsing.cpp index 0638bc6..5e141bc 100644 --- a/tests/parsing.cpp +++ b/tests/parsing.cpp @@ -37,7 +37,8 @@ INSTANTIATE_TEST_CASE_P( TestParams{"/sparql{?query,default-graph-uri}", "", {/* not parsed */}}, TestParams{"/sparql{?query){&default-graph-uri*}", "", {/* not parsed */}}, TestParams{"/resolution{?x, y}" , "", {/* not parsed */}}, - TestParams{"{var:3000000000000}" , "", {/* not parsed */}} + TestParams{"{var:3000000000000}" , "", {/* not parsed */}}, + TestParams{"{+}", "", {/* not parsed */}} ) ); // clang-format on