REM Compare two files byte by byte.  Prints IDENTICAL, or where they part.
REM Called as:  Compare <first> <second>
ON ERROR PRINT REPORT$;" at line ";ERL : END
PROCargs
IF a$ = "" OR b$ = "" THEN PRINT "Compare <file> <file>" : END
ha% = OPENIN(a$) : IF ha% = 0 THEN PRINT "MISSING ";a$ : END
hb% = OPENIN(b$) : IF hb% = 0 THEN CLOSE#ha% : PRINT "MISSING ";b$ : END
la% = EXT#ha% : lb% = EXT#hb%
IF la% <> lb% THEN PRINT "DIFFERENT LENGTH ";la%;" vs ";lb% : CLOSE#ha% : CLOSE#hb% : END
chunk% = 32768
DIM pa% chunk%, pb% chunk%
pos% = 0 : bad% = -1
WHILE pos% < la% AND bad% < 0
  n% = la% - pos% : IF n% > chunk% THEN n% = chunk%
  SYS "OS_GBPB",4,ha%,pa%,n%
  SYS "OS_GBPB",4,hb%,pb%,n%
  FOR i% = 0 TO n% - 1
    IF pa%?i% <> pb%?i% THEN bad% = pos% + i% : i% = n%
  NEXT
  pos% += n%
ENDWHILE
CLOSE#ha% : CLOSE#hb%
IF bad% < 0 THEN
  PRINT "IDENTICAL ";la%;" bytes"
ELSE
  PRINT "DIFFERS at byte ";bad%;" of ";la%
ENDIF
END
DEF PROCargs
REM Running a tokenised program puts "BASIC -quit <program>" in front of the
REM arguments, so counting words from the left lands on the wrong one.  This
REM takes the last two words instead, which is what the two file names are.
LOCAL p%, c$, i%, n%
SYS "OS_GetEnv" TO p%
c$ = ""
WHILE ?p% <> 13 AND ?p% <> 0
  c$ += CHR$(?p%)
  p% += 1
ENDWHILE
WHILE RIGHT$(c$,1) = " "
  c$ = LEFT$(c$)
ENDWHILE
b$ = "" : a$ = ""
i% = LEN(c$)
WHILE i% > 0 AND MID$(c$,i%,1) <> " "
  i% -= 1
ENDWHILE
b$ = MID$(c$, i% + 1)
c$ = LEFT$(c$, i% - 1)
WHILE RIGHT$(c$,1) = " "
  c$ = LEFT$(c$)
ENDWHILE
i% = LEN(c$)
WHILE i% > 0 AND MID$(c$,i%,1) <> " "
  i% -= 1
ENDWHILE
a$ = MID$(c$, i% + 1)
ENDPROC
