'set novalue on' /* force KEXX and its way of SIGNAL ON NOVALUE */ /* Usage: [MACRO] HEXE [file] */ /* Or: KEDIT file (PROFile HEXE */ /* Example: HEXE kedit.exe => Kedit binary KEDIT.EXE */ /* HEXE => hex. view current file */ /* Purpose: (Ab)use KEDIT as hex. editor. If HEXE is used */ /* within Kedit, it "copies" some local file/view */ /* settings like colors, ARROW, ARBCHAR, and WRAP. */ /* Otherwise HEXE tries to DEFINE INITIAL.KML and */ /* to execute MACRO COLOR (resp. MONO or WINDOWS): */ /* INITIAL.KML and COLOR.KEX are only used to get */ /* "normal" file/view settings like colors etc. */ /* SETLINES.KEX: HEXE can be used with 80 columns, but LRECL 24 */ /* is a bad compromise. 100 columns for LRECL 32 */ /* would be optimal. HEXE tries to execute macro */ /* SETLINES 0 to set 100 columns (OS/2 TEXTWINDOW) */ /* or SETLINES - to set 132 columns (FULLSCREEN or */ /* DOS). 132 columns is more than the optimal 100 */ /* but still better than 80. */ /* HEXE uses PSCREEN.2() to determine the actual */ /* screen width => KeditW not yet fully supported. */ /* HEXE.BAT: With SETLINES.COM a DOS batch is pretty simple: */ /* @SETLINES - KEDIT %1 (PROF HEXE) */ /* HEXE.CMD: A trivial OS/2 HEXE.CMD script is a one-liner: */ /* EXTPROC KEDIT %1 (PROF HEXE) */ /* A better solution uses REXX SysTextScreenSize() */ /* before @(MODE 100 || MODE 132) and restores the */ /* old MODE after KEDIT returns. */ /* Warning: Do not use Kedit to insert or delete bytes in a */ /* binary. It is possible to replace bytes in a */ /* binary loaded by HEXE if some critical settings */ /* are not changed: EOFOUT, EOLOUT, LRECL, RECFM, */ /* TABSOUT, TRAILING. Please check the file size */ /* of a patched binary, it should be the same. */ /* Requires: Kedit 5.0 (KeditW should also work, test it) */ /* Optional: SETLINES.KEX, INITIAL.KML, COLOR.KEX, MONO.KEX */ /* (Frank Ellermann, 2004) */ parse source . . NAME if profile() then exit EDIT( NAME ) ; call INIT if arg( 1 ) <> '' then do 'kedit' arg( 1 ) '(PROFile' NAME ; exit rc end 'extract /FEXT/FILEID' if alt.2() <> 0 then do 'emsg' FILEID.1 'changed' ; exit 12 end if FEXT.1 = 'BAK' then 'fext TMP' ; else 'fext BAK' if rc <> 0 then exit rc ; FILEID.0 = fileid.1() 'kedit "' || FILEID.1 || '" (PROFile' NAME if rc <> 0 then do /* trouble: reset old fileid */ NAME = rc ; 'fext' FEXT.2 ; exit NAME end 'kedit "' || FILEID.0 || '" (NEW' ; 'quit' 'kedit "' || FILEID.1 || '" (NEW' ; exit rc EDIT: procedure /* -------------------------------------------- */ if initial() then do /* initialize global settings */ 'hexdisp on' ; 'reprof on' ; 'shifts on' ; 'beep on' 'nomsg define initial.kml' ; 'nomsg macro' monitor.1() 'arbchar on' ; 'arrow off' ; 'backup temp' 'number on' ; 'wrap on' ; 'varblank on' call INIT /* save new favoured settings */ end 'editv get HEXE.0' do N = 1 to HEXE.0 /* restore any local settings */ 'editv get HEXE.' || N /* for file resp. view saved */ 'set' HEXE.N /* by procedure INIT before */ end /* -------------------------------------------- */ COL = 4 /* should be 8, 16, or 32, but VER accepts only */ /* 20 arg.s, so COL * 4 + 4 <= 20 is the limit. */ if pscreen.2() < 16 * 3 + COL then LEN = 8 /* 40 ? */ else if pscreen.2() < 24 * 3 + COL then LEN = 16 /* oops! */ else if pscreen.2() < 32 * 3 + COL then LEN = 24 /* 80 ? */ else LEN = 32 /* 132 ? */ if LEN * 3 + COL + 6 <= pscreen.2() then 'prefix nulls right' 'lrecl' LEN ; 'trunc' LEN ; 'zone 1' LEN 'eofin allow' ; 'eolin none' ; 'tabsin off' 'eofout none' ; 'eolout none' ; 'tabsout off' 'trailing on' ; 'recfm varying' 'hex on' ; 'screen 1' ; 'autoscroll off' /* RECFM FIXED would add blanks to last record upto LRECL, for */ /* patching binaries this is no good idea. Use HEXE only for */ /* viewing (and maybe replacing a few bytes). CAVEAT: Do not */ /* insert or delete bytes or "lines" (= records = LEN bytes). */ SPACE = 2 * LEN ; R = '' ; S = R ; V = R do J = 1 to LEN by LEN % COL /* process record, COL parts */ K = LEN % COL + J - 1 do I = J - 1 to K - 1 /* process a part of record: */ R = R d2x( I // 16 ) /* build text for RESERVED */ S = S || d2x( I // 16 ) end R = R '' /* build text for the VERIFY */ V = V 'H' || J K SPACE SPACE end /* Hex. col.s J to K, + space */ 'reserved' msgline.2() attr.11() R || S 'verify' V 1 LEN SPACE '*' ; return rc INIT: procedure /* -------------------------------------------- */ if pscreen.2() < 100 then do if opmode.1() = 'TEXTWINDOW' then 'nomsg macro setlines 0' else 'nomsg macro setlines -' pscreen.1() end 'nomsg query attr' ; HEXE.1 = lastmsg.1() 'nomsg query arbchar' ; HEXE.2 = lastmsg.1() 'nomsg query arrow' ; HEXE.3 = lastmsg.1() 'nomsg query backup' ; HEXE.4 = lastmsg.1() 'nomsg query number' ; HEXE.5 = lastmsg.1() 'nomsg query varblank' ; HEXE.6 = lastmsg.1() 'nomsg query wrap' ; HEXE.7 = lastmsg.1() HEXE.0 = 7 do N = 0 to HEXE.0 ; 'editv put HEXE.' || N ; end return