diff options
author | Sergey Poznyakoff <gray@gnu.org> | 2020-04-27 09:28:38 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org> | 2020-04-27 09:28:38 +0300 |
commit | e19cf8e1303700b5b2e4f3e525285f63a3c7b51f (patch) | |
tree | 3d104c781bdc181fac49d38402e10f0bca9f1610 /src/directive.c | |
parent | 563d555bc14424066973a4dbc92123d308344a49 (diff) | |
download | wydawca-e19cf8e1303700b5b2e4f3e525285f63a3c7b51f.tar.gz wydawca-e19cf8e1303700b5b2e4f3e525285f63a3c7b51f.tar.bz2 |
Minor improvement
* src/directive.c (directive_parse): Optimize two sequential directives
referring for filename and filename.sig
Diffstat (limited to 'src/directive.c')
-rw-r--r-- | src/directive.c | 91 |
1 files changed, 91 insertions, 0 deletions
diff --git a/src/directive.c b/src/directive.c index f6c9a83..8e7afeb 100644 --- a/src/directive.c +++ b/src/directive.c @@ -18,6 +18,74 @@ /* Directive file support */ +#define ISSPACE(c) ((c)==' '||(c)=='\t') + +/* + * An auxiliary function to compare two directive lines. + * If A and B have the same directive name portion, analyze the directive + * argument (or arguments, in case of "symlink". If each argument of B + * is the corresponding argument of A plus the ".sig" suffix, return 1. + * If the relation is the reverse (arg(A) = arg(B) + ".sig"), return -1. + * Otherwise, return 0. + */ +static int +str_dirname_sig(char const *a, char const *b) +{ + char const *p = a; + int arg2; + + while (1) { + if (*a != *b) + return 0; + if (*a == 0 || *a == ':') + break; + a++; + b++; + } + + arg2 = (a-p+1 == sizeof("symlink") && memcmp(p, "symlink", a-p) == 0); + + do { + if (!*++a) + return 0; + } while (ISSPACE(*a)); + + do { + if (!*++b) + return 0; + } while (ISSPACE(*b)); + + while (*a && *b) { + if (*a != *b) { + if (arg2) { + if (ISSPACE(*a) && strncmp(b, ".sig", 4) == 0) { + arg2 = 1; + b += 4; + } else if (ISSPACE(*b) && strncmp(a, ".sig", 4) == 0) { + arg2 = -1; + a += 4; + } else + return 0; + while (*a && ISSPACE(*a)) + a++; + while (*b && ISSPACE(*b)) + b++; + } else + return 0; + } + a++; + b++; + } + + if (*a == 0 && strcmp(b, ".sig") == 0) + return (arg2 == 0 || arg2 == 1) ? 1 : 0; + + if (*b == 0 && strcmp(a, ".sig") == 0) + return (arg2 == 0 || arg2 == -1) ? -1 : 0; + + return 0; +} + /* Parse directives from TRP->blurb. Fill TRP->directive */ int directive_parse(struct wy_triplet *trp) @@ -49,6 +117,29 @@ directive_parse(struct wy_triplet *trp) trp->directive = NULL; return 1; } + if (j > 1) { + /* + * The gnupload script (as of version 2018-05-19.18) when given the + * --symlink-regex option generates two symlink directives in + * sequence: the first one for the filename, and second one + * for filename.sig. This contradicts The Automated FTP Uploads + * specification, which says that: + * + * "The .sig file should not be explicitly mentioned in a + * directive. When you specify a directive to operate on + * a file, its corresponding .sig file will be handled + * automatically." + * + * The following optimizes this case. + */ + switch (str_dirname_sig(trp->directive[j-1], trp->directive[j])) { + case 1: + continue; + case -1: + trp->directive[j-1] = trp->directive[j]; + continue; + } + } j++; if (!p) break; |