https://gitlab.synchro.net/main/sbbs/-/commit/64cf7e3d7f7a26349f1e009a
Added Files:
docs/boolsrch.md src/sbbs3/boolsrch.c boolsrch.h boolsrch_test.c Modified Files:
ctrl/text.dat exec/load/text.js src/sbbs3/listfile.cpp objects.mk prntfile.cpp readmail.cpp readmsgs.cpp sbbs.jsdocs.vcxproj sbbs.vcxproj scandirs.cpp scansubs.cpp text.h text_defaults.c text_id.c
Log Message:
boolsrch: add boolean text-search engine (issue #1139)
PCBoard/Wildcat-compatible boolean search syntax (AND/OR/NOT with parens, quoted phrases for whole-word match) for the four "Text to search for"
prompts: message-base scan/F-find, private mail / search, file-listing
search, and the less-style file pager. Bare-word queries keep their
current case-insensitive substring semantics, so existing usage is
unchanged; the new operators unlock multi-term searches that the old strcasestr-only code couldn't express.
New engine (src/sbbs3/boolsrch.[ch], one TU):
bool_expr_compile() parses query into AST, malloc'd errmsg on fail
bool_expr_match() evaluate against a single haystack
bool_expr_match_fields() evaluate against N fields (term hits doc if it
appears in ANY field) - the shape callers want
for scanning subj/body/tags or name/desc/tags/
author
bool_expr_free() frees the compiled expression tree
Recursive-descent parser, precedence NOT > AND > OR, supports both
symbol (& | !) and keyword (AND OR NOT, case-insens, whole-word) forms.
Quoted "..." phrases apply a word-boundary check at each side that
contains no whitespace inside the quotes - so "TEST" won't match TESTING/BACKTEST while " TEST " is pure substring (escape hatch).
Implicit AND is inserted before ! / NOT (Wildcat's
"(windows|DOS) & (modem|comm) !OS/2" idiom).
Wired through:
readmsgs.cpp scanposts, searchposts (F find at scan and read-loop)
listfile.cpp listfiles (FL_FIND across name/desc/extdesc/tags/author)
prntfile.cpp printfile() P_SEEK / and n search
readmail.cpp searchmail / at the mail read prompt
scansubs.cpp getstr buffer raised from 40 to 120 for boolean queries
scandirs.cpp same
Engine compiles the expression once per scan and reuses it across every document - no per-record parsing cost. Malformed queries print the new
text.dat string InvalidSearchExpression (#948) and return cleanly to the prompt; pre-existing stale defaults for SeekPrompt (#944) and SeekHelp
(#947) were re-emitted by textgen at the same time.
Standalone unit test (src/sbbs3/boolsrch_test.c, TU-include of
boolsrch.c) covers 95 cases: precedence, parens, quoting + whitespace-
boundary suppression, keyword-vs-substring discrimination (BANDIT not
split on AND), implicit AND, syntax errors, multi-field matching.
Public API is exactly the four entry points above; diagnostic helpers (describe/is_simple/simple_text) stay file-local.
User-facing docs at docs/boolsrch.md for later wiki import.
Co-Authored-By: Claude Opus 4.7 (1M context) <
noreply@anthropic.com>
--- SBBSecho 3.37-Linux
* Origin: Vertrauen - [vert/cvs/bbs].synchro.net (1:103/705)