BFind
This utility will search a file, or multiple files, for the occurance of one or more strings.
If you load this program and run it you can execute with a " ?" after it to get help (e.g. BFIND ?). This outputs a list of options and usage notes like:
This utility will find a string of characters within any record in the file specified. You will be prompted to enter a string to search for. You can edit the items directly or select the items into a select-list. If an '*' is used instead of 'FileName' then all files are searched, or if there is an ActiveList the selected items are searched.
Syntax:
BFIND FileName{[*]} {(options} (same syntax with a SelectList)
* options:
A - c[A]se does matter in the search
C - set the [C]ol# to start the match on (enter numeric)
F - display only the [F]irst match then goto next item
I - only look for matching [I]temId's
S - [S]uppress the display of the matching lines
T - [T]rim each item of redundant spaces before comparing
X - search for a he[X]adecimal character(s)
Example: SSELECT VOC = "[BP]"
xx ITEMS SELECTED
: BFIND * (S
Enter a string to search for: ON ACCPAY
Unless the '(S' option is used matching lines will be displayed with the search-string lined up starting in column 15 of the displayed output. Once the search process completes you'll be asked:
EDIT item(s) selected (#/Yes/No/LineEditor/Quit) ?
You should answer with the line# you wish to edit, [Y] to edit all items that match, [L] to edit all matching items with the Line-Editor, or [Q] to quit processing. If you edit the items they are edited one at a time and you have the option to stop editing items any time. The next question is:
Do you wish to ACTIVATE this list (Y/N) ?
This allows you to activate a select-list of the matching items. This will search all files with a 'BP' in it's name looking for the string 'ON ACCPAY'. This is a general search for any program that writes to the ACCPAY file!
Note: if the 's' option is used, the 'f' option is overridden! Also, if the
'i' option is used, all other options are negated!
I use it all the time to search program files, UV files, O/S files, etc.
!
** Find item/s with string 'X' BASIC utility
** (C) Copyright 1985-2007, Advantos Systems, Inc. All Rights Reserved.
!
** Last Modified: 23 Oct 2006, wph
** First Created: 01 Jan 1987, wph
** Program Type-: Utility
!
** Notes:
** This utility will select a list of items within a file that
** contain at least one of the specified search strings.
**
** If '*' is used instead of a [[FileName]] then all files are searched,
** or if a select list is active, those files in the select file are
** searched.
**
** If no edit then return select list for further processing
**
** If a SELECTLIST is available when this program is executed then
** it is assumed that the select list contains the file names you
** want to search.
**
** There are 2 q-pointers needed in the voc/md of the account you're
** running this utility in:
** 1) VOC or MD
** 2) SAVEDLISTS (_SAVEDLISTS_, &SAVEDLISTS&, POINTER-FILE)
**
**
**-------------------------------------------------------------------**
** **
** I N I T I A L I Z A T I O N **
** **
**-------------------------------------------------------------------**
*
** Initialize program variables
*$OPTIONS EXT ; ** D3 version
*
** initialize local variables
PROMPT ''
NULL$ = ''
*PORT.NO = OCONV(@USER.NO, 'MCU') ; ** UV version
PORT.NO = OCONV(@UDTNO, 'MCU') ; ** UD version
*PORT.NO = SYSTEM(22) ; ** D3 version
SP1 = ' '
SP2 = ' '
SP3 = ' '
SP4 = ' '
SP5 = ' '
SP10 = SPACE(10)
SP20 = SPACE(20)
*
** initialize screen variables
SCRN.WIDTH = SYSTEM(2)
SCRN.LENGTH = SYSTEM(3) - 1
TERM.TYPE = SYSTEM(7)
EOS = @(-3)
EOL = @(-4)
C.BCK = @(-9)
C.UP = @(-10)
VC.BCK = C.BCK
*
** assign continue message
CONT.MSG = "Press [Enter] to see more or any other key to quit:"
*
** dimension for the maximum number of search strings
DIM STRINGS(15), TERMINALS(150)
*
** assign other local variables
PG.CNT = 0
FIND.CNT = 0
LIST.ID = "FIND.SELECT.LIST_" : PORT.NO
FILE.LIST = NULL$
ITEM.LIST = NULL$
*
QUIT.AND.PROCESS = 0 ; ** quit display & process
*
** Read 'TCL' sentence
*TCL.LINE = @COMMAND ; ** UV version
TCL.LINE = @SENTENCE ; ** UD version
*TCLREAD TCL.LINE ; ** D3 version
*
OPTIONS = OCONV(FIELD(TCL.LINE, '(', 2), 'MCU')
TCL.LINE = TRIM(FIELD(TCL.LINE, '(', 1))
*
** Access help if desired
BEGIN CASE
CASE INDEX(TCL.LINE, ' HELP ', 1) ; GOTO DISPLAY.HELP
CASE TCL.LINE[LEN(TCL.LINE)-4,5] = ' HELP' ; GOTO DISPLAY.HELP
CASE INDEX(TCL.LINE, '?' , 1) ; GOTO DISPLAY.HELP
CASE FIELD(TCL.LINE, SP1 , 2) = NULL$ ; GOTO DISPLAY.HELP
END CASE
*
** Process file information
FNAME = FIELD(TCL.LINE, ' ', 2)
IF OCONV(FNAME, 'MCU') = 'DICT' THEN
DSW = 'DICT'
FNAME = FIELD(TCL.LINE, ' ', 3)
END ELSE
DSW = ''
END
*
** Validate options
IF INDEX(OPTIONS, 'I', 1) THEN
FIND.ITEM = 1
OPTIONS = 'I'
END ELSE
FIND.ITEM = 0
END
IF INDEX(OPTIONS, 'A', 1) THEN [[CaseMatters]] = 1 ELSE [[CaseMatters]] = 0
IF INDEX(OPTIONS, 'C', 1) THEN COL.DISP = 1 ELSE COL.DISP = 0
IF INDEX(OPTIONS, 'F', 1) THEN FIRST.ITEM = 1 ELSE FIRST.ITEM = 0
IF INDEX(OPTIONS, 'S', 1) THEN SUPP.DISP = 1 ELSE SUPP.DISP = 0
IF INDEX(OPTIONS, 'T', 1) THEN TRIM.ITEM = 1 ELSE TRIM.ITEM = 0
IF INDEX(OPTIONS, 'X', 1) THEN HEX.SEARCH = 1 ELSE HEX.SEARCH = 0
*
** Get column display start column
IF COL.DISP THEN
[[ColStart]] = OCONV(OPTIONS, 'MCN')
END ELSE [[ColStart]] = 15
*
** Build item list (if '*' files then build file list).
* READLIST ITEM.LINE ELSE ITEM.LINE = NULL$ ; ** UV version
*
ITEM.LINE = NULL$ ; ** D3[[/UD]] version
IF SYSTEM(11) THEN ; ** D3[[/UD]] version
LOOP ; ** D3[[/UD]] version
READNEXT ID ELSE EXIT ; ** D3[[/UD]] version
ITEM.LINE<-1> = ID ; ** D3[[/UD]] version
REPEAT ; ** D3[[/UD]] version
END ; ** D3[[/UD]] version
*
** Build file list to parse through
FILE.LINE = NULL$ ; ** initialize file names to search
*
** no active list so let`s build one
IF FNAME = '*' THEN
IF ITEM.LINE = NULL$ THEN
EXECUTE \SELECT MD WITH D[[/CODE]] = "D]""F"\ CAPTURING OUTPUT
IF SYSTEM(11) THEN
LOOP
READNEXT ID ELSE EXIT
IF FILE.LINE NE NULL$ THEN
FILE.LINE = ID : @AM : FILE.LINE
END ELSE FILE.LINE = ID
REPEAT
END
END ELSE
*
** use the item list previously built as the file list
FILE.LINE = ITEM.LINE
END
ITEM.LINE = NULL$ ; ** default to search through ALL items
END ELSE FILE.LINE = FNAME
*
** Open files
** another 'Open' statement occurs later as each selected file is opened
OPEN 'PERIPHERALS' TO PERIPHERALS ELSE STOP 201, 'PERIPHERALS'
OPEN 'SAVEDLISTS' TO SAVEDLISTS ELSE STOP 201, 'SAVEDLISTS'
*
** Read terminal characteristics
[[TermId]] = 'CCRT_' : OCONV(TERM.TYPE, 'MCU')
MATREAD TERMINALS FROM PERIPHERALS, [[TermId]] ELSE
MAT TERMINALS = NULL$
END
*
** extract video attributes
HI = TERMINALS(12)
HO = TERMINALS(13)
FORE.COLOR1 = TERMINALS(104)
IF FORE.COLOR1 NE NULL$ THEN
HI = FORE.COLOR1
END
V.HI = HI
V.HO = HO
*
** Build appropriate file list
*SELECTV FILE.LINE TO FILE.LIST ; ** UV version
SELECT FILE.LINE TO FILE.LIST ; ** D3[[/UD]] version
*
** Enter string(s) to search for
INPUTCLEAR
*
ITEMNUM = 0
*IF NOT(FIND.ITEM) THEN
LOOP
CRT "Enter a string to search for: ":
INPUT STRING
UNTIL STRING = NULL$ OR ITEMNUM = 15 DO
ITEMNUM = ITEMNUM + 1
IF HEX.SEARCH THEN
STRING = CHAR(XTD(STRING))
END
IF NOT([[CaseMatters]]) THEN
STRING = OCONV(STRING, 'MCU') ; ** case doesn't matter
END
STRINGS(ITEMNUM) = STRING
REPEAT
IF ITEMNUM = 0 THEN STOP
*END
CRT
*
**-------------------------------------------------------------------**
** **
** S T A R T P R O G R A M R U N **
** **
**-------------------------------------------------------------------**
*
LN.CNT = 0 ; ** #of lines printed on a page - count
SELECT.IDS = NULL$ ; ** list of items found
LOOP
READNEXT FILENAME FROM FILE.LIST ELSE EXIT
*
** open appropriate file to search
OPEN DSW, FILENAME TO F.NAME THEN
CRT V.HI : "File: " : FILENAME : V.HO
GOSUB CHECK.PAGE ; ** page-stop test routine
IF QUIT.AND.PROCESS THEN GOTO EDIT.LIST
END ELSE
CRT V.HI : "File: " : FILENAME : " does not exist!" : V.HO
GOSUB CHECK.PAGE ; ** page-stop test routine
IF QUIT.AND.PROCESS THEN GOTO EDIT.LIST
GOTO END.OF.LOOP1 ; ** skip further processing & loop again
END
EDIT.PATH = TRIM(DSW : SP1 : FILENAME)
** build item list to search
IF ITEM.LINE = NULL$ THEN
* SELECTV F.NAME TO ITEM.LIST ; ** UV version
SELECT F.NAME TO ITEM.LIST ; ** D3[[/UD]] version
END ELSE
* SELECTV ITEM.LINE TO ITEM.LIST ; ** UV version
SELECT ITEM.LINE TO ITEM.LIST ; ** D3[[/UD]] version
END
** select file & search for desired string
CNT = 0
LOOP
READNEXT ID FROM ITEM.LIST ELSE EXIT
READ REC FROM F.NAME, ID THEN
IF NOT(FIND.ITEM) THEN
REC = ID : @AM : REC ; ** include the item id
END ELSE
REC = ID ; ** we're only searching the Ids
END
HREC = REC ; ** keep 2 copies of record
IF NOT([[CaseMatters]]) THEN
REC = OCONV(REC, 'MCU') ; ** case doesn't matter
END
FOR J = 1 TO ITEMNUM
IF TRIM.ITEM THEN REC = TRIM(REC)
IF INDEX(REC, STRINGS(J), 1) THEN
IF FNAME = '*' THEN
SELECT.IDS<-1> = EDIT.PATH : SP1 : ID
END ELSE
SELECT.IDS<-1> = ID
END
FIND.CNT += 1
** display matches
IF NOT(SUPP.DISP) THEN
REC = TRIM(REC)
HREC = TRIM(HREC)
JJ.HIGH = COUNT(REC, STRINGS(J))
FOR JJ = 1 TO JJ.HIGH
COL.S = INDEX(REC, STRINGS(J), JJ)
IF JJ = 1 THEN
CRT FIND.CNT "L(#4)" :
IF SCRN.WIDTH < 132 THEN
CRT ID "L(#20)":
END ELSE CRT ID "L(#30)":
END ELSE
CRT SP20:SP4:
IF SCRN.WIDTH GE 132 THEN CRT SP10:
END
START.POS = COL.S - [[ColStart]]
START.LEN = [[ColStart]]
IF START.POS LE 0 THEN
START.LEN = 14 + START.POS
START.POS = 1
END
[[DispMask]] = "R(#" : [[ColStart]]-2 : ")"
DISP.LINE = ":" : HREC[START.POS,START.LEN] [[DispMask]]
DISP.LINE := HREC[COL.S,999]
o[[DispLine]] = OCONV(CONVERT(@AM:@VM:@SVM, '^]\', DISP.LINE), 'MCP') ; ** U2 version
* o[[DispLine]] = OCONV(CONVERT(DISP.LINE, @AM:@VM:@SVM, '^]\'), 'MCP') ; ** D3 version
IF SCRN.WIDTH < 132 THEN
CRT o[[DispLine]] "L(#54)"
END ELSE
CRT o[[DispLine]] "L(#96)"
END
GOSUB CHECK.PAGE ; ** page-stop test routine
IF QUIT.AND.PROCESS THEN GOTO EDIT.LIST
IF FIRST.ITEM THEN EXIT
NEXT JJ
END ELSE
IF MOD(FIND.CNT, 10) = 1 THEN CRT '.':
END
END
NEXT J
END
***************
END.OF.LOOP2:
***************
REPEAT
***************
END.OF.LOOP1:
***************
IF SUPP.DISP THEN CRT ; ** drop a line
REPEAT
** Edit list once selected
*
***************
EDIT.LIST:
***************
*
IF SELECT.IDS NE NULL$ THEN
IF FIND.ITEM THEN CRT DCOUNT(SELECT.IDS , @AM) : " items selected."
EDIT.CMD = 'U '
CRT V.HI : "EDIT item(s) selected (#[[/Yes/No/LineEditor/Quit]]) ?" :
CRT V.HO : "N" : C.BCK :
INPUT EDIT
EDIT = TRIM(OCONV(EDIT , 'MCU'))
NUMB = TRIM(OCONV(EDIT , 'MCN'))
IF EDIT = '' THEN EDIT = 'N'
BEGIN CASE
CASE EDIT[1,1] = 'Q' ; GOTO END.OF.PROGRAM
CASE EDIT[1,1] = 'X' ; GOTO END.OF.PROGRAM
CASE EDIT[1,1] = 'Y' ; EDIT = 0
CASE EDIT[1,1] = 'N' ; EDIT = -1
CASE EDIT[1,1] = 'L'
EDIT.CMD = 'ED '
IF NUMB THEN EDIT = NUMB ELSE EDIT = 0
CASE NUMB ; EDIT = NUMB
CASE 1 ; EDIT = -1
END CASE
** Edit select list
FIND.CNT = DCOUNT(SELECT.IDS , @AM)
CRT FIND.CNT : " items found"
IF EDIT GE 0 THEN
IF EDIT > 0 THEN
IF EDIT > FIND.CNT THEN EDIT = FIND.CNT
FIND.CNT = EDIT
END ELSE EDIT = 1
YN = 'Y' ; ** initialize prompt variable
FOR X = EDIT TO FIND.CNT
NEW.ITEM = SELECT.IDS<X>
IF FNAME = '*' THEN
CRT "Editing.. " : EDIT.PATH : SP1 : NEW.ITEM
EXECUTE EDIT.CMD : NEW.ITEM
END ELSE
CRT "Editing.. " : EDIT.PATH : SP1 : NEW.ITEM
EXECUTE EDIT.CMD : EDIT.PATH : SP1 : NEW.ITEM
END
IF X = FIND.CNT THEN CRT "End of selected items." ; EXIT
CRT V.HI:"Continue editing (Yes[[/No/Back/Quit]]) ?":V.HO:YN:C.BCK:
H.YN = YN
INPUT YN,1
YN = OCONV(YN,'MCU')[1,1]
IF YN = 'Q' OR YN = 'X' THEN GOTO END.OF.PROGRAM
IF YN = NULL$ THEN YN = H.YN
IF YN = 'N' THEN EXIT
IF YN NE 'E' THEN EDIT.CMD = 'U ' ELSE EDIT.CMD = 'ED '
IF YN = '-' OR YN = 'B' THEN
X = X - 2
IF X < 0 THEN X = 0
* CONTINUE
END
NEXT X
END ELSE
INPUTCLEAR
CRT
CRT V.HI : "Do you wish to ACTIVATE this List (Y[[/N]]) ?" :
CRT V.HO : "N" : C.BCK :
INPUT YN,1 ; YN = OCONV(YN , 'MCU')
CRT C.UP : EOL :
IF YN = 'Y' THEN
FORMLIST SELECT.IDS TO 0 ; ** UD version
EXECUTE \SAVE-LIST \ : LIST.ID CAPTURING OUTPUT ; ** UD version
CHAIN \GET-LIST \ : LIST.ID ; ** UD version
* WRITE SELECT.IDS ON SAVEDLISTS, LIST.ID ; ** D3 version
* CHAIN \QSELECT SAVEDLISTS \ : LIST.ID ; ** D3 version
END
END
GOSUB CLEAR.SELECT
END ELSE CRT "No items found"
GOTO END.OF.PROGRAM
*
**---------------------------------------------------------------**
** **
** S U B R O U T I N E S **
** **
**---------------------------------------------------------------**
*
** Check page for stopping and prompting to continue
***************
CHECK.PAGE:
***************
*
LN.CNT += 1
IF LN.CNT = SCRN.LENGTH THEN
INPUTCLEAR
LN.CNT = 1
PG.CNT += 1
QUIT.AND.PROCESS = 0
CRT V.HI:"Page ":V.HO:PG.CNT:V.HI:". Press [":V.HO:"Enter":V.HI:
CRT "] to continue, [":V.HO:"P":V.HI:"] to stop & Process,":
CRT " or [":V.HO:"Q":V.HI:"] to Quit:":V.HO:
INPUT ZZ,1
ZZ = OCONV(ZZ,'MCU')[1,1]
IF ZZ = 'E' THEN GOTO SELECT.ABORT
IF ZZ = 'Q' THEN GOTO SELECT.ABORT
IF ZZ = 'S' THEN GOTO SELECT.ABORT
IF ZZ = 'X' THEN GOTO SELECT.ABORT
IF ZZ = 'P' THEN
QUIT.AND.PROCESS = 1
END ELSE
** display file on top of new page
CRT V.HI : "File: " : FILENAME : V.HO
END
END
RETURN
*
** Clear select list & pointer file item
***************
CLEAR.SELECT:
***************
*
CLEARSELECT
RETURN
*
** Help display
***************
DISPLAY.HELP:
***************
*
CRT
CRT "This utility will find a string of characters within any record in the file"
CRT "specified. You will be prompted to enter a string to search for. You can"
CRT "edit the items directly or select the items into a select-list. If an '*'"
CRT "is used instead of '[[FileName]]' then all files are searched, or if there is"
CRT "an [[ActiveList]] the selected items are searched."
CRT
CRT "Syntax:"
CRT " BFIND [[FileName]]{[*]} {(options} (same syntax with a [[SelectList]])"
CRT
CRT " * options:"
CRT " A - c[A]se does matter in the search"
CRT " C - set the [C]ol# to start the match on (enter numeric)"
CRT " F - display only the [F]irst match then goto next item"
CRT " I - only look for matching [I]temId's"
CRT " S - [S]uppress the display of the matching lines"
CRT " T - [T]rim each item of redundant spaces before comparing"
CRT " X - search for a he[X]adecimal character(s)"
CRT
CRT 'Example: SSELECT VOC = "[BP]"'
CRT " xx ITEMS SELECTED"
CRT " : BFIND * (S"
CRT " Enter a string to search for: ON ACCPAY"
CRT
CRT CONT.MSG :
INPUT ZZ,1
IF ZZ = NULL$ THEN
CRT C.UP : EOL
CRT "Unless the '(S' option is used matching lines will be displayed with the"
CRT "search-string lined up starting in column 15 of the displayed output. Once"
CRT "the search process completes you'll be asked:"
CRT
CRT " EDIT item(s) selected (#[[/Yes/No/LineEditor/Quit]]) ?"
CRT
CRT "You should answer with the line# you wish to edit, [Y] to edit all items"
CRT "that match, [L] to edit all matching items with the Line-Editor, or [Q] to"
CRT "quit processing. If you edit the items they are edited one at a time and"
CRT "you have the option to stop editing items any time. The next question is:"
CRT
CRT " Do you wish to ACTIVATE this list (Y[[/N]]) ?"
CRT
CRT "This allows you to activate a select-list of the matching items. This will"
CRT "search all files with a 'BP' in it's name looking for the string 'ON ACCPAY'."
CRT "This is a general search for any program that writes to the ACCPAY file!"
CRT
CRT "Note: if the 's' option is used, the 'f' option is overridden! Also, if the"
CRT " 'i' option is used, all other options are negated!"
END
GOTO END.OF.PROGRAM
*
**----------------------------------------------------------------**
** **
** E N D O F P R O G R A M **
** **
**----------------------------------------------------------------**
*
** Clear select list and stop program
***************
SELECT.ABORT:
***************
*
GOSUB CLEAR.SELECT
*
***************
END.OF.PROGRAM:
***************
*
END