From b6aef35495e30c5c66f1b92112eff870efe92781 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 21 Oct 2024 09:52:32 +0200 Subject: [PATCH 01/12] COPYING: add the "and many contributors" text from the curl license Makes them identically phrased. Fixes #365 Reported-by: Carlos Henrique Lima Melara --- COPYING | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/COPYING b/COPYING index 3185e2ba..fcf1896c 100644 --- a/COPYING +++ b/COPYING @@ -1,6 +1,7 @@ COPYRIGHT AND PERMISSION NOTICE -Copyright (c) 2023 - 2024, Daniel Stenberg, +Copyright (c) 2023 - 2024, Daniel Stenberg, , and many +contributors, see the THANKS file. All rights reserved. From 9329ad684c8676269e681172a480e0946ea4b329 Mon Sep 17 00:00:00 2001 From: Jacob Mealey Date: Mon, 25 Nov 2024 08:52:29 -0500 Subject: [PATCH 02/12] trurl.md: fix typo in --replace-append Closes https://github.com/curl/trurl/pull/376 --- trurl.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/trurl.md b/trurl.md index 723cf308..123210b5 100644 --- a/trurl.md +++ b/trurl.md @@ -305,7 +305,7 @@ queries trurl ignores that item. trurl URL encodes both sides of the `=` character in the given input data argument. -## --replace--append [data] +## --replace-append [data] Works the same as *--replace*, but trurl appends a missing query string if it is not in the query list already. From e095d943df2781ec7de877d08ea6617acc6dd402 Mon Sep 17 00:00:00 2001 From: Jacob Mealey Date: Wed, 4 Dec 2024 08:33:00 -0500 Subject: [PATCH 03/12] Update README.md to link to the getting trurl wiki page --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 80026f31..2112c3e7 100644 --- a/README.md +++ b/README.md @@ -137,7 +137,7 @@ cc -W -Wall -pedantic -g -c -o trurl.o trurl.c cc trurl.o -lcurl -o trurl ``` -trurl is also available in [some Linux distributions](https://github.com/curl/trurl/discussions/51). You can try searching for it using the package manager of your preferred distribution. +trurl is also available in [some package managers](https://github.com/curl/trurl/wiki/Get-trurl-for-your-OS). If it is not listed you can try searching for it using the package manager of your preferred distribution. ### Windows From 6b52fa5aea0e3bc5160b63172952d6792003fa98 Mon Sep 17 00:00:00 2001 From: Jacob Mealey Date: Mon, 9 Dec 2024 21:51:01 -0500 Subject: [PATCH 04/12] Autogenerate ZSH completions based on trurl.md --- .gitignore | 5 ++ Makefile | 12 ++++- completions/_trurl.zsh.in | 66 +++++++++++++++++++++++ completions/generate_completions.sh | 81 +++++++++++++++++++++++++++++ 4 files changed, 163 insertions(+), 1 deletion(-) create mode 100644 completions/_trurl.zsh.in create mode 100755 completions/generate_completions.sh diff --git a/.gitignore b/.gitignore index 37e8aaeb..b0d7be3d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ # compiled program /trurl +/trurl.1 +_trurl.zsh # Prerequisites *.d @@ -60,3 +62,6 @@ winbuild/obj/ # Dependencies for msvc from vcpkg winbuild/vcpkg_installed/ + +# vim +*.sw* diff --git a/Makefile b/Makefile index 84d941e8..67acb5ce 100644 --- a/Makefile +++ b/Makefile @@ -38,6 +38,8 @@ MANUAL = trurl.1 PREFIX ?= /usr/local BINDIR ?= $(PREFIX)/bin MANDIR ?= $(PREFIX)/share/man/man1 +ZSH_COMPLETIONSDIR ?= $(PREFIX)/share/zsh/site-functions +COMPLETION_FILES=completions/_trurl.zsh INSTALL ?= install PYTHON3 ?= python3 @@ -55,10 +57,14 @@ install: (if test -f $(MANUAL); then \ $(INSTALL) -m 0644 $(MANUAL) $(DESTDIR)$(MANDIR); \ fi) + (if test -f $(COMPLETION_FILES); then \ + $(INSTALL) -d $(DESTDIR)$(ZSH_COMPLETIONSDIR); \ + $(INSTALL) -m 0755 $(COMPLETION_FILES) $(ZSH_COMPLETIONSDIR)/_trurl; \ + fi) .PHONY: clean clean: - rm -f $(OBJS) $(TARGET) + rm -f $(OBJS) $(TARGET) $(COMPLETION_FILES) .PHONY: test test: $(TARGET) @@ -71,3 +77,7 @@ test-memory: $(TARGET) .PHONY: checksrc checksrc: ./checksrc.pl trurl.c version.h + +.PHONY: completions +completions: trurl.md + ./completions/generate_completions.sh $^ diff --git a/completions/_trurl.zsh.in b/completions/_trurl.zsh.in new file mode 100644 index 00000000..a063ceaa --- /dev/null +++ b/completions/_trurl.zsh.in @@ -0,0 +1,66 @@ +#compdef trurl +########################################################################## +# _ _ +# Project | |_ _ __ _ _ _ __| | +# | __| '__| | | | '__| | +# | |_| | | |_| | | | | +# \__|_| \__,_|_| |_| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################## + + +# This file is generated from trurls generate_completions.sh + +# standalone flags - things that have now follow on +standalone_flags=(@TRURL_STANDALONE_FLAGS@) + +# component options - flags that expected to come after them +component_options=(@TRURL_COMPONENT_OPTIONS@) + +# components that take *something* as a param but we can't +# be sure what +random_options=(@TRURL_RANDOM_OPTIONS@) + +# Components are specific URL parts that are only completed +# after a component_options appears +component_list=( @TRURL_COMPONENT_LIST@) + +if (( "${component_options[(Ie)${words[$CURRENT-1]}]}" )); then + compadd -S "=" "${component_list[@]}" + return 0 +fi + +# if we expect another parameter that trurl doesn't define then +# we should (i.e. a component) then fall back on ZSH _path_file +if (( "${random_options[(Ie)${words[$CURRENT-1]}]}" )); then + _path_files + return 0 +fi + +# calling compadd directly allows us the let the flags be +# repeatable so we can recall --set, --get etc. +repeatable=( "${component_options[@]}" "${random_options[@]}" ) +args=( "${repeatable[@]}" ) +# only apply single completions which haven't been used. +for sf in "${standalone_flags[@]}"; do + if ! (( "${words[(Ie)$sf]}" )); then + args+=("$sf") + fi +done + +compadd "${args[@]}" diff --git a/completions/generate_completions.sh b/completions/generate_completions.sh new file mode 100755 index 00000000..bd2170ae --- /dev/null +++ b/completions/generate_completions.sh @@ -0,0 +1,81 @@ +#!/bin/bash +########################################################################## +# _ _ +# Project | |_ _ __ _ _ _ __| | +# | __| '__| | | | '__| | +# | |_| | | |_| | | | | +# \__|_| \__,_|_| |_| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################## + + +if [ -z "$1" ]; then + echo "expected a trurl.md file to be passed in..." + exit 1 +fi + +TRURL_MD_FILE=$1 + + + +ALL_FLAGS="$(sed -n \ + -e 's/"//g' \ + -e '/\# URL COMPONENTS/q;p' \ + < "${TRURL_MD_FILE}" \ + | grep "##" \ + | awk '{printf "%s%s%s%s ", $2, $3, $4, $5}')" + + +TRURL_COMPONENT_OPTIONS="" +TRURL_STANDALONE_FLAGS="" +TRURL_RANDOM_OPTIONS="" +TRURL_COMPONENT_LIST="$(sed -n \ + -e 's/"//g' \ + -e '1,/\# URL COMPONENTS/ d' \ + -e '/\# JSON output format/q;p' \ + < "${TRURL_MD_FILE}" \ + | grep "##" \ + | awk '{printf "\"%s\" ", $2}')" + +for flag in $ALL_FLAGS; do + # these are now TRURL_STANDALONE + if echo "$flag" | grep -q "="; then + TRURL_COMPONENT_OPTIONS+="$(echo "$flag" \ + | awk '{split($0, a, ","); for(i in a) {printf "%s ", a[i]}}' \ + | cut -f1 -d '[' \ + | awk '{printf "\"%s\" ", $1}')" + elif echo "$flag" | grep -q "\["; then + TRURL_RANDOM_OPTIONS+="$(echo "$flag" \ + | awk '{split($0, a, ","); for(i in a) {printf "%s ", a[i]}}' \ + | cut -f1 -d '[' \ + | awk '{printf "\"%s\" ", $1}')" + else + TRURL_STANDALONE_FLAGS+="$(echo "$flag" \ + | awk '{split($0, a, ","); for(i in a) {printf "\"%s\" ", a[i]}}')" + fi +done + +function generate_zsh() { + sed -e "s/@TRURL_RANDOM_OPTIONS@/${TRURL_RANDOM_OPTIONS}/g" \ + -e "s/@TRURL_STANDALONE_FLAGS@/${TRURL_STANDALONE_FLAGS}/g" \ + -e "s/@TRURL_COMPONENT_OPTIONS@/${TRURL_COMPONENT_OPTIONS}/g" \ + -e "s/@TRURL_COMPONENT_LIST@/${TRURL_COMPONENT_LIST}/g" \ + ./completions/_trurl.zsh.in > ./completions/_trurl.zsh +} + +generate_zsh "$TRURL_RANDOM_OPTIONS" From e93323cc2c4e0c9c3747f52190ed416bab79fc0d Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 12 Feb 2025 13:24:04 +0100 Subject: [PATCH 05/12] scripts: import cd2nroff from curl From curl's commit b0009d0216a09a3e0ffa34fdb Build it in the makefile --- Makefile | 7 +- mkrelease | 2 +- scripts/cd2nroff | 584 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 591 insertions(+), 2 deletions(-) create mode 100755 scripts/cd2nroff diff --git a/Makefile b/Makefile index 67acb5ce..75bd1afa 100644 --- a/Makefile +++ b/Makefile @@ -44,11 +44,16 @@ COMPLETION_FILES=completions/_trurl.zsh INSTALL ?= install PYTHON3 ?= python3 +all: $(TARGET) $(MANUAL) + $(TARGET): $(OBJS) $(CC) $(LDFLAGS) $(OBJS) -o $(TARGET) $(LDLIBS) trurl.o: trurl.c version.h +$(MANUAL): trurl.md + ./scripts/cd2nroff trurl.md > $(MANUAL) + .PHONY: install install: $(INSTALL) -d $(DESTDIR)$(BINDIR) @@ -64,7 +69,7 @@ install: .PHONY: clean clean: - rm -f $(OBJS) $(TARGET) $(COMPLETION_FILES) + rm -f $(OBJS) $(TARGET) $(COMPLETION_FILES) $(MANUAL) .PHONY: test test: $(TARGET) diff --git a/mkrelease b/mkrelease index 7d5213cc..d55a9f58 100755 --- a/mkrelease +++ b/mkrelease @@ -46,7 +46,7 @@ sed -ie "s/^Source: trurl \([0-9.]*\)/Source: trurl $version/" trurl.md sed -ie "s/\"[\.0-9]*\"/\"$version\"/" version.h # render the manpage into nroff -./curl/scripts/cd2nroff trurl.md > $rel/trurl.1 +./scripts/cd2nroff trurl.md > $rel/trurl.1 # create a release directory tree cp -p --parents $(git ls-files | grep -vE '^(.github/|.reuse/|.gitignore|LICENSES/)') $rel diff --git a/scripts/cd2nroff b/scripts/cd2nroff new file mode 100755 index 00000000..01b2f1ac --- /dev/null +++ b/scripts/cd2nroff @@ -0,0 +1,584 @@ +#!/usr/bin/env perl +#*************************************************************************** +# _ _ ____ _ +# Project ___| | | | _ \| | +# / __| | | | |_) | | +# | (__| |_| | _ <| |___ +# \___|\___/|_| \_\_____| +# +# Copyright (C) Daniel Stenberg, , et al. +# +# This software is licensed as described in the file COPYING, which +# you should have received as part of this distribution. The terms +# are also available at https://curl.se/docs/copyright.html. +# +# You may opt to use, copy, modify, merge, publish, distribute and/or sell +# copies of the Software, and permit persons to whom the Software is +# furnished to do so, under the terms of the COPYING file. +# +# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY +# KIND, either express or implied. +# +# SPDX-License-Identifier: curl +# +########################################################################### + +=begin comment + +Converts a curldown file to nroff (manpage). + +=end comment +=cut + +use strict; +use warnings; + +my $cd2nroff = "0.1"; # to keep check +my $dir; +my $extension; +my $keepfilename; + +while(@ARGV) { + if($ARGV[0] eq "-d") { + shift @ARGV; + $dir = shift @ARGV; + } + elsif($ARGV[0] eq "-e") { + shift @ARGV; + $extension = shift @ARGV; + } + elsif($ARGV[0] eq "-k") { + shift @ARGV; + $keepfilename = 1; + } + elsif($ARGV[0] eq "-h") { + print < Write the output to the file name from the meta-data in the + specified directory, instead of writing to stdout +-e If -d is used, this option can provide an added "extension", arbitrary + text really, to append to the file name. +-h This help text, +-v Show version then exit +HELP + ; + exit 0; + } + elsif($ARGV[0] eq "-v") { + print "cd2nroff version $cd2nroff\n"; + exit 0; + } + else { + last; + } +} + +use POSIX qw(strftime); +my @ts; +if (defined($ENV{SOURCE_DATE_EPOCH})) { + @ts = gmtime($ENV{SOURCE_DATE_EPOCH}); +} else { + @ts = localtime; +} +my $date = strftime "%Y-%m-%d", @ts; + +sub outseealso { + my (@sa) = @_; + my $comma = 0; + my @o; + push @o, ".SH SEE ALSO\n"; + for my $s (sort @sa) { + push @o, sprintf "%s.BR $s", $comma ? ",\n": ""; + $comma = 1; + } + push @o, "\n"; + return @o; +} + +sub outprotocols { + my (@p) = @_; + my $comma = 0; + my @o; + push @o, ".SH PROTOCOLS\n"; + + if($p[0] eq "TLS") { + push @o, "This functionality affects all TLS based protocols: HTTPS, FTPS, IMAPS, POP3S, SMTPS etc."; + } + else { + my @s = sort @p; + push @o, "This functionality affects "; + for my $e (sort @s) { + push @o, sprintf "%s%s", + $comma ? (($e eq $s[-1]) ? " and " : ", "): "", + lc($e); + $comma = 1; + } + if($#s == 0) { + if($s[0] eq "All") { + push @o, " supported protocols"; + } + else { + push @o, " only"; + } + } + } + push @o, "\n"; + return @o; +} + +sub outtls { + my (@t) = @_; + my $comma = 0; + my @o; + if($t[0] eq "All") { + push @o, "\nAll TLS backends support this option."; + } + elsif($t[0] eq "none") { + push @o, "\nNo TLS backend supports this option."; + } + else { + push @o, "\nThis option works only with the following TLS backends:\n"; + my @s = sort @t; + for my $e (@s) { + push @o, sprintf "%s$e", + $comma ? (($e eq $s[-1]) ? " and " : ", "): ""; + $comma = 1; + } + } + push @o, "\n"; + return @o; +} + +my %knownprotos = ( + 'DICT' => 1, + 'FILE' => 1, + 'FTP' => 1, + 'FTPS' => 1, + 'GOPHER' => 1, + 'GOPHERS' => 1, + 'HTTP' => 1, + 'HTTPS' => 1, + 'IMAP' => 1, + 'IMAPS' => 1, + 'LDAP' => 1, + 'LDAPS' => 1, + 'MQTT' => 1, + 'POP3' => 1, + 'POP3S' => 1, + 'RTMP' => 1, + 'RTMPS' => 1, + 'RTSP' => 1, + 'SCP' => 1, + 'SFTP' => 1, + 'SMB' => 1, + 'SMBS' => 1, + 'SMTP' => 1, + 'SMTPS' => 1, + 'TELNET' => 1, + 'TFTP' => 1, + 'WS' => 1, + 'WSS' => 1, + 'TLS' => 1, + 'TCP' => 1, + 'QUIC' => 1, + 'All' => 1 + ); + +my %knowntls = ( + 'BearSSL' => 1, + 'GnuTLS' => 1, + 'mbedTLS' => 1, + 'OpenSSL' => 1, + 'rustls' => 1, + 'Schannel' => 1, + 'Secure Transport' => 1, + 'wolfSSL' => 1, + 'All' => 1, + 'none' => 1, + ); + +sub single { + my @seealso; + my @proto; + my @tls; + my $d; + my ($f)=@_; + my $copyright; + my $errors = 0; + my $fh; + my $line; + my $list; + my $tlslist; + my $section; + my $source; + my $addedin; + my $spdx; + my $start = 0; + my $title; + + if(defined($f)) { + if(!open($fh, "<:crlf", "$f")) { + print STDERR "cd2nroff failed to open '$f' for reading: $!\n"; + return 1; + } + } + else { + $f = "STDIN"; + $fh = \*STDIN; + binmode($fh, ":crlf"); + } + while(<$fh>) { + $line++; + if(!$start) { + if(/^---/) { + # header starts here + $start = 1; + } + next; + } + if(/^Title: *(.*)/i) { + $title=$1; + } + elsif(/^Section: *(.*)/i) { + $section=$1; + } + elsif(/^Source: *(.*)/i) { + $source=$1; + } + elsif(/^See-also: +(.*)/i) { + $list = 1; # 1 for see-also + push @seealso, $1; + } + elsif(/^See-also: */i) { + if($seealso[0]) { + print STDERR "$f:$line:1:ERROR: bad See-Also, needs list\n"; + return 2; + } + $list = 1; # 1 for see-also + } + elsif(/^Protocol:/i) { + $list = 2; # 2 for protocol + } + elsif(/^TLS-backend:/i) { + $list = 3; # 3 for TLS backend + } + elsif(/^Added-in: *(.*)/i) { + $addedin=$1; + if(($addedin !~ /^[0-9.]+[0-9]\z/) && + ($addedin ne "n/a")) { + print STDERR "$f:$line:1:ERROR: invalid version number in Added-in line: $addedin\n"; + return 2; + } + } + elsif(/^ +- (.*)/i) { + # the only lists we support are see-also and protocol + if($list == 1) { + push @seealso, $1; + } + elsif($list == 2) { + push @proto, $1; + } + elsif($list == 3) { + push @tls, $1; + } + else { + print STDERR "$f:$line:1:ERROR: list item without owner?\n"; + return 2; + } + } + # REUSE-IgnoreStart + elsif(/^C: (.*)/i) { + $copyright=$1; + } + elsif(/^SPDX-License-Identifier: (.*)/i) { + $spdx=$1; + } + # REUSE-IgnoreEnd + elsif(/^---/) { + # end of the header section + if(!$title) { + print STDERR "$f:$line:1:ERROR: no 'Title:' in $f\n"; + return 1; + } + if(!$section) { + print STDERR "$f:$line:1:ERROR: no 'Section:' in $f\n"; + return 2; + } + if(!$source) { + print STDERR "$f:$line:1:ERROR: no 'Source:' in $f\n"; + return 2; + } + if(($source eq "libcurl") && !$addedin) { + print STDERR "$f:$line:1:ERROR: no 'Added-in:' in $f\n"; + return 2; + } + if(!$seealso[0]) { + print STDERR "$f:$line:1:ERROR: no 'See-also:' present\n"; + return 2; + } + if(!$copyright) { + print STDERR "$f:$line:1:ERROR: no 'C:' field present\n"; + return 2; + } + if(!$spdx) { + print STDERR "$f:$line:1:ERROR: no 'SPDX-License-Identifier:' field present\n"; + return 2; + } + if($section == 3) { + if(!$proto[0]) { + printf STDERR "$f:$line:1:ERROR: missing Protocol:\n"; + exit 2; + } + my $tls = 0; + for my $p (@proto) { + if($p eq "TLS") { + $tls = 1; + } + if(!$knownprotos{$p}) { + printf STDERR "$f:$line:1:ERROR: invalid protocol used: $p:\n"; + exit 2; + } + } + # This is for TLS, require TLS-backend: + if($tls) { + if(!$tls[0]) { + printf STDERR "$f:$line:1:ERROR: missing TLS-backend:\n"; + exit 2; + } + for my $t (@tls) { + if(!$knowntls{$t}) { + printf STDERR "$f:$line:1:ERROR: invalid TLS backend: $t:\n"; + exit 2; + } + } + } + } + last; + } + else { + chomp; + print STDERR "$f:$line:1:ERROR: unrecognized header keyword: '$_'\n"; + $errors++; + } + } + + if(!$start) { + print STDERR "$f:$line:1:ERROR: no header present\n"; + return 2; + } + + my @desc; + my $quote = 0; + my $blankline = 0; + my $header = 0; + + # cut off the leading path from the file name, if any + $f =~ s/^(.*[\\\/])//; + + push @desc, ".\\\" generated by cd2nroff $cd2nroff from $f\n"; + push @desc, ".TH $title $section \"$date\" $source\n"; + while(<$fh>) { + $line++; + + $d = $_; + + if($quote) { + if($quote == 4) { + # remove the indentation + if($d =~ /^ (.*)/) { + push @desc, "$1\n"; + next; + } + else { + # end of quote + $quote = 0; + push @desc, ".fi\n"; + next; + } + } + if(/^~~~/) { + # end of quote + $quote = 0; + push @desc, ".fi\n"; + next; + } + # convert single backslahes to doubles + $d =~ s/\\/\\\\/g; + # lines starting with a period needs it escaped + $d =~ s/^\./\\&./; + push @desc, $d; + next; + } + + # remove single line HTML comments + $d =~ s///g; + + # **bold** + $d =~ s/\*\*(\S.*?)\*\*/\\fB$1\\fP/g; + # *italics* + $d =~ s/\*(\S.*?)\*/\\fI$1\\fP/g; + + my $back = $d; + + # remove all backticked pieces + $back =~ s/\`(.*?)\`//g; + + if($back =~ /[^\\][\<\>]/) { + print STDERR "$f:$line:1:ERROR: un-escaped < or > used\n"; + $errors++; + } + # convert backslash-'<' or '> to just the second character + $d =~ s/\\([<>])/$1/g; + + # mentions of curl symbols with manpages use italics by default + $d =~ s/((lib|)curl([^ ]*\(3\)))/\\fI$1\\fP/gi; + + # backticked becomes italics + $d =~ s/\`(.*?)\`/\\fI$1\\fP/g; + + if(/^## (.*)/) { + my $word = $1; + # if there are enclosing quotes, remove them first + $word =~ s/[\"\'\`](.*)[\"\'\`]\z/$1/; + + # enclose in double quotes if there is a space present + if($word =~ / /) { + push @desc, ".IP \"$word\"\n"; + } + else { + push @desc, ".IP $word\n"; + } + $header = 1; + } + elsif(/^##/) { + # end of IP sequence + push @desc, ".PP\n"; + $header = 1; + } + elsif(/^# (.*)/) { + my $word = $1; + # if there are enclosing quotes, remove them first + $word =~ s/[\"\'](.*)[\"\']\z/$1/; + + if($word eq "PROTOCOLS") { + print STDERR "$f:$line:1:WARN: PROTOCOLS section in source file\n"; + } + elsif($word eq "AVAILABILITY") { + print STDERR "$f:$line:1:WARN: AVAILABILITY section in source file\n"; + } + elsif($word eq "%PROTOCOLS%") { + # insert the generated PROTOCOLS section + push @desc, outprotocols(@proto); + + if($proto[0] eq "TLS") { + push @desc, outtls(@tls); + } + $header = 1; + next; + } + elsif($word eq "%AVAILABILITY%") { + if($addedin ne "n/a") { + # insert the generated AVAILABILITY section + push @desc, ".SH AVAILABILITY\n"; + push @desc, "Added in curl $addedin\n"; + } + $header = 1; + next; + } + push @desc, ".SH $word\n"; + $header = 1; + } + elsif(/^~~~c/) { + # start of a code section, not indented + $quote = 1; + push @desc, "\n" if($blankline && !$header); + $header = 0; + push @desc, ".nf\n"; + } + elsif(/^~~~/) { + # start of a quote section; not code, not indented + $quote = 1; + push @desc, "\n" if($blankline && !$header); + $header = 0; + push @desc, ".nf\n"; + } + elsif(/^ (.*)/) { + # quoted, indented by 4 space + $quote = 4; + push @desc, "\n" if($blankline && !$header); + $header = 0; + push @desc, ".nf\n$1\n"; + } + elsif(/^[ \t]*\n/) { + # count and ignore blank lines + $blankline++; + } + else { + # don't output newlines if this is the first content after a + # header + push @desc, "\n" if($blankline && !$header); + $blankline = 0; + $header = 0; + + # quote minuses in the output + $d =~ s/([^\\])-/$1\\-/g; + # replace single quotes + $d =~ s/\'/\\(aq/g; + # handle double quotes first on the line + $d =~ s/^(\s*)\"/$1\\&\"/; + + # lines starting with a period needs it escaped + $d =~ s/^\./\\&./; + + if($d =~ /^(.*) /) { + printf STDERR "$f:$line:%d:ERROR: 2 spaces detected\n", + length($1); + $errors++; + } + if($d =~ /^[ \t]*\n/) { + # replaced away all contents + $blankline= 1; + } + else { + push @desc, $d; + } + } + } + if($fh != \*STDIN) { + close($fh); + } + push @desc, outseealso(@seealso); + if($dir) { + if($keepfilename) { + $title = $f; + $title =~ s/\.[^.]*$//; + } + my $outfile = "$dir/$title.$section"; + if(defined($extension)) { + $outfile .= $extension; + } + if(!open(O, ">", $outfile)) { + print STDERR "Failed to open $outfile : $!\n"; + return 1; + } + print O @desc; + close(O); + } + else { + print @desc; + } + return $errors; +} + +if(@ARGV) { + for my $f (@ARGV) { + my $r = single($f); + if($r) { + exit $r; + } + } +} +else { + exit single(); +} From 0ddc31d23bc4545d3389f6006e63663178145e69 Mon Sep 17 00:00:00 2001 From: Sertonix Date: Tue, 21 Jan 2025 10:29:32 +0000 Subject: [PATCH 06/12] Makefile: only create MANDIR when manpage is installed When not installing the manpage there is no use in creating the directory Fixes f3523912562 Makefile: check for trurl.1 before installing --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 75bd1afa..09318242 100644 --- a/Makefile +++ b/Makefile @@ -58,8 +58,8 @@ $(MANUAL): trurl.md install: $(INSTALL) -d $(DESTDIR)$(BINDIR) $(INSTALL) -m 0755 $(TARGET) $(DESTDIR)$(BINDIR) - $(INSTALL) -d $(DESTDIR)$(MANDIR) (if test -f $(MANUAL); then \ + $(INSTALL) -d $(DESTDIR)$(MANDIR); \ $(INSTALL) -m 0644 $(MANUAL) $(DESTDIR)$(MANDIR); \ fi) (if test -f $(COMPLETION_FILES); then \ From bf421e511e44b351760d22d3a1c5eba42011a958 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 9 May 2025 14:26:01 +0200 Subject: [PATCH 07/12] trurl: handle zero length query pairs Added several new test cases for it Fixes #387 Reported-by: joveian on github --- tests.json | 44 ++++++++++++++++++++++++++++++++++++++++++++ trurl.c | 4 ++-- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/tests.json b/tests.json index 4d935061..891271ca 100644 --- a/tests.json +++ b/tests.json @@ -3274,5 +3274,49 @@ "stderr": "trurl error: --json is mutually exclusive with --get\ntrurl error: Try trurl -h for help\n", "returncode": 4 } + }, + { + "input": { + "arguments": [ + "e?e&&" + ] + }, + "expected": { + "stdout": "http://e/?e\n", + "returncode": 0 + } + }, + { + "input": { + "arguments": [ + "e?e&" + ] + }, + "expected": { + "stdout": "http://e/?e\n", + "returncode": 0 + } + }, + { + "input": { + "arguments": [ + "e?e&&&&&&&&&&&&&&&&&&&&&" + ] + }, + "expected": { + "stdout": "http://e/?e\n", + "returncode": 0 + } + }, + { + "input": { + "arguments": [ + "e?e&&&&&&&&&&a&&&&&&&&&&&" + ] + }, + "expected": { + "stdout": "http://e/?e&a\n", + "returncode": 0 + } } ] diff --git a/trurl.c b/trurl.c index a0fdc652..b5a716ca 100644 --- a/trurl.c +++ b/trurl.c @@ -1572,8 +1572,8 @@ static void qpair2query(CURLU *uh, struct option *o) for(i = 0; iqsep : "", - qpairs[i].str); + (nq && *nq && qpairs[i].len) ? o->qsep : "", + qpairs[i].len ? qpairs[i].str : ""); curl_free(oldnq); } if(nq) { From 86e17e7e73b2f775ed2f5f0e4c3a4ab72811d411 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 12 Feb 2025 13:55:48 +0100 Subject: [PATCH 08/12] checksrc.pl: move into the scripts/ dir --- Makefile | 2 +- checksrc.pl => scripts/checksrc.pl | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename checksrc.pl => scripts/checksrc.pl (100%) diff --git a/Makefile b/Makefile index 09318242..535eb583 100644 --- a/Makefile +++ b/Makefile @@ -81,7 +81,7 @@ test-memory: $(TARGET) .PHONY: checksrc checksrc: - ./checksrc.pl trurl.c version.h + ./scripts/checksrc.pl trurl.c version.h .PHONY: completions completions: trurl.md diff --git a/checksrc.pl b/scripts/checksrc.pl similarity index 100% rename from checksrc.pl rename to scripts/checksrc.pl From 53fd1d42aecc9e04d9b8c44b8a9ecb2dcff122f2 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Wed, 12 Feb 2025 13:57:01 +0100 Subject: [PATCH 09/12] mkrelease: move script into scripts/ --- RELEASE-PROCEDURE.md | 2 +- mkrelease => scripts/mkrelease | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename mkrelease => scripts/mkrelease (100%) diff --git a/RELEASE-PROCEDURE.md b/RELEASE-PROCEDURE.md index 90fa0a24..f09b8840 100644 --- a/RELEASE-PROCEDURE.md +++ b/RELEASE-PROCEDURE.md @@ -6,7 +6,7 @@ in the source code repo - edit `RELEASE-NOTES` to be accurate -- run `./mkrelease [version]` +- run `./scripts/mkrelease [version]` - make sure all relevant changes are committed on the master branch diff --git a/mkrelease b/scripts/mkrelease similarity index 100% rename from mkrelease rename to scripts/mkrelease From 859616a783806d6d87cbdd5645d3448f19481a59 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Fri, 9 May 2025 15:30:42 +0200 Subject: [PATCH 10/12] generate_completions.sh: move to scripts/ --- Makefile | 4 ++-- {completions => scripts}/generate_completions.sh | 0 2 files changed, 2 insertions(+), 2 deletions(-) rename {completions => scripts}/generate_completions.sh (100%) diff --git a/Makefile b/Makefile index 535eb583..8192781f 100644 --- a/Makefile +++ b/Makefile @@ -39,7 +39,7 @@ PREFIX ?= /usr/local BINDIR ?= $(PREFIX)/bin MANDIR ?= $(PREFIX)/share/man/man1 ZSH_COMPLETIONSDIR ?= $(PREFIX)/share/zsh/site-functions -COMPLETION_FILES=completions/_trurl.zsh +COMPLETION_FILES=scripts/_trurl.zsh INSTALL ?= install PYTHON3 ?= python3 @@ -85,4 +85,4 @@ checksrc: .PHONY: completions completions: trurl.md - ./completions/generate_completions.sh $^ + ./scripts/generate_completions.sh $^ diff --git a/completions/generate_completions.sh b/scripts/generate_completions.sh similarity index 100% rename from completions/generate_completions.sh rename to scripts/generate_completions.sh From 77684e92544651f22229c14d7d6d98705bc79f5c Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 12 May 2025 08:23:45 +0200 Subject: [PATCH 11/12] RELEASE-NOTES: add 0.16.1 details --- RELEASE-NOTES | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 7886006c..0fe6a84d 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -1,20 +1,15 @@ -# trurl 0.16 - -## News - -- introduce --qtrim for trimming queries (only) -- Lots of new tests -- Expanded documentation +# trurl 0.16.1 ## Bugfixes -- normalize the fragment -- make sure URL encoded %-hex is done lowercase -- silence --replace-append when appending -- normalize user, password and options -- clarify the --help text for --urlencode -- fix a few returns codes for out of memory +- COPYING: add the "and many contributors" text from the curl license +- scripts: import cd2nroff from curl +- trurl: handle zero length query pairs +- trurl.md: fix typo in --replace-append +- Update README.md to link to the getting trurl wiki page +- Autogenerate ZSH completions based on trurl.md +- Makefile: only create MANDIR when manpage is installed Contributors to this release: - Daniel Stenberg + Daniel Stenberg, Jacob Mealey, Sertonix From b3c52ef9f84c5f31cebc0c1e05dcccaf298965e7 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 12 May 2025 08:24:10 +0200 Subject: [PATCH 12/12] RELEASE: 0.16.1 --- trurl.md | 2 +- version.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/trurl.md b/trurl.md index 123210b5..f47c7bbe 100644 --- a/trurl.md +++ b/trurl.md @@ -3,7 +3,7 @@ c: Copyright (C) Daniel Stenberg, , et al. SPDX-License-Identifier: curl Title: trurl Section: 1 -Source: trurl 0.16 +Source: trurl 0.16.1 See-also: - curl (1) - wcurl (1) diff --git a/version.h b/version.h index 9706338c..1d020d38 100644 --- a/version.h +++ b/version.h @@ -24,6 +24,6 @@ * ***************************************************************************/ -#define TRURL_VERSION_TXT "0.16" +#define TRURL_VERSION_TXT "0.16.1" #endif