4 * hed - Hexadecimal editor
5 * Copyright (C) 2004 Petr Baudis <pasky@ucw.cz>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * 'You see: Mr. Drogo, he married poor Miss Primula Brandybuck. She was our
23 * Mr. Bilbo's first cousin on the mother's side (her mother being the youngest
24 * of the Old Took's daughters); and Mr. Drogo was his second cousin. So Mr.
25 * Frodo is his first _and_ second cousin, once removed either way, as the
26 * saying is, if you follow me.
38 #include <util/numbers.h>
39 #include <util/lists.h>
43 /* This is really just trivial implementation. */
45 #define SIZE_AUTO ((size_t)-1L)
48 struct list_head list
;
50 size_t len
; // SIZE_AUTO == auto (defaults to 1 at root)
62 /* atom_evaluator returns a flag bitmask, see the HED_AEF_xxx constants */
63 typedef long (*atom_evaluator
)(struct hed_expr
*expr
, struct atom
*atom
,
64 unsigned char *scramble
, size_t len
);
65 static long atom_un(struct hed_expr
*expr
, struct atom
*atom
,
66 unsigned char *scramble
, size_t len
);
67 static long atom_bin(struct hed_expr
*expr
, struct atom
*atom
,
68 unsigned char *scramble
, size_t len
);
69 static long atom_bytestr(struct hed_expr
*expr
, struct atom
*atom
,
70 unsigned char *scramble
, size_t len
);
71 static long atom_register(struct hed_expr
*expr
, struct atom
*atom
,
72 unsigned char *scramble
, size_t len
);
73 static long atom_mark(struct hed_expr
*expr
, struct atom
*atom
,
74 unsigned char *scramble
, size_t len
);
75 static atom_evaluator evals
[ATOM_T_MAX
] = {
76 atom_un
, atom_bin
, atom_bytestr
, atom_register
, atom_mark
79 typedef void (*atom_free
)(void *atom
);
80 static void free_un(void *p
);
81 static void free_bin(void *p
);
82 static void free_register(void *p
);
83 static atom_free frees
[ATOM_T_MAX
] = {
84 free_un
, free_bin
, free
, free_register
, free
114 struct atom_bytestr
{
116 size_t len
; /* Length of @bytes */
117 unsigned char bytes
[0]; /* [len] */
120 struct atom_register
{
123 struct hed_expr
*offset
;
132 free_atom(struct atom
*atom
)
134 frees
[atom
->type
](atom
);
141 static const char hx
[] = "0123456789abcdef89ABCDEF";
142 unsigned idx
= strchr(hx
, x
) - hx
;
143 return (idx
& 0x0f) | ((idx
& 0x10) >> 1);
147 skip_white(char **sexpr
)
149 while (isspace(**sexpr
))
153 static struct atom
*atom_parse(char **sexpr
);
154 static struct hed_expr
*expr_compile_till(char **sexpr
, char till
);
156 #if __BYTE_ORDER == __LITTLE_ENDIAN
157 # define BYTESTR_LSB(s, len) (s)
158 # define BYTESTR_STEP (+1)
159 # define BYTESTR_MSB(s, len) ((s) + (len) - 1)
160 # define BYTESTR_LOPART(s, len, plen) (s)
161 # define BYTESTR_HIPART(s, len, plen) ((s) + (len) - (plen))
162 # define HED_AEF_NATIVEORDER HED_AEF_FORCELE
163 #elif __BYTE_ORDER == __BIG_ENDIAN
164 # define BYTESTR_LSB(s, len) ((s) + (len) - 1)
165 # define BYTESTR_STEP (-1)
166 # define BYTESTR_MSB(s, len) (s)
167 # define BYTESTR_LOPART(s, len, plen) ((s) + (len) - (plen))
168 # define BYTESTR_HIPART(s, len, plen) (s)
169 # define HED_AEF_NATIVEORDER HED_AEF_FORCEBE
171 # error "Unsupported byte order"
175 hed_bytestr2off(unsigned char *bytestr
, size_t len
, long flags
)
177 unsigned char *p
, *q
;
179 register hed_off_t ret
;
181 if ((flags
& HED_AEF_ENDIANMASK
) == HED_AEF_KEEPENDIAN
||
182 (flags
& HED_AEF_ENDIANMASK
) == HED_AEF_NATIVEORDER
) {
183 p
= BYTESTR_MSB(bytestr
, len
);
184 q
= BYTESTR_LSB(bytestr
, len
);
185 step
= -BYTESTR_STEP
;
187 p
= BYTESTR_LSB(bytestr
, len
);
188 q
= BYTESTR_MSB(bytestr
, len
);
192 if (flags
& HED_AEF_SIGNED
&& (signed char)*p
< 0)
193 flags
|= HED_AEF_NEGATIVE
;
194 ret
= flags
& HED_AEF_NEGATIVE
? -1 : 0;
205 /* The following function always uses the native byte order.
206 * FIXME? Should the API be more analogous to hed_bytestr2off?
209 hed_off2bytestr(unsigned char *bytestr
, size_t len
, hed_off_t num
)
211 unsigned char *p
= BYTESTR_LSB(bytestr
, len
);
212 unsigned char *q
= BYTESTR_MSB(bytestr
, len
) + BYTESTR_STEP
;
220 /* bytestr arithmetics */
222 bytestr_not(unsigned char *s
, size_t len
)
231 bytestr_and(unsigned char *s1
, unsigned char *s2
, size_t len
)
238 bytestr_or(unsigned char *s1
, unsigned char *s2
, size_t len
)
245 bytestr_xor(unsigned char *s1
, unsigned char *s2
, size_t len
)
251 /* Get the maximum length of the shift bytestr and check that the
252 * actual value in @s fits into that size. If @s is larger than
253 * the maximum shift for @len-sized numbers, return 0. This would
254 * be otherwise an invalid value, because even a zero-sized bytestr
258 max_shiftlen(unsigned char *s
, size_t len
)
260 size_t maxshiftoff
= ((bitsize(len
) + 3) - 1) >> 3;
261 unsigned char *p
= BYTESTR_LSB(s
, len
) + maxshiftoff
* BYTESTR_STEP
;
262 while (p
!= BYTESTR_MSB(s
, len
)) {
267 return maxshiftoff
+ 1;
270 /* Get the shift size in bytes. */
272 shift_bytecount(unsigned char *s
, size_t len
, size_t shiftlen
)
276 s
= BYTESTR_LSB(s
, len
) + shiftlen
* BYTESTR_STEP
;
279 ret
= (ret
<< 8) | carry
| (*s
>> 3);
280 carry
= (*s
& 7) << 5;
286 bytestr_shl(unsigned char *s1
, unsigned char *s2
, size_t len
)
288 size_t shiftlen
, byteoff
, bitshift
;
290 shiftlen
= max_shiftlen(s2
, len
);
291 byteoff
= shiftlen
? shift_bytecount(s2
, len
, shiftlen
) : len
;
295 bitshift
= *BYTESTR_LSB(s2
, len
) & 7;
296 for (p
= BYTESTR_MSB(s1
, len
) - byteoff
* BYTESTR_STEP
;
297 p
!= BYTESTR_LSB(s1
, len
);
299 p
[byteoff
* BYTESTR_STEP
] =
301 p
[-BYTESTR_STEP
] >> (8 - bitshift
);
302 p
[byteoff
* BYTESTR_STEP
] = *p
<< bitshift
;
305 memset(BYTESTR_LOPART(s1
, len
, byteoff
), 0, byteoff
);
309 bytestr_shr(unsigned char *s1
, unsigned char *s2
, size_t len
)
311 size_t shiftlen
, byteoff
, bitshift
;
313 shiftlen
= max_shiftlen(s2
, len
);
314 byteoff
= shiftlen
? shift_bytecount(s2
, len
, shiftlen
) : len
;
318 bitshift
= *BYTESTR_LSB(s2
, len
) & 7;
319 for (p
= BYTESTR_LSB(s1
, len
) + byteoff
* BYTESTR_STEP
;
320 p
!= BYTESTR_MSB(s1
, len
);
322 p
[-byteoff
* BYTESTR_STEP
] =
324 p
[BYTESTR_STEP
] << (8 - bitshift
);
325 p
[-byteoff
* BYTESTR_STEP
] = *p
>> bitshift
;
328 memset(BYTESTR_HIPART(s1
, len
, byteoff
), 0, byteoff
);
332 bytestr_inc(unsigned char *s
, size_t len
)
335 s
= BYTESTR_LSB(s
, len
);
339 } while (carry
&& --len
);
344 bytestr_add(unsigned char *s1
, unsigned char *s2
, size_t len
)
347 s1
= BYTESTR_LSB(s1
, len
);
348 s2
= BYTESTR_LSB(s2
, len
);
360 bytestr_sub(unsigned char *s1
, unsigned char *s2
, size_t len
)
363 s1
= BYTESTR_LSB(s1
, len
);
364 s2
= BYTESTR_LSB(s2
, len
);
375 /* multiply @src by @mul and add it to @dst */
377 muladd(unsigned char *dst
, unsigned char *src
, size_t len
, unsigned char mul
)
380 unsigned char *p
= BYTESTR_LSB(src
, len
);
381 unsigned char *q
= BYTESTR_LSB(dst
, len
);
382 while (p
!= BYTESTR_MSB(src
, len
) + BYTESTR_STEP
) {
383 carry
+= *p
* mul
+ *q
;
393 bytestr_mul(unsigned char *s1
, unsigned char *s2
, size_t len
)
395 unsigned char ret
[len
];
399 for (mlen
= len
; mlen
; --mlen
)
400 muladd(BYTESTR_HIPART(ret
, len
, mlen
),
401 BYTESTR_LOPART(s1
, len
, mlen
), mlen
,
402 BYTESTR_MSB(s2
, len
)[(1-mlen
) * BYTESTR_STEP
]);
403 memcpy(s1
, ret
, len
);
407 shl_one(unsigned char *s
, size_t len
, unsigned carry
)
409 unsigned char *p
= BYTESTR_LSB(s
, len
);
410 while (p
!= BYTESTR_MSB(s
, len
) + BYTESTR_STEP
) {
419 /* Simple non-restoring algorithm for now.
420 * Feel free to improve.
423 bytestr_div(unsigned char *s1
, unsigned char *s2
, size_t len
,
426 unsigned char *p
, mask
;
429 p
= BYTESTR_MSB(s1
, len
);
431 while (p
!= BYTESTR_LSB(s1
, len
) - BYTESTR_STEP
) {
432 if (shl_one(mod
, len
, !!(*p
& mask
)))
433 bytestr_add(mod
, s2
, len
);
435 bytestr_sub(mod
, s2
, len
);
437 if (*BYTESTR_MSB(mod
, len
) & 0x80)
442 if (! (mask
>>= 1) ) {
447 if (*BYTESTR_MSB(mod
, len
) & 0x80)
448 bytestr_add(mod
, s2
, len
);
451 /* Remove any MSB zeroes from @s and update *@plen. */
452 static unsigned char*
453 bytestr_shrink(unsigned char *s
, size_t *plen
)
455 size_t origlen
= *plen
;
456 unsigned char *p
= BYTESTR_MSB(s
, origlen
);
458 while (*plen
> 1 && !*p
) {
462 return memmove(s
, BYTESTR_LOPART(s
, origlen
, *plen
), *plen
);
465 static unsigned char*
466 bytestr_from_hex(char **nptr
, size_t *plen
)
469 unsigned char *ret
, *s
;
472 for (q
= p
= *nptr
; isxdigit(*q
); ++q
);
474 *plen
= ((size_t)(q
- p
) + 1) >> 1;
476 if (! (ret
= calloc(1, *plen
)) )
479 s
= BYTESTR_LSB(ret
, *plen
);
482 *s
|= unhex(*q
) << shift
;
493 static unsigned char*
494 bytestr_from_oct(char **nptr
, size_t *plen
)
497 unsigned char *ret
, *s
;
500 for (q
= p
= *nptr
; *q
>= '0' && *q
<= '7'; ++q
);
502 *plen
= ((size_t)(q
- p
) * 3 + 7)/8 ?: 1;
503 if (! (ret
= calloc(1, *plen
)) )
506 s
= BYTESTR_LSB(ret
, *plen
);
509 acc
|= (*q
- '0') << shift
;
521 return bytestr_shrink(ret
, plen
);
524 /* Number of bits per decimal digit scaled by 256 (8 bit shift) */
525 #define SBITSPERDECDIG 851
527 static unsigned char*
528 bytestr_from_dec(char **nptr
, size_t *plen
)
531 unsigned char *ret
, *s
;
533 /* We must make sure that the resulting bytestr will fit into
534 * the allocated space, so we must always round to the nearest
535 * higher integer. Because of this, the approximation of log2(10)
536 * and the dependency on the actual number, the allocated space
537 * may be larger than necessary.
539 for (p
= q
= *nptr
; isdigit(*q
); ++q
);
541 *plen
= (((size_t)(q
- p
) * SBITSPERDECDIG
+ 255)/256 + 7)/8 ?: 1;
542 if (! (ret
= calloc(1, *plen
)) )
546 unsigned carry
= *p
++ - '0';
547 for (s
= BYTESTR_LSB(ret
, *plen
);
548 s
!= BYTESTR_MSB(ret
, *plen
) + BYTESTR_STEP
;
556 return bytestr_shrink(ret
, plen
);
559 /* Convert an ascii representation to a bytestr */
560 static unsigned char*
561 bytestr_from_ascii(char **nptr
, size_t *plen
)
565 if ((**nptr
== 'x' || **nptr
== 'X') &&
566 isxdigit((*nptr
)[1])) {
568 return bytestr_from_hex(nptr
, plen
);
570 return bytestr_from_oct(nptr
, plen
);
572 return bytestr_from_dec(nptr
, plen
);
576 bytestr_unop(unsigned char *s
, size_t len
, long flags
, enum atom_un_op op
)
582 if (op
== AUO_MINUS
) {
583 if (!bytestr_inc(s
, len
))
584 flags
^= HED_AEF_NEGATIVE
;
595 bytestr_binop(unsigned char *s1
, unsigned char *s2
, size_t len
,
596 long flags1
, long flags2
, enum atom_bin_op op
)
600 int sign
= !!(flags1
& HED_AEF_NEGATIVE
);
601 int sign2
= !!(flags2
& HED_AEF_NEGATIVE
);
602 long ret
= (flags1
& ~HED_AEF_NEGATIVE
) | (flags2
& HED_AEF_DYNAMIC
);
607 bytestr_or(s1
, s2
, len
);
611 bytestr_and(s1
, s2
, len
);
615 bytestr_xor(s1
, s2
, len
);
618 carry
= bytestr_add(s1
, s2
, len
);
619 sign
^= (sign
^ sign2
) & (sign
^ !carry
);
622 carry
= bytestr_sub(s1
, s2
, len
);
623 sign
^= ((sign
^ sign2
) | (sign
^ !carry
)) ^ 1;
627 bytestr_mul(s1
, s2
, len
);
632 if (! (smod
= malloc(len
)) ) {
633 flags1
= HED_AEF_ERROR
;
636 bytestr_div(s1
, s2
, len
, smod
);
638 memcpy(s1
, smod
, len
);
642 bytestr_shl(s1
, s2
, len
);
645 bytestr_shr(s1
, s2
, len
);
651 ret
|= HED_AEF_NEGATIVE
& -sign
;
656 alloc_atom(enum atom_type type
, size_t len
)
658 static const size_t sizes
[] = {
659 sizeof(struct atom_un
),
660 sizeof(struct atom_bin
),
661 sizeof(struct atom_bytestr
),
662 sizeof(struct atom_register
),
663 sizeof(struct atom_mark
)
665 size_t asize
= sizes
[type
];
668 if (type
== ATOM_BYTESTR
)
671 a
= calloc(1, asize
);
678 val_parse(char **sexpr
)
680 char uopc
[] = "~-"; // in atom_un_op order
686 if (**sexpr
== '(') {
688 ret
= atom_parse(sexpr
);
690 } else if ( (uop
= strchr(uopc
, **sexpr
)) ) {
695 sa
= val_parse(sexpr
);
699 a
= alloc_atom(ATOM_UN
, sa
->len
);
704 } else if (**sexpr
== '"') {
705 struct atom_register
*a
;
712 a
= alloc_atom(ATOM_REGISTER
, SIZE_AUTO
);
715 if (**sexpr
== '[') {
717 a
->offset
= expr_compile_till(sexpr
, ']');
722 } else if (**sexpr
== '@') {
730 a
= alloc_atom(ATOM_MARK
, sizeof(hed_off_t
));
734 } else if (**sexpr
== '\'') {
735 struct atom_bytestr
*a
;
741 while (**sexpr
&& **sexpr
!= '\'') {
742 if (**sexpr
== '\\') {
751 a
= alloc_atom(ATOM_BYTESTR
, i
);
753 for (i
= 0; base
< *sexpr
; i
++, base
++) {
761 } else if (**sexpr
== 'x') {
762 struct atom_bytestr
*a
;
768 while (isxdigit(**sexpr
))
771 a
= alloc_atom(ATOM_BYTESTR
, (*sexpr
- base
+ 1)/2);
775 if ((*sexpr
- base
) % 2)
776 a
->bytes
[i
++] = unhex(*base
++);
777 while (base
< *sexpr
) {
778 a
->bytes
[i
++] = (unhex(base
[0]) << 4) + unhex(base
[1]);
783 } else if (isdigit(**sexpr
)) {
784 struct atom_bytestr
*a
;
788 if (! (num
= bytestr_from_ascii(sexpr
, &len
)) )
791 a
= alloc_atom(ATOM_BYTESTR
, len
);
793 memcpy(a
->bytes
, num
, len
);
800 if (**sexpr
== '{') {
802 ret
->len
= strtoull(*sexpr
, sexpr
, 0);
803 if (**sexpr
!= '}') {
813 atom_lparse(char **sexpr
, struct atom
*sa1
)
817 char bopc
[] = "|&^+-*/%<>"; // in atom_bin_op order
823 if (**sexpr
== ')') {
825 return sa1
; // *SLAMM*
827 bop
= strchr(bopc
, **sexpr
);
831 if (*bop
== '<' || *bop
== '>') {
832 if (*(*sexpr
)++ != *bop
)
835 sa2
= val_parse(sexpr
);
839 //fprintf(stderr, "parse error at <%s>\n", *sexpr);
842 if (sa1
->len
== SIZE_AUTO
)
844 else if (sa2
->len
== SIZE_AUTO
)
846 /* Note that BOTH may be SIZE_AUTO, but that's ok */
848 a
= alloc_atom(ATOM_BIN
, max(sa1
->len
, sa2
->len
));
852 /* Try to expand the epxression */
853 return atom_lparse(sexpr
, &a
->a
) ? : &a
->a
;
857 atom_parse(char **sexpr
)
859 struct atom
*a
, *sa1
;
861 sa1
= val_parse(sexpr
);
863 //fprintf(stderr, "parse error at <%s>\n", *sexpr);
864 (*sexpr
)++; // no luck, maybe next char
867 a
= atom_lparse(sexpr
, sa1
);
875 static struct hed_expr
*
876 expr_compile_till(char **sexpr
, char till
)
878 struct hed_expr
*expr
= calloc(1, sizeof(struct hed_expr
));
880 INIT_LIST_HEAD(&expr
->atoms
);
881 while (**sexpr
!= till
) {
882 struct atom
*a
= atom_parse(sexpr
);
886 list_add_tail(&a
->list
, &expr
->atoms
);
887 if (a
->len
== SIZE_AUTO
)
889 if (a
->type
== ATOM_BIN
&& a
->len
> tmplen
)
895 expr
->buf
= malloc(expr
->len
+ tmplen
);
898 expr
->tmp
= expr
->buf
+ expr
->len
;
909 hed_expr_compile(char *sexpr
)
911 return expr_compile_till(&sexpr
, '\0');
916 atom_eval(struct hed_expr
*expr
, struct atom
*atom
,
917 unsigned char *scramble
, size_t len
)
922 return evals
[atom
->type
](expr
, atom
, scramble
, len
);
926 atom_un(struct hed_expr
*expr
, struct atom
*atom
,
927 unsigned char *scramble
, size_t len
)
929 struct atom_un
*data
= (struct atom_un
*) atom
;
933 flags
= atom_eval(expr
, data
->atom
, scramble
, len
);
934 if (flags
& HED_AEF_ERROR
)
936 return bytestr_unop(scramble
, len
, flags
, data
->op
);
940 atom_bin(struct hed_expr
*expr
, struct atom
*atom
,
941 unsigned char *scramble
, size_t len
)
943 struct atom_bin
*data
= (struct atom_bin
*) atom
;
946 assert(data
->atom1
&& data
->atom2
);
948 flags1
= atom_eval(expr
, data
->atom1
, scramble
, len
);
949 if (flags1
& HED_AEF_ERROR
)
952 flags2
= atom_eval(expr
, data
->atom2
, expr
->tmp
, len
);
953 if (flags2
& HED_AEF_ERROR
)
956 return bytestr_binop(scramble
, expr
->tmp
, len
,
957 flags1
, flags2
, data
->op
);
961 atom_bytestr(struct hed_expr
*expr
, struct atom
*atom
,
962 unsigned char *scramble
, size_t len
)
964 struct atom_bytestr
*data
= (struct atom_bytestr
*) atom
;
966 if (len
> data
->len
) {
967 memcpy(BYTESTR_LOPART(scramble
, len
, data
->len
),
968 data
->bytes
, data
->len
);
969 memset(BYTESTR_HIPART(scramble
, len
, len
- data
->len
),
973 BYTESTR_LOPART(data
->bytes
, data
->len
, len
), len
);
978 atom_mark(struct hed_expr
*expr
, struct atom
*atom
,
979 unsigned char *scramble
, size_t len
)
981 struct atom_mark
*data
= (struct atom_mark
*) atom
;
983 if (!expr
->mark_cb
) {
984 memset(scramble
, 0, len
);
988 return expr
->mark_cb(expr
->cb_data
, data
->mark
, scramble
, len
);
993 atom_register(struct hed_expr
*expr
, struct atom
*atom
,
994 unsigned char *scramble
, size_t len
)
996 struct atom_register
*data
= (struct atom_register
*) atom
;
1000 memset(scramble
, 0, len
);
1005 if (hed_expr_eval(data
->offset
, expr
->reg_cb
,
1006 expr
->mark_cb
, expr
->cb_data
)
1008 return HED_AEF_ERROR
;
1010 ofs
= hed_expr2off(data
->offset
);
1014 if (data
->reg
== '.')
1015 ofs
+= expr
->cb_pos
;
1016 return expr
->reg_cb(expr
->cb_data
, data
->reg
, ofs
,
1022 hed_expr_eval(struct hed_expr
*expr
,
1023 hed_expr_reg_cb rcb
, hed_expr_mark_cb mcb
, void *data
)
1028 expr
->mark_cb
= mcb
;
1029 expr
->cb_data
= data
;
1033 assert(expr
&& expr
->len
>= 0);
1034 list_for_each_entry (a
, &expr
->atoms
, list
) {
1037 flags
= atom_eval(expr
, a
,
1038 expr
->buf
+ expr
->cb_pos
, a
->len
);
1039 expr
->flags
|= (flags
& (HED_AEF_DYNAMIC
| HED_AEF_ERROR
));
1041 expr
->flags
|= (flags
& HED_AEF_NEGATIVE
);
1043 expr
->flags
&= ~HED_AEF_NEGATIVE
;
1044 expr
->cb_pos
+= a
->len
;
1046 assert(expr
->cb_pos
== expr
->len
);
1053 struct atom_un
*un
= (struct atom_un
*) p
;
1054 free_atom(un
->atom
);
1061 struct atom_bin
*bin
= (struct atom_bin
*) p
;
1062 free_atom(bin
->atom1
);
1063 free_atom(bin
->atom2
);
1068 free_register(void *p
)
1070 struct atom_register
*reg
= (struct atom_register
*) p
;
1072 hed_expr_free(reg
->offset
);
1077 hed_expr_free(struct hed_expr
*expr
)
1079 struct atom
*a
, *next
;
1081 list_for_each_entry_safe (a
, next
, &expr
->atoms
, list
)