Skip to content

Commit

Permalink
Add support for half-open search terms like 5-.
Browse files Browse the repository at this point in the history
However, `-5` is a NEGATION search, not a half-open term. Use
`1-5`.
  • Loading branch information
kohler committed Jan 27, 2024
1 parent d99a795 commit 7d6d279
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 8 deletions.
4 changes: 2 additions & 2 deletions src/papersearch.php
Original file line number Diff line number Diff line change
Expand Up @@ -727,7 +727,7 @@ private function _kwdef_parse($kwdef, $sword, $kwexplicit) {
static private function _search_word_is_paperid($str) {
$ch = substr($str, 0, 1);
return ($ch === "#" || ctype_digit($ch))
&& preg_match('/\A(?:#?\d+(?:(?:-|–|—)#?\d+)?(?:\s*,\s*|\z))+\z/s', $str);
&& preg_match('/\A(?:#?\d++(?:(?:-|–|—)(?:|#?\d++))?(?:\s*,\s*|\z))+\z/s', $str);
}

/** @param string $str
Expand Down Expand Up @@ -763,7 +763,7 @@ private function _search_word($kw, $sword, $scope) {
}
}

// Paper ID search term (`1-2`, `#1-#2`, etc.)
// Paper ID search term (`1-2`, `#1-#2`, `1-`, etc.)
if (!$sword->quoted
&& !$scope->defkw
&& self::_search_word_is_paperid($sword->word)) {
Expand Down
24 changes: 18 additions & 6 deletions src/searchterm.php
Original file line number Diff line number Diff line change
Expand Up @@ -1467,7 +1467,11 @@ private function add_drange($p0, $p1, $rev, $explicit) {
$n = $this->n + ($rev ? $p1x - $p0 - 1 : 0);
array_splice($this->r, $i, 0, [[$p0, $p1x, $n, $rev, $explicit]]);
}
$this->n += $p1x - $p0;
// ensure `$this->n <= PHP_INT_MAX`
// (it naturally will be, UNLESS someone calls add_range
// with negative PIDs)
$delta = min($p1x - $p0, PHP_INT_MAX - $this->n);
$this->n += $delta;
}
$p0 = max($p0, $p1x);
}
Expand Down Expand Up @@ -1524,7 +1528,7 @@ function sql_predicate($field) {
return "false";
} else if ($this->n <= 8 * count($this->r)
&& ($pids = $this->paper_ids()) !== null) {
return "$field in (" . join(",", $pids) . ")";
return "{$field} in (" . join(",", $pids) . ")";
} else {
$s = [];
foreach ($this->r as $r) {
Expand Down Expand Up @@ -1568,10 +1572,18 @@ static function parse_pidcode($word, SearchWord $sword, PaperSearch $srch) {
* @return PaperID_SearchTerm */
static function parse_normal($word) {
$st = new PaperID_SearchTerm;
while (preg_match('/\A#?(\d+)(?:(?:-|–|—)#?(\d+))?\s*,?\s*(.*)\z/s', $word, $m)) {
$m[2] = (isset($m[2]) && $m[2] ? $m[2] : $m[1]);
$st->add_range(intval($m[1]), intval($m[2]));
$word = $m[3];
$pos = 0;
while (preg_match('/\G#?(\d++)((?:-|–|—)#?(\d++)|(?:-|–|—)|)\s*,?\s*/s', $word, $m, 0, $pos)) {
$p1 = intval($m[1]);
if ($m[2] === "") {
$p2 = $p1;
} else if (!isset($m[3]) || $m[3] === "") {
$p2 = PHP_INT_MAX;
} else {
$p2 = intval($m[3]);
}
$st->add_range($p1, $p2);
$pos += strlen($m[0]);
}
return $st;
}
Expand Down
6 changes: 6 additions & 0 deletions test/t_search.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ function test_xor() {
xassert_search($this->conf->root_user(), "1-10 XOR 4-5", "1 2 3 6 7 8 9 10");
}

function test_halfopen_interval() {
xassert_search($this->conf->root_user(), "5-100000 XOR 10-100000", "5 6 7 8 9");
xassert_search($this->conf->root_user(), "5- XOR 10-100000", "5 6 7 8 9");
xassert_search($this->conf->root_user(), "8-,7-,6-,5- XOR 10-100000", "5 6 7 8 9");
}

function test_review_term_to_round_mask() {
$rl = $this->conf->round_list();
xassert_eqq($rl[0], "");
Expand Down

0 comments on commit 7d6d279

Please sign in to comment.