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.*/
22 int move_cursor(INT delta
)
24 return set_cursor(base
+ cursor
+ delta
);
27 int set_cursor(INT loc
)
29 if (loc
< 0 && base
% lineLength
)
36 if (loc
- base
% lineLength
< 0)
38 else if (!move_base(myfloor(loc
- base
% lineLength
, lineLength
) + base
% lineLength
- base
))
41 } else if (loc
>= base
+ page
) {
42 if (!move_base(myfloor(loc
- base
% lineLength
, lineLength
) + base
% lineLength
- page
+ lineLength
- base
))
45 } else if (loc
> base
+ nbBytes
) {
56 int move_base(INT delta
)
58 if (mode
== bySector
) {
59 if (delta
> 0 && delta
< page
)
61 else if (delta
< 0 && delta
> -page
)
64 return set_base(base
+ delta
);
71 if (!tryloc(loc
)) return FALSE
;
75 if (mode
!= bySector
&& nbBytes
< page
- lineLength
&& base
!= 0) {
76 base
-= myfloor(page
- nbBytes
- lineLength
, lineLength
);
77 if (base
< 0) base
= 0;
81 if (cursor
> nbBytes
) cursor
= nbBytes
;
86 int computeLineSize(void) { return computeCursorXPos(lineLength
- 1, 0) + 1; }
87 int computeCursorXCurrentPos(void) { return computeCursorXPos(cursor
, hexOrAscii
); }
88 int computeCursorXPos(int cursor
, int hexOrAscii
)
91 int x
= cursor
% lineLength
;
92 int h
= (hexOrAscii
? x
: lineLength
- 1);
94 r
+= normalSpaces
* (h
% blocSize
) + (h
/ blocSize
) * (normalSpaces
* blocSize
+ 1) + (hexOrAscii
&& cursorOffset
);
96 if (!hexOrAscii
) r
+= x
+ normalSpaces
+ 1;
103 /*******************************************************************************/
104 /* Curses functions */
105 /*******************************************************************************/
106 void initCurses(void)
109 have_colors
= has_colors();
110 if (have_colors
&& colored
) {
112 use_default_colors();
113 init_pair(1, COLOR_RED
, -1); /* null zeros */
114 init_pair(2, COLOR_GREEN
, -1); /* control chars */
115 init_pair(3, COLOR_BLUE
, -1); /* extended chars */
121 keypad(stdscr
, TRUE
);
123 if (mode
== bySector
) {
124 lineLength
= modes
[bySector
].lineLength
;
125 page
= modes
[bySector
].page
;
126 page
= myfloor((LINES
- 1) * lineLength
, page
);
127 blocSize
= modes
[bySector
].blocSize
;
128 if (computeLineSize() > COLS
) DIE("%s: term is too small for sectored view (width)\n");
129 if (page
== 0) DIE("%s: term is too small for sectored view (height)\n");
130 } else { /* mode == maximized */
131 if (LINES
<= 4) DIE("%s: term is too small (height)\n");
133 blocSize
= modes
[maximized
].blocSize
;
134 for (lineLength
= blocSize
; computeLineSize() <= COLS
; lineLength
+= blocSize
);
135 lineLength
-= blocSize
;
136 if (lineLength
== 0) DIE("%s: term is too small (width)\n");
138 page
= lineLength
* (LINES
- 1);
140 colsUsed
= computeLineSize();
141 buffer
= malloc(page
);
142 bufferAttr
= malloc(page
* sizeof(*bufferAttr
));
145 void exitCurses(void)
157 for (i
= 0; i
< nbBytes
; i
+= lineLength
) {
158 move(i
/ lineLength
, 0);
159 displayLine(i
, nbBytes
);
161 for (; i
< page
; i
+= lineLength
) {
163 move(i
/ lineLength
, 0);
164 for (j
= 0; j
< colsUsed
; j
++) printw(" "); /* cleanup the line */
165 move(i
/ lineLength
, 0);
166 PRINTW(("%08lX", (int) (base
+ i
)));
171 for (i
= 0; i
< colsUsed
; i
++) printw("-");
173 if (isReadOnly
) i
= '%';
174 else if (edited
) i
= '*';
176 printw("-%c%c %s --0x%llX", i
, i
, baseName
, base
+ cursor
);
177 if (MAX(fileSize
, lastEditedLoc
)) printw("/0x%llX", getfilesize());
178 if (mode
== bySector
) printw("--sector %d", (base
+ cursor
) / SECTOR_SIZE
);
180 move(cursor
/ lineLength
, computeCursorXCurrentPos());
183 void displayLine(int offset
, int max
)
187 PRINTW(("%08lX ", (int) (base
+ offset
)));
188 for (i
= offset
; i
< offset
+ lineLength
; i
++) {
189 if (i
> offset
) MAXATTRPRINTW(bufferAttr
[i
] & MARKED
, (((i
- offset
) % blocSize
) ? " " : " "));
192 (!(have_colors
&& colored
) ? 0 :
193 buffer
[i
] == 0 ? COLOR_PAIR(1) :
194 buffer
[i
] < ' ' ? COLOR_PAIR(2) :
195 buffer
[i
] >= 127 ? COLOR_PAIR(3) : 0) |
196 bufferAttr
[i
], ("%02X", buffer
[i
]));
201 for (i
= offset
; i
< offset
+ lineLength
; i
++) {
202 if (i
>= max
) PRINTW((" "));
203 else if (buffer
[i
] >= ' ' && buffer
[i
] < 127) ATTRPRINTW(bufferAttr
[i
], ("%c", buffer
[i
]));
204 else ATTRPRINTW(bufferAttr
[i
], ("."));
208 void clr_line(int line
) { move(line
, 0); clrtoeol(); }
210 void displayCentered(char *msg
, int line
)
213 move(line
, (COLS
- strlen(msg
)) / 2);
217 void displayOneLineMessage(char *msg
)
219 int center
= page
/ lineLength
/ 2;
220 clr_line(center
- 1);
221 clr_line(center
+ 1);
222 displayCentered(msg
, center
);
225 void displayTwoLineMessage(char *msg1
, char *msg2
)
227 int center
= page
/ lineLength
/ 2;
228 clr_line(center
- 2);
229 clr_line(center
+ 1);
230 displayCentered(msg1
, center
- 1);
231 displayCentered(msg2
, center
);
234 void displayMessageAndWaitForKey(char *msg
)
236 displayTwoLineMessage(msg
, pressAnyKey
);
240 int displayMessageAndGetString(char *msg
, char **last
, char *p
, int p_size
)
244 displayOneLineMessage(msg
);
247 getnstr(p
, p_size
- 1);
250 if (*last
) strcpy(p
, *last
); else ret
= FALSE
;
258 void ungetstr(char *s
)
262 for (p
= s
+ strlen(s
) - 1; p
>= s
; p
--) ungetch(*p
);
265 int get_number(INT
*i
)
267 char tmp
[BLOCK_SEARCH_SIZE
];
269 getnstr(tmp
, BLOCK_SEARCH_SIZE
- 1);
271 int base
= ((tmp
[0] == '0' && tmp
[1] == 'x') ? 16 : 10);
273 unsigned long val
= strtoul(tmp
, NULL
, base
);
275 return (errno
!= EINVAL
);