Compare commits

..

1 Commits

Author SHA1 Message Date
Xavier Roche
c0d94f867f The wizard-precedence comments restate the code (#1272)
Review of #1257 flagged seven comment blocks that restate the code or narrate the change rather than saying why. This trims them to the house one-line default: a five-line re-listing of httrack.c's query3 answer codes, an aside about where the scenarios abort, wording that called the counter a block size, and a six-line header on `hts_wizard_insert_filters`.

The contract facts stay. The log-echo caller reads back the range the function reports, so the return count and the placement of the inserted filters at the tail of the block are still documented at the declaration.

Comment-only: a whitespace-ignoring diff shows no code change.

Signed-off-by: Xavier Roche <xroche@gmail.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-14 22:50:02 +00:00
8 changed files with 18 additions and 85 deletions

View File

@@ -588,7 +588,6 @@ const char *optalias_help(const char *token) {
if it cannot. */
static hts_boolean cmdl_reserve(cmdl_argv *cmd, int count) {
char **slots;
hts_boolean *flags;
int capacity;
if (count <= cmd->capacity)
@@ -604,12 +603,6 @@ static hts_boolean cmdl_reserve(cmdl_argv *cmd, int count) {
if (slots == NULL)
return HTS_FALSE;
cmd->argv = slots;
/* hts_boolean is no wider than a pointer, so this cannot wrap either */
flags = (hts_boolean *) realloct(cmd->unquoted,
sizeof(hts_boolean) * (size_t) capacity);
if (flags == NULL) /* argv stays grown; capacity does not, so it is retried */
return HTS_FALSE;
cmd->unquoted = flags;
cmd->capacity = capacity;
return HTS_TRUE;
}
@@ -626,7 +619,6 @@ hts_boolean cmdl_init(cmdl_argv *cmd, int slots) {
void cmdl_free(cmdl_argv *cmd) {
hts_arena_free(&cmd->tokens);
freet(cmd->argv);
freet(cmd->unquoted);
memset(cmd, 0, sizeof(*cmd));
}
@@ -641,23 +633,13 @@ hts_boolean cmdl_ins(cmdl_argv *cmd, const char *token, int pos) {
copy = hts_arena_strdup(&cmd->tokens, token);
if (copy == NULL)
return HTS_FALSE;
for (i = cmd->argc; i > pos; i--) {
for (i = cmd->argc; i > pos; i--)
cmd->argv[i] = cmd->argv[i - 1];
cmd->unquoted[i] = cmd->unquoted[i - 1];
}
cmd->argv[pos] = copy;
cmd->unquoted[pos] = HTS_FALSE;
cmd->argc++;
return HTS_TRUE;
}
hts_boolean cmdl_ins_unquoted(cmdl_argv *cmd, const char *token, int pos) {
if (!cmdl_ins(cmd, token, pos))
return HTS_FALSE;
cmd->unquoted[pos] = HTS_TRUE;
return HTS_TRUE;
}
hts_boolean cmdl_add(cmdl_argv *cmd, const char *token) {
return cmdl_ins(cmd, token, cmd->argc);
}

View File

@@ -59,9 +59,6 @@ void expand_home(String * str);
and every pointer a caller kept into one, valid. */
typedef struct {
char **argv; /* argc slots used out of capacity allocated */
/* per slot: the token arrived already unquoted, so the parser must not strip
a quote pair off it again (doit.log tokens, unquoted by next_token) */
hts_boolean *unquoted;
int argc;
int capacity;
hts_arena tokens;
@@ -83,10 +80,6 @@ hts_boolean cmdl_add(cmdl_argv *cmd, const char *token);
grown. */
hts_boolean cmdl_ins(cmdl_argv *cmd, const char *token, int pos);
/* cmdl_ins for a token that has already been unquoted by its reader, marking
it so the parser leaves its quotes alone. */
hts_boolean cmdl_ins_unquoted(cmdl_argv *cmd, const char *token, int pos);
typedef enum {
CMDL_FILE_MISSING, /* not found, or unreadable */
CMDL_FILE_READ, /* expanded into the command line */

View File

@@ -252,7 +252,7 @@ HTSEXT_API int hts_main2(int argc, char **argv, httrackp * opt) {
static int hts_main_internal(int argc, char **argv, httrackp * opt) {
/* command line rebuilt from argv, config files and doit.log */
cmdl_argv x_cmd = {NULL, NULL, 0, 0, {NULL, 0, 0}};
cmdl_argv x_cmd = {NULL, 0, 0, {NULL, 0, 0}};
//
int argv_url = -1; // ==0 : utiliser cache et doit.log
@@ -623,7 +623,7 @@ static int hts_main_internal(int argc, char **argv, httrackp * opt) {
/* Insert parameters BUT so that they can be in the same order */
if (lastp) {
if (strnotempty(lastp) || quoted) {
if (!cmdl_ins_unquoted(&x_cmd, lastp, insert_after)) {
if (!cmdl_ins(&x_cmd, lastp, insert_after)) {
cmdl_free(&x_cmd);
HTS_PANIC_PRINTF("Error, not enough memory");
htsmain_free();
@@ -999,12 +999,9 @@ static int hts_main_internal(int argc, char **argv, httrackp * opt) {
char *com;
int na;
/* the flags below are indexed with argv, which still aliases x_cmd */
assertf(argv == x_cmd.argv && argc == x_cmd.argc);
for(na = 1; na < argc; na++) {
if (argv[na][0] == '"' && !x_cmd.unquoted[na]) {
if (argv[na][0] == '"') {
char BIGSTK tempo[HTS_CDLMAXSIZE + 256];
strcpybuff(tempo, argv[na] + 1);

View File

@@ -568,12 +568,12 @@ struct httrackp {
growing it would shift every httrackp field declared after it. */
void *sitemap_state; /**< hts_sitemap_state*, or NULL. Tail: ABI */
void *singlefile_state; /**< hts_singlefile_state*, or NULL. Tail: ABI */
String host_alias; /**< --host-alias: '\n'-separated "alias[,alias...]=host"
rules folding the hostnames of one site onto a single
canonical host. Tail: ABI */
/* Live state, not an option: copy_htsopt must leave it alone. */
String host_alias; /**< --host-alias: '\n'-separated "alias[,alias...]=host"
rules folding the hostnames of one site onto a single
canonical host. Tail: ABI */
int wizard_filters; /**< count of filters the wizard has inserted, held at the
low indices of the array. Tail: ABI */
low indices of the array. Live state, so copy_htsopt
must leave it alone. Tail: ABI */
};
/* Running statistics for a mirror. */

View File

@@ -4467,7 +4467,7 @@ static void wz_seed(httrackp *opt, char **filters, int *filptr,
}
/* Asserts the array holds exactly `want`, in order, naming the slot that
differs: every scenario below aborts through here. */
differs. */
static void wz_holds(char **filters, int filptr, const char *const *want) {
int i;
@@ -4498,10 +4498,8 @@ static int st_wizardinsert(httrackp *opt, int argc, char **argv) {
opt->filters.filters = &filters;
opt->filters.filptr = &filptr;
opt->wizard_filters = 0;
/* Answers, from httrack.c's question: 0 this link, 1 this directory, 2 the
host, 3 the parent, 4 this page only, 5 the directory and below, 6 the host,
7 the directory's files, 50 nothing. seeker_up is pinned off, so answer 5
takes its directory branch; 264 covers the host one. */
/* Answers are httrack.c's query3 codes; seeker_up is pinned off, so answer 5
takes its directory branch (tests/264 covers the host one). */
#define INSERT(n, adr, fil) \
hts_wizard_insert_filters(opt, (n), (adr), (fil), HTS_FALSE)
#define HOLDS(...) \
@@ -4538,7 +4536,7 @@ static int st_wizardinsert(httrackp *opt, int argc, char **argv) {
goto done;
}
/* the block size indexes one crawl's array, so binding an array empties it */
/* wizard_filters indexes one crawl's array, so binding another resets it */
{
char **other = NULL;
int otherptr = 7;
@@ -4550,7 +4548,7 @@ static int st_wizardinsert(httrackp *opt, int argc, char **argv) {
filters_bind(opt, &filters, &filptr);
}
/* and a counter that outlived its array still cannot index past the end */
/* a counter that outlived its array still cannot index past the end */
SEED("-*.zip");
opt->wizard_filters = 99;
INSERT(6, "h", "/dir/two.html");

View File

@@ -73,10 +73,9 @@ void hts_wizard_answer_filter(htsbuff *f, int slot, int n, const char *adr,
const char *fil, hts_boolean seeker_up);
/* Records the filters answer `n` leaves behind for the link (adr,fil), on top
of the wizard's own block at the low indices of opt->filters. Last match
wins, so a later answer outranks an earlier one, while the command-line
filters sitting above the block outrank every answer. The verdict half is
hts_wizard_apply_verdict(). Returns the number inserted, which sit at the
of the wizard's block at the low indices of opt->filters: last match wins, so
a later answer outranks an earlier one and the command-line filters above the
block outrank every answer. Returns the number inserted, which sit at the
tail of the block, ending at opt->wizard_filters. */
int hts_wizard_insert_filters(httrackp *opt, int n, const char *adr,
const char *fil, hts_boolean seeker_up);

View File

@@ -159,39 +159,4 @@ grep -qF -- '-%F "\"<!-- MARK -->" -r2' "$out3/hts-cache/doit.log" || {
exit 1
}
# --- 5. a plain argument keeps its leading quote too (#1263) -----------------
# A filter, not an option value, so it meets the second strip pass too. Three
# leading quotes: that pass and the -O one each eat one.
out4="$tmp/out4"
site4="$tmp/site4"
mkdir -p "$site4"
printf '<html><body><a href="foo.html">f</a></body></html>' >"$site4/index.html"
echo '<html><body>foo</body></html>' >"$site4/foo.html"
rc=0
"$bin" "file://$site4/index.html" -O "$out4" --quiet -n -%v0 '"""+*foo*""' \
>/dev/null 2>&1 || rc=$?
test "$rc" -eq 0 || {
echo "FAIL: initial mirror with a leading-quote filter exited $rc"
exit 1
}
grep -qF -- '"\"+*foo*"' "$out4/hts-cache/doit.log" || {
echo "FAIL: the filter was not recorded escaped"
head -1 "$out4/hts-cache/doit.log"
exit 1
}
cp "$out4/hts-cache/doit.log" "$tmp/doit4.before"
# no arguments at all: any would be recorded too, and the point here is that
# the file is a fixed point of its own replay.
rc=0
(cd "$out4" && "$bin" >/dev/null 2>&1) || rc=$?
test "$rc" -eq 0 || {
echo "FAIL: leading-quote filter reprise exited $rc (token stripped twice?)"
exit 1
}
cmp -s "$tmp/doit4.before" "$out4/hts-cache/doit.log" || {
echo "FAIL: the reprise rewrote doit.log differently"
diff "$tmp/doit4.before" "$out4/hts-cache/doit.log" | head -4
exit 1
}
exit 0

View File

@@ -1,13 +1,12 @@
#!/bin/bash
#
# #1250: last match wins, so the order below is each answer's precedence.
set -euo pipefail
# shellcheck source=tests/testlib.sh
. "$(dirname "$0")/testlib.sh"
# #1250: last match wins, so the order below is each answer's precedence.
# answering "ignore this link" and then "mirror the whole host" takes it back
list=$(httrack -O /dev/null -#test=wizardinsert h /dir/one.html 0 6)
test "$list" = "-h/dir/one.html +h/*" || fail "answer order: got [$list]"