From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 20-OCT-1989 05:53
To:	MRGATE::"ARISIA::EVERHART"
Subj:	Updates to latest LIBSEARCH

Message-Id:  <8910200940.AA23941@crdgw1.ge.com>
Received: From NSFNET-RELAY.AC.UK by CRVAX.SRI.COM with TCP; Thu, 19 OCT 89 14:33:52 PDT
Received: from ncdlab.ulcc.ac.uk by NSFnet-Relay.AC.UK   via Janet with NIFTP
           id aa05836; 19 Oct 89 16:28 BST
Date:           Thu, 19 Oct 89  16:42 BST
From: "Kevin Ashley - ULCC Networks Development." <KEVIN%ncdlab.ulcc.ac.uk@NSFnet-Relay.AC.UK>
To: INFO-VAX <@NSFnet-Relay.AC.UK:INFO-VAX@crvax.sri.com>
Subject:        Updates to latest LIBSEARCH

As I promised in my message of Tuesday (in this timezone, anyway),
here is a VMS_SHAR format file containing a number of updates and
fixes for LIBSEARCH. To apply the update, you need an un_SHAR'ed
copy of the LIBSEARCH I sent a day or so ago.

Unpack LIBSEARCH_UPDATE.SHAR
@update

And that's it. AAAREADME.TX2 contains information about the update.
It is distributed in some SLP-format files (of type .DIF). UPDATE.COM
applies these updates to the originals and then rebuilds LIBSEARCH.

The update contains the fixes mentioned in my previous message, plus
some new code from Pat Rankin (thanks again, Pat) which correctly
handles search strings which contain case-sensitive characters which
are not standard ASCII alphabetical characters.

Feel free to use and distribute this program unless you work for
Clyde Corporation, in which case I demand a hefty patent licensing fee ;-)

------------------------------------------------------------------------------
Kevin Ashley                              janet: K.Ashley@Uk.Ac.Ulcc.Ncdlab
Network Development Group Manager         Telephone: +44 1 405 8400
University of London Computer Centre. 

Arpa:        K.Ashley@Ncdlab.ulcc.Ac.uk OR
             K.Ashley%Ncdlab.ulcc.Ac.uk@nsfnet-relay.ac.uk
Bitnet/EARN: K.Ashley@ncdlab.ulcc.ac.uk OR  K.Ashley%Uk.ac.ulcc.ncdlab@UKACRL
Ean:  K.Ashley@Ncdlab.Ulcc.Ac.Uk

