diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..1fe685f --- /dev/null +++ b/.envrc @@ -0,0 +1,3 @@ +use guix +dotenv +export C_INCLUDE_PATH="$PWD/include:$HOME/src/mruby/include:$C_INCLUDE_PATH" diff --git a/.github/workflows/doc.yml b/.github/workflows/doc.yml new file mode 100644 index 0000000..6e1f0b1 --- /dev/null +++ b/.github/workflows/doc.yml @@ -0,0 +1,37 @@ +name: Build and deploy Doxygen to GitHub Pages +on: + push: + branches: [ "main" ] + pull_request: + workflow_dispatch: + +jobs: + build-and-deploy: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Doxygen and Graphviz + run: sudo apt-get update && sudo apt-get install -y doxygen graphviz + + - name: Run Doxygen + run: doxygen Doxyfile + + - name: Upload Pages artifact + uses: actions/upload-pages-artifact@v3 + with: + path: doc/html + + deploy: + needs: build-and-deploy + runs-on: ubuntu-latest + steps: + - name: Deploy to GitHub Pages + uses: actions/deploy-pages@v4 + permissions: + id-token: write + pages: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} diff --git a/Doxyfile b/Doxyfile index c0a50ed..e5e00c8 100644 --- a/Doxyfile +++ b/Doxyfile @@ -2349,7 +2349,7 @@ ENABLE_PREPROCESSING = YES # The default value is: NO. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -MACRO_EXPANSION = NO +MACRO_EXPANSION = YES # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then # the macro expansion is limited to the macros specified with the PREDEFINED and @@ -2390,7 +2390,7 @@ INCLUDE_FILE_PATTERNS = # recursively expanded use the := operator instead of the = operator. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -PREDEFINED = +PREDEFINED = HAVE_URI_HAS_HOST # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this # tag can be used to specify a list of macro names that should be expanded. The diff --git a/TODO.org b/TODO.org new file mode 100644 index 0000000..ebb42fe --- /dev/null +++ b/TODO.org @@ -0,0 +1,64 @@ +* URIParserモジュール +** ClassMethodsモジュール +*** splitメソッド +#+begin_src ruby + def split(uri) + uri = parse(uri) + + # TODO: Support registry, path, and opaque + [uri.scheme, uri.userinfo, + nil, # host + uri.port, + nil, # registry + nil, # path + nil, # opaque + uri.query, uri.fragment] + end +#+end_src +** URIクラス +*** hierarchical?メソッド +#+begin_src ruby + def hierarchical? + path ? true : false + end +#+end_src +* Guixパッケージ +#+begin_src scheme + (define-public ruby-yard-mruby + (package + (name "ruby-yard-mruby") + (version "0.3.0") + (source + (origin + (method url-fetch) + (uri (rubygems-uri "yard-mruby" version)) + (sha256 + (base32 "1vv4s9lv0bif1xcn12yavr05adpj41y0xkrvwzza9rxxr3jz6l7r")))) + (build-system ruby-build-system) + (arguments (list #:test-target "spec")) + (native-inputs (list ruby-rspec)) + (propagated-inputs (list ruby-yard)) + (synopsis "Generate Yard documentation for MRuby projects.") + (description "Generate Yard documentation for MRuby projects.") + (home-page "https://github.com/sagmor/yard-mruby") + (license license:expat))) + + (define-public ruby-yard-coderay + (package + (name "ruby-yard-coderay") + (version "0.1.0") + (source + (origin + (method url-fetch) + (uri (rubygems-uri "yard-coderay" version)) + (sha256 + (base32 "0gqn2m83vxvp579malqi1jhkh0xcwpbz9190qr64zwbiljp5kfrq")))) + (build-system ruby-build-system) + (arguments (list #:test-target "spec")) + (native-inputs (list ruby-rspec)) + (propagated-inputs (list ruby-coderay ruby-yard)) + (synopsis "Add's coderay syntax highlighting to YARD docs") + (description "Add's coderay syntax highlighting to YARD docs.") + (home-page "https://github.com/sagmor/yard-coderay") + (license license:expat))) +#+end_src diff --git a/build/check_uri_copy_uri.c b/build/check_uri_copy_uri.c new file mode 100644 index 0000000..5bc27a4 --- /dev/null +++ b/build/check_uri_copy_uri.c @@ -0,0 +1,2 @@ +#include +int main(void) { uriCopyUriA(NULL, NULL); } diff --git a/build/check_uri_equals_uri.c b/build/check_uri_equals_uri.c new file mode 100644 index 0000000..f31673a --- /dev/null +++ b/build/check_uri_equals_uri.c @@ -0,0 +1,2 @@ +#include +int main(void) { uriEqualsUriA(NULL, NULL); } diff --git a/build/check_uri_has_host.c b/build/check_uri_has_host.c new file mode 100644 index 0000000..354e05f --- /dev/null +++ b/build/check_uri_has_host.c @@ -0,0 +1,2 @@ +#include +int main(void) { uriHasHostA(NULL); } diff --git a/build/check_uri_set_fragment.c b/build/check_uri_set_fragment.c new file mode 100644 index 0000000..404c5c7 --- /dev/null +++ b/build/check_uri_set_fragment.c @@ -0,0 +1,2 @@ +#include +int main(void) { uriSetFragmentA(NULL, NULL, NULL); } diff --git a/build/check_uri_set_host.c b/build/check_uri_set_host.c new file mode 100644 index 0000000..37da0bb --- /dev/null +++ b/build/check_uri_set_host.c @@ -0,0 +1,2 @@ +#include +int main(void) { uriSetHostAutoA(NULL, NULL, NULL); } diff --git a/build/check_uri_set_path.c b/build/check_uri_set_path.c new file mode 100644 index 0000000..7aa46df --- /dev/null +++ b/build/check_uri_set_path.c @@ -0,0 +1,2 @@ +#include +int main(void) { uriSetPathA(NULL, NULL, NULL); } diff --git a/build/check_uri_set_port.c b/build/check_uri_set_port.c new file mode 100644 index 0000000..b5901b0 --- /dev/null +++ b/build/check_uri_set_port.c @@ -0,0 +1,2 @@ +#include +int main(void) { uriSetPortTextA(NULL, NULL, NULL); } diff --git a/build/check_uri_set_query.c b/build/check_uri_set_query.c new file mode 100644 index 0000000..c3a56fe --- /dev/null +++ b/build/check_uri_set_query.c @@ -0,0 +1,2 @@ +#include +int main(void) { uriSetQueryA(NULL, NULL, NULL); } diff --git a/build/check_uri_set_scheme.c b/build/check_uri_set_scheme.c new file mode 100644 index 0000000..c2953ed --- /dev/null +++ b/build/check_uri_set_scheme.c @@ -0,0 +1,2 @@ +#include +int main(void) { uriSetSchemeA(NULL, NULL, NULL); } diff --git a/build/check_uri_set_userinfo.c b/build/check_uri_set_userinfo.c new file mode 100644 index 0000000..4e31211 --- /dev/null +++ b/build/check_uri_set_userinfo.c @@ -0,0 +1,2 @@ +#include +int main(void) { uriSetUserInfoA(NULL, NULL, NULL); } diff --git a/build_config.rb b/build_config.rb index e3f5b0f..528670b 100644 --- a/build_config.rb +++ b/build_config.rb @@ -1,3 +1,32 @@ +require "tmpdir" +require "shellwords" +require "open3" + +def check_function(name:, checker:, macro:, conf:) + Dir.mktmpdir("mruby_check_") do |tmpdir| + exe = File.join(tmpdir, "check_#{name}") + command = [conf.cc.command, + *conf.cc.flags.flatten, + "-l", "uriparser", + '-o', exe, + File.join(__dir__, "build/#{checker}")] + output, status = Open3.capture2e(ENV, *command) + puts "status: #{status}" + output.strip! + if output + puts ">>> output >>>" + puts output + puts "<<< output <<<" + end + if status.success? + conf.defines << macro + puts "found #{name}" + else + warn "not found #{name}" + end + end +end + MRuby::Build.new do |conf| toolchain :gcc conf.gem File.expand_path(File.dirname(__FILE__)) @@ -5,9 +34,51 @@ conf.linker.libraries << 'uriparser' + check_function(name: "uriHasHostA", + checker: "check_uri_has_host.c", + macro: "HAVE_URI_HAS_HOST", + conf:) + check_function(name: "uriCopyUriA", + checker: "check_uri_copy_uri.c", + macro: "HAVE_URI_COPY_URI", + conf:) + check_function(name: "uriEqualsUriA", + checker: "check_uri_equals_uri.c", + macro: "HAVE_URI_EQUALS_URI", + conf:) + check_function(name: "uriSetSchemeA", + checker: "check_uri_set_scheme.c", + macro: "HAVE_URI_SET_SCHEME", + conf:) + check_function(name: "uriSetUserInfoA", + checker: "check_uri_set_userinfo.c", + macro: "HAVE_URI_SET_USERINFO", + conf:) + check_function(name: "uriSetHostAutoA", + checker: "check_uri_set_host.c", + macro: "HAVE_URI_SET_HOST", + conf:) + check_function(name: "uriSetPortTextA", + checker: "check_uri_set_port.c", + macro: "HAVE_URI_SET_PORT", + conf:) + check_function(name: "uriSetPathA", + checker: "check_uri_set_path.c", + macro: "HAVE_URI_SET_PATH", + conf:) + check_function(name: "uriSetQueryA", + checker: "check_uri_set_query.c", + macro: "HAVE_URI_SET_QUERY", + conf:) + check_function(name: "uriSetFragmentA", + checker: "check_uri_set_fragment.c", + macro: "HAVE_URI_SET_FRAGMENT", + conf:) + if ENV['DEBUG'] == 'true' conf.enable_debug - conf.cc.defines = %w(MRB_ENABLE_DEBUG_HOOK) + conf.defines << "MRB_ENABLE_DEBUG_HOOK" conf.gem core: 'mruby-bin-debugger' + conf.gem core: 'mruby-bin-mirb' end end diff --git a/manifest.scm b/manifest.scm new file mode 100644 index 0000000..b9496aa --- /dev/null +++ b/manifest.scm @@ -0,0 +1,8 @@ +(use-modules (guix profiles) + (gnu packages commencement) + (gnu packages web) + (gnu packages documentation)) + +(packages->manifest (list gcc-toolchain + uriparser + doxygen)) diff --git a/mrblib/mrb_uriparser.rb b/mrblib/mrb_uriparser.rb index 2591431..1117f42 100644 --- a/mrblib/mrb_uriparser.rb +++ b/mrblib/mrb_uriparser.rb @@ -21,20 +21,6 @@ def join(uri_str, *path) # TODO: Remove parsing each path after implement accepting URI by merge methods. path.reduce(URIParser.parse(uri_str)) { |memo, pat| memo.merge!(URIParser.parse(pat)) } end - - # TODO: Implement this. - def split(uri) - uri = parse(uri) - - # TODO: Support registry, path, and opaque - [uri.scheme, uri.userinfo, - nil, # host - uri.port, - nil, # registry - nil, # path - nil, # opaque - uri.query, uri.fragment] - end end class << self @@ -70,11 +56,6 @@ def to_filename(windows: false) URIParser.uri_string_to_filename(to_s, windows:) end - # TODO: Implement path. - def hierarchical? - path ? true : false - end - def relative? !absolute? end diff --git a/build b/run-all similarity index 100% rename from build rename to run-all diff --git a/src/mrb_uriparser.c b/src/mrb_uriparser.c index c6e3a72..2bdbf99 100644 --- a/src/mrb_uriparser.c +++ b/src/mrb_uriparser.c @@ -38,12 +38,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -145,7 +145,8 @@ static mrb_value mrb_uriparser_new(mrb_state *const mrb, UriUriA *uri) { * URIParser::URI.parse(str) * ``` * - * @param str URI string to parse. + * where `str` is a URI string to parse. + * * @return `URIParser::URI` instance. * @sa mrb_uriparser_recompose */ @@ -177,8 +178,9 @@ static mrb_value mrb_uriparser_parse(mrb_state *const mrb, * URIParser::URI.from_filename(filename, windows: false) * ``` * - * @param filename Absolute filename. - * @param windows If true, use Windows path conversion. + * where `filename` is an absolute filename. If `windows` is true, use + * Windows path conversion. + * * @return URI string. * @sa mrb_uriparser_uri_string_to_filename */ @@ -216,13 +218,17 @@ static mrb_value mrb_uriparser_filename_to_uri_string(mrb_state *const mrb, * * ```ruby * URIParser.uri_string_to_filename(uri, windows: false) + * ``` + * + * where `uri` is a URI string. If `windows` is true, use Windows path + * conversion. + * + * ```ruby * uri.to_filename(windows: false) * ``` * * where `uri` is kind of `URIParser::URI`. * - * @param uri URI string. - * @param windows If `true`, use Windows path conversion. * @return Filename string. * @sa mrb_uriparser_filename_to_uri_string */ @@ -261,8 +267,8 @@ static mrb_value mrb_uriparser_uri_string_to_filename(mrb_state *const mrb, * URIParser.encode_www_form(query_list) * ``` * - * @param query_list Array of `[key, value]` pairs. Key is `String`. Value - * may be `nil` or `String`. + * where `query_list` is `Array` of `[key, value]` pairs. Key is `String`. + * Value may be `nil` or `String`. * * @return Encoded query string. * @sa mrb_uriparser_dissect_query @@ -302,6 +308,56 @@ static mrb_value mrb_uriparser_compose_query(mrb_state *const mrb, return str; } +#ifdef HAVE_URI_COPY_URI +/** + * @brief Copy URI. + * + * ```ruby + * uri.dup + * uri.clone + * ``` + * + * where `uri` is a `URIParser::URI` instance. + * + * @return New URI. + */ +static mrb_value mrb_uriparser_initialize_copy(mrb_state *mrb, mrb_value self) { + mrb_value original; + mrb_get_args(mrb, "o", &original); + UriUriA *uri = MRB_URIPARSER_URI(original); + UriUriA *new_uri = mrb_malloc(mrb, sizeof(UriUriA)); + if (uriCopyUriA(new_uri, uri)) { + MRB_URIPARSER_RAISE(mrb, "failed to copy URI"); + } + DATA_TYPE(self) = &mrb_uriparser_data_type; + mrb_uriparser_data *data = mrb_malloc(mrb, sizeof(mrb_uriparser_data)); + data->uri = new_uri; + DATA_PTR(self) = data; + return self; +} +#endif + +#ifdef HAVE_URI_EQUALS_URI +/** + * @brief Check two URIs for equivalence. + * + * ```ruby + * uri == another_uri + * ``` + * + * where `uri` and `another_uri` are `URIParser::URI` instances. + * + * @return Boolean. + */ +static mrb_value mrb_uriparser_equals(mrb_state *mrb, mrb_value self) { + mrb_value another; + mrb_get_args(mrb, "o", &another); + UriBool result = + uriEqualsUriA(MRB_URIPARSER_URI(self), MRB_URIPARSER_URI(another)); + return mrb_bool_value(result); +} +#endif + /** * @brief Get the scheme component of the URI. * @@ -309,7 +365,8 @@ static mrb_value mrb_uriparser_compose_query(mrb_state *const mrb, * uri.scheme * ``` * - * @param self `URIParser::URI` instance. + * where `uri` is a `URIParser::URI` instance. + * * @return Scheme string or `nil`. */ static mrb_value mrb_uriparser_scheme(mrb_state *const mrb, @@ -317,6 +374,27 @@ static mrb_value mrb_uriparser_scheme(mrb_state *const mrb, return MRB_URIPARSER_STR_IN_RANGE(mrb, MRB_URIPARSER_URI(self), scheme); } +#ifdef HAVE_URI_SET_SCHEME +/** + * @brief Set the scheme component of the URI. + * ```ruby + * uri.scheme = ... + * ``` + * + * where `uri` is a `URIParser::URI` instance. + * + * @return `nil`. + */ +static mrb_value mrb_uriparser_set_scheme(mrb_state *mrb, mrb_value self) { + char *component; + mrb_get_args(mrb, "z", &component); + if (uriSetSchemeA(MRB_URIPARSER_URI(self), component, + component + strlen(component))) + MRB_URIPARSER_RAISE(mrb, "failed to set scheme"); + return mrb_nil_value(); +} +#endif + /** * @brief Get the userinfo component of the URI. * @@ -324,7 +402,8 @@ static mrb_value mrb_uriparser_scheme(mrb_state *const mrb, * uri.userinfo * ``` * - * @param self `URIParser::URI` instance. + * where `uri` is a `URIParser::URI` instance. + * * @return Userinfo string or `nil`. */ static mrb_value mrb_uriparser_userinfo(mrb_state *const mrb, @@ -332,6 +411,27 @@ static mrb_value mrb_uriparser_userinfo(mrb_state *const mrb, return MRB_URIPARSER_STR_IN_RANGE(mrb, MRB_URIPARSER_URI(self), userInfo); } +#ifdef HAVE_URI_SET_USERINFO +/** + * @brief Set the userinfo component of the URI. + * ```ruby + * uri.userinfo = ... + * ``` + * + * where `uri` is a `URIParser::URI` instance. + * + * @return `nil`. + */ +static mrb_value mrb_uriparser_set_userinfo(mrb_state *mrb, mrb_value self) { + char *component; + mrb_get_args(mrb, "z", &component); + if (uriSetUserInfoA(MRB_URIPARSER_URI(self), component, + component + strlen(component))) + MRB_URIPARSER_RAISE(mrb, "failed to set userinfo"); + return mrb_nil_value(); +} +#endif + /** * @brief Get the hostname component of the URI. * @@ -339,7 +439,8 @@ static mrb_value mrb_uriparser_userinfo(mrb_state *const mrb, * uri.hostname * ``` * - * @param self `URIParser::URI` instance. + * where `uri` is a `URIParser::URI` instance. + * * @return Hostname string or `nil`. * * Note that it returns `::1` for `http://[::1]/bar` so it corresponds to @@ -350,6 +451,44 @@ static mrb_value mrb_uriparser_hostname(mrb_state *const mrb, return MRB_URIPARSER_STR_IN_RANGE(mrb, MRB_URIPARSER_URI(self), hostText); } +#ifdef HAVE_URI_SET_HOST +/** + * @brief Set the host component of the URI. + * ```ruby + * uri.host = ... + * ``` + * + * where `uri` is a `URIParser::URI` instance. + * + * @return `nil`. + */ +static mrb_value mrb_uriparser_set_host(mrb_state *mrb, mrb_value self) { + char *component; + mrb_get_args(mrb, "z", &component); + if (uriSetHostAutoA(MRB_URIPARSER_URI(self), component, + component + strlen(component))) + MRB_URIPARSER_RAISE(mrb, "failed to set host"); + return mrb_nil_value(); +} +#endif + +#ifdef HAVE_URI_HAS_HOST +/** + * @brief Check if the URI has host. + * + * ```ruby + * uri.host? + * ``` + * + * where `uri` is a `URIParser::URI` instance. + * + * @return Boolean. + */ +static mrb_value mrb_uriparser_has_host(mrb_state *mrb, mrb_value self) { + return mrb_bool_value(uriHasHostA(MRB_URIPARSER_URI(self))); +} +#endif + /** * @brief Get the port component of the URI as a string. * @@ -357,7 +496,8 @@ static mrb_value mrb_uriparser_hostname(mrb_state *const mrb, * uri.port * ``` * - * @param self `URIParser::URI` instance. + * where `uri` is a `URIParser::URI` instance. + * * @return Port string or `nil`. */ static mrb_value mrb_uriparser_port(mrb_state *const mrb, @@ -365,6 +505,27 @@ static mrb_value mrb_uriparser_port(mrb_state *const mrb, return MRB_URIPARSER_STR_IN_RANGE(mrb, MRB_URIPARSER_URI(self), portText); } +#ifdef HAVE_URI_SET_PORT +/** + * @brief Set the port component of the URI. + * ```ruby + * uri.port = ... + * ``` + * + * where `uri` is a `URIParser::URI` instance. + * + * @return `nil`. + */ +static mrb_value mrb_uriparser_set_port(mrb_state *mrb, mrb_value self) { + char *component; + mrb_get_args(mrb, "z", &component); + if (uriSetPortTextA(MRB_URIPARSER_URI(self), component, + component + strlen(component))) + MRB_URIPARSER_RAISE(mrb, "failed to set port"); + return mrb_nil_value(); +} +#endif + /** * @brief Get the path segments as an array of strings. * @@ -372,7 +533,8 @@ static mrb_value mrb_uriparser_port(mrb_state *const mrb, * uri.path_segments * ``` * - * @param self `URIParser::URI` instance. + * where `uri` is a `URIParser::URI` instance. + * * @return Array of path segment strings. */ static mrb_value mrb_uriparser_path_segments(mrb_state *const mrb, @@ -386,6 +548,27 @@ static mrb_value mrb_uriparser_path_segments(mrb_state *const mrb, return ary; } +#ifdef HAVE_URI_SET_PATH +/** + * @brief Set the path component of the URI. + * ```ruby + * uri.path = ... + * ``` + * + * where `uri` is a `URIParser::URI` instance. + * + * @return `nil`. + */ +static mrb_value mrb_uriparser_set_path(mrb_state *mrb, mrb_value self) { + char *component; + mrb_get_args(mrb, "z", &component); + if (uriSetPathA(MRB_URIPARSER_URI(self), component, + component + strlen(component))) + MRB_URIPARSER_RAISE(mrb, "failed to set path"); + return mrb_nil_value(); +} +#endif + /** * @brief Get the query component of the URI. * @@ -393,7 +576,8 @@ static mrb_value mrb_uriparser_path_segments(mrb_state *const mrb, * uri.query * ``` * - * @param self `URIParser::URI` instance. + * where `uri` is a `URIParser::URI` instance. + * * @return Query string or `nil`. */ static mrb_value mrb_uriparser_query(mrb_state *const mrb, @@ -401,6 +585,27 @@ static mrb_value mrb_uriparser_query(mrb_state *const mrb, return MRB_URIPARSER_STR_IN_RANGE(mrb, MRB_URIPARSER_URI(self), query); } +#ifdef HAVE_URI_SET_QUERY +/** + * @brief Set the query component of the URI. + * ```ruby + * uri.query = ... + * ``` + * + * where `uri` is a `URIParser::URI` instance. + * + * @return `nil`. + */ +static mrb_value mrb_uriparser_set_query(mrb_state *mrb, mrb_value self) { + char *component; + mrb_get_args(mrb, "z", &component); + if (uriSetQueryA(MRB_URIPARSER_URI(self), component, + component + strlen(component))) + MRB_URIPARSER_RAISE(mrb, "failed to set query"); + return mrb_nil_value(); +} +#endif + /** * @brief Get the fragment component of the URI. * @@ -408,7 +613,8 @@ static mrb_value mrb_uriparser_query(mrb_state *const mrb, * uri.fragment * ``` * - * @param self `URIParser::URI` instance. + * where `uri` is a `URIParser::URI` instance. + * * @return Fragment string or `nil`. */ static mrb_value mrb_uriparser_fragment(mrb_state *const mrb, @@ -416,6 +622,27 @@ static mrb_value mrb_uriparser_fragment(mrb_state *const mrb, return MRB_URIPARSER_STR_IN_RANGE(mrb, MRB_URIPARSER_URI(self), fragment); } +#ifdef HAVE_URI_SET_FRAGMENT +/** + * @brief Set the fragment component of the URI. + * ```ruby + * uri.fragment = ... + * ``` + * + * where `uri` is a `URIParser::URI` instance. + * + * @return `nil`. + */ +static mrb_value mrb_uriparser_set_fragment(mrb_state *mrb, mrb_value self) { + char *component; + mrb_get_args(mrb, "z", &component); + if (uriSetFragmentA(MRB_URIPARSER_URI(self), component, + component + strlen(component))) + MRB_URIPARSER_RAISE(mrb, "failed to set fragment"); + return mrb_nil_value(); +} +#endif + /** * @brief Check if the URI has an absolute path. * @@ -426,7 +653,8 @@ static mrb_value mrb_uriparser_fragment(mrb_state *const mrb, * uri.relative? * ``` * - * @param self `URIParser::URI` instance. + * where `uri` is a `URIParser::URI` instance. + * * @return Boolean. */ static mrb_value mrb_uriparser_absolute_path(mrb_state *const mrb, @@ -441,7 +669,8 @@ static mrb_value mrb_uriparser_absolute_path(mrb_state *const mrb, * uri.to_s * ``` * - * @param self `URIParser::URI` instance. + * where `uri` is a `URIParser::URI` instance. + * * @return URI string. * @sa mrb_uriparser_parse * @@ -469,8 +698,9 @@ static mrb_value mrb_uriparser_recompose(mrb_state *const mrb, * uri.merge!(rel) * ``` * - * @param self `URIParser::URI` instance. - * @param rel Relative URI (`URIParser::URI`). + * where `uri` is a `URIParser::URI` instance, and `rel` is relative URI + * (`URIParser::URI`). + * * @return Modified `URIParser::URI` instance. * @sa mrb_uriparser_merge */ @@ -501,8 +731,9 @@ static mrb_value mrb_uriparser_merge_mutably(mrb_state *const mrb, * uri + rel * ``` * - * @param self `URIParser::URI` instance. - * @param rel Relative URI (`URIParser::URI`). + * where `uri` is a `URIParser::URI` instance, and `rel` is relative URI + * (`URIParser::URI`). + * * @return New resolved `URIParser::URI` instance. * @sa mrb_uriparser_merge_mutably * @sa mrb_uriparser_create_reference @@ -533,8 +764,9 @@ static mrb_value mrb_uriparser_merge(mrb_state *const mrb, * uri.route_to(dest, domain_root: false) * ``` * - * @param base Base URI (`URIParser::URI`). - * @param domain_root If true, reference is from domain root. + * where `base` is a base URI (`URIParser::URI`). If `domain_root` is true, + * reference is from domain root. + * * @return New relative `URIParser::URI` instance. * @sa mrb_uriparser_merge */ @@ -574,9 +806,10 @@ static mrb_value mrb_uriparser_create_reference(mrb_state *const mrb, * fragment: true) * ``` * - * @param self `URIParser::URI` instance. - * @param scheme, userinfo, host, path, query, fragment: Enable normalization - * for each component. + * where `uri` is kind of `URIParser::URI`. `scheme`, `userinfo`, `host`, + * `path`, `query`, `fragment` are for enabling normalization for each + * component. + * * @return Modified `URIParser::URI` instance. * * By default all parts are normalized. If path is empty, this @@ -622,7 +855,8 @@ static mrb_value mrb_uriparser_normalize(mrb_state *const mrb, * uri.decode_www_form * ``` * - * @param self `URIParser::URI` instance. + * where `uri` is a `URIParser::URI` instance. + * * @return Array of `[key, value]` pairs. * @sa mrb_uriparser_compose_query * @@ -666,17 +900,52 @@ void mrb_mruby_uriparser_gem_init(mrb_state *const mrb) { mrb_uriparser_compose_query, MRB_ARGS_REQ(1)); struct RClass *const uri = mrb_define_class_under( mrb, uriparser, MRB_URIPARSER_URI_MODULE_NAME, mrb->object_class); +#ifdef HAVE_URI_COPY_URI + mrb_define_method(mrb, uri, "initialize_copy", mrb_uriparser_initialize_copy, + MRB_ARGS_REQ(1)); +#endif +#ifdef HAVE_URI_EQUALS_URI + mrb_define_method(mrb, uri, "==", mrb_uriparser_equals, MRB_ARGS_REQ(1)); +#endif mrb_define_method(mrb, uri, "scheme", mrb_uriparser_scheme, MRB_ARGS_NONE()); +#ifdef HAVE_URI_SET_SCHEME + mrb_define_method(mrb, uri, "scheme=", mrb_uriparser_set_scheme, + MRB_ARGS_REQ(1)); +#endif mrb_define_method(mrb, uri, "userinfo", mrb_uriparser_userinfo, MRB_ARGS_NONE()); +#ifdef HAVE_URI_SET_USERINFO + mrb_define_method(mrb, uri, "userinfo=", mrb_uriparser_set_userinfo, + MRB_ARGS_REQ(1)); +#endif mrb_define_method(mrb, uri, "hostname", mrb_uriparser_hostname, MRB_ARGS_NONE()); +#ifdef HAVE_URI_SET_HOST + mrb_define_method(mrb, uri, "host=", mrb_uriparser_set_host, MRB_ARGS_REQ(1)); +#endif +#ifdef HAVE_URI_HAS_HOST + mrb_define_method(mrb, uri, "host?", mrb_uriparser_has_host, MRB_ARGS_NONE()); +#endif mrb_define_method(mrb, uri, "port", mrb_uriparser_port, MRB_ARGS_NONE()); +#ifdef HAVE_URI_SET_PORT + mrb_define_method(mrb, uri, "port=", mrb_uriparser_set_port, MRB_ARGS_REQ(1)); +#endif mrb_define_method(mrb, uri, "path_segments", mrb_uriparser_path_segments, MRB_ARGS_NONE()); +#ifdef HAVE_URI_SET_PATH + mrb_define_method(mrb, uri, "path=", mrb_uriparser_set_path, MRB_ARGS_REQ(1)); +#endif mrb_define_method(mrb, uri, "query", mrb_uriparser_query, MRB_ARGS_NONE()); +#ifdef HAVE_URI_SET_QUERY + mrb_define_method(mrb, uri, "query=", mrb_uriparser_set_query, + MRB_ARGS_REQ(1)); +#endif mrb_define_method(mrb, uri, "fragment", mrb_uriparser_fragment, MRB_ARGS_NONE()); +#ifdef HAVE_URI_SET_FRAGMENT + mrb_define_method(mrb, uri, "fragment=", mrb_uriparser_set_fragment, + MRB_ARGS_REQ(1)); +#endif mrb_define_method(mrb, uri, "absolute_path?", mrb_uriparser_absolute_path, MRB_ARGS_NONE()); mrb_define_method(mrb, uri, "to_s", mrb_uriparser_recompose, MRB_ARGS_NONE()); diff --git a/test/mrb_uriparser.rb b/test/mrb_uriparser.rb index 6fba87a..cc06a48 100644 --- a/test/mrb_uriparser.rb +++ b/test/mrb_uriparser.rb @@ -195,3 +195,28 @@ assert_true(URIParser.parse("http://example.com/").absolute?) assert_false(URIParser.parse("./").absolute?) end + +assert("URIParser::URI#host?") do + assert_true(URIParser.parse("http://example.com").host?) +end + +assert("URIParser::URI#dup") do + uri = URIParser.parse("http://example.com") + new_uri = uri.dup + assert_equal("example.com", new_uri.hostname) + assert_not_same(uri, new_uri) +end + +assert("URIParser::URI#==") do + source = "http://example.com:12345/some/path?query" + uri = URIParser.parse(source) + assert_true(uri == URIParser.parse(source)) + another_source = "http://foo.example.com:12345/some/path?query" + assert_false(uri == URIParser.parse(another_source)) +end + +assert("URIParser::URI#scheme=") do + uri = URIParser.parse("http://example.com") + uri.scheme = "https" + assert_equal("https://example.com", uri.to_s) +end