Streamline compression suffix detection

* src/suffix.c (struct compression_suffix):
Use arrays rather than pointers that need relocation.
All uses changed.
(compression_suffixes): Now const.
Omit trailing null entry; all uses changed.
(find_compression_suffix): Simplify length calculations.
No longer any need to call strlen.
This commit is contained in:
Paul Eggert
2024-11-01 09:40:36 -07:00
parent 317e4d6a3c
commit 23582f3445

View File

@@ -21,15 +21,17 @@
struct compression_suffix struct compression_suffix
{ {
const char *suffix; char suffix[sizeof "tbz2"]; /* "tbz2" is tied for longest. */
idx_t length; char program[max (max (max (sizeof GZIP_PROGRAM, sizeof COMPRESS_PROGRAM),
const char *program; max (sizeof BZIP2_PROGRAM, sizeof LZIP_PROGRAM)),
max (max (sizeof LZMA_PROGRAM, sizeof LZOP_PROGRAM),
max (sizeof XZ_PROGRAM, sizeof ZSTD_PROGRAM)))];
}; };
static struct compression_suffix compression_suffixes[] = { static struct compression_suffix const compression_suffixes[] = {
#define __CAT2__(a,b) a ## b #define __CAT2__(a,b) a ## b
#define S(s,p) #s, sizeof (#s) - 1, __CAT2__(p,_PROGRAM) #define S(s, p) #s, __CAT2__(p,_PROGRAM)
{ "tar", 3, NULL }, { "tar", "" },
{ S(gz, GZIP) }, { S(gz, GZIP) },
{ S(z, GZIP) }, { S(z, GZIP) },
{ S(tgz, GZIP) }, { S(tgz, GZIP) },
@@ -49,7 +51,6 @@ static struct compression_suffix compression_suffixes[] = {
{ S(txz, XZ) }, /* Slackware */ { S(txz, XZ) }, /* Slackware */
{ S(zst, ZSTD) }, { S(zst, ZSTD) },
{ S(tzst, ZSTD) }, { S(tzst, ZSTD) },
{ NULL }
#undef S #undef S
#undef __CAT2__ #undef __CAT2__
}; };
@@ -60,27 +61,22 @@ static struct compression_suffix compression_suffixes[] = {
there the length of NAME with that suffix stripped, or 0 if NAME has there the length of NAME with that suffix stripped, or 0 if NAME has
no suffix. */ no suffix. */
static struct compression_suffix const * static struct compression_suffix const *
find_compression_suffix (const char *name, idx_t *ret_len) find_compression_suffix (char const *name, idx_t *ret_len)
{ {
char *suf = strrchr (name, '.'); char const *suf = strrchr (name, '.');
if (suf && suf[1] != 0 && suf[1] != '/') if (suf && suf[1] != 0 && suf[1] != '/')
{ {
idx_t len;
struct compression_suffix *p;
suf++;
len = strlen (suf);
if (ret_len) if (ret_len)
*ret_len = strlen (name) - len - 1; *ret_len = suf - name;
suf++;
for (p = compression_suffixes; p->suffix; p++) for (struct compression_suffix const *p = compression_suffixes;
{ p < (compression_suffixes
if (p->length == len && memcmp (p->suffix, suf, len) == 0) + sizeof compression_suffixes / sizeof *compression_suffixes);
{ p++)
return p; if (strcmp (p->suffix, suf) == 0)
} return p;
}
} }
else if (ret_len) else if (ret_len)
*ret_len = 0; *ret_len = 0;
@@ -98,7 +94,7 @@ set_compression_program_by_suffix (const char *name, const char *defprog,
idx_t len; idx_t len;
struct compression_suffix const *p = find_compression_suffix (name, &len); struct compression_suffix const *p = find_compression_suffix (name, &len);
if (p) if (p)
use_compress_program_option = p->program; use_compress_program_option = p->program[0] ? p->program : NULL;
else else
{ {
use_compress_program_option = defprog; use_compress_program_option = defprog;