Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package trurl for openSUSE:Factory checked 
in at 2024-06-03 17:43:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/trurl (Old)
 and      /work/SRC/openSUSE:Factory/.trurl.new.24587 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "trurl"

Mon Jun  3 17:43:24 2024 rev:12 rq:1178135 version:0.13

Changes:
--------
--- /work/SRC/openSUSE:Factory/trurl/trurl.changes      2024-04-23 
18:57:21.157232951 +0200
+++ /work/SRC/openSUSE:Factory/.trurl.new.24587/trurl.changes   2024-06-03 
17:43:30.635138445 +0200
@@ -1,0 +2,10 @@
+Wed May 15 15:47:08 UTC 2024 - Martin Hauke <mar...@gmx.de>
+
+- Update to version 0.13
+  * Free allocated pointer on OOM error.
+  * short options need no space separation for the argument anymore
+  * trurl.1: use present tense.
+  * trurl: only append the first iterate loop.
+  * fix Coverity nits.
+
+-------------------------------------------------------------------

Old:
----
  trurl-0.12.tar.gz

New:
----
  trurl-0.13.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ trurl.spec ++++++
--- /var/tmp/diff_new_pack.hND1uu/_old  2024-06-03 17:43:31.271161885 +0200
+++ /var/tmp/diff_new_pack.hND1uu/_new  2024-06-03 17:43:31.271161885 +0200
@@ -18,7 +18,7 @@
 
 
 Name:           trurl
-Version:        0.12
+Version:        0.13
 Release:        0
 Summary:        Command line tool for URL parsing and manipulation
 License:        MIT

++++++ trurl-0.12.tar.gz -> trurl-0.13.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/trurl-trurl-0.12/.github/workflows/codeql.yml 
new/trurl-trurl-0.13/.github/workflows/codeql.yml
--- old/trurl-trurl-0.12/.github/workflows/codeql.yml   2024-04-18 
22:13:05.000000000 +0200
+++ new/trurl-trurl-0.13/.github/workflows/codeql.yml   2024-05-15 
08:23:20.000000000 +0200
@@ -34,11 +34,11 @@
 
     steps:
       - name: Checkout repository
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       # Initializes the CodeQL tools for scanning.
       - name: Initialize CodeQL
-        uses: github/codeql-action/init@v2
+        uses: github/codeql-action/init@v3
         with:
           languages: ${{ matrix.language }}
 
@@ -51,6 +51,6 @@
         run: make
 
       - name: Perform CodeQL Analysis
-        uses: github/codeql-action/analyze@v2
+        uses: github/codeql-action/analyze@v3
         with:
           category: "/language:${{matrix.language}}"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/trurl-trurl-0.12/.github/workflows/codespell.yml 
new/trurl-trurl-0.13/.github/workflows/codespell.yml
--- old/trurl-trurl-0.12/.github/workflows/codespell.yml        2024-04-18 
22:13:05.000000000 +0200
+++ new/trurl-trurl-0.13/.github/workflows/codespell.yml        2024-05-15 
08:23:20.000000000 +0200
@@ -5,7 +5,7 @@
     runs-on: ubuntu-latest
     steps:
       - name: Checkout repository
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
 
       - name: install codespell
         run: |
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/trurl-trurl-0.12/.github/workflows/curl-for-win.yml 
new/trurl-trurl-0.13/.github/workflows/curl-for-win.yml
--- old/trurl-trurl-0.12/.github/workflows/curl-for-win.yml     2024-04-18 
22:13:05.000000000 +0200
+++ new/trurl-trurl-0.13/.github/workflows/curl-for-win.yml     2024-05-15 
08:23:20.000000000 +0200
@@ -49,7 +49,7 @@
 
       - name: 'list dependencies'
         run: cat urls.txt
-      - uses: actions/upload-artifact@v3
+      - uses: actions/upload-artifact@v4
         with:
           name: 'trurl-windows'
           retention-days: 5
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/trurl-trurl-0.12/.github/workflows/makefile.yml 
new/trurl-trurl-0.13/.github/workflows/makefile.yml
--- old/trurl-trurl-0.12/.github/workflows/makefile.yml 2024-04-18 
22:13:05.000000000 +0200
+++ new/trurl-trurl-0.13/.github/workflows/makefile.yml 2024-05-15 
08:23:20.000000000 +0200
@@ -25,7 +25,7 @@
               LDFLAGS="-fsanitize=address,undefined,signed-integer-overflow -g"
 
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
 
       - name: install libcurl
         run: |
