From:	CSBVAX::MRGATE!@KL.SRI.Com,@RELAY.CS.NET:kenw%noah.arc.cdn@UBC.CSNET@SMTP 22-AUG-1987 16:34
To:	EVERHART
Subj:	PIPE source part 1 of 3

Received: from RELAY.CS.NET by KL.SRI.COM with TCP; Sat 22 Aug 87 13:01:46-PDT
Received: from relay2.cs.net by RELAY.CS.NET id aa26769; 22 Aug 87 15:57 EDT
Received: from ubc by RELAY.CS.NET id ad04326; 22 Aug 87 15:47 EDT
Received: by ubc.csnet id AA01893; Sat, 22 Aug 87 12:43:17 pdt
Date: 22 Aug 87  4:43 -0800
From: Ken Wallewein <kenw%noah.arc.cdn%ubc.csnet@RELAY.CS.NET>
To: info-vax@KL.SRI.COM
Message-Id: <793*kenw@noah.arc.cdn>
Subject: PIPE source part 1 of 3

  Since there has been a bit of discussion of PIPEing here lately, it appears
to be time to post my work in that area. It works for me, and maybe it will
contribute to the development of something better.

  Included are the main .COM file PIPE, a number of filters in DCL, Vax BASIC
and C, and a few .COM's I have found useful: FORALL, MULTI, PURGABLE, 
SUBSTITUTE.

  It works for me. However, it could be improved through conversion from DCL
to C or something, the use of SPAWN and mailboxes rather than temporary
files, etc. I have sent a previous version of the package out to those who
requested it earlier - it has been improved a bit since then.

  As usual, it's in self-unpacking SHAR format - cut it out and '@' it.

/kenw
                                                                 A L B E R T A
Ken Wallewein                                                  R E S E A R C H
                                                                 C O U N C I L


