Rewrite the hed_expr API
[hed.git] / libhed / expr.h
blob6dfa53c189754105b3a277fcdd6a054e1a87d3de
1 /* The expression evaluator */
3 /* This is a libhed PUBLIC file.
4 * This header file will be installed on the target system.
5 * When you add new things here, make sure they start with hed_.
6 */
8 /*
9 * hed - Hexadecimal editor
10 * Copyright (C) 2004 Petr Baudis <pasky@ucw.cz>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of version 2 of the GNU General Public License as
14 * published by the Free Software Foundation.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #ifndef LIBHED__EXPR_H
27 #define LIBHED__EXPR_H
29 #include <libhed/types.h>
31 /*******************************************************************
32 * BYTE STRINGS
35 hed_off_t hed_bytestr2off(unsigned char *bytestr, size_t len, long flags);
36 void hed_off2bytestr(unsigned char *bytestr, size_t len, hed_off_t num);
38 /*******************************************************************
39 * EXPRESSIONS
42 typedef long (*hed_expr_reg_cb)(void *data, char reg, hed_off_t ofs, /* */
43 unsigned char *scramble, size_t len);
44 typedef long (*hed_expr_mark_cb)(void *data, char mark,
45 unsigned char *scramble, size_t len);
47 struct hed_expr {
48 struct hed_list_head atoms;
49 size_t len;
50 unsigned char *buf;
51 unsigned char *tmp; /* Temporary buffer for ATOM_BIN */
52 hed_expr_reg_cb reg_cb;
53 hed_expr_mark_cb mark_cb;
54 void *cb_data;
55 size_t cb_pos;
56 long flags;
59 /* Return flags for callbacks */
60 #define HED_AEF_NEGATIVE 1 // the result should be treated as negative
61 #define HED_AEF_SIGNED 2 // take the sign bit from the result
62 #define HED_AEF_DYNAMIC 4 // result is not constant
64 #define HED_AEF_ENDIANMASK (3<<3) // endianity mask
65 #define HED_AEF_KEEPENDIAN (0<<3) // keep endianity (no change)
66 #define HED_AEF_FORCELE (1<<3) // force little-endian
67 #define HED_AEF_FORCEBE (2<<3) // force big-endian
68 #define HED_AEF_SWAPENDIAN (3<<3) // always swap endianity
70 #define HED_AEF_ERROR (~(~0UL>>1))
72 /* NB: The HED_AEF_NEGATIVE flag behaves as an extra "hidden" MSB bit,
73 * which is used in calculations, but not included in the final result.
74 * This allows to fit unsigned values in the range 0..2^n-1 as well as
75 * signed values from -2^(n-1)..2^(n-1)-1 into only n bits.
77 * In particular, a zero with HED_AEF_NEGATIVE set is not treated as
78 * a negative zero, but rather as the largest negative signed value,
79 * e.g. "00" byte string with HED_AEF_NEGATIVE represents -256.
81 * HED_AEF_NEGATIVE takes precedence over HED_AEF_SIGNED. The following
82 * table shows the relation betwen the various bits and the resulting sign:
84 * HED_AEF_NEGATIVE HED_AEF_SIGNED MSB result
85 * 0 0 x positive
86 * 0 1 0 positive
87 * 0 1 1 negative
88 * 1 x x negative
91 struct hed_expr *hed_expr_new(char *sexpr,
92 hed_expr_reg_cb reg_cb,
93 hed_expr_mark_cb mark_cb,
94 void *cb_data);
95 long hed_expr_eval(struct hed_expr *expr);
96 void hed_expr_free(struct hed_expr *expr);
98 static inline size_t
99 hed_expr_len(const struct hed_expr *expr)
101 return expr->len;
104 static inline unsigned char *
105 hed_expr_buf(const struct hed_expr *expr)
107 return expr->buf;
110 static inline long
111 hed_expr_flags(const struct hed_expr *expr)
113 return expr->flags;
116 static inline hed_off_t
117 hed_expr2off(const struct hed_expr *expr)
119 return hed_bytestr2off(hed_expr_buf(expr), hed_expr_len(expr),
120 hed_expr_flags(expr));
123 #endif