@@ -48,7 +48,7 @@
     runs-on: windows-latest
 
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
 
       - name: install cygwin
         uses: cygwin/cygwin-install-action@master
@@ -68,7 +68,7 @@
     runs-on: macos-latest
 
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
 
       - name: make
         run: make
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/trurl-trurl-0.12/.github/workflows/reuse.yml 
new/trurl-trurl-0.13/.github/workflows/reuse.yml
--- old/trurl-trurl-0.12/.github/workflows/reuse.yml    2024-04-18 
22:13:05.000000000 +0200
+++ new/trurl-trurl-0.13/.github/workflows/reuse.yml    2024-05-15 
08:23:20.000000000 +0200
@@ -24,6 +24,6 @@
   check:
     runs-on: ubuntu-latest
     steps:
-    - uses: actions/checkout@v3
+    - uses: actions/checkout@v4
     - name: REUSE Compliance Check
       uses: fsfe/reuse-action@v1
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/trurl-trurl-0.12/CONTRIBUTING.md 
new/trurl-trurl-0.13/CONTRIBUTING.md
--- old/trurl-trurl-0.12/CONTRIBUTING.md        2024-04-18 22:13:05.000000000 
+0200
+++ new/trurl-trurl-0.13/CONTRIBUTING.md        2024-05-15 08:23:20.000000000 
+0200
@@ -36,7 +36,7 @@
 `test.py` will also skip tests that require a specific curl runtime or 
buildtime.
 
 ### Adding tests
