FSearch

Blurb

FSearch is a simple, skeletal, program to demonstrate the use of the XSEARCH and FMUL2MEMT% functions. It is also supposed to be useful, namely in order to let you search files for the presence of some word or byte sequence. The main thing, however, is that the main routine, FSearch, can be extracted and made use of for some project of your own, to save you from having to reinvent the fiddly bits, and concentrate on the bigger picture of what you want to do.

Prerequisites

This program can be RUN under SuperBASIC or EXECuted as an SBASIC program (SMSQ/E only (and perhaps MultiBASIC with a wee bit of twiddling)). The compiled version can, of course, be EXECuted on most QL platforms. In its SBASIC form it requires that the FINDNAME% command is present. This could be loaded with your boot program.

For Super- and Minerva BASIC you should LRESPR the two mentioned toolkits first, or edit the program accordingly. The compiled version only needs Qlib_run or equivalent preloaded.

What FSearch does

FSearch uses a medium sized buffer to load a file, or part file, into memory, where it can be quickly searched, using a slightly modified version of Simon Goodwin's very nice Msearch V0.8 routine from his DIY toolkit volume X.

The buffering thing is done like this: If the whole file fits into the buffer, then it is loaded with LBYTES. If it doesn't fit, then a buffer load at a time is fetched using FMUL2MEMT%. The partial file is scanned, and if the item searched for is not found, the routine backtracks the length of the search item and then loads the next portion into the buffer. This is repeated until the first instance of the looked for item is found or the end of the file reached.

As I said before, this program is only a simple demonstration of the core facilities of both XSEARCH and FMUL2MEMT%. One could expand on this to make it a more versatile program - or use it as part of some other project. (Or forget about the whole thing and go and sniff some more soldering flux.. ;o)

10 REMark $$asmb=dev4_mem_search_XSEARCH_BIN,0,10
11 REMark $$asmb=dev4_io_iob_IOB2MEMT_BIN,0,10
12 :
13 EXT_FN 'XSEARCH', 'FMUL2MEMT%'
14 :
15 REMark + ************************************************************************ +
16 REMark *<                             File Search                                >*
17 REMark + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +
18 REMark *                   FSearch function and harness to test                   *
19 REMark *                                                                          *
20 REMark + ------------------------------------------------------------------------ +
21 REMark * V0.01, pjw, 2025 Dec 12                                                  *
22 REMark + ************************************************************************ +
23 :
24 REMark $$off
25  IF PEEK$(\\-4, 4) = 'SBAS' THEN
26   CLOSE: CLCHP:                            REMark Tidy after any (failed) previous run
27   IF NOT FINDNAME%("XSEARCH"): LRESPR 'dev4_mem_search_XSEARCH_BIN'
28   IF NOT FINDNAME%("FMUL2MEMT%"): LRESPR 'dev4_io_iob_IOB2MEMT_BIN'
29  END IF
30 REMark $$on
31 :
32 buffer = 4096:                           REMark Buffer, max 32766b
33 t%     = -1:                             REMark Timeout (only needed if using IOB2MEMT%)
34 addr   = ALCHP(buffer):                  REMark Use same buffer for repeated runs
35 IF addr <= 0: ERT -3
36 :
37 dc = FOPEN("con_252x62a128x96"):         REMark For Qdos
38 REPeat main
39  CLS#dc
40  INPUT#dc; 'Full name of file to search'\, ifn$
41  IF LEN(ifn$) = 0: EXIT main
42  REPeat sloop
43   INPUT#dc; 'Enter string to search for'\, ss$
44   l% = LEN(ss$)
45   IF l% = 0: EXIT sloop
46   DIM rtv$(l%): rtv$(0) = l%:             REMark Used to check for correct return value
47   :
48   fnd  = FSearch(ifn$, ss$)
49   IF fnd >= 0 THEN
50    ch = FOP_IN(ifn$): BGET#ch\ (fnd), rtv$(1 TO l%): CLOSE#ch
51    PRINT#dc; 'Found "'; rtv$; '" at file position'! fnd
52   ELSE
53    PRINT#dc; '"'; ss$; '" not found', fnd
54   END IF
55   PRINT#dc
56  END REPeat sloop
57 END REPeat main
58 PRINT#dc; 'Finished': PAUSE 50
59 :
60 CLOSE#dc
61 RECHP addr
62 :
63 :
100 REMark + ------------------------------------------------------------------------ +
102 REMark |<                                FSearch                                 >|
104 REMark + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +
106 REMark |                     Search a file for a given string                     |
108 REMark |                                                                          |
110 REMark | A suitable buffer of min string length and max 32k must have been        |
112 REMark | reserved in advance. If file larger than buffer one buffer length is     |
114 REMark | processed at the time.                                                   |
116 REMark |                                                                          |
118 REMark | GLOBal buffer = buffer size, addr = buffer address, (t% = timeout)       |
120 REMark | Dependencies: Either FMUL2MEM% or FMUL2MEMT%, and XSEARCH                |
122 REMark + ------------------------------------------------------------------------ +
124 REMark | V0.01, pjw, 2023 Jun 01                                                  |
126 REMark | V0.02, pjw, 2025 Dec 11, returns position in file and not only in buffer |
128 REMark + ------------------------------------------------------------------------ +
130 :
132 DEFine FuNction FSearch(fnm$, str$)
134 LOCal loop, ch, l, fleng, er
136 LOCal part, remain, fps
138 :
140 l = LEN(str$): IF l = 0: RETurn 0
142 :
144 ch = FOP_IN(fnm$): IF ch < 0: RETurn ch
146 fleng = FLEN(#ch): IF l > fleng: CLOSE#ch: RETurn -7
148 :
150 IF fleng <= buffer THEN
152  CLOSE#ch
154  LBYTES fnm$, addr
156  er = XSEARCH(addr, fleng, str$)
158  IF er > 0: RETurn er - addr
160  RETurn -7
162 END IF
164 :
166 part   = buffer: fps = 0
168 remain = fleng
170 :
172 REPeat loop
174  IF remain < part THEN
176   part = remain
178   remain  = 0
180  ELSE
182   remain  = remain - part
184  END IF
186  :
188  er = FMUL2MEMT%(#ch; t%, part, addr)
190  IF er <= 0 THEN
192   IF er = 0: er = -10
194   EXIT loop
196  END IF
198  :
200  er = XSEARCH(addr, part, str$)
202  IF er OR remain = 0 THEN
204   IF er = 0 THEN
206    er = -7
208   ELSE
210    er = er + fps - addr
212   END IF
214   EXIT loop
216  END IF
218  :
220  remain = remain + l
222  fps = fps + part - l
224  :
226  GET#ch\ FPOS(#ch) - l
228 END REPeat loop
230 :
232 CLOSE#ch
234 RETurn er
236 END DEFine FSearch
238 :
240 :
  
Generated with sb2htm on 2025 Dec 12