Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

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