-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathbinary.kex
146 lines (134 loc) · 7.71 KB
/
binary.kex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
'set novalue on' /* force KEXX and its way of SIGNAL ON NOVALUE */
/* Usage: [MACRO] BINARY [file [ ( init-options [)] ]] */
/* Or: KEDIT file (PROFile BINARY [init-options[)]] */
/* Example: BINARY file use BINARY settings */
/* BINARY reload current file */
/* Purpose: BINARY loads a file "as is" ignoring line ends, */
/* preserving TABs, EOF characters, and trailing */
/* white space. BINARY is a variant of HEXA and */
/* HEXE.KEX sans hex. display. */
/* See also: Macro A-F12 in INITIAL.KML toggles normal and */
/* binary views. Normal view would also reset all */
/* BINARY settings to normal defprof.1() values. */
/* If macro ZOO.KEX is assigned to a key 'zoo .' */
/* reports the binary offset of the focus column. */
/* For the "reload strategy" used by BINARY.KEX */
/* compare BROWSE, HEXA, HEXE, or UNIX.KEX. This */
/* macro automatically uses PROFDEBUG if "DEFINEd" */
/* by TRACE.KEX for debugging. */
/* Position: The actual position in the file is preserved if */
/* possible. This fails if an intended EOLOUT LF */
/* or CRLF does not reflect the actually used EOL */
/* character(s) for files not yet saved with this */
/* intended EOLOUT. The EOLIN value does not help */
/* in this scenario, EOLIN LF in essence means LF */
/* or CRLF. File positions depending on EOFIN and */
/* EOFOUT also cannot be accurately preserved, but */
/* affect only the last line or record. Likewise */
/* TABSIN, TABSOUT, or TRAILING can confuse binary */
/* offsets. Function length.1() correctly counts */
/* trailing blanks only for TRAILING ON. */
/* Caveats: Do not use Kedit to insert or delete bytes in a */
/* binary. It is possible to replace bytes in a */
/* binary if 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 as before. */
/* Optional: INITIAL.KML and one of COLOR, MONO, WINDOWS.KEX */
/* depending on monitor.1() can be used for other */
/* settings (colours, keys, etc.) not conflicting */
/* with BINARY settings. STATUS.KEX reports the */
/* relevant non-default settings (if available). */
/* Requires: Kedit 5.0 or KeditW 1.0 (Frank Ellermann, 2008) */
if profile() then exit EDIT() ; else PROF = INIT()
if arg( 1 ) <> '' then do /* accept one file + options: */
Q = left( strip( arg( 1 )), 1 )
if Q = '"' | Q = "'" then parse arg (Q) FILE (Q) Q '(' R
else parse arg FILE Q '(' R
parse var R OPTS ')' R ; R = length( strip( Q R ))
if R + pos( 'PROF', translate( OPTS )) > 0 then do
'emsg BINARY' arg( 1 ) '?!?' ; exit 20
end /* avoid PROF-option conflict */
'kedit "' || strip( FILE ) || '" (PROFile' PROF OPTS || ')'
if undo.3() + size.1() + alt() + rc = 0 then do
FILE = fileid.1() ; 'quit'
'emsg BINARY found no' FILE ; exit 28
end /* empty binary is a bad plan */
exit rc /* anything else done as PROF */
end /* -------------------------- */
'extract /FEXT/FILEID'
if dir() | alt() then do /* cannot reload changed file */
'emsg save' FILEID.1 'first, BINARY has to reload this file'
'cmsg save' ; exit 12
end
if FEXT.1 = 'BAK' then 'fext TMP' ; else 'fext BAK'
if rc <> 0 then exit rc ; FILEID.0 = fileid.1()
Q = eolout.1() <> 'NONE' /* text EOL at length.1() + 1 */
Q = max( 0, -1 + min( column.1(), Q + length.1()))
R = max( 0, -1 + min( line.1(), size.1()))
if eolout.1() <> 'NONE' then do /** EOLOUT CR 1, LF 1, CRLF 2 */
Q = Q + R * ( 2 - ( 'CRLF' <> eolout.1()))
if tabsout.1() = 'ON' then do
'compress -*' ; 'locate :' R + 1
end /* length.1() includes blanks */
do until rc <> 0 /* for TRAILING ON, 0 for TOF */
'up' ; Q = Q + length.1()
end /* undo TABSO, edit can fail: */
if tabsout.1() = 'ON' then do until 1
'undo' ; if rc = 0 then leave
'expand' R + 2 ; 'set alt 0 0'
end /* position in actual line is */
end /* not accurate if COMPRESSed */
else Q = Q + R * lrecl.1() /* determines a binary offset */
'kedit "' || FILEID.1 || '" (PROFile' PROF || ')'
if rc <> 0 then do /* trouble: reset old fileid */
R = rc ; 'fext' FEXT.2 ; exit R
end
'kedit "' || FILEID.0 || '" (NEW)' ; 'quit'
'kedit "' || FILEID.1 || '" (NEW)' ; R = lrecl.1()
'locate :' || ( 1 + Q % R ) 'clocate :' ( 1 + Q // R )
exit 0
EDIT: procedure /* -------------------------------------------- */
if initial() then do /* initialize global settings */
'nomsg define initial.kml' ; 'nomsg macro' monitor.1()
end
if version.1() = 'KEDIT' then 'scr 1'
else 'win max'
'nomsg editv get HEXE.0'
if HEXE.0 = '' then do /* save local settings HEXE.n */
'reprof on' ; 'wrap on' ; 'arrow off'
'shifts on' ; 'arbchar on' ; 'backup temp'
'number on' ; 'hexdisp on' ; 'varblank on'
call INIT ; 'editv get HEXE.0'
end
do N = 1 to HEXE.0 /* load local settings HEXE.n */
'editv get HEXE.' || N ; 'set' HEXE.N
end /* -------------------------------------------- */
LEN = lscreen.2() /* if no nice LEN use PREFIX: */
if 80 < LEN & LEN <> 100 & LEN <> 128 then do
LEN = (( LEN - 2 ) % 4 - 1 ) * 4 ; 'prefix on right'
end
'hex on' ; 'beep on' ; 'autoscroll off'
'trailing on' ; 'recfm vary' /** use 11 critical settings **/
'lrecl' LEN ; 'trunc' LEN ; 'zone 1' LEN
'eofin allow' ; 'eolin none' ; 'tabsin off'
'eofout none' ; 'eolout none' ; 'tabsout off'
/* RECFM FIXED would add blanks to the last line up to LRECL, */
/* for patching binaries this is no good idea. CAVEAT, do not */
/* insert or delete bytes or "lines" (= records = LEN bytes). */
'nomsg locate :1' /* avoid 5.0 SL1+2 TRUNC bug: */
if LEN = 1 + length.1() then 'trunc' LEN + 1
'nomsg locate :0 macro status' /* restore TOP, check STATUS */
if 0 <= rc then 'macro status' ; return 0
INIT: procedure /* -------------------------------------------- */
SET = 'attr arbchar arrow backup number undoing varblank wrap'
if version.1() <> 'KEDIT' then do
if toolset.2() = 'USER' then SET = SET 'toolset'
end
HEXE.0 = words( SET ) ; 'editv put HEXE.0'
do N = 1 to HEXE.0
'nomsg query' word( SET, N ) ; HEXE.N = lastmsg.1()
'editv put HEXE.' || N
end
parse source . . PROF ; 'nomsg query macro' PROF
if rc <> 0 then return PROF ; return PROF 'PROFDEBUG'