1 /* hexedit -- Hexadecimal Editor for Binary Files
2 Copyright (C) 1998 Pixel (Pascal Rigaux)
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*/
19 int move_cursor(INT delta
)
21 return set_cursor(base
+ cursor
+ delta
);
24 int set_cursor(INT loc
)
26 if (loc
< 0 && base
% lineLength
)
33 if (loc
- base
% lineLength
< 0)
35 else if (!move_base(myfloor(loc
- base
% lineLength
, lineLength
) + base
% lineLength
- base
))
38 } else if (loc
>= base
+ page
) {
39 if (!move_base(myfloor(loc
- base
% lineLength
, lineLength
) + base
% lineLength
- page
+ lineLength
- base
))
42 } else if (loc
> base
+ nbBytes
) {
53 int move_base(INT delta
)
55 if (mode
== bySector
) {
56 if (delta
> 0 && delta
< page
)
58 else if (delta
< 0 && delta
> -page
)
61 return set_base(base
+ delta
);
68 if (!tryloc(loc
)) return FALSE
;
72 if (mode
!= bySector
&& nbBytes
< page
- lineLength
&& base
!= 0) {
73 base
-= myfloor(page
- nbBytes
- lineLength
, lineLength
);
74 if (base
< 0) base
= 0;
78 if (cursor
> nbBytes
) cursor
= nbBytes
;
83 int computeLineSize(void) { return computeCursorXPos(lineLength
- 1, 0) + 1; }
84 int computeCursorXCurrentPos(void) { return computeCursorXPos(cursor
, hexOrAscii
); }
85 int computeCursorXPos(int cursor
, int hexOrAscii
)
88 int x
= cursor
% lineLength
;
89 int h
= (hexOrAscii
? x
: lineLength
- 1);
91 r
+= normalSpaces
* (h
% blocSize
) + (h
/ blocSize
) * (normalSpaces
* blocSize
+ 1) + (hexOrAscii
&& cursorOffset
);
93 if (!hexOrAscii
) r
+= x
+ normalSpaces
+ 1;
100 /*******************************************************************************/
101 /* Curses functions */
102 /*******************************************************************************/
103 void initCurses(void)
110 use_default_colors();
111 init_pair(1, COLOR_RED
, -1); /* null zeros */
112 init_pair(2, COLOR_GREEN
, -1); /* control chars */
113 init_pair(3, COLOR_BLUE
, -1); /* extended chars */
120 keypad(stdscr
, TRUE
);
122 if (mode
== bySector
) {
123 lineLength
= modes
[bySector
].lineLength
;
124 page
= modes
[bySector
].page
;
125 page
= myfloor((LINES
- 1) * lineLength
, page
);
126 blocSize
= modes
[bySector
].blocSize
;
127 if (computeLineSize() > COLS
) DIE("%s: term is too small for sectored view (width)\n");
128 if (page
== 0) DIE("%s: term is too small for sectored view (height)\n");
129 } else { /* mode == maximized */
130 if (LINES
<= 4) DIE("%s: term is too small (height)\n");
132 blocSize
= modes
[maximized
].blocSize
;
133 for (lineLength
= blocSize
; computeLineSize() <= COLS
; lineLength
+= blocSize
);
134 lineLength
-= blocSize
;
135 if (lineLength
== 0) DIE("%s: term is too small (width)\n");
137 page
= lineLength
* (LINES
- 1);
139 colsUsed
= computeLineSize();
140 buffer
= malloc(page
);
141 bufferAttr
= malloc(page
* sizeof(*bufferAttr
));
144 void exitCurses(void)
156 for (i
= 0; i
< nbBytes
; i
+= lineLength
) {
157 move(i
/ lineLength
, 0);
158 displayLine(i
, nbBytes
);
160 for (; i
< page
; i
+= lineLength
) {
162 move(i
/ lineLength
, 0);
163 for (j
= 0; j
< colsUsed
; j
++) printw(" "); /* cleanup the line */
164 move(i
/ lineLength
, 0);
165 PRINTW(("%08lX", (int) (base
+ i
)));
170 for (i
= 0; i
< colsUsed
; i
++) printw("-");
172 if (isReadOnly
) i
= '%';
173 else if (edited
) i
= '*';
175 printw("-%c%c %s --0x%llX", i
, i
, baseName
, base
+ cursor
);
176 if (MAX(fileSize
, lastEditedLoc
)) printw("/0x%llX", getfilesize());
177 if (mode
== bySector
) printw("--sector %d", (base
+ cursor
) / SECTOR_SIZE
);
179 move(cursor
/ lineLength
, computeCursorXCurrentPos());
182 void displayLine(int offset
, int max
)
186 PRINTW(("%08lX ", (int) (base
+ offset
)));
187 for (i
= offset
; i
< offset
+ lineLength
; i
++) {
188 if (i
> offset
) MAXATTRPRINTW(bufferAttr
[i
] & MARKED
, (((i
- offset
) % blocSize
) ? " " : " "));
193 buffer
[i
] == 0 ? COLOR_PAIR(1) :
194 buffer
[i
] < ' ' ? COLOR_PAIR(2) :
195 buffer
[i
] >= 127 ? COLOR_PAIR(3) : 0) |
197 bufferAttr
[i
], ("%02X", buffer
[i
]));
202 for (i
= offset
; i
< offset
+ lineLength
; i
++) {
203 if (i
>= max
) PRINTW((" "));
204 else if (buffer
[i
] >= ' ' && buffer
[i
] < 127) ATTRPRINTW(bufferAttr
[i
], ("%c", buffer
[i
]));
205 else ATTRPRINTW(bufferAttr
[i
], ("."));
209 void clr_line(int line
) { move(line
, 0); clrtoeol(); }
211 void displayCentered(char *msg
, int line
)
214 move(line
, (COLS
- strlen(msg
)) / 2);
218 void displayOneLineMessage(char *msg
)
220 int center
= page
/ lineLength
/ 2;
221 clr_line(center
- 1);
222 clr_line(center
+ 1);
223 displayCentered(msg
, center
);
226 void displayTwoLineMessage(char *msg1
, char *msg2
)
228 int center
= page
/ lineLength
/ 2;
229 clr_line(center
- 2);
230 clr_line(center
+ 1);
231 displayCentered(msg1
, center
- 1);
232 displayCentered(msg2
, center
);
235 void displayMessageAndWaitForKey(char *msg
)
237 displayTwoLineMessage(msg
, pressAnyKey
);
241 int displayMessageAndGetString(char *msg
, char **last
, char *p
, int p_size
)
245 displayOneLineMessage(msg
);
248 getnstr(p
, p_size
- 1);
251 if (*last
) strcpy(p
, *last
); else ret
= FALSE
;
259 void ungetstr(char *s
)
263 for (p
= s
+ strlen(s
) - 1; p
>= s
; p
--) ungetch(*p
);
266 int get_number(INT
*i
)
269 char tmp
[BLOCK_SEARCH_SIZE
];
271 getnstr(tmp
, BLOCK_SEARCH_SIZE
- 1);
273 if (strbeginswith(tmp
, "0x"))
274 err
= sscanf(tmp
+ strlen("0x"), "%llx", i
);
276 err
= sscanf(tmp
, "%lld", i
);