aboutsummaryrefslogtreecommitdiff
path: root/lib.h
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2004-11-26 16:44:27 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-07 21:04:58 -0700
commitf49eaba11f55bf7584ede71618f0958421fb2739 (patch)
tree3b100deddefb19f40000b67eb84a5a2488886069 /lib.h
parentAdd some type-safety features to the list pointer operations. (diff)
downloadsparse-f49eaba11f55bf7584ede71618f0958421fb2739.tar.gz
sparse-f49eaba11f55bf7584ede71618f0958421fb2739.tar.bz2
sparse-f49eaba11f55bf7584ede71618f0958421fb2739.zip
Who says you can't do type-safe function-overloading in C?
You just have to be a bit crazy (*), and use "__typeof__" in creative ways. (*) Ok, a _lot_ crazy. But dammit, I want type-safety _and_ convenience, and I'm willing to do a few crazy macros to get it.
Diffstat (limited to 'lib.h')
-rw-r--r--lib.h23
1 files changed, 18 insertions, 5 deletions
diff --git a/lib.h b/lib.h
index 0a8d7e4..ed39324 100644
--- a/lib.h
+++ b/lib.h
@@ -48,6 +48,8 @@ struct pseudo;
/* Silly type-safety check ;) */
#define DECLARE_PTR_LIST(listname,type) struct listname { type *list[1]; }
#define CHECK_TYPE(head,ptr) (void)(&(ptr) == &(head)->list[0])
+#define TYPEOF(head) __typeof__(&(head)->list[0])
+#define VRFY_PTR_LIST(head) (void)(sizeof((head)->list[0]))
DECLARE_PTR_LIST(symbol_list, struct symbol);
DECLARE_PTR_LIST(statement_list, struct statement);
@@ -111,14 +113,25 @@ int delete_ptr_list_entry(struct ptr_list **, void *);
int replace_ptr_list_entry(struct ptr_list **, void *old, void *new);
extern void sort_list(struct ptr_list **, int (*)(const void *, const void *));
-extern void **add_ptr_list(struct ptr_list **, void *);
+extern void **__add_ptr_list(struct ptr_list **, void *);
extern void concat_ptr_list(struct ptr_list *a, struct ptr_list **b);
-extern void free_ptr_list(struct ptr_list **);
+extern void __free_ptr_list(struct ptr_list **);
extern int ptr_list_size(struct ptr_list *);
extern char **handle_switch(char *arg, char **next);
extern void add_pre_buffer(const char *fmt, ...);
int linearize_ptr_list(struct ptr_list *, void **, int);
+/*
+ * Hey, who said that you can't do overloading in C?
+ *
+ * You just have to be creative, and use some gcc
+ * extensions..
+ */
+#define add_ptr_list(list,entry) \
+ (TYPEOF(*(list))) (CHECK_TYPE(*(list),(entry)),__add_ptr_list((struct ptr_list **)(list), (entry)))
+#define free_ptr_list(list) \
+ do { VRFY_PTR_LIST(*(list)); __free_ptr_list((struct ptr_list **)(list)); } while (0)
+
extern unsigned int pre_buffer_size;
extern unsigned char pre_buffer[8192];
extern int include_fd;
@@ -229,17 +242,17 @@ static inline void concat_instruction_list(struct instruction_list *from, struct
static inline void add_symbol(struct symbol_list **list, struct symbol *sym)
{
- add_ptr_list((struct ptr_list **)list, sym);
+ add_ptr_list(list, sym);
}
static inline void add_statement(struct statement_list **list, struct statement *stmt)
{
- add_ptr_list((struct ptr_list **)list, stmt);
+ add_ptr_list(list, stmt);
}
static inline void add_expression(struct expression_list **list, struct expression *expr)
{
- add_ptr_list((struct ptr_list **)list, expr);
+ add_ptr_list(list, expr);
}
#define DO_PREPARE(head, ptr, __head, __list, __nr) \