2 * UCW Library -- Extended Types
4 * (c) 2014--2015 Martin Mares <mj@ucw.cz>
6 * This software may be freely distributed and used according to the terms
7 * of the GNU Lesser General Public License.
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
31 * Definitions of types
32 * ~~~~~~~~~~~~~~~~~~~~
36 * A parsing callback. Takes a string, interprets it as a value of the particular
37 * xtype and stores it where @dest points. Returns NULL on success and an error message
38 * otherwise. It may allocate memory from the @pool and the parsed value can contain
39 * pointers to this memory.
41 typedef const char * (*xtype_parser)(const char *str, void *dest, struct mempool *pool);
44 * A formatting callback. Takes a value of the particular xtype and a formatting
45 * mode @fmt (see below for how the modes work) and returns a string representation
46 * of the value. The string can be allocated from the @pool, but it does not have to.
48 * When @fmt is set to `XTYPE_FMT_DEFAULT`, the resulting string should be
49 * parseable via the parsing callback and yield a semantically equivalent value.
51 typedef const char * (*xtype_formatter)(void *src, u32 fmt, struct mempool *pool);
54 * Formatting of values is controlled by a mode parameter, which is generally
55 * a 32-bit integer. If the most significant bit is clear, it is one of generic
56 * well-known modes (`XTYPE_FMT_`'something'), which can be passed to all formatters
57 * and if it is not understood, it acts like `XTYPE_FMT_DEFAULT`. When the most
58 * significant bit is set, the meaning of the mode is specific to the particular
62 XTYPE_FMT_DEFAULT = 0, // Default format: readable, but not hostile to machine parsing
63 XTYPE_FMT_RAW = 1, // Raw data with no frills
64 XTYPE_FMT_PRETTY = 2, // Try to please humans (e.g., like "ls -h")
65 XTYPE_FMT_CUSTOM = 0x80000000,
69 * A callback for parsing non-generic formatting modes. See `xtype_parser` for more
70 * details. It is usually called via `xtype_parse_fmt`, which handles the generic modes.
72 typedef const char * (*xtype_fmt_parser)(const char *str, u32 *dest, struct mempool *pool);
75 * A callback for constructing a string representation of non-generic formatting modes,
76 * analogous to `xtype_formatter`. It is usually called via `xtype_format_fmt`,
77 * which handles the generic modes. Returns an empty string for unknown modes.
79 typedef const char * (*xtype_fmt_formatter)(u32 fmt, struct mempool *pool);
82 * This structure describes an xtype. Among other things, it points to callback
83 * functions handling this xtype.
86 size_t size; // How many bytes does a single value occupy
87 const char *name; // Name used in debug messages
88 xtype_parser parse; // Parsing callback
89 xtype_formatter format; // Formatting callback
90 xtype_fmt_parser parse_fmt; // Format mode parsing callback (optional)
91 xtype_fmt_formatter format_fmt; // Format mode formatting callback (optional)
95 * Construct a formatting mode from its string representation. It is a wrapper
96 * around the `xtype_fmt_parser` hook, which handles generic modes first.
98 * The generic modes are called `default`, `raw`, and `pretty`.
100 const char *xtype_parse_fmt(const struct xtype *xt, const char *str, u32 *dest, struct mempool *pool);
103 * Construct a string representation of a formatting mode. It is a wrapper
104 * around the `xtype_fmt_formatter` hook, which handles generic modes first.
105 * Returns an empty string for unknown modes.
107 const char *xtype_format_fmt(struct xtype *xt, u32 fmt, struct mempool *pool);
110 * Basic pre-defined types
111 * ~~~~~~~~~~~~~~~~~~~~~~~
113 * We provide xtypes for many basic data types:
116 * * `xt_double` -- in addition to the generic formatting modes, you can use
117 * `XT_DOUBLE_FMT_PREC(`'n'`)` to generate a mode for fixed formatting with
118 * 'n' decimal places.
122 * * `xt_str` -- string, represented by a `const char *`
128 extern const struct xtype xt_bool;
129 extern const struct xtype xt_double;
130 extern const struct xtype xt_int;
131 extern const struct xtype xt_intmax;
132 extern const struct xtype xt_s64;
133 extern const struct xtype xt_str;
134 extern const struct xtype xt_u64;
135 extern const struct xtype xt_uint;
136 extern const struct xtype xt_uintmax;
138 // Fixed-precision formats for xt_double
139 #define XT_DOUBLE_FMT_PREC(_prec) (_prec | XT_DOUBLE_FMT_PREC_FLAG)
140 #define XT_DOUBLE_FMT_PREC_FLAG XTYPE_FMT_CUSTOM
146 * Various xtypes accept values accompanied by a unit of measure.
147 * Units by handled by the xtypes themselves, but we provide a couple
148 * of generic functions for their convenience.
152 * Each unit is defined by a conversion ratio, which is a fraction with 64-bit numerator
153 * and denominator. Therefore, a value of 'x' units is interpreted as 'x' * 'num' / 'denon'.
155 struct unit_definition {
156 const char *unit; // Symbol (name of the unit, as appended to values)
157 u64 num; // Numerator
158 u64 denom; // Denominator
162 * Given an array @units of unit definitions (terminated by an all-zero entry),
163 * parse a name of a unit and return its index in the array, or -1 if it is not found.
165 int xtype_unit_parser(const char *str, const struct unit_definition *units);