$! ------------------ CUT HERE -----------------------
$ v='f$verify(f$trnlnm("SHARE_VERIFY"))'
$!
$! This archive created by VMS_SHARE Version 7.1-004  3-AUG-1989
$!   On 19-OCT-1989 16:21:19.34   By user KEVIN (Kevin Ashley, ULCC)
$!
$! This VMS_SHARE Written by:
$!    Andy Harper, Kings College London UK
$!
$! Acknowledgements to:
$!    James Gray       - Original VMS_SHARE
$!    Michael Bednarek - Original Concept and implementation
$!
$! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER
$! AND EXECUTE AS A COMMAND PROCEDURE  (  @name  )
$!
$! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING:
$!       1. AAAREADME.TX2;1
$!       2. PRSCOM.DIF;1
$!       3. PRSTARGET.DIF;1
$!       4. STATCOM.DIF;1
$!       5. STATS.DIF;1
$!       6. UPDATE.COM;3
$!
$set="set"
$set symbol/scope=(nolocal,noglobal)
$f=f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID"))
$e="write sys$error  ""%UNPACK"", "
$w="write sys$output ""%UNPACK"", "
$ if f$trnlnm("SHARE_LOG") then $ w = "!"
$ if f$getsyi("version") .ges. "V4.4" then $ goto START
$ e "-E-OLDVER, Must run at least VMS 4.4"
$ v=f$verify(v)
$ exit 44
$UNPACK: SUBROUTINE ! P1=filename, P2=checksum
$ if f$search(P1) .eqs. "" then $ goto file_absent
$ e "-W-EXISTS, File ''P1' exists. Skipped."
$ delete/nolog 'f'*
$ exit
$file_absent:
$ if f$parse(P1) .nes. "" then $ goto dirok
$ dn=f$parse(P1,,,"DIRECTORY")
$ w "-I-CREDIR, Creating directory ''dn'."
$ create/dir 'dn'
$ if $status then $ goto dirok
$ e "-E-CREDIRFAIL, Unable to create ''dn'. File skipped."
$ delete/nolog 'f'*
$ exit
$dirok:
$ w "-I-PROCESS, Processing file ''P1'."
$ define/user sys$output nl:
$ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1'
PROCEDURE Unpacker ON_ERROR ENDON_ERROR;SET(FACILITY_NAME,"UNPACK");SET(
SUCCESS,OFF);SET(INFORMATIONAL,OFF);f:=GET_INFO(COMMAND_LINE,"file_name");
buff:=CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(buff))
;LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION(
BEGINNING_OF(buff));g:=0;LOOP EXITIF MARK(NONE)=END_OF(buff);x:=
ERASE_CHARACTER(1);IF g = 0 THEN IF x="X" THEN MOVE_VERTICAL(1);ENDIF;IF x=
"V" THEN APPEND_LINE;MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF;
IF x="+" THEN g:=1;ERASE_LINE;ENDIF;ELSE IF x="-" THEN g:=0;ENDIF;ERASE_LINE;
ENDIF;ENDLOOP;p:="`";POSITION(BEGINNING_OF(buff));LOOP r:=SEARCH(p,FORWARD);
EXITIF r=0;POSITION(r);ERASE(r);COPY_TEXT(ASCII(INT(ERASE_CHARACTER(3))));
ENDLOOP;o:=GET_INFO(COMMAND_LINE,"output_file");WRITE_FILE(buff,o);
ENDPROCEDURE;Unpacker;EXIT;
$ delete/nolog 'f'*
$ CHECKSUM 'P1'
$ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT
$ e "-E-CHKSMFAIL, Checksum of ''P1' failed."
$ ENDSUBROUTINE
$START:
$ create/nolog 'f'
XThis set of updates can be used to convert LIBSEARCH 1.4 to LIBSEARCH
X1.5. The following fixes/improvements are made:
X
X     /HIGHLIGHT is correctly default to BOLD, REVERSE or NONE depending
X       on your terminal type.
X
X     Output file type defaults to .LIS
X
X     Statistics output includes number of modules and files with hits.
X
X     Search strings containing multi-national case-sensitive characters are
X     handled correctly.
X
XThanks to Pat Rankin again for code to handle the last case. An earlier`032
Ximprovement attempted to detect non-alphabetic search strings, and force
Xexact matching in this case because of its greater speed. It would fail
Xif the string contained characters which are not part of standard 7-bit
XASCII, but which are nevertheless case-sensitive.
X
XTo build the updated version, you should have available all the files from
Xthe last LIBSEARCH distribution. Having unpacked the new VMS_SHAR file, you
Xwill have this file, a number of .DIF files, and UPDATE.COM. UPDATE.COM will
Xapply the updates, and rebuild LIBSEARCH using BUILD.COM. You can delete
Xthe .DIF files when it is done if you wish.
X
XEnjoy.
X`009`009`009`009Kevin Ashley
X----------------------------------------------------------------------------
XFor those who are interested, I hope to make a sort of callable version
Xof LIBSEARCH in the next few months. I envisage using this in conjunction
Xwith the HELP routines in order to provide keyword-based HELP. For instance,
Xa user could type XHELP TAPE, and the LIBSEARCH routines would find all topi
Vcs
Xcontaining TAPE. The user would then be presented with a menu, and the
Xcallable HELP routines would present the HELP topics selected. I will probab
Vly
Xdo this anyway, because I think it would be fun, but would anyone find this
Xuseful if I do ?
X
X
$ CALL UNPACK AAAREADME.TX2;1 591817175
$ create/nolog 'f'
X-   14,   14
X`009Logical Hilite_Used,Avo,Ansi
X-  119
X`009`009HiLite = 0
X-  195,  196
X*
X*`009If highlight was not specified, default it based on the characteristics
X*`009of the output device.
X*
X`009If(.Not. Hilite_Used) Then
X`009`009Call GetTermCap(Temp(1:Tlen),Ansi,Avo)
X`009`009If(Ansi .and. Avo) Then
X`009`009`009Hilite = Hilite_Bold
X`009`009Else If(Ansi) Then
X`009`009`009Hilite = Hilite_Rev
X`009`009Endif
X`009Endif
X
X`009Open(Unit=Outlun,Status='New',Name=Temp(1:Tlen),
X     $      CarriageControl='LIST',Recl=Lbr$C_Maxrecsiz,
X     $      DefaultFile='.LIS')
X-  272
X
X`009Subroutine GetTermCap(Name,Ansi,Avo)
X*
X*`009Get terminal capabilities
X*`009Any errors from LIB$GETDVI are assumed to indicate that the name
X*`009is not a device name, so they are ignored.
X*
X`009Implicit None
X`009Character*(*) Name
X`009Logical Ansi,Avo
X`009Include '($DVIDEF)'
X`009Integer Lib$Getdvi
X
X`009If(.not. (Lib$GetDvi(Dvi$_TT_ANSICRT,,Name,Ansi))) Ansi = .False.
X`009If(.not. (Lib$GetDvi(Dvi$_TT_AVO,,Name,Avo))) Avo = .False.
X`009Return
X`009End
X/
$ CALL UNPACK PRSCOM.DIF;1 1110131267
$ create/nolog 'f'
X-    8
X*`009Following a further suggestion of his, a more reliable algorithm
X*`009is used to check for alphabetic strings, which copes with multi-
X*`009-national sets.
X-   18,   19
X`009character *128`009alphabet
X`009integer`009`009alen
X-   25
X`009If(.not.Exact)`009Call Case_Sensitive_Chars( alphabet, alen, 1)
X-   40,   41
X`009        If ( ignore_case )
X     &`009`009  ignore_case = (Str$Find_First_in_Set( Temp(1:Tlen),
X     &`009`009`009`009`009`009alphabet(:alen)) .eq. 0)`032
X-   80
X      subroutine  Case_Sensitive_Chars ( string, length, typ_flag )
X`009!`009`009`009`009`009`009Pat Rankin, May'89
X`009!   Create a string that contains all characters that are
X`009!   case sensitive `091based on STR$UPCASE conversion behavior`093.
X`009!   (This is not quite the same as "alphabetic" characters.)
X`009!   Don't bother checking characters 0 through 63 because we
X`009!   assume that they are definitely non-alphabetic.
X`009!
X`009!   'typ_flag' indicates whether to collect upper-case (1),
X`009!   lower-case (2), or both (3) types of characters.
X`009!
X`009!   In the standard DEC-Multinational character set, there are
X`009!   55 case-sensitive 'letters', giving a string of length 110
X`009!   if both upper- and lower-case characters are requested.
X`009!
X`009implicit none
XC     input:
X`009integer`009`009typ_flag
XC     output:
X`009character *(*)`009string
X`009integer *2`009length
XC     local:
X`009character *(256-64) mixed,  upper`009!(192)
X`009integer`009`009i,  o,`009ln
XC     functions:
X`009intrinsic`009CHAR,  LEN
X*`009subroutine`009STR$UPCASE
X
XC     make string containing all characters of interest
X`009do i = 64, 255`009`009!skip 0..63 (they are non-alphabetic)
X`009    mixed(i-63:i-63) = CHAR(i)
X`009end do
XC     convert it into uppercase
X`009call STR$UPCASE( upper, mixed)
XC     compare upper-case string with mixed-case string, collecting difs
X`009ln = LEN(string)`009!loop limit; reduce if both types wanted
X`009if ( (typ_flag.and.3).eq. 3 )  ln = ln - 1  !simplify bounds check
X`009o = 0`009`009`009!output string length (so far)
X`009do i = 1, LEN(upper)`009!loop through string
X`009    if ( upper(i:i) .ne. mixed(i:i) .and. o .lt. ln ) then
XC`009      got character (actually, pair of them) that's case sensitive
X`009`009if ( typ_flag.and.1 ) then`009`009!want upper-case
X`009`009    o = o + 1`009`009`009!increment output length
X`009`009    string(o:o) = upper(i:i)`009!store character
X`009`009end if
X`009`009if ( (typ_flag.and.2).ne. 0 ) then`009!want lower-case
X`009`009    o = o + 1`009`009`009!increment output length
X`009`009    string(o:o) = mixed(i:i)`009!store character
X`009`009end if
X`009    end if
X`009end do
XC     done
X`009if ( o .lt. LEN(string) )  string(o+1:) = ' '`009!blank fill
X`009length = o`009`009!return length of output string
X`009return
X      end !of Case_Sensitive_Chars
X
X/
$ CALL UNPACK PRSTARGET.DIF;1 695156141
$ create/nolog 'f'
X-    4
X`009Integer TotModMat,TotFmat
X-    8,    8
X     $                 TotModMat,TotFmat,Frec,Fmatch,Fmod,Fmodmatch,
X/
$ CALL UNPACK STATCOM.DIF;1 1581087105
$ create/nolog 'f'
X-   57,   57
X*`009Accumulate overall statistics for total things searched and matched.
X-   60
X`009TotModMat = TotModmat + Fmodmatch
X`009If(FmodMatch .ne. 0) TotfMat = Totfmat + 1
X-  102,  104
X`009Character*(*) Fmt1,Fmt2,Fmt3
X`009Parameter (Fmt1 = '(1X,A,T22,I13,T41,A,T61,I10)')
X`009Parameter (Fmt2 = '(1X,A,T22,I13,T41,A,T58,A)')
X`009Parameter (Fmt3 = '(1X,A,T22,I13,T41,A,T58,I13)')
X-  128,  133
X*Files searched:                 6       Match Criteria:     /MATCH=AND/NOEX
VACT
X*Modules searched:              20       Buffered I/O count:        15
X*Records searched:             646       Direct I/O count:           8
X*Characters searched:        14424       Page faults:               47
X*Files matched:`009`009`009 0       Elapsed CPU time:  0 00:00:00.87
X*Modules matched:`009`009 0       Elapsed time:      0 00:00:01.45
X*Records matched:                0`009 Lines printed:              0
X-  153,  154
X`009Write(*,Fmt2) 'Files searched:',Totfil,'Match Criteria:',Criteria
X`009Write(*,Fmt1) 'Modules searched:',Totmod,'Buffered I/O count:',Bio
X-  158,  158
X`009Write(*,Fmt2) 'Files matched:',TotFMat,'Elapsed CPU time:',CPU
X-  164,  164
X`009Write(*,Fmt2) 'Modules matched:',Totmodmat,'Elapsed time:',Elapsed
X`009Write(*,Fmt3) 'Records matched:',Totmat,'Lines printed:',Totout
X-  181
X`009TotFmat = 0
X`009TotModmat = 0
X/
$ CALL UNPACK STATS.DIF;1 775576748
$ create/nolog 'f'
X$!
X$!  Build LIBSEARCH 1.5, given LIBSEARCH 1.4 sources.
X$!
X$EDIT/SUM  PRSCOM.FOR/UPDATE=PRSCOM.DIF    `032
X$EDIT/SUM   PRSTARGET.FOR/UPDATE=PRSTARGET.DIF `032
X$EDIT/SUM   STATCOM.INC/UPDATE=STATCOM.DIF   `032
X$EDIT/SUM   STATS.FOR/UPDATE=STATS.DIF     `032
X$@BUILD
$ CALL UNPACK UPDATE.COM;3 1345482218
$ v=f$verify(v)
$ EXIT

