* the number of mandatory arguments in a mask.
*/
#define ARGM(m) \
- (m & 15)
+ (m & ARGM_MASK)
#define ARG1(m, t1) \
- (ARGM(m) + (ARGT_##t1 << 4))
+ (ARGM(m) + (ARGT_##t1 << (ARGM_BITS)))
#define ARG2(m, t1, t2) \
- (ARG1(m, t1) + (ARGT_##t2 << 8))
+ (ARG1(m, t1) + (ARGT_##t2 << (ARGM_BITS + ARGT_BITS)))
#define ARG3(m, t1, t2, t3) \
- (ARG2(m, t1, t2) + (ARGT_##t3 << 12))
+ (ARG2(m, t1, t2) + (ARGT_##t3 << (ARGM_BITS + ARGT_BITS * 2)))
#define ARG4(m, t1, t2, t3, t4) \
- (ARG3(m, t1, t2, t3) + (ARGT_##t4 << 16))
+ (ARG3(m, t1, t2, t3) + (ARGT_##t4 << (ARGM_BITS + ARGT_BITS * 3)))
#define ARG5(m, t1, t2, t3, t4, t5) \
- (ARG4(m, t1, t2, t3, t4) + (ARGT_##t5 << 20))
+ (ARG4(m, t1, t2, t3, t4) + (ARGT_##t5 << (ARGM_BITS + ARGT_BITS * 4)))
#define ARG6(m, t1, t2, t3, t4, t5, t6) \
- (ARG5(m, t1, t2, t3, t4, t5) + (ARGT_##t6 << 24))
+ (ARG5(m, t1, t2, t3, t4, t5) + (ARGT_##t6 << (ARGM_BITS + ARGT_BITS * 5)))
#define ARG7(m, t1, t2, t3, t4, t5, t6, t7) \
- (ARG6(m, t1, t2, t3, t4, t5, t6) + (ARGT_##t7 << 28))
+ (ARG6(m, t1, t2, t3, t4, t5, t6) + (ARGT_##t7 << (ARGM_BITS + ARGT_BITS * 6)))
/* This dummy arg list may be used by default when no arg is found, it helps
* parsers by removing pointer checks.
*/
-extern struct arg empty_arg_list[8];
+extern struct arg empty_arg_list[ARGM_NBARGS];
struct arg_list *arg_list_clone(const struct arg_list *orig);
struct arg_list *arg_list_add(struct arg_list *orig, struct arg *arg, int pos);
#include <common/chunk.h>
#include <common/mini-clist.h>
+/* encoding of each arg type */
+#define ARGT_BITS 4
+#define ARGT_NBTYPES (1 << ARGT_BITS)
+#define ARGT_MASK (ARGT_NBTYPES - 1)
+
+/* encoding of the arg count */
+#define ARGM_MASK ((1 << ARGM_BITS) - 1)
+#define ARGM_BITS 4
+#define ARGM_NBARGS (32 - ARGM_BITS) / sizeof(int)
+
enum {
ARGT_STOP = 0, /* end of the arg list */
ARGT_UINT, /* unsigned integer, which is a positive integer without any sign */
ARGT_SRV, /* a pointer to a server */
ARGT_USR, /* a pointer to a user list */
ARGT_MAP, /* a pointer to a map descriptor */
- ARGT_NBTYPES /* no more values past 15 */
};
/* context where arguments are used, in order to help error reporting */
/* This dummy arg list may be used by default when no arg is found, it helps
* parsers by removing pointer checks.
*/
-struct arg empty_arg_list[8] = { };
+struct arg empty_arg_list[ARGM_NBARGS] = { };
/* This function clones a struct arg_list template into a new one which is
* returned.
* type ARGT_STOP (0), unless the mask indicates that no argument is supported.
* Unresolved arguments are appended to arg list <al>, which also serves as a
* template to create new entries. The mask is composed of a number of
- * mandatory arguments in its lower 4 bits, and a concatenation of each
- * argument type in each subsequent 4-bit block. If <err_msg> is not NULL, it
- * must point to a freeable or NULL pointer.
+ * mandatory arguments in its lower ARGM_BITS bits, and a concatenation of each
+ * argument type in each subsequent ARGT_BITS-bit sblock. If <err_msg> is not
+ * NULL, it must point to a freeable or NULL pointer.
*/
int make_arg_list(const char *in, int len, unsigned int mask, struct arg **argp,
char **err_msg, const char **err_ptr, int *err_arg,
*argp = NULL;
- min_arg = mask & 15;
- mask >>= 4;
+ min_arg = mask & ARGM_MASK;
+ mask >>= ARGM_BITS;
pos = 0;
- /* find between 0 and 8 the max number of args supported by the mask */
- for (nbarg = 0; nbarg < 8 && ((mask >> (nbarg * 4)) & 0xF); nbarg++);
+ /* find between 0 and NBARGS the max number of args supported by the mask */
+ for (nbarg = 0; nbarg < ARGM_NBARGS && ((mask >> (nbarg * ARGT_BITS)) & ARGT_MASK); nbarg++);
if (!nbarg)
goto end_parse;
free(word);
word = my_strndup(beg, in - beg);
- arg->type = (mask >> (pos * 4)) & 15;
+ arg->type = (mask >> (pos * ARGT_BITS)) & ARGT_MASK;
switch (arg->type) {
case ARGT_SINT:
/* not enough arguments */
memprintf(err_msg,
"missing arguments (got %d/%d), type '%s' expected",
- pos, min_arg, arg_type_names[(mask >> (pos * 4)) & 15]);
+ pos, min_arg, arg_type_names[(mask >> (pos * ARGT_BITS)) & ARGT_MASK]);
goto err;
}
empty_err:
memprintf(err_msg, "expected type '%s' at position %d, but got nothing",
- arg_type_names[(mask >> (pos * 4)) & 15], pos + 1);
+ arg_type_names[(mask >> (pos * ARGT_BITS)) & ARGT_MASK], pos + 1);
goto err;
parse_err:
memprintf(err_msg, "failed to parse '%s' as type '%s' at position %d",
- word, arg_type_names[(mask >> (pos * 4)) & 15], pos + 1);
+ word, arg_type_names[(mask >> (pos * ARGT_BITS)) & ARGT_MASK], pos + 1);
goto err;
not_impl:
memprintf(err_msg, "parsing for type '%s' was not implemented, please report this bug",
- arg_type_names[(mask >> (pos * 4)) & 15]);
+ arg_type_names[(mask >> (pos * ARGT_BITS)) & ARGT_MASK]);
goto err;
}