]> mj.ucw.cz Git - libucw.git/blob - ucw/xtypes.h
xtypes: overflow detection updated
[libucw.git] / ucw / xtypes.h
1 /*
2  *      UCW Library -- Extended Types
3  *
4  *      (c) 2014 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #ifndef _UCW_XTYPE_H
11 #define _UCW_XTYPE_H
12
13 #ifdef CONFIG_UCW_CLEAN_ABI
14 #define xt_bool ucw_xt_bool
15 #define xt_double ucw_xt_double
16 #define xt_int ucw_xt_int
17 #define xt_intmax ucw_xt_intmax
18 #define xt_s64 ucw_xt_s64
19 #define xt_str ucw_xt_str
20 #define xt_u64 ucw_xt_u64
21 #define xt_uint ucw_xt_uint
22 #define xt_uintmax ucw_xt_uintmax
23 #define xtype_format_fmt ucw_xtype_format_fmt
24 #define xtype_parse_fmt ucw_xtype_parse_fmt
25 #define xtype_unit_parser ucw_xtype_unit_parser
26 #endif
27
28 struct mempool;
29
30 /**
31  * A parsing callback. Takes a string, interprets it as a value of the particular
32  * xtype and stores it where @dest points. Returns NULL on success and an error message
33  * otherwise. It may allocate memory from the @pool and the parsed value can contain
34  * pointers to this memory.
35  **/
36 typedef const char * (*xtype_parser)(const char *str, void *dest, struct mempool *pool);
37
38 /**
39  * A formatting callback. Takes a value of the particular xtype and a formatting
40  * mode @fmt (see below for how the modes work) and returns a string representation
41  * of the value. The string can be allocated from the @pool, but it does not have to.
42  *
43  * When @fmt is set to `XTYPE_FMT_DEFAULT`, the resulting string should be
44  * parseable via the parsing callback and yield a semantically equivalent value.
45  **/
46 typedef const char * (*xtype_formatter)(void *src, u32 fmt, struct mempool *pool);
47
48 /**
49  * Formatting of values is controlled by a mode parameter, which is generally
50  * a 32-bit integer. If the most significant bit is clear, it is one of generic
51  * well-known modes (`XTYPE_FMT_`'something'), which can be passed to all formatters
52  * and if it is not understood, it acts like `XTYPE_FMT_DEFAULT`. When the most
53  * significant bit is set, the meaning of the mode is specific to the particular
54  * xtype.
55  **/
56
57 enum xtype_fmt {
58   XTYPE_FMT_DEFAULT = 0,        // Default format: readable, but not hostile to machine parsing
59   XTYPE_FMT_RAW = 1,            // Raw data with no frills
60   XTYPE_FMT_PRETTY = 2,         // Try to please humans (e.g., like "ls -h")
61   XTYPE_FMT_CUSTOM = 0x80000000,
62 };
63
64 /**
65  * A callback for parsing non-generic formatting modes. See `xtype_parser` for more
66  * details. It is usually called via `xtype_parse_fmt`, which handles the generic modes.
67  **/
68 typedef const char * (*xtype_fmt_parser)(const char *str, u32 *dest, struct mempool *pool);
69
70 /**
71  * A callback for constructing a string representation of non-generic formatting modes,
72  * analogous to `xtype_formatter`. It is usually called via `xtype_format_fmt`,
73  * which handles the generic modes. Returns an empty string for unknown modes.
74  **/
75 typedef const char * (*xtype_fmt_formatter)(u32 fmt, struct mempool *pool);
76
77 /**
78  * This structure describes an xtype. Among other things, it points to callback
79  * functions handling this xtype.
80  **/
81 struct xtype {
82   size_t size;                          // How many bytes does a single value occupy
83   const char *name;                     // Name used in debug messages
84   xtype_parser parse;                   // Parsing callback
85   xtype_formatter format;               // Formatting callback
86   xtype_fmt_parser parse_fmt;           // Format mode parsing callback (optional)
87   xtype_fmt_formatter format_fmt;       // Format mode formatting callback (optional)
88 };
89
90 /**
91  * Construct a formatting mode from its string representation. It is a wrapper
92  * around the `xtype_fmt_parser` hook, which handles generic modes first.
93  *
94  * The generic modes are called `default`, `raw`, and `pretty`.
95  **/
96 const char *xtype_parse_fmt(struct xtype *xt, const char *str, u32 *dest, struct mempool *pool);
97
98 /**
99  * Construct a string representation of a formatting mode. It is a wrapper
100  * around the `xtype_fmt_formatter` hook, which handles generic modes first.
101  * Returns an empty string for unknown modes.
102  **/
103 const char *xtype_format_fmt(struct xtype *xt, u32 fmt, struct mempool *pool);
104
105 // Basic set of extended types
106 extern const struct xtype xt_str;
107 extern const struct xtype xt_int;
108 extern const struct xtype xt_s64;
109 extern const struct xtype xt_intmax;
110 extern const struct xtype xt_uint;
111 extern const struct xtype xt_u64;
112 extern const struct xtype xt_uintmax;
113 extern const struct xtype xt_bool;
114 extern const struct xtype xt_double;
115
116 // Fixed-precision formats for xt_double
117 #define XT_DOUBLE_FMT_PREC(_prec) (_prec | XT_DOUBLE_FMT_PREC_FLAG)
118 #define XT_DOUBLE_FMT_PREC_FLAG XTYPE_FMT_CUSTOM
119
120 /* Tables of units, provided as convenience for the implementations of xtypes */
121
122 /**
123  * Definition of the units that are appended to an xtype value. The value with units is represented
124  * by the following string: "<value><units>". The final value of the of the string is computed using
125  * the following formula: <value> * <num>/<denom>.
126  **/
127 struct unit_definition {
128   const char *unit; // string representation of unit
129   u64 num;
130   u64 denom;
131 };
132
133 /**
134  * Parse a name of a unit and return its index in the @units array or -1
135  * if is not present there.
136  **/
137 int xtype_unit_parser(const char *str, const struct unit_definition *units);
138
139 #endif