.......................... Cut between dotted lines and save ....................
$!..............................................................................
$!
$! VAX/VMS archive file created by VMS_SHAR Version:'09-Jun-1987'
$! Copyright (c) 1987, by Michael Bednarek
$! To unpack, simply execute (@) the file.
$! This archive was created by KENW
$!      on Saturday 22-AUG-1987 13:27:49.81
$! It contains the following file(s):
$! AAAREADME.TXT ALLDUPS.COM COUNT.COM DUPS.BAS DUPS.COM ECHO.COM EDIT.COM
$! ELEMENT.COM EXTRACT.COM FORALL.COM MULTI.COM NOCTRL.C NODUPS.COM PIPE.COM
$! PIPE.HLP PURGABLE.COM SKIP.COM STEM.BAS STEM.C STEM.COM STEMS.C
$! SUBSTITUTE.COM TEE.COM TIME.COM TOTAL.COM WIDE.BAS
$!==============================================================================
$! ATTENTION: To keep each article below 15872 bytes, this program
$!            has been transmitted in several parts.
$! You should concatenate ALL parts to ONE file and execute (@) that file.
$!==============================================================================
$ Set Symbol/Scope=(NoLocal,NoGlobal)
$ CR[0,8]=13
$ Pass_or_Failed="failed!,passed."
$ Goto Start
$Convert_File:
$ Read/Time_Out=0/Error=No_Error1/Prompt="creating ''File_is'" SYS$Command ddd
$No_Error1:Open/Write Out 'File_is
$ Open/Read In VMS_SHAR_DUMMY.DUMMY
$Next_Record: Read/End_Of_File=EOF In Record
$ Write Out F$Extract(1,255,Record)
$ Goto Next_Record
$EOF: Close Out
$ Close In
$ Delete VMS_SHAR_DUMMY.DUMMY;*
$ Checksum 'File_is
$ Success=F$Element(Check_Sum_is.eq.CHECKSUM$CHECKSUM,",",Pass_or_Failed)+CR
$ Read/Time_Out=0/Error=No_Error2/Prompt=" CHECKSUM ''Success'" SYS$Command ddd
$No_Error2:Return
$Start:
$ File_is="AAAREADME.TXT"
$ Check_Sum_is=1465404749
$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
XX!
XX$       DEASS SYS$INPUT
XX$       DEASS SYS$OUTPUT
XX$       IF F$LOGICAL("PIPE_INPUT") .NES. "" THEN ASSIGN PIPE_INPUT  SYS$INPUT 
XX
XX$       IF F$LOGICAL("PIPE_OUTPUT") .NES. "" THEN ASSIGN PIPE_OUTPUT SYS$OUTPUT
XX$
XX$	count = 0
XX$
XX$READ:  READ/END=DONE SYS$INPUT LINE
XX!
XX$	count = count + 1
XX!
XX$       if p1 .nes. "" then WRITE SYS$OUTPUT LINE
XX$       GOTO READ
XX$DONE:
XX$	if p1 .eqs. "" then write sys$output count
XX$	if p1 .nes. "" then write 'p1 count
X$ GoSub Convert_File
X$ File_is="DUPS.BAS"
X$ Check_Sum_is=537551969
X$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
XX1       ! grpDUP.BAS V1.0 - PIPE DUPS FINDER !
XX        ON ERROR GOTO 32000
XX
XX        EXTERNAL LONG FUNCTION LIB$GET_FOREIGN
XX        EXTERNAL INTEGER CONSTANT SS$_NORMAL
XX
XX        DIM P$(31)
XX
XX        DECLARE INTEGER CONSTANT        TRUE  = -1
XX        DECLARE INTEGER CONSTANT        FALSE =  0
XX
XX        DECLARE INTEGER CONSTANT        INP = 1
XX        DECLARE INTEGER CONSTANT        OUT = 2
XX        DECLARE INTEGER CONSTANT        ECH = 3
XX
XX        COMMAND_BUFFER$ = SPACE$(80)
XX
XX        OPEN "SYS$OUTPUT"  FOR OUTPUT AS FILE #OUT,     &
XX                RECORDSIZE 132
XX        OPEN "SYS$COMMAND" AS FILE #ECH
XX
XX10      STATUS% = LIB$GET_FOREIGN(COMMAND_BUFFER$,,COMMAND_LENGTH%)
XX        IF STATUS% <> SS$_NORMAL
XX        THEN
XX            PRINT #ECH, '%GET_COMMAND error'; STATUS%
XX            GOTO 32767
XX        END IF
XX
XX        CMD_CNT% = 0%
XX
XX        IF COMMAND_LENGTH% > 0%
XX        THEN
XX
XX            COMMAND$ = LEFT$(COMMAND_BUFFER$,COMMAND_LENGTH%) + ' '
XX
XX            OS% = 0%
XX            S% = INSTR(OS%+1%,COMMAND$,' ')
XX
XX            WHILE S% > 0%
XX                CMD_CNT% = CMD_CNT%+1%
XX                P$(CMD_CNT%) = MID$(COMMAND$,OS%+1%,S%-OS%-1%)
XX                OS% = S%
XX                S% = INSTR(OS%+1%,COMMAND$,' ')
XX            NEXT
XX
XX        END IF
XX
XX        ! START AND END OF COMPARE
XX        START% = VAL(P$(1%))
XX        LENGTH% = VAL(P$(2%))
XX        IF LENGTH% = 0%
XX        THEN
XX                LENGTH% = 999%
XX        END IF
XX
XX        SAVED_LINE$ = ""
XX        SAVED_SUBSTR$ = ""
XX        SAVED_LINE_WRITTEN% = FALSE
XX
XX        LINLEN% = 0%
XX        MAXLEN% = 128%
XX
XX100     LINPUT LINE$
XX        SUBSTR$ = MID$(LINE$,START%,LENGTH%)
XX        IF SUBSTR$ = SAVED_SUBSTR$
XX        THEN
XX            IF NOT SAVED_LINE_WRITTEN%
XX            THEN
XX                PRINT #OUT
XX                PRINT #OUT, SAVED_LINE$; "   ";
XX                LINLEN% = LEN(SAVED_LINE$)+3%
XX                SAVED_LINE_WRITTEN% = TRUE
XX            END IF
XX            IF LINLEN%+LEN(LINE$) > MAXLEN%
XX            THEN
XX                PRINT #OUT, "-"
XX                LINLEN%=0%
XX            END IF
XX            PRINT #OUT, LINE$; "   ";
XX            LINLEN% = LINLEN%+LEN(LINE$)+3%
XX        ELSE
XX            SAVED_LINE$ = LINE$
XX            SAVED_SUBSTR$ = SUBSTR$
XX            SAVED_LINE_WRITTEN% = FALSE
XX        END IF
XX
XX        GOTO 100
XX
XX
XX32000   ! ERROR TRAPS
XX
XX        IF ERR=11       ! NORMAL EOF?
XX        THEN
XX                IF ERL=100
XX                THEN
XX                        PRINT #OUT
XX                        RESUME 32767
XX                END IF
XX        END IF
XX
XX32100 ON ERROR GOTO 0   ! FATAL ERRORS
XX
XX32767 END
XX
X$ GoSub Convert_File
X$ File_is="DUPS.COM"
X$ Check_Sum_is=1531336782
X$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
XX!       NODUPS.COM - REMOVES DUPLICATE RECORDS FROM TEXT FILES
XX$       DEASS SYS$INPUT
XX$       DEASS SYS$OUTPUT
XX$       IF F$LOGICAL("PIPE_INPUT") .NES. "" THEN ASSIGN PIPE_INPUT  SYS$INPUT 
XX$       IF F$LOGICAL("PIPE_OUTPUT") .NES. "" THEN ASSIGN PIPE_OUTPUT SYS$OUTPUT
XX!
XX$       OFFSET = P1
XX$       LENGTH = P2
XX$       IF LENGTH .EQ. 0 THEN LENGTH = 999      ! START AND END OF COMPARE
XX!
XX$       SAVED_SUBSTR = ""
XX!
XX$READ:  READ/END=DONE SYS$INPUT LINE
XX$       SUBSTR = F$EXTRACT(OFFSET,LENGTH,LINE)
XX$       IF SUBSTR .EQS. SAVED_SUBSTR THEN GOTO READ
XX$       SAVED_SUBSTR = SUBSTR
XX$       WRITE SYS$OUTPUT LINE
XX$       GOTO READ
XX$DONE:
XX
X$ GoSub Convert_File
X$ File_is="ECHO.COM"
X$ Check_Sum_is=556757182
X$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
XX$!	echo.COM - echo arguments
XX$!
XX$	WRITE SYS$OUTPUT "p1:''p1, p2:''p2, p3:''p3, p4:''p4, p5:''p5, "
XX$DONE:
X$ GoSub Convert_File
X$ File_is="EDIT.COM"
X$ Check_Sum_is=1968973785
X$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
XX$!	edit.COM - edit line with f$edit()
XX$!		 - arguments: p1: list of f$edit() operation eg: trim,compress
XX$!
XX$	DEASS SYS$INPUT
XX$	DEASS SYS$OUTPUT
XX$	IF F$LOGICAL("PIPE_INPUT") .NES. "" THEN ASSIGN PIPE_INPUT  SYS$INPUT 
XX$	IF F$LOGICAL("PIPE_OUTPUT") .NES. "" THEN ASSIGN PIPE_OUTPUT SYS$OUTPUT
XX$!
XX$READ:  READ/END=DONE SYS$INPUT LINE
XX$	WRITE SYS$OUTPUT f$edit(LINE,p1)
XX$	GOTO READ
XX$DONE:
X$ GoSub Convert_File
X$ File_is="ELEMENT.COM"
X$ Check_Sum_is=1802570204
X$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
XX!	element.COM - pass selected element of line
XX!		    - delimiter: any combination spaces/tabs
XX$	DEASS SYS$INPUT
XX$	DEASS SYS$OUTPUT
XX$	IF F$LOGICAL("PIPE_INPUT") .NES. "" THEN ASSIGN PIPE_INPUT  SYS$INPUT 
XX
XX$	IF F$LOGICAL("PIPE_OUTPUT") .NES. "" THEN ASSIGN PIPE_OUTPUT SYS$OUTPUT
XX$!
XX$READ:  READ/END=DONE SYS$INPUT LINE
XX$	WRITE SYS$OUTPUT F$ELEMENT('P1," ",F$EDIT(LINE,"COMPRESS"))
XX$	GOTO READ
XX$DONE:
X$ GoSub Convert_File
X$ File_is="EXTRACT.COM"
X$ Check_Sum_is=34762435
X$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
XX! EXTRACT.COM - pass selected element of line
XX!
XX$	DEASS SYS$INPUT
XX$	DEASS SYS$OUTPUT
XX$	IF F$LOGICAL("PIPE_INPUT") .NES. "" THEN ASSIGN PIPE_INPUT  SYS$INPUT 
XX
XX$	IF F$LOGICAL("PIPE_OUTPUT") .NES. "" THEN ASSIGN PIPE_OUTPUT SYS$OUTPUT
XX$!
XX$READ:  READ/END=DONE SYS$INPUT LINE
XX$	WRITE SYS$OUTPUT F$EXTRACT('P1,'P2,LINE)
XX$	GOTO READ
XX$DONE:
X$ GoSub Convert_File
X$ File_is="FORALL.COM"
X$ Check_Sum_is=1546316471
X$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
XX$	SAVE_VERIFY = F$VERIFY("''SAVE_VERIFY'")
XX!
XX! FORALL - For all items named in filespec P1 or in a file specified
XX!	  in P1 by "@filename", do P2, P3...
XX!	- I.E. FORALL *.FOR FORTRAN,
XX!	    or FORALL @FOR.LIS FORTRAN
XX!
XX$	ON ERROR	THEN GOTO FINISH
XX$	ON CONTROL_Y	THEN GOTO FINISH
XX$
XX$	DEASS SYS$INPUT
XX$	DEASS SYS$OUTPUT
XX$	IF F$LOGICAL("PIPE_INPUT") .NES. "" THEN ASSIGN PIPE_INPUT  SYS$INPUT 
XX$	IF F$LOGICAL("PIPE_OUTPUT") .NES. "" THEN ASSIGN PIPE_OUTPUT SYS$OUTPUT
XX$
XX$	DELETE = "!"	! NULL
XX$	COUNT = 0	! ZERO
XX$	NOT_INT = 1	! .TRUE.
XX$
XX$	CMD := 'P2 'P3 'P4 'P5 'P6 'P7 'P8 'P9 
XX$
XX$	P = F$LOCATE("&ITEM",CMD)
XX$	IF P .GE. F$LENGTH(CMD) THEN GOTO END_INT
XX$		NOT_INT = 0	!.FALSE.
XX$		CMD = F$EXTRACT(0,P,CMD)+"'"+F$EXTRACT(P+1,999,CMD)
XX$END_INT:
XX$
XX$	IF "''F$EXTRACT(0,1,P1)'" .EQS. "@" THEN GOTO OLD
XX$
XX$!NEW:
XX$	TMPFIL = "FORALL.TMP;"	  ! MAKE A FRESH LIST
XX$	DIRECTORY/COL:1/NOHEADER/NOTRAILER/OUTPUT:'TMPFIL 'P1
XX$	P1 = TMPFIL
XX$	DELETE = "DELETE ''TMPFIL'"
XX$	GOTO OPEN
XX$
XX$OLD:
XX$	P1 = F$EXTRACT(1,99,P1)	 ! USE AN OLD LIST
XX$	P1 = F$PARSE(P1,".LIS")
XX$
XX$OPEN:
XX$	OPEN FILE 'P1
XX$
XX$LOOP:
XX$	READ/END=FINISH FILE ITEM
XX$	IF NOT_INT THEN P10 = ITEM
XX$	WRITE SYS$OUTPUT "vvvvvvvvvvvvvvvvvvvvvvvvvvvv"
XX$	WRITE SYS$OUTPUT "$ ''CMD' ''P10'"
XX$ 'CMD 'P10
XX$	COUNT = COUNT + 1
XX$	GOTO LOOP
XX$
XX$FINISH:
XX$	SET NOON
XX$	CLOSE FILE
XX$	DELETE
XX$	WRITE SYS$OUTPUT "Finish (''COUNT' items)"
XX$	!F$VERIFY(SAVE_VERIFY)
X$ GoSub Convert_File
X$ File_is="MULTI.COM"
X$ Check_Sum_is=543124724
X$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
XX! MULTI - HANDLE MULTIPLE COMMANDS ON ONE LINE
XX!
XX$	SAVE_VERIFY = F$VERIFY("''SAVE_VERIFY'")
XX$
XX$	ON ERROR	THEN GOTO FINISH
XX$	ON CONTROL_Y	THEN GOTO FINISH
XX$
XX$	CMD := 'P1 'P2 'P3 'P4 'P5 'P6 'P7 'P8 'P9 
XX$	i = 0
XX$
XX$LOOP:
XX$	part = f$element(i,"\",cmd)
XX$	IF part .eqs. "\" then goto finish
XX$	'PART
XX$	i = i + 1
XX$	GOTO LOOP
XX$
XX$FINISH:
XX$	!F$VERIFY(SAVE_VERIFY)
X$ GoSub Convert_File
X$ File_is="NOCTRL.C"
X$ Check_Sum_is=891367336
X$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
XX/*
XXnoctrl.c - removes control characters from files
XX	 - useful for looking at ascii test in object files
XX*/
XX
XX#define EOF -1
XX
XXmain()
XX{
XX        int byte,chrcnt;
XX
XX        chrcnt = 0;
XX
XX        while ( ( byte = getchar() ) != EOF )
XX        {
XX                if      (byte > 31 & byte < 127)
XX                {
XX                        putchar( byte );
XX                        if (chrcnt++ > 76)
XX                        {
XX                                printf( "\n" );
XX                                chrcnt = 0;
XX                        }
XX                }
XX        }
XX}
XX
X$ GoSub Convert_File
X$ File_is="NODUPS.COM"
X$ Check_Sum_is=1531336782
X$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
XX!       NODUPS.COM - REMOVES DUPLICATE RECORDS FROM TEXT FILES
XX$       DEASS SYS$INPUT
XX$       DEASS SYS$OUTPUT
XX$       IF F$LOGICAL("PIPE_INPUT") .NES. "" THEN ASSIGN PIPE_INPUT  SYS$INPUT 
XX$       IF F$LOGICAL("PIPE_OUTPUT") .NES. "" THEN ASSIGN PIPE_OUTPUT SYS$OUTPUT
XX!
XX$       OFFSET = P1
XX$       LENGTH = P2
XX$       IF LENGTH .EQ. 0 THEN LENGTH = 999      ! START AND END OF COMPARE
XX!
XX$       SAVED_SUBSTR = ""
XX!
XX$READ:  READ/END=DONE SYS$INPUT LINE
XX$       SUBSTR = F$EXTRACT(OFFSET,LENGTH,LINE)
XX$       IF SUBSTR .EQS. SAVED_SUBSTR THEN GOTO READ
XX$       SAVED_SUBSTR = SUBSTR
XX$       WRITE SYS$OUTPUT LINE
XX$       GOTO READ
XX$DONE:
XX
X$ GoSub Convert_File
$ GoSub Convert_File
$ File_is="ALLDUPS.COM"
$ Check_Sum_is=605318451
$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
X!alldups.com - pipe command to find all duplicate filenames 
XPIPE "D1 ALL" | "JUST ] 30 . 40" | SRT | "DUPS 31 13"
X
$ GoSub Convert_File
$ File_is="COUNT.COM"
$ Check_Sum_is=1847146071
$ Copy SYS$Input VMS_SHAR_DUMMY.DUMMY
X!       count.COM - count number of lines in input stream
X!		  - optionally "tee" count
X!
X$       DEASS SYS$INPUT
X$       DEASS SYS$OUTPUT
X$       IF F$LOGICAL("PIPE_INPUT") .NES. "" THEN ASSIGN PIPE_INPUT  SYS$INPUT 
X
X$       IF F$LOGICAL("PIPE_OUTPUT") .NES. "" THEN ASSIGN PIPE_OUTPUT SYS$OUTPUT
X$
X$	count = 0
X$
X$READ:  READ/END=DONE SYS$INPUT LINE
X!
X$	count = count + 1
X!
X$       if p1 .nes. "" then WRITE SYS$OUTPUT LINE
X$       GOTO READ
X$DONE:
X$	if p1 .eqs. "" then write sys$output count
X$	if p1 .nes. "" then write 'p1 count
$ GoSub Convert_File

