WIP path: Make extensions start at the "."

This includes the "." in what `path extension` prints.

This allows distinguishing between an empty extension (just `.`) and a
non-existent extension (no `.` at all).
This commit is contained in:
Fabian Homborg 2021-12-09 16:36:17 +01:00
parent 17a8dd8f62
commit 1c1e643218
3 changed files with 26 additions and 15 deletions

View file

@ -109,9 +109,9 @@ Examples
path extension [(-z | --null-in)] [(-Z | --null-out)] [(-q | --quiet)] [PATH...] path extension [(-z | --null-in)] [(-Z | --null-out)] [(-q | --quiet)] [PATH...]
``path extension`` returns the extension of the given path. This is the part after (and excluding) the last ".", unless that "." followed a "/" or the basename is "." or "..", in which case there is no extension and nothing is printed. ``path extension`` returns the extension of the given path. This is the part after (and including) the last ".", unless that "." followed a "/" or the basename is "." or "..", in which case there is no extension and an empty line is printed.
If the filename ends in a ".", the extension is empty, so an empty line will be printed. If the filename ends in a ".", only a "." is printed.
It returns 0 if there was an extension. It returns 0 if there was an extension.
@ -121,19 +121,19 @@ Examples
:: ::
>_ path extension ./foo.mp4 >_ path extension ./foo.mp4
mp4 .mp4
>_ path extension ../banana >_ path extension ../banana
# nothing, status 1 # an empty line, status 1
>_ path extension ~/.config >_ path extension ~/.config
# nothing, status 1 # an empty line, status 1
>_ path extension ~/.config.d >_ path extension ~/.config.d
d .d
>_ path extension ~/.config. >_ path extension ~/.config.
# one empty line, status 0 .
.. _cmd-path-filter: .. _cmd-path-filter:
@ -281,10 +281,12 @@ Examples
path change-extension [(-z | --null-in)] [(-Z | --null-out)] \ path change-extension [(-z | --null-in)] [(-Z | --null-out)] \
[(-q | --quiet)] EXTENSION [PATH...] [(-q | --quiet)] EXTENSION [PATH...]
``path change-extension`` returns the given paths, with their extension changed to the given new extension. The extension is the part after (and excluding) the last ".", unless that "." followed a "/" or the basename is "." or "..", in which case there is no previous extension and the new one is simply added. ``path change-extension`` returns the given paths, with their extension changed to the given new extension. The extension is the part after (and including) the last ".", unless that "." followed a "/" or the basename is "." or "..", in which case there is no previous extension and the new one is simply added.
If the extension is empty, any previous extension is stripped, along with the ".". This is, of course, the inverse of ``path extension``. If the extension is empty, any previous extension is stripped, along with the ".". This is, of course, the inverse of ``path extension``.
One leading dot on the extension is ignored, so ".mp3" and "mp3" are treated the same.
It returns 0 if it was given any paths. It returns 0 if it was given any paths.
Examples Examples
@ -295,6 +297,9 @@ Examples
>_ path change-extension mp4 ./foo.wmv >_ path change-extension mp4 ./foo.wmv
./foo.mp4 ./foo.mp4
>_ path change-extension .mp4 ./foo.wmv
./foo.mp4
>_ path change-extension '' ../banana >_ path change-extension '' ../banana
../banana ../banana
# but status 1, because there was no extension. # but status 1, because there was no extension.

View file

@ -580,7 +580,7 @@ static int path_extension(parser_t &parser, io_streams_t &streams, int argc, con
if (!pos) continue; if (!pos) continue;
wcstring ext = arg->substr(*pos + 1); wcstring ext = arg->substr(*pos);
if (opts.quiet && !ext.empty()) { if (opts.quiet && !ext.empty()) {
return STATUS_CMD_OK; return STATUS_CMD_OK;
} }
@ -612,7 +612,9 @@ static int path_change_extension(parser_t &parser, io_streams_t &streams, int ar
// Only add on the extension "." if we have something. // Only add on the extension "." if we have something.
// That way specifying an empty extension strips it. // That way specifying an empty extension strips it.
if (*opts.arg1) { if (*opts.arg1) {
ext.push_back(L'.'); if (opts.arg1[0] != L'.') {
ext.push_back(L'.');
}
ext.append(opts.arg1); ext.append(opts.arg1);
} }
path_out(streams, opts, ext); path_out(streams, opts, ext);

View file

@ -21,7 +21,7 @@ or echo None once more
# CHECK: None once more # CHECK: None once more
path extension /foo.txt path extension /foo.txt
and echo Success and echo Success
# CHECK: txt # CHECK: .txt
# CHECK: Success # CHECK: Success
path extension /foo.txt/bar path extension /foo.txt/bar
or echo Not even here or echo Not even here
@ -30,7 +30,7 @@ path extension . ..
or echo No extension or echo No extension
# CHECK: No extension # CHECK: No extension
path extension ./foo.mp4 path extension ./foo.mp4
# CHECK: mp4 # CHECK: .mp4
path extension ../banana path extension ../banana
# nothing, status 1 # nothing, status 1
echo $status echo $status
@ -40,15 +40,19 @@ path extension ~/.config
echo $status echo $status
# CHECK: 1 # CHECK: 1
path extension ~/.config.d path extension ~/.config.d
# CHECK: d # CHECK: .d
path extension ~/.config. path extension ~/.config.
echo $status echo $status
# one empty line, status 0 # status 0
# CHECK: # CHECK: .
# CHECK: 0 # CHECK: 0
path change-extension '' ./foo.mp4 path change-extension '' ./foo.mp4
# CHECK: ./foo # CHECK: ./foo
path change-extension wmv ./foo.mp4
# CHECK: ./foo.wmv
path change-extension .wmv ./foo.mp4
# CHECK: ./foo.wmv
path change-extension '' ../banana path change-extension '' ../banana
# CHECK: ../banana # CHECK: ../banana
# still status 0, because there was an argument # still status 0, because there was an argument