REM Parse/combine stdin, work filename contents, and command line.
REM Example to copy paths from temp.lst:
REM   Type temp.lst | Parse *.txt *.lst
REM Example to copy paths from temp.lst and a file list:
REM   Type temp.lst | Parse @filelist.txt *.txt *.lst

' declare all variables integer
DEFINT A-Z
REM $DYNAMIC

' declare routines
DECLARE SUB MorePrompt (Input.String$, Input.Mask$, Output.String$)

' define boolean values
CONST True = -1
CONST False = NOT True
CONST TrueD = -1#
CONST FalseD = NOT TrueD
CONST NUL = ""

' define color values
CONST Black = 0
CONST Cyan = 11
CONST Green = 10
CONST Plain = 7
CONST Red = 12
CONST White = 15
CONST Yellow = 14

' get include files
REM $INCLUDE: 'qbx.bi'

' declare registers
COMMON SHARED Inregs AS RegType, Outregs AS RegType
COMMON SHARED InregsX AS RegTypeX, OutregsX AS RegTypeX

' declare some variables
COMMON SHARED Data.Error AS INTEGER

' increase stack size
STACK STACK

' declare error routine
ON ERROR GOTO Error.Routine

' read command line from PSP
Command.Line$ = NUL
InregsX.AX = &H6200
CALL InterruptX(&H21, InregsX, OutregsX)
PSPsegment = OutregsX.BX
PSPoffset = 128
DEF SEG = PSPsegment
FOR Count = 1 TO 127
   Command.Char = PEEK(PSPoffset + Count)
   SELECT CASE Command.Char
   CASE 0, 10, 13
      EXIT FOR
   CASE ELSE
      Command.Line$ = Command.Line$ + CHR$(Command.Char)
   END SELECT
NEXT
DEF SEG

' store command line
Command.Line$ = RTRIM$(Command.Line$)
Command.Line$ = LTRIM$(Command.Line$)
Command.Line.Redirect$ = Command.Line$

' search through all input filenames
DO
   ' get standard input
   Redirected.Input = False
   Standard.Input$ = NUL

   ' read standard input
   DO

      ' get input character
      InregsX.AX = &H600
      InregsX.DX = &H0FF
      CALL InterruptX(&H21, InregsX, OutregsX)

      ' check zero flag
      IF (OutregsX.Flags AND &H40) = &H40 THEN
         EXIT DO
      END IF

      ' store input
      Redirected.Input = True
      Char$ = CHR$(OutregsX.AX AND &HFF)

      ' check input character
      SELECT CASE ASC(Char$)
      CASE 10, 26
      CASE 13
	 EXIT DO
      CASE ELSE
	 Standard.Input$ = Standard.Input$ + Char$
      END SELECT
   LOOP

   ' check standard input
   IF Redirected.Input THEN
      IF Standard.Input$ = NUL THEN
	 EXIT DO
      END IF
   END IF

   ' process redirected input
   Command.Line$ = Command.Line.Redirect$

   ' process command loop
   DO

      ' store redirected input
      Standard.Input$ = RTRIM$(Standard.Input$)
      Standard.Input$ = LTRIM$(Standard.Input$)
      IF LEFT$(Standard.Input$, 1) = CHR$(34) THEN
         Standard.Input$ = MID$(Standard.Input$, 2)
      END IF
      IF RIGHT$(Standard.Input$, 1) = CHR$(34) THEN
         Standard.Input$ = LEFT$(Standard.Input$, LEN(Standard.Input$) - 1)
      END IF

      ' process work filename
      IF LEFT$(Command.Line$, 1) = "@" THEN

	 ' make input filename
         Command.Line$ = MID$(Command.Line$, 2)
         GOSUB Make.Filename

	 ' process work filename
	 Data.Error = False
	 CLOSE #1
         OPEN Command.Work$ FOR INPUT SHARED AS #1

	 ' check error flag
	 IF Data.Error THEN
            PRINT "Error" + STR$(Data.Error) + "opening file " + Command.Work$
	 ELSE

	    ' process input filenames
	    DO UNTIL EOF(1)
               LINE INPUT #1, Command.Work$

	       ' process search filename
               Command.Work$ = RTRIM$(Command.Work$)
               IF LEN(Command.Work$) THEN
                  Command.Work$ = Standard.Input$ + Command.Work$
                  COLOR Yellow, Black
                  PRINT Command.Work$
	       END IF
	    LOOP
	 END IF
      ELSE
         IF LEN(Command.Line$) THEN
	    GOSUB Make.Filename
            Command.Work$ = Standard.Input$ + Command.Work$
            COLOR Yellow, Black
            PRINT Command.Work$
	 ELSE
	    EXIT DO
	 END IF
      END IF
   LOOP

   ' check standard input
   IF Standard.Input$ = NUL THEN
      EXIT DO
   END IF
LOOP
End.Parse:
COLOR Plain, Black
END

Make.Filename:
 IF LEFT$(Command.Line$, 1) = CHR$(34) THEN
    Imbedded = INSTR(2, Command.Line$, CHR$(34))
    IF Imbedded THEN
       Command.Work$ = MID$(Command.Line$, 2, Imbedded - 2)
       Command.Line$ = MID$(Command.Line$, Imbedded + 1)
    ELSE
       Command.Work$ = Command.Line$
       Command.Line$ = NUL
    END IF
 ELSE
    Imbedded = INSTR(Command.Line$, " ")
    IF Imbedded THEN
       Command.Work$ = LEFT$(Command.Line$, Imbedded - 1)
       Command.Line$ = MID$(Command.Line$, Imbedded + 1)
    ELSE
       Command.Work$ = Command.Line$
       Command.Line$ = NUL
    END IF
 END IF
 RETURN

' critical error trap
Error.Routine:
 Data.Error = ERR
 SELECT CASE Data.Error
 CASE 53
    Temp.Outpt$ = "File not found."
 CASE 61
    Temp.Outpt$ = "Disk full."
 CASE 70
    Temp.Outpt$ = "Permission denied."
 CASE 71
    Temp.Outpt$ = "Disk not ready."
 CASE ELSE
    Temp.Outpt$ = "Untrapped error" + STR$(Data.Error) + "."
 END SELECT
 COLOR White, Black
 PRINT Temp.Outpt$
 Prompt$ = "Press R to retry, Q to quit, C to continue:"
 CALL MorePrompt(Prompt$, "rqc", Outpt$)
 SELECT CASE Outpt$
 CASE "r"
    RESUME
 CASE "q"
    Error.Level = True
    RESUME End.Parse
 CASE "c"
    OutregsX.Flags = &H1
    RESUME NEXT
 END SELECT
 END 0

SUB MorePrompt (Input.String$, Input.Mask$, Output.String$)
 COLOR White, Black
 PRINT Input.String$ + " ";
 Input.Char$ = NUL
 DO
    LOCATE , , 1
    Input.Char$ = INKEY$
    IF LEN(Input.Char$) THEN
       Input.Char$ = LCASE$(Input.Char$)
       IF INSTR(Input.Mask$, Input.Char$) THEN
	  PRINT Input.Char$
	  Output.String$ = Input.Char$
	  EXIT DO
       END IF
    END IF
 LOOP
END SUB