-tests are located in 
[tests.json](https://github.com/curl/trurl/blob/master/tests.json). This file 
is an array of json objects when outline an input and what the expected
+Tests are located in 
[tests.json](https://github.com/curl/trurl/blob/master/tests.json). This file 
is an array of json objects when outline an input and what the expected
 output should be. Below is a simple example of a single test:
 ```json
     {
@@ -72,7 +72,7 @@
     }
 ```
 trurl may also return json. It you are adding a test that returns json to 
stdout, write the json directly instead of a string in the examples above. 
Below is an example
-of what stdout should be if it is a json test, where `"input"` is what trul 
accepts from the command line and `"expected"` is what trurl should return.
+of what stdout should be if it is a json test, where `"input"` is what trurl 
accepts from the command line and `"expected"` is what trurl should return.
 ```json
 "expected": {
     "stdout": [
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/trurl-trurl-0.12/RELEASE-NOTES 
new/trurl-trurl-0.13/RELEASE-NOTES
--- old/trurl-trurl-0.12/RELEASE-NOTES  2024-04-18 22:13:05.000000000 +0200
+++ new/trurl-trurl-0.13/RELEASE-NOTES  2024-05-15 08:23:20.000000000 +0200
@@ -1,17 +1,17 @@
-# trurl 0.12
+# trurl 0.13
 
 ## What's Changed
 
-- This is the same as 0.11 but with the version string set correctly
-
-- check valgrind function by @eh-san in #273
-- Added UTF-8 detection to test runner by @jacobmealey in #276
-- use of free() instead of curl_free() by @bagder in #283
-- output the list of components correctly in the help output by @bagder in #282
-- if query is not updated, leave it untouched by @bagder in #284
-- expand the warning on "internal problem" by @bagder in #285
-- error when using an unrecognized URL component by @bagder in #286
+ - (also) support --flag=argument style for long options
+ - fix unchecked return values from libcurl calls
+ - fixed typos
+ - free allocated pointer on OOM error
+ - memdupdec: free memory in OOM exit path
+ - only --append in the first iterate loop
+ - short options need no space separation for the argument anymore
+ - support ?= for set, to only do it if not already set
+ - trurl.1: use present tense
 
 Contributors to this release:
 
-  Daniel Stenberg, Jacob Mealey, Ehsan
+ Daniel Gustafsson, Daniel Stenberg, Jacob Mealey, Viktor Szakats
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/trurl-trurl-0.12/tests.json 
new/trurl-trurl-0.13/tests.json
--- old/trurl-trurl-0.12/tests.json     2024-04-18 22:13:05.000000000 +0200
+++ new/trurl-trurl-0.13/tests.json     2024-05-15 08:23:20.000000000 +0200
@@ -151,6 +151,32 @@
     {
         "input": {
             "arguments": [
+                "-shost=moo",
+                "-sscheme=http"
+            ]
+        },
+        "expected": {
+            "stdout": "http://moo/\n";,
+            "stderr": "",
+            "returncode": 0
+        }
+    },
+    {
+        "input": {
+            "arguments": [
+                "--set=host=moo",
+                "--set=scheme=http"
+            ]
+        },
+        "expected": {
+            "stdout": "http://moo/\n";,
+            "stderr": "",
+            "returncode": 0
+        }
+    },
+    {
+        "input": {
+            "arguments": [
                 "-s",
                 "host=moo",
                 "-s",
@@ -322,6 +348,20 @@
     {
         "input": {
             "arguments": [
+                "--url",
+                "https://curl.se/we/are.html";,
+                "-g{path}"
+            ]
+        },
+        "expected": {
+            "stdout": "/we/are.html\n",
+            "stderr": "",
+            "returncode": 0
+        }
+    },
+    {
+        "input": {
+            "arguments": [
                 "--default-port",
                 "--url",
                 "imap://curl.se/we/are.html",
@@ -2444,5 +2484,65 @@
           "stderr": "",
           "returncode": 0
       }
+  },
+  {
+      "input": {
+          "arguments": [
+              "example.com:88",
+              "--set",
+              "port?=99"
+          ]
+      },
+      "expected": {
+          "stdout": "http://example.com:88/\n";,
+          "stderr": "",
+          "returncode": 0
+      }
+  },
+  {
+      "input": {
+          "arguments": [
+              "example.com",
+              "--set",
+              "port?=99"
+          ]
+      },
+      "expected": {
+          "stdout": "http://example.com:99/\n";,
+          "stderr": "",
+          "returncode": 0
+      }
+  },
+  {
+      "input": {
+          "arguments": [
+              "example.com",
+              "--append",
+              "query=add",
+              "--iterate",
+              "scheme=http ftp"
+          ]
+      },
+      "expected": {
+          "stdout": "http://example.com/?add\nftp://example.com/?add\n";,
+          "stderr": "",
+          "returncode": 0
+      }
+  },
+  {
+      "input": {
+          "arguments": [
+              "example.com",
+              "--append",
+              "path=add",
+              "--iterate",
+              "scheme=http ftp"
+          ]
+      },
+      "expected": {
+          "stdout": "http://example.com/add\nftp://example.com/add\n";,
+          "stderr": "",
+          "returncode": 0
+      }
   }
 ]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/trurl-trurl-0.12/trurl.1 new/trurl-trurl-0.13/trurl.1
--- old/trurl-trurl-0.12/trurl.1        2024-04-18 22:13:05.000000000 +0200
+++ new/trurl-trurl-0.13/trurl.1        2024-05-15 08:23:20.000000000 +0200
@@ -55,6 +55,8 @@
 options; any argument after the end of options is interpreted as a URL
 argument even if it starts with a dash.
 
+Long options can be provided either as "--flag argument" or as
+"--flag=argument".
 .IP "-a, --append [component]=[data]"
 Append data to a component. This can only append data to the path and the
 query components.
@@ -64,16 +66,16 @@
 
 For query, this URL encodes and appends the new segment to the query,
 separated with an ampersand (&). If the appended segment contains an equal
-sign ('=') that one will be kept verbatim and both sides of the first
-occurrence will be URL encoded separately.
+sign ('=') that one is kept verbatim and both sides of the first
+occurrence are URL encoded separately.
 .IP "--accept-space"
-When set, trurl will try to accept spaces as part of the URL and instead URL
+When set, trurl tries to accept spaces as part of the URL and instead URL
 encode such occurrences accordingly.
 
 According to RFC 3986, a space cannot legally be part of a URL. This option
 provides a best-effort to convert the provided string into a valid URL.
 .IP "--default-port"
-When set, trurl will use the scheme's default port number for URLs with a known
+When set, trurl uses the scheme's default port number for URLs with a known
 scheme, and without an explicit port number.
 
 Note that trurl only knows default port numbers for URL schemes that are
@@ -86,9 +88,9 @@
 Read URLs to work on from the given file. Use the file name "-" (a single
 minus) to tell trurl to read the URLs from stdin.
 
-Each line needs to be a single valid URL. trurl will remove one carriage return
-character at the end of the line if present, trim off all the trailing space 
and
-tab characters, and skip all empty (after trimming) lines.
+Each line needs to be a single valid URL. trurl removes one carriage return
+character at the end of the line if present, trims off all the trailing space
+and tab characters, and skips all empty (after trimming) lines.
 
 The maximum line length supported in a file like this is 4094 bytes. Lines that
 exceed that length are skipped, and a warning is printed to stderr when they 
are
@@ -103,7 +105,7 @@
 The following component names are available (case sensitive): url, scheme,
 user, password, options, host, port, path, query, fragment and zoneid.
 
-\fB{component}\fP will expand to nothing if the given component does
+\fB{component}\fP expands to nothing if the given component does
 not have a value.
 
 Components are shown URL decoded by default. If you instead write the
@@ -114,36 +116,36 @@
 
 If \fBdefault:\fP is specified, like "{default:url}" or
 "{default:port}", and the port is not explicitly specified in the URL,
-the scheme's default port will be output if it is known.
+the scheme's default port is output if it is known.
 
 If \fBpuny:\fP is specified, like "{puny:url}" or "{puny:host}", the
-"punycoded" version of the host name will be used in the output. This
+"punycoded" version of the host name is used in the output. This
 option is mutually exclusive with \fBidn:\fP.
 
 If \fBidn:\fP is specified like "{idn:url}" or "{idn:host}", the International
-Domain Name version of the host name will be used in the output if it is 
provided as a correctly encoded punycode version. This
-option is mutually exclusive with \fBpuny:\fP.
+Domain Name version of the host name is used in the output if it is provided as
+a correctly encoded punycode version. This option is mutually exclusive with 
\fBpuny:\fP.
 
 If \fI--default-port\fP is specified, all formats are expanded as if
 they used \fIdefault:\fP; and if \fI--punycode\fP is used, all formats
 are expanded as if they used \fIpuny:\fP. Also note that "{url}" is
 affected by the \fI--keep-port\fP option.
 
-Hosts provided as IPv6 numerical addresses will be provided within square
+Hosts provided as IPv6 numerical addresses are provided within square
 brackets. Like "[fe80::20c:29ff:fe9c:409b]".
 
-Hosts provided as IPv4 numerical addresses will be "normalized" and provided
+Hosts provided as IPv4 numerical addresses are "normalized" and provided
 as four dot-separated decimal numbers when output.
 
 You can access specific keys in the query string using the format
-\fB{query:key}\fP. Then the value of the first matching key will be output
+\fB{query:key}\fP. Then the value of the first matching key is output
 using a case sensitive match. When extracting a URL decoded query key that
-contains %00, such octet will be replaced with a single period '.' in the
+contains %00, such octet is replaced with a single period '.' in the
 output.
 
 You can access specific keys in the query string and out all values using the
-format \fB{query-all:key}\fP. This looks for 'key' case sensitively and will
-output all values for that key space-separated.
+format \fB{query-all:key}\fP. This looks for 'key' case sensitively and
+outputs all values for that key space-separated.
 
 The "format" string supports the following backslash sequences:
 
@@ -159,7 +161,7 @@
 
 \&\\[ - an open bracket that does not start a variable
 
-All other text in the format string will be shown as-is.
+All other text in the format string is shown as-is.
 .IP "-h, --help"
 Show the help output.
 .IP "--iterate [component]=[item1 item2 ...]"
@@ -169,15 +171,15 @@
 over should be separated by single spaces.
 .IP "--json"
 Outputs all set components of the URLs as JSON objects. All components of the
-URL that have data will get populated in the parts object using their
-component names. See below for details on the format.
+URL that have data get populated in the parts object using their component
+names. See below for details on the format.
 .IP "--keep-port"
 By default, trurl removes default port numbers from URLs with a known scheme
 even if they are explicitly specified in the input URL. This options, makes
 trurl not remove them.
 .IP "--no-guess-scheme"
 Disables libcurl's scheme guessing feature. URLs that do not contain a scheme
-will be treated as invalid URLs.
+are treated as invalid URLs.
 .IP "--punycode"
 Uses the "punycoded" version of the host name, which is how International 
Domain
 Names are converted into plain ASCII. If the host name is not using IDN, the
@@ -195,43 +197,47 @@
 .IP "--redirect [URL]"
 Redirect the URL to this new location.
 The redirection is performed on the base URL, so, if no base URL is specified,
-no redirection will be performed.
+no redirection is performed.
 .IP "--replace [data]"
 Replaces a URL query.
 
 data can either take the form of a single value, or as a key/value pair in the
 shape \fIfoo=bar\fP. If replace is called on an item that isn't in the list of
-queries trurl will ignore that item.
+queries trurl ignores that item.
 .IP "--force-replace [data]"
-Works the same as \fI--replace\fP, but trurl will append a missing query 
string if 
+Works the same as \fI--replace\fP, but trurl appends a missing query string if
 it is not in the query list already.
 .IP "-s, --set [component][:]=[data]"
-Set this URL component. Setting blank string ("") will clear the component
+Set this URL component. Setting blank string ("") clears the component
 from the URL.
 
 The following components can be set: url, scheme, user, password,
 options, host, port, path, query, fragment and zoneid.
 
 If a simple "="-assignment is used, the data is URL encoded when applied. If
-":=" is used, the data is assumed to already be URL encoded and will be stored
-as-is.
+":=" is used, the data is assumed to already be URL encoded and stored as-is.
 
-If no URL or \fI--url-file\fP argument is provided, trurl will try to create
+If "?=" is used, the set is only performed if the component is not already
+set. It avoids overwriting any already set data.
+
+You can also combine : and ? into "?:=" if desired.
+
+If no URL or \fI--url-file\fP argument is provided, trurl tries to create
 a URL using the components provided by the \fI--set\fP options. If not enough
-components are specified, this will fail.
+components are specified, this fails.
 .IP "--sort-query"
 The "variable=content" tuplets in the query component are sorted in a case
 insensitive alphabetical order. This helps making URLs identical that
 otherwise only had their query pairs in different orders.
 .IP "--url [URL]"
 Set the input URL to work with. The URL may be provided without a scheme,
-which then typically is not actually a legal URL but trurl will try to figure
+which then typically is not actually a legal URL but trurl tries to figure
 out what is meant and guess what scheme to use (unless \fI--no-guess-scheme\fP
 is used).
 
-Providing multiple URLs will make trurl act on all URLs in a serial fashion.
+Providing multiple URLs makes trurl act on all URLs in a serial fashion.
 
-If the URL cannot be parsed for whatever reason, trurl will simply move on to
+If the URL cannot be parsed for whatever reason, trurl simply moves on to
 the next provided URL - unless \fI--verify\fP is used.
 .IP "--urlencode"
 Outputs URL encoded version of components by default when using \fI--get\fP or
@@ -292,7 +298,7 @@
 .B "port"
 The provided port number as a string. If the port number was not provided in 
the
 URL, but the scheme is a known one, and \fI--default-port\fP is in use, the
-default port for that scheme will be provided here.
+default port for that scheme is provided here.
 .TP
 .B "path"
 The path. Including the leading slash.
@@ -335,7 +341,7 @@
 https://curl.se/we/here.html
 .fi
 .IP "Change port number"
-This also shows how trurl will remove dot-dot sequences
+This also shows how trurl removes dot-dot sequences
 .nf
 $ trurl --url https://curl.se/we/../are.html --set port=8080
 https://curl.se:8080/are.html
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/trurl-trurl-0.12/trurl.c new/trurl-trurl-0.13/trurl.c
--- old/trurl-trurl-0.12/trurl.c        2024-04-18 22:13:05.000000000 +0200
+++ new/trurl-trurl-0.13/trurl.c        2024-05-15 08:23:20.000000000 +0200
@@ -488,13 +488,26 @@
   if(n)
     o->replace_list = n;
 }
-static bool checkoptarg(struct option *o, const char *str,
+
+static bool longarg(const char *flag, const char *check)
+{
+  /* the given flag might end with an equals sign */
+  size_t len = strlen(flag);
+  return (!strcmp(flag, check) ||
+          (!strncmp(flag, check, len) && check[len] == '='));
+}
+
+static bool checkoptarg(struct option *o, const char *flag,
                         const char *given,
                         const char *arg)
 {
-  if(!strcmp(str, given)) {
+  bool shortopt = false;
+  if((flag[0] == '-') && (flag[1] != '-'))
+    shortopt = true;
+  if((!shortopt && longarg(flag, given)) ||
+     (!strncmp(flag, given, 2) && shortopt)) {
     if(!arg)
-      errorf(o, ERROR_ARG, "Missing argument for %s", str);
+      errorf(o, ERROR_ARG, "Missing argument for %s", flag);
     return true;
   }
   return false;
@@ -505,8 +518,21 @@
                   const char *arg,
                   bool *usedarg)
 {
+  bool gap = true;
   *usedarg = false;
 
+  if((flag[0] == '-') && (flag[1] != '-') && flag[2]) {
+    arg = (char *)&flag[2];
+    gap = false;
+  }
+  else if((flag[0] == '-') && (flag[1] == '-')) {
+    char *equals = strchr(&flag[2], '=');
+    if(equals) {
+      arg = (char *)&equals[1];
+      gap = false;
+    }
+  }
+
   if(!strcmp("--", flag))
     o->end_of_options = true;
   else if(!strcmp("-v", flag) || !strcmp("--version", flag))
@@ -515,32 +541,32 @@
     help();
   else if(checkoptarg(o, "--url", flag, arg)) {
     urladd(o, arg);
-    *usedarg = true;
+    *usedarg = gap;
   }
   else if(checkoptarg(o, "-f", flag, arg) ||
           checkoptarg(o, "--url-file", flag, arg)) {
     urlfile(o, arg);
-    *usedarg = true;
+    *usedarg = gap;
   }
   else if(checkoptarg(o, "-a", flag, arg) ||
           checkoptarg(o, "--append", flag, arg)) {
     appendadd(o, arg);
-    *usedarg = true;
+    *usedarg = gap;
   }
   else if(checkoptarg(o, "-s", flag, arg) ||
           checkoptarg(o, "--set", flag, arg)) {
     setadd(o, arg);
-    *usedarg = true;
+    *usedarg = gap;
   }
   else if(checkoptarg(o, "--iterate", flag, arg)) {
     iteradd(o, arg);
-    *usedarg = true;
+    *usedarg = gap;
   }
   else if(checkoptarg(o, "--redirect", flag, arg)) {
     if(o->redirect)
       errorf(o, ERROR_FLAG, "only one --redirect is supported");
     o->redirect = arg;
-    *usedarg = true;
+    *usedarg = gap;
   }
   else if(checkoptarg(o, "--query-separator", flag, arg)) {
     if(o->qsep)
@@ -549,11 +575,11 @@
       errorf(o, ERROR_FLAG,
                    "only single-letter query separators are supported");
     o->qsep = arg;
-    *usedarg = true;
+    *usedarg = gap;
   }
   else if(checkoptarg(o, "--trim", flag, arg)) {
     trimadd(o, arg);
-    *usedarg = true;
+    *usedarg = gap;
   }
   else if(checkoptarg(o, "-g", flag, arg) ||
           checkoptarg(o, "--get", flag, arg)) {
@@ -561,13 +587,13 @@
       errorf(o, ERROR_FLAG, "only one --get is supported");
     if(o->jsonout)
       errorf(o, ERROR_FLAG,
-                   "--get is mututally exclusive with --json");
+                   "--get is mutually exclusive with --json");
     o->format = arg;
-    *usedarg = true;
+    *usedarg = gap;
   }
   else if(!strcmp("--json", flag)) {
     if(o->format)
-      errorf(o, ERROR_FLAG, "--json is mututally exclusive with --get");
+      errorf(o, ERROR_FLAG, "--json is mutually exclusive with --get");
     o->jsonout = true;
   }
   else if(!strcmp("--verify", flag))
@@ -606,12 +632,12 @@
     o->quiet_warnings = true;
   else if(!strcmp("--replace", flag)) {
     replaceadd(o, arg);
-    *usedarg = true;
+    *usedarg = gap;
   }
   else if(!strcmp("--force-replace", flag)) {
     replaceadd(o, arg);
     o->force_replace = true;
-    *usedarg = true;
+    *usedarg = gap;
   }
   else
     return 1;  /* unrecognized option */
@@ -873,20 +899,47 @@
   if(ptr && (ptr > setline)) {
     size_t vlen = ptr - setline;
     bool urlencode = true;
+    bool conditional = false;
     bool found = false;
-    if(ptr[-1] == ':') {
-      urlencode = false;
-      vlen--;
+    if(vlen) {
+      int back = -1;
+      size_t reqlen = 1;
+      while(vlen > reqlen) {
+        if(ptr[back] == ':') {
+          urlencode = false;
+          vlen--;
+        }
+        else if(ptr[back] == '?') {
+          conditional = true;
+          vlen--;
+        }
+        else
+          break;
+        reqlen++;
+        back--;
+      }
     }
     v = comp2var(setline, vlen);
     if(v) {
-      CURLUcode rc;
+      CURLUcode rc = CURLUE_OK;
+      bool skip = false;
       if((v->part == CURLUPART_HOST) && ('[' == ptr[1]))
         /* when setting an IPv6 numerical address, disable URL encoding */
         urlencode = false;
-      rc = curl_url_set(uh, v->part, ptr[1] ? &ptr[1] : NULL,
-                        (o->curl ? 0 : CURLU_NON_SUPPORT_SCHEME)|
-                        (urlencode ? CURLU_URLENCODE : 0) );
+
+      if(conditional) {
+        char *piece;
+        rc = curl_url_get(uh, v->part, &piece, 0);
+        if(!rc) {
+          skip = true;
+          curl_free(piece);
+        }
+      }
+
+      if(!skip)
+        rc = curl_url_set(uh, v->part, ptr[1] ? &ptr[1] : NULL,
+                          (o->curl ? 0 : CURLU_NON_SUPPORT_SCHEME)|
+                          (urlencode ? CURLU_URLENCODE : 0) );
       if(rc)
         warnf("Error setting %s: %s", v->name, curl_url_strerror(rc));
       found = true;
@@ -1122,18 +1175,21 @@
     char *p;
     int plen;
     right = strurldecode(sep + 1, (int)(len - (sep - source) - 1),
-            &right_len);
+                         &right_len);
 
     /* convert null bytes to periods */
     for(plen = right_len, p = right; plen; plen--, p++) {
       if(!*p && !json) {
         *p = REPLACE_NULL_BYTE;
       }
-     }
+    }
   }
   str = malloc(sizeof(char) * (left_len + (sep?(right_len + 1):0)));
-  if(!str)
+  if(!str) {
+    curl_free(right);
+    curl_free(left);
     return NULL;
+  }
   memcpy(str, left, left_len);
   if(sep) {
     str[left_len] = '=';
@@ -1143,6 +1199,7 @@
   curl_free(left);
   ret = malloc(sizeof(struct string));
   if(!ret) {
+    free(str);
     return NULL;
   }
   ret->str = str;
@@ -1342,6 +1399,7 @@
                       struct curl_slist *iter)
 {
   CURLU *uh = iinfo->uh;
+  bool first_lap = true;
   if(!uh) {
     uh = curl_url();
     if(!uh)
@@ -1431,9 +1489,10 @@
         wlen = strlen(w);
         iinfo->ptr = NULL;
       }
-      curl_msnprintf(iterbuf, sizeof(iterbuf), "%.*s%s=%.*s", (int)plen, part,
-                     urlencode ? "" : ":",
-                     (int)wlen, w);
+      (void)curl_msnprintf(iterbuf, sizeof(iterbuf),
+                           "%.*s%s=%.*s", (int)plen, part,
+                           urlencode ? "" : ":",
+                           (int)wlen, w);
       setone(uh, iterbuf, o);
       if(iter->next) {
         struct iterinfo info;
@@ -1444,29 +1503,33 @@
       }
     }
 
-    /* append path segments */
-    for(p = o->append_path; p; p = p->next) {
-      char *apath = p->data;
-      char *opath;
-      char *npath;
-      size_t olen;
-      /* extract the current path */
-      curl_url_get(uh, CURLUPART_PATH, &opath, 0);
-
-      /* does the existing path end with a slash, then don't
-         add one in between */
-      olen = strlen(opath);
-
-      /* append the new segment */
-      npath = curl_maprintf("%s%s%s", opath,
-                            opath[olen-1] == '/' ? "" : "/",
-                            apath);
-      if(npath) {
-        /* set the new path */
-        curl_url_set(uh, CURLUPART_PATH, npath, 0);
+    if(first_lap) {
+      /* append path segments */
+      for(p = o->append_path; p; p = p->next) {
+        char *apath = p->data;
+        char *opath;
+        char *npath;
+        size_t olen;
+        /* extract the current path */
+        if(curl_url_get(uh, CURLUPART_PATH, &opath, 0))
+          errorf(o, ERROR_ITER, "out of memory");
+
+        /* does the existing path end with a slash, then don't
+           add one in between */
+        olen = strlen(opath);
+
+        /* append the new segment */
+        npath = curl_maprintf("%s%s%s", opath,
+                              opath[olen-1] == '/' ? "" : "/",
+                              apath);
+        if(npath) {
+          /* set the new path */
+          if(curl_url_set(uh, CURLUPART_PATH, npath, 0))
+            errorf(o, ERROR_ITER, "out of memory");
+        }
+        curl_free(npath);
+        curl_free(opath);
       }
-      curl_free(npath);
-      curl_free(opath);
     }
 
     extractqpairs(uh, o);
@@ -1477,10 +1540,12 @@
     /* replace parts */
     replace(o);
 
-    /* append query segments */
-    for(p = o->append_query; p; p = p->next) {
-      addqpair(p->data, strlen(p->data), o->jsonout);
-      query_is_modified = true;
+    if(first_lap) {
+      /* append query segments */
+      for(p = o->append_query; p; p = p->next) {
+        addqpair(p->data, strlen(p->data), o->jsonout);
+        query_is_modified = true;
+      }
     }
 
     sortquery(o);
@@ -1549,6 +1614,7 @@
 
     o->urls++;
 
+    first_lap = false;
   } while(iinfo->ptr);
   if(!iinfo->uh)
     curl_url_cleanup(uh);
@@ -1567,8 +1633,12 @@
     bool usedarg = false;
     if(!o.end_of_options && argv[0][0] == '-') {
       /* dash-dash prefixed */
-      if(getarg(&o, argv[0], argv[1], &usedarg))
-        errorf(&o, ERROR_FLAG, "unknown option: %s", argv[0]);
+      if(getarg(&o, argv[0], argv[1], &usedarg)) {
+        /* if the long option ends with an equals sign, cut it there,
+           if it is a short option, show just two letters */
+        size_t not_e = argv[0][1] == '-' ? strcspn(argv[0], "=") : 2;
+        errorf(&o, ERROR_FLAG, "unknown option: %.*s", (int)not_e, argv[0]);
+      }
     }
     else {
       /* this is a URL */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/trurl-trurl-0.12/version.h 
new/trurl-trurl-0.13/version.h
--- old/trurl-trurl-0.12/version.h      2024-04-18 22:13:05.000000000 +0200
+++ new/trurl-trurl-0.13/version.h      2024-05-15 08:23:20.000000000 +0200
@@ -24,6 +24,6 @@
  *
  ***************************************************************************/
 
-#define TRURL_VERSION_TXT "0.12"
+#define TRURL_VERSION_TXT "0.13"
 
 #endif

Reply via email to