Builtin macros are defined via the add_pre_buffer() mechanism which is quite powerful/flexible but for small, simple builtin macros, it's a bit sad to have to compose a buffer and then tokenize it when it would be easy to directly define these macros. This is what is done by this patch. Two new functions are created one, predefine(), for static arguments and another, predefinef() where the argument is printf formatted. Signed-off-by: Luc Van Oostenryck <luc.vanoostenryck@xxxxxxxxx> --- lib.h | 2 ++ pre-process.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/lib.h b/lib.h index 4d613936e..cc2812183 100644 --- a/lib.h +++ b/lib.h @@ -129,6 +129,8 @@ enum phase { extern void add_pre_buffer(const char *fmt, ...) FORMAT_ATTR(1); +void predefinef(const char *name, int weak, const char *fmt, ...) FORMAT_ATTR(3); +void predefine(const char *name, int weak, const char *val); extern int preprocess_only; diff --git a/pre-process.c b/pre-process.c index fbd6c9cd2..72c91d0e3 100644 --- a/pre-process.c +++ b/pre-process.c @@ -1384,6 +1384,63 @@ out: return ret; } +/// +// predefine a macro with a fixed value +// @name: the name of the macro +// @weak: 0/1 for a normal or a weak define +// @val: the macro definition/value +// +// The type of the value is automatically infered: +// TOKEN_NUMBER if it starts by a digit, TOKEN_IDENT otherwise. +// If @val is null, the macro is defined with an empty definition. +void predefine(const char *name, int weak, const char *val) +{ + struct ident *ident = built_in_ident(name); + struct token *value = &eof_token_entry; + int attr = weak ? SYM_ATTR_WEAK : SYM_ATTR_NORMAL; + + if (val) { + value = __alloc_token(0); + if (isdigit(val[0])) { + token_type(value) = TOKEN_NUMBER; + value->number = val; + } else { + token_type(value) = TOKEN_IDENT; + value->ident = built_in_ident(val); + } + value->pos.whitespace = 1; + value->next = &eof_token_entry; + } + + do_define(value->pos, NULL, ident, NULL, value, attr); +} + +/// +// predefine a macro with a printf-formatted value. +// @name: the name of the macro +// @weak: 0/1 for a normal or a weak define +// @fmt: the printf format followed by it's arguments. +// +// This function is identical to :func:`predefine` only +// that the value is first printf-formatted. +void predefinef(const char *name, int weak, const char *fmt, ...) +{ + va_list args, copy; + char *buf; + int n; + + va_start(args, fmt); + va_copy(args, copy); + n = vsnprintf(NULL, 0, fmt, args); + va_end(args); + + buf = __alloc_bytes(++n); + vsnprintf(buf, n, fmt, copy); + va_end(args); + + predefine(name, weak, buf); +} + static int do_handle_define(struct stream *stream, struct token **line, struct token *token, int attr) { struct token *arglist, *expansion; -- 2.17.1 -- To unsubscribe from this list: send the line "unsubscribe linux-sparse" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html