Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 309 lines (277 sloc) 7.952 kB
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
1 /* dmhex.c */
2 /* Copyright 1995 by Steve Kirkendall */
3
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
4 char id_dmhex[] = "$Id: dmhex.c,v 2.15 1998/07/31 02:03:45 steve Exp $";
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
5
6 #include "elvis.h"
7 #ifdef DISPLAY_HEX
8
9 #ifdef CHAR16
10 "hex mode doesn't support 16-bit characters"
11 #endif
12
13 #if USE_PROTOTYPES
14 static DMINFO *init(WINDOW win);
15 static void term(DMINFO *info);
16 static long mark2col(WINDOW w, MARK mark, BOOLEAN cmd);
17 static MARK move(WINDOW w, MARK from, long linedelta, long column, BOOLEAN cmd);
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
18 static MARK setup(WINDOW win, MARK top, long cursor, MARK bottom, DMINFO *info);
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
19 static MARK image(WINDOW w, MARK line, DMINFO *info, void (*draw)(CHAR *p, long qty, _char_ font, long offset));
20 #endif
21
22 /* Lines look like this:
23 _offset____0__1__2__3___4__5__6__7___8__9__a__b___c__d__e__f__0123456789abcdef
24 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000000000000000
25 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000000000000000
26 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000000000000000
27 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000000000000000
28 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000000000000000
29 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0000000000000000
30 */
31
32 /* This array is used to convert a column number to an offset within a line */
33 static char col2offset[] = "00000000000011122233334445556667777888999aaabbbbcccdddeeeffff00123456789abcdef";
34
35 /* start the mode, and allocate dminfo */
36 static DMINFO *init(win)
37 WINDOW win;
38 {
39 /* inherit some functions from dmnormal */
40 if (!dmhex.wordmove)
41 {
42 dmhex.wordmove = dmnormal.wordmove;
43 dmhex.tagatcursor = dmnormal.tagatcursor;
44 dmhex.tagload = dmnormal.tagload;
45 dmhex.tagnext = dmnormal.tagnext;
46 }
47
48 return NULL;
49 }
50
51 /* end the mode, and free the modeinfo */
52 static void term(info)
53 DMINFO *info; /* window-specific info about mode */
54 {
55 }
56
57 /* Convert a mark to a screen-relative column number */
58 static long mark2col(w, mark, cmd)
59 WINDOW w; /* window where buffer is shown */
60 MARK mark; /* mark to convert */
61 BOOLEAN cmd; /* if True, we're in command mode; else input mode */
62 {
63 return 62 + (markoffset(mark) & 0xf);
64 }
65
66 /* Move vertically, and to a given column (or as close to column as possible) */
67 static MARK move(w, from, linedelta, column, cmd)
68 WINDOW w; /* window where buffer is shown */
69 MARK from; /* old location */
70 long linedelta; /* line movement */
71 long column; /* desired column number */
72 BOOLEAN cmd; /* if True, we're in command mode; else input mode */
73 {
74 static MARKBUF mark;
75 long offset;
76 long coloff;
77
78 /* compute line movement first */
79 offset = (markoffset(from) & ~0xf) + 0x10 * linedelta;
80
81 /* convert requested column to nearest buffer offset */
82 if (column >= (int)strlen(col2offset))
83 {
84 coloff = 0xf;
85 }
86 else if (col2offset[column] >= '0' && col2offset[column] <= '9')
87 {
88 coloff = col2offset[column] - '0';
89 }
90 else
91 {
92 coloff = col2offset[column] - 'a' + 0xa;
93 }
94 offset += coloff;
95
96 /* never return an offset past the end of the buffer, or before the
97 * beginning.
98 */
99 if (offset >= o_bufchars(markbuffer(from)))
100 {
101 if (o_bufchars(markbuffer(from)) == 0)
102 {
103 offset = 0;
104 }
105 else
106 {
107 offset = o_bufchars(markbuffer(from)) - 1;
108 }
109 }
110 else if (offset < 0)
111 {
112 offset = coloff;
113 }
114
115 return marktmp(mark, markbuffer(from), offset);
116 }
117
118 /* Choose a line to appear at the top of the screen, and return its mark.
119 * Also, initialize the info for the next line.
120 */
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
121 static MARK setup(win, top, cursor, bottom, info)
122 WINDOW win; /* window to be updated */
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
123 MARK top; /* where previous image started */
124 long cursor; /* offset of cursor */
125 MARK bottom; /* where previous image ended */
126 DMINFO *info; /* window-specific info about mode */
127 {
128 static MARKBUF mark;
129 long topoff, bottomoff;
130
131 /* extract the offsets. Round down to multiple of 16 */
132 topoff = (top ? (markoffset(top) & ~0xf) : -1);
133 bottomoff = (bottom ? (markoffset(bottom) & ~0xf) : -1);
134 cursor &= ~0xf;
135
136 /* if cursor is on the screen, or very near the bottom, then
137 * keep the current top
138 */
139 if (cursor >= topoff && cursor <= bottomoff + 16)
140 {
141 return marktmp(mark, markbuffer(top), topoff);
142 }
143
144 /* if the cursor is on the line before the top, then make the cursor's
145 * line become the new top line.
146 */
147 if (cursor == topoff - 16)
148 {
149 return marktmp(mark, markbuffer(top), cursor);
150 }
151
152 /* else it is distantly before or after the the old screen. Center
153 * the cursor's line in the screen.
154 */
155 topoff = (cursor - (bottomoff - topoff) / 2) & ~0xf;
156 if (topoff < 0)
157 {
158 topoff = 0;
159 }
160 return marktmp(mark, markbuffer(top), topoff);
161 }
162
163 static MARK image(w, line, info, draw)
164 WINDOW w; /* window where drawing will go */
165 MARK line; /* start of line to draw */
166 DMINFO *info; /* window-specific info about mode */
167 void (*draw)P_((CHAR *p, long qty, _char_ font, long offset));
168 /* function for drawing a single character */
169 {
170 char *c8p;
171 CHAR *cp;
172 CHAR tmp;
173 CHAR space; /* usually a space character, maybe bracket character */
174 char buf[10];
175 int i, j;
176
177 /* output headings, if necessary */
178 if ((markoffset(line) & 0xf0) == 0)
179 {
180 for (c8p = " offset 0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef";
181 *c8p; c8p++)
182 {
183 tmp = *c8p;
184 (*draw)(&tmp, 1, 'u', -1);
185 }
186 tmp = '\n';
187 (*draw)(&tmp, 1, 'n', -1);
188 }
189
190 /* output the line offset */
191 sprintf(buf, "%08lx", markoffset(line));
192 for (i = 0; buf[i]; i++)
193 {
194 tmp = buf[i];
195 (*draw)(&tmp, 1, 'n', -1);
196 }
197
198 /* output the hex codes of the line */
199 j = markoffset(w->cursor) - markoffset(line);
200 space = ' ';
201 for ((void)scanalloc(&cp, line), i = 0; i < 16 && cp; scannext(&cp), i++)
202 {
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
203 /* special case: if the last newline was added by elvis
204 * (not in the file) then hide it unless the cursor is on it.
205 */
206 if (o_partiallastline(markbuffer(line))
207 && (o_readeol(markbuffer(line)) == 'b' || o_writeeol == 'b')
208 && *cp == '\n'
209 && markoffset(line) + i == o_bufchars(markbuffer(line)) - 1
210 && j != i)
211 {
212 break;
213 }
214
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
215 if ((i & 0x03) == 0)
216 {
217 (*draw)(&space, 1, 'n', -1);
218 space = ' ';
219 }
220 if (j == i)
221 {
222 tmp = '<';
223 (*draw)(&tmp, 1, 'n', -1);
224 space = '>';
225 }
226 else
227 {
228 (*draw)(&space, 1, 'n', -1);
229 space = ' ';
230 }
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
231
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
232 sprintf(buf, "%02x", *cp);
233 tmp = buf[0];
234 (*draw)(&tmp, 1, (char)(j==i ? 'u' : 'n'), markoffset(line) + i);
235 tmp = buf[1];
236 (*draw)(&tmp, 1, (char)(j==i ? 'u' : 'n'), markoffset(line) + i);
237 }
238 (*draw)(&space, 1, 'n', -1);
239
240 /* pad with blanks, if necessary */
241 space = ' ';
242 while (i < 16)
243 {
244 (*draw)(&space, ((i & 0x03) == 0) ? -4 : -3, 'n', -1);
245 i++;
246 }
247 (*draw)(&space, 1, 'n', -1);
248
249 /* output the characters */
250 tmp = '.';
251 for ((void)scanseek(&cp, line), i = 0; i < 16 && cp; scannext(&cp), i++)
252 {
8d1ac0c @mbert Import Elvis 2.1 (written by Steve Kirkendall)
authored
253 /* special case: if the last newline was added by elvis
254 * (not in the file) then hide it unless the cursor is on it.
255 */
256 if (o_partiallastline(markbuffer(line))
257 && (o_readeol(markbuffer(line)) == 'b' || o_writeeol == 'b')
258 && *cp == '\n'
259 && markoffset(line) + i == o_bufchars(markbuffer(line)) - 1
260 && j != i)
261 {
262 (*draw)(blanks, 1, 'n', markoffset(line) + i);
263 }
264 else if (*cp < ' ' || *cp == '\177')
cf92e3b @mbert Import Elvis 2.0 (written by Steve Kirkendall)
authored
265 {
266 (*draw)(&tmp, 1, 'n', markoffset(line) + i);
267 }
268 else
269 {
270 (*draw)(cp, 1, 'n', markoffset(line) + i);
271 }
272 }
273 scanfree(&cp);
274 tmp = '\n';
275 (*draw)(&tmp, 1, 'n', -1);
276
277 /* output a blank line after every 16th data line */
278 if ((markoffset(line) & 0xf0) == 0xf0)
279 {
280 (*draw)(&tmp, 1, 'n', -1);
281 }
282
283 markoffset(line) += i;
284 return line;
285 }
286
287 DISPMODE dmhex =
288 {
289 "hex",
290 "Binary hex dump",
291 False, /* display generating can't be optimized */
292 False, /* shouldn't do normal wordwrap */
293 0, /* no window options */
294 NULL,
295 0, /* no global options */
296 NULL,
297 NULL,
298 init,
299 term,
300 mark2col,
301 move,
302 NULL, /* wordmove will be set to dmnormal.wordmove in init() */
303 setup,
304 image,
305 NULL, /* doesn't need a header */
306 NULL /* no autoindent */
307 };
308 #endif /* DISPLAY_HEX */
Something went wrong with that request. Please try again.