From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX" 25-APR-1989 22:27
To:	MRGATE::"ARISIA::EVERHART"
Subj:	PIPE.3_of_4

Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Tue, 25 APR 89 17:43:53 PDT
Received: from relay.ubc.ca by KL.SRI.COM with TCP; Tue, 25 Apr 89 17:20:07 PDT
Received: by relay.ubc.ca (5.59/1.14)
	id AA01296; Tue, 25 Apr 89 17:18:55 PDT
Date: 25 Apr 89 17:11 -0600
From: Ken Wallewein <kenw%noah.arc.cdn@relay.ubc.ca>
To: <info-vax@kl.sri.com>
Message-Id: <2859*kenw@noah.arc.cdn>
Subject: PIPE.3_of_4

+-+-+-+ Beginning of part 3 +-+-+-+
X$!`009`009- top-level I/O redirection will not work properly within`032
X$!`009`009command files.  DCL lies about filespecs and doesn't stack`032
X$!`009`009them.
X$!`009`009- VERFIFY handling is tricky, since there is no DCL equivalent
X$!`009`009to DEBUG's input/output redirection logicals. VFY$INPUT/OUTPUT
X$!`009`009would allow debugging without corruption of data.
X$!`009`009- control-Y handling awkward with called DCL.
X$!
X$!
X$!Initialization
X$!==============
X$
X$`009ON ERROR     THEN GOTO FINISH
X$`009ON CONTROL_Y THEN GOTO FINISH
X$!
X$`009TMPFILE = "SYS$SCRATCH:"+F$GETJPI("","PID")+".PIPE;"
X$!
X$`009DEASSIGN SYS$INPUT`009`009! PREPARE FOR PIPE I/O
X$`009DEASSIGN SYS$OUTPUT
X$
X$`009DEBUG_VERIFY = SAVE_VERIFY.AND.(F$MODE().EQS."INTERACTIVE")
X$`009`009`009`009`009! "set verify" interactive only
X$!
X$! FILTER symbol definitions for PIPE.COM`032
X$! note: this isn't the best way, but it's the fastest without global symbols
X$
X$`009COM*BINE`009:= @PIPE:COMBINE
X$`009COU*NT`009`009:= @PIPE:COUNT
X$`009DI*RECT`009`009:= DIRECTORY/COLUMNS:1/NOHEADER/NOTRAILER
X$`009DUP*S`009`009:= $PIPE:DUPS
X$`009ECHO`009`009:= write sys$output """
X$`009EDIT`009`009:= @PIPE:EDIT
X$`009ELEM*ENT`009:= @PIPE:ELEMENT
X$`009EXTR*ACT`009:= @PIPE:EXTRACT
X$`009FIL2*DIR`009:= @PIPE:FIL2DIR
X$`009FIN*D`009`009:= SEARCH/WIN=0/NOHEA
X$`009GREP`009`009:= SEARCH SYS$INPUT
X$`009GRP*DUP`009`009:= $PIPE:GRPDUP
X$`009ITEM`009`009:= @PIPE:ITEM
X$`009JUS*TIF`009`009:= @PIPE:JUSTIF
X$`009LS`009`009:= 'DI
X$`009MO*RE`009`009:= TYPE/PAGE SYS$INPUT
X$`009NOCT*RL`009`009:= $PIPE:NOCTRL `032
X$`009NODUP*S`009`009:= @PIPE:NODUPS
X$`009SK*IP`009`009:= @PIPE:SKIP
X$`009SO*RT`009`009:= SORT SYS$INPUT SYS$OUTPUT
X$`009TEE`009`009:= @PIPE:TEE
X$`009TOT*AL`009`009:= @PIPE:TOTAL
X$`009WI*DE`009`009:= $PIPE:WIDE
X$`009XARG*S`009`009:= @PIPE:XARGS
X$!
X$`009true = -1
X$`009false = .not. true
X$!
X$!`009Optionally, display command as seen by PIPE
X$`009IF DEBUG_VERIFY THEN WRITE SYS$OUTPUT -
X`009P1," ",P2," ",P3," ",P4," ",P5," ",P6," ",P7," ",P8
X$!
X$!
X$!
X$!Command Parsing
X$!===============
X$!
X$!===========
X$`009wcmd = f$edit(P1+" "+P2+" "+P3+" "+P4+" "+P5+" "+P6+" "+P7+" "+P8, -
X`009`009"TRIM")
X$
X$`009interactive = wcmd .eqs. ""
X$
X$GET_wcmd:
X$`009if interactive then -
X$`009`009inquire/nopunct wcmd "`124 "
X$!`009`009read sys$command wcmd/error=exit/end=exit/prompt="PIPE> "
X$`009if wcmd .eqs. "" then goto exit
X$
X$`009wcmd = f$edit(wcmd,"compress,trim")
X$
X$!===========
X$
X$`009q = -1
X$`009I = 0`009!parameter number
X$`009P = ""`009!current parameter
X$`009PIPEFILE = TMPFILE
X$
X$`009CMD = ""`009!comand storage pseudo-array
X$`009INPT = ""`009!input device storage pseudo-array
X$`009OUPT = ""`009!output devide storage pseudo-array
X$`009PUSHING = FALSE
X$`009COND_PUSH= FALSE
X$
X$!parser states
X$`009NEUTRAL = 6
X$`009STATE = NEUTRAL
X$
X$DECODE:
X$`009IF P .NES. "" THEN GOTO PARSE
X$
X$!===========
X$`009if q/2*2.eq.q then goto RLOOP`009!if even
X$QLOOP:
X$`009q = q + 1
X$`009x = f$edit(f$element(q,"""",wcmd),"trim")
X$`009if x.eqs."""" then GOTO DONE_DECODE
X$`009r = 0
X$`009if q/2*2.eq.q then goto RLOOP`009!if even
X$`009P = x
X$`009GOTO EPARSE
X$RLOOP:
X$`009y = f$element(r," ",x)
X$`009r = r + 1
X$`009if y.eqs." " then goto QLOOP
X$`009P = y
X$
X$EPARSE:
X$!===========
X$
X$`009IF STATE .NE. NEUTRAL THEN GOTO PARSE
X$
X$`009FC = F$EXTRACT( 0,1,P )`009`009!get first character
X$`009STATE = F$LOCATE( FC,";`124<>+?" )`009!get it's type (p<>"" here)
X$
X$`009IF STATE .NE. NEUTRAL THEN -
X`009`009P = F$EXTRACT( 1,999,P )`009!strip the prefix
X$
X$PARSE:`009
X$`009GOTO TYPE_'STATE
X$
X$!
X$TYPE_0:
X$`009!multiple command w/o piping
X$`009GOSUB EXECUTE
X$!
X$`009GOTO NEXT_CMD
X$
X$!
X$TYPE_1:
X$`009!pipe redirect`032
X$`009OUPT = OUPT
X$`009IF OUPT .EQS. "" THEN OUPT = PIPEFILE !allow ">" to override "`124"
X$!
X$`009GOSUB EXECUTE
X$!
X$`009INPT = PIPEFILE
X$`009PIPEFILE = TMPFILE
X$
X$NEXT_CMD:
X$`009!handle end of a command section
X$`009OUPT = ""
X$`009CMD = ""
X$`009PUSHING = FALSE
X$`009COND_PUSH= FALSE
X$`009STATE = NEUTRAL`009!pass any argument back to neutral parser
X$`009GOTO DECODE
X$
X$TYPE_2:
X$`009!input redirection
X$`009IF P .EQS. "" THEN GOTO DECODE
X$`009INPT =  P
X$`009GOTO CLEAR_STATE
X$
X$TYPE_3:
X$`009!output redirection
X$`009IF P .EQS. "" THEN GOTO DECODE
X$`009OUPT =  P
X$`009PIPEFILE = "NL:"
X$`009GOTO CLEAR_STATE
X$
X$TYPE_4:
X$`009!push - almost neutral
X$`009PUSHING = TRUE
X$`009TYPE = NEUTRAL
X$`009GOTO TYPE_6
X$
X$TYPE_5:
X$`009!conditional pipe
X$`009COND_PUSH = TRUE
X$`009GOTO TYPE_4
X$
X$!TYPE_NEUTRAL:
X$TYPE_6:
X$`009!neutral/command
X$`009CMD`009= CMD + " " + P
X$
X$CLEAR_STATE:
X$`009P  = ""
X$`009STATE = NEUTRAL`009!input state is satisfied
X$`009GOTO DECODE
X$!
X$!
X$DONE_DECODE:
X$`009CMD`009= CMD + " " + P
X$`009GOSUB EXECUTE
X$`009GOTO FINISH
X$
X$
X$!
X$!
X$!Execute the Command Line
X$!========================
X$!
X$EXECUTE:
X$
X$`009OCMD = CMD`009`009`009`009! Save original command
X$
X$! open channels
X$
X$`009IF "''INPT'" .EQS. "" THEN $GOTO 1`009! PREPARE INPUT CHANNEL
X$`009    OPEN PIPE_INPUT 'INPT
X$`009    IF .NOT. pushing THEN ASSIGN/NOLOG PIPE_INPUT SYS$INPUT
X$`0091:
X$
X$`009IF "''OUPT'" .EQS. "" THEN $GOTO 2`009! PREPARE OUTPUT CHANNEL
X$`009    OPEN/WRITE PIPE_OUTPUT 'OUPT
X$`009    ASSIGN/NOLOG PIPE_OUTPUT SYS$OUTPUT
X$`0092:
X$
X$! loop control
X$`009IF .NOT. pushing THEN GOTO 2_3`009!if "pushing", read data first
X$
X$2_1:
X$`009READ/END=2_5 PIPE_INPUT LINE`009! read data for "+" commands
X$
X$`009x = f$locate("&LINE",ocmd)
X$`009IF x .lE. F$LENGTH(oCMD) THEN goto in_line
X$
X$`009`009cmd = ocmd + " " + LINE`009!if the "&LINE" symbol is not in the`032
X$`009`009`009`009`009!command, tack it on the end
X$`009`009goto 2_2
X$
X$`009in_line:
X$`009`009x = f$locate("&LINE",ocmd)
X$`009`009cmd = f$extract(0,x,ocmd)+line+f$extract(x+5,999,ocmd)
X$`009`009`009`009`009! else stick it in the middle
X$
X$2_2:
X$`009if .not. COND_PUSH then goto 2_3
X$`009`009read sys$command doit/error=finish/end=finish -
X`009`009`009/prompt="$''cmd' [Y]? "
X$`009`009doit=f$edit(doit,"UPCASE,TRIM")
X$`009`009if doit .eqs. "" then doit = "Y"
X$`009`009if doit then goto 2_3
X$`009`009if doit .nes. "ALL" then goto 2_1
X$`009`009COND_PUSH = FALSE
X$
X$2_3:
X$! do the command
X$`009PIPE_JUNK=F$VERIFY(DEBUG_VERIFY)`009! restore external verify
X$`009set noon
X$ 'CMD
X$`009set on
X$`009!'F$VERIFY(FORCE_VERIFY)`009`009! restore internal verify
X$2_4:
X$`009IF pushing THEN GOTO 2_1`009!if "pushing", repeat command until`032
X$`009`009`009`009`009!there is no more data in the pipe
X$
X$! close channels
X$
X$2_5:
X$`009IF "''INPT'" .EQS. "" THEN $GOTO 3`009! cleanup for input channel
X$`009    IF .NOT. pushing THEN DEASSIGN SYS$INPUT
X$`009    CLOSE PIPE_INPUT
X$`009    IF F$SEARCH("PIPE_INPUT") .NES. "" THEN DELETE PIPE_INPUT
X$`0093:
X$
X$`009IF "''OUPT'" .EQS. "" THEN $GOTO 4`009! cleanup for output channel
X$`009    DEASSIGN SYS$OUTPUT
X$`009    CLOSE PIPE_OUTPUT
X$`0094:
X$
X$
X$ RETURN
X$
X$
X$!
X$! Cleanup and exit
X$!=================
X$!
X$FINISH:
X$`009IF F$LOGICAL("PIPE_INPUT")  .NES. "" THEN CLOSE PIPE_INPUT
X$`009IF F$LOGICAL("PIPE_OUTPUT") .NES. "" THEN CLOSE PIPE_OUTPUT
X$
X$`009IF INTERACTIVE THEN GOTO GET_WCMD
X$
X$EXIT:
X$`009IF F$SEARCH(TMPFILE) .NES. "" THEN DELETE 'TMPFILE'*
X$
X$`009PIPE_JUNK=F$VERIFY(SAVE_VERIFY)`009`009! RESTORE VERIFY
$ GOSUB UNPACK_FILE

$ FILE_IS = "PIPE.HLP"
$ CHECKSUM_IS = 1879769410
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X1`009PIPE
X`009$ P*IPE [ <fromfile] [ +][command...] [""][args][""] [&line]`032
X`009[ >tofile] [ `124 ...] [ ; ...]
X
X`009eg: pipe SHOW LOGICALS * `124 grep DU `124 srt >LP:
X
X2`009Operators
X`009<filespec    redirects input to come from 'filespec'
X
X`009>filespec    redirects output to go to 'filespec'
X
X`009`124            'pipe the output from a the previous command to the`032
X`009             input of the next
X
X`009;            separate the previous command from the next _without_
X`009             piping
X
X`009+            switch mode of command from 'execute with data as input'
X`009             to 'execute with data as argumants'
X
X`009?            same as '+', but confirms each command execution
X
X`009&LINE        not really an operator, more a 'reserved symbol'.  Used`032
X`009             with '+' and '?' to place the data _within_ a command`032
X                     line.  Note that the use of uppercase is NOT optional.
X
X`009""           pass a single quote (") to DCL when the command is`032
X`009             executed.  Confusing, but DCL makes it necessary.
X
V`009All PIPE operators MUST be preceeded by a space or tab, otherwise they`03
X2
X`009will not be recognized as operators.
X
X2`009COMBINE
X`009COMBINE groups of sequential lines of input into one output record
X
X2`009COUNT
X`009Counts number of lines/entries`032
X
X2`009DI*RECTORY
X`009DIRECTORY filespec
X
X`009Single-column filespec-only directory to provide lists of filenames
X
X`009Note: This is intended to override any other similar definition
X`009      while in PIPE.
X
X2`009DUPS
X`009DUPS start length
X
X`009Finds duplicate entries in the specified portion of the line
X
X`009eg: PIPE DIR `124 DUPS 1 10
X
X2`009EDIT
X`009EDIT edit_options
X
X`009Performs a DCL F$EDIT (eg: UPCASE,TRIM) on each line of text
X
X2`009ELEMENT
X`009ELEMENT  element_number [...]
X
X`009Performs a DCL F$ELEMENT(n," ",line) on each line of input, where
X`009the first element is 0, and " " represents any combination of spaces
X`009and tabs`032
X
X2`009EXTRACT`032
X`009EXTRACT offset length [... ...]
X
X`009Performs a DCL F$EXTRACT(P1,P2,line) on each line of input
X
X2`009FIL2DIR
X`009FIL2DIR filespec
X
X`009turns filespecs into directory specs,
X`009e.g. DUA1:[JOHNSON]GROK.DIR;  => DUA1:[JOHNSON.GROK]
X
X2`009FIND`032
X`009FIND filespec search_spec
X
X`009Finds files containing given search arguments. Returns filespec only,`032
X`009for further action, eg: pipe find auditer `124 +edit
X
X2`009GREP`032
X`009GREP search_spec
X
X`009Pass only entries containing given text.  Supports all SEARCH`032
X`009options.  Exactly equivalent to SEARCH SYS$INPUT
X
X2`009ITEM`032
X`009ITEM _text_ [...]
X
X`009Element following element containing _text_.
X
X2`009LOCAL_COPIES
X`009Update local copies of files as needed, according to input`032
X`009parameters.   Could be modified to be a MAKE.
X
X2`009JUSTIFY
X`009JUSTIFY`009find_char to_column [find_char to_column...]
X
X`009Useful for using context to align data into columns, suchs as
X`009aligning all file extensions prior to sorting.
X
X`009Not currently inplemented
X
X2`009MORE
X`009    Exactly equivalent quivalent to TYPE/PAGE SYS$INPUT
X
X2`009NOCTRL
X`009Filters out control characters - allows viewing binary files for
X`009embedded text.
X
X2`009SKIP`032
X`009SKIP number_of_lines
X
X`009Skips the first number_of_lines lines (eg: headers) in the input
X
X2`009TEE`032
X`009TEE filespec
X
X`009Writes a copy of the input to the specified file. Defaults to`032
X`009SYS$COMMAND
X
X2`009TOTAL`032
X`009TOTAL start-column length [... ...(I think)]
X
X`009Total value of all entries in given columns
X
X2`009UNIQ
X`009Everything BUT duplicates (See NODUPS). Input _must_ be in same`032
X`009sorted order.
X`009
X2`009WIDE
X`009Prints lists in wide format
X
X2`009Examples
X`009A selective SHOW SYSTEM
X`009`009$ gs :== 'pipe show system `124grep`032
X`009`009$ gs up    or     $ gs acp     etc
X
X`009An 'appropos' or 'index' for VMS HELP
X`009`009$ pipe <nl: help lex f$* * `124grep f$,node
X
X`009Delete empty files
X`009`009$ pipe dir */sel=siz=max=0/siz=used `124 +delete/confirm
X
X`009Wildcard DEASSIGN
X`009`009$ pipe sho log news$* `124element 1 `124skip 9 `124 +deassign/sys
X
X`009Wildcard SHOW TERMINAL
V`009`009$ pipe sho dev t `124element 1 `124skip 2 `124 +sho ter `124grep dev,
Xdma
X
X`009Wildcard EDIT
X`009`009$ pipe DIR PS*.FOR `124 +edit
X
X`009Show processes with specific files open, or vice versa, or both
X`009`009$ pipe sho dev dua0/files `124grep junk.dat
$ GOSUB UNPACK_FILE

$ FILE_IS = "PIPE_LOGIN.COM"
$ CHECKSUM_IS = 1148470783
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
V! PIPE_LOGIN.COM - symbol definitions for PIPE package - K. Wallewein ARC 890
X127
V! note: PIPE assumes that all files in the this package are located in the`03
X2
X!       same directory
X!
X$`009! determine procedure location
X$`009here=F$PARSE(F$ENVIRONMENT("PROCEDURE"),,,,"NO_CONCEAL")-"]["
X$`009here=F$EXTRACT(0,F$LOCATE("]",here),here)
X$
-+-+-+-+-+ End of part 3 +-+-+-+-+-

