Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
ccan
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
mirror
ccan
Commits
5c451bbb
Commit
5c451bbb
authored
Sep 22, 2011
by
Rusty Russell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
tcon: routines for creating typesafe generic containers
parent
37965b33
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
209 additions
and
0 deletions
+209
-0
ccan/tcon/_info
ccan/tcon/_info
+26
-0
ccan/tcon/tcon.h
ccan/tcon/tcon.h
+81
-0
ccan/tcon/test/compile_fail-tcon_cast.c
ccan/tcon/test/compile_fail-tcon_cast.c
+29
-0
ccan/tcon/test/compile_fail.c
ccan/tcon/test/compile_fail.c
+25
-0
ccan/tcon/test/compile_ok-void.c
ccan/tcon/test/compile_ok-void.c
+21
-0
ccan/tcon/test/compile_ok.c
ccan/tcon/test/compile_ok.c
+27
-0
No files found.
ccan/tcon/_info
0 → 100644
View file @
5c451bbb
#include "config.h"
#include <string.h>
/**
* tcon - routines for creating typesafe generic containers
*
* This code lets users create a structure with a typecanary; your API
* is then a set of macros which check the type canary before calling
* the generic routines.
*
* License: Public domain
*
* Author: Rusty Russell <rusty@rustcorp.com.au>
*/
int main(int argc, char *argv[])
{
/* Expect exactly one argument */
if (argc != 2)
return 1;
if (strcmp(argv[1], "depends") == 0) {
return 0;
}
return 1;
}
ccan/tcon/tcon.h
0 → 100644
View file @
5c451bbb
/* Placed into the public domain */
#ifndef CCAN_TCON_H
#define CCAN_TCON_H
#include "config.h"
/**
* TCON - declare a _tcon type containing canary variables.
* @decls: the semi-colon separated list of type canaries.
*
* This declares a _tcon member for a structure. It should be the
* last element in your structure; with sufficient compiler support it
* will not use any actual storage. tcon_to_raw() will compare
* expressions with one of these "type canaries" to cause warnings if
* the container is misused.
*
* A type of "void *" will allow tcon_to_raw() to pass on any (pointer) type.
*
* Example:
* // Simply typesafe linked list.
* struct list_head {
* struct list_head *prev, *next;
* };
*
* struct string_list {
* struct list_head raw;
* TCON(char *canary);
* };
*
* // More complex: mapping from one type to another.
* struct map {
* void *contents;
* };
*
* struct int_to_string_map {
* struct map raw;
* TCON(char *charp_canary; int int_canary);
* };
*/
#if HAVE_FLEXIBLE_ARRAY_MEMBER
#define TCON(decls) struct { decls; } _tcon[]
#else
#define TCON(decls) struct { decls; } _tcon[1]
#endif
/**
* tcon_check - typecheck a typed container
* @x: the structure containing the TCON.
* @canary: which canary to check against.
* @expr: the expression whose type must match the TCON (not evaluated)
*
* This macro is used to check that the expression is the type
* expected for this structure (note the "useless" sizeof() argument
* which contains this comparison with the type canary).
*
* It evaluates to @x so you can chain it.
*
* Example:
* #define tlist_add(h, n, member) \
* list_add(&tcon_check((h), canary, (n))->raw, &(n)->member)
*/
#define tcon_check(x, canary, expr) \
(sizeof((x)->_tcon[0].canary == (expr)) ? (x) : (x))
/**
* tcon_cast - cast to a canary type for this container (or void *)
* @x: a structure containing the TCON.
* @canary: which canary to cast to.
* @expr: the value to cast
*
* This is used to cast to the correct type for this container. If the
* platform doesn't HAVE_TYPEOF, then it casts to void * (which will
* cause a warning if the user doesn't expect a pointer type).
*/
#if HAVE_TYPEOF
#define tcon_cast(x, canary, expr) ((__typeof__((x)->_tcon[0].canary))(expr))
#else
#define tcon_cast(x, canary, expr) ((void *)(expr))
#endif
#endif
/* CCAN_TCON_H */
ccan/tcon/test/compile_fail-tcon_cast.c
0 → 100644
View file @
5c451bbb
#include <ccan/tcon/tcon.h>
#include <stdlib.h>
struct
container
{
void
*
p
;
};
struct
int_and_charp_container
{
struct
container
raw
;
TCON
(
int
*
tc1
;
char
*
tc2
);
};
int
main
(
int
argc
,
char
*
argv
[])
{
struct
int_and_charp_container
icon
;
#ifdef FAIL
#if !HAVE_TYPEOF
#error We cannot detect type problems without HAVE_TYPEOF
#endif
char
*
#else
int
*
#endif
x
;
icon
.
raw
.
p
=
NULL
;
x
=
tcon_cast
(
&
icon
,
tc1
,
icon
.
raw
.
p
);
return
0
;
}
ccan/tcon/test/compile_fail.c
0 → 100644
View file @
5c451bbb
#include <ccan/tcon/tcon.h>
#include <stdlib.h>
struct
container
{
void
*
p
;
};
struct
int_container
{
struct
container
raw
;
TCON
(
int
*
canary
);
};
int
main
(
int
argc
,
char
*
argv
[])
{
struct
int_container
icon
;
#ifdef FAIL
char
*
#else
int
*
#endif
x
=
NULL
;
tcon_check
(
&
icon
,
canary
,
x
)
->
raw
.
p
=
x
;
return
0
;
}
ccan/tcon/test/compile_ok-void.c
0 → 100644
View file @
5c451bbb
#include <ccan/tcon/tcon.h>
#include <stdlib.h>
struct
container
{
void
*
p
;
};
struct
void_container
{
struct
container
raw
;
TCON
(
void
*
canary
);
};
int
main
(
int
argc
,
char
*
argv
[])
{
struct
void_container
vcon
;
tcon_check
(
&
vcon
,
canary
,
NULL
)
->
raw
.
p
=
NULL
;
tcon_check
(
&
vcon
,
canary
,
argv
[
0
])
->
raw
.
p
=
NULL
;
tcon_check
(
&
vcon
,
canary
,
main
)
->
raw
.
p
=
NULL
;
return
0
;
}
ccan/tcon/test/compile_ok.c
0 → 100644
View file @
5c451bbb
#include <ccan/tcon/tcon.h>
#include <stdlib.h>
struct
container
{
void
*
p
;
};
struct
int_container
{
struct
container
raw
;
TCON
(
int
tc
);
};
struct
charp_and_int_container
{
struct
container
raw
;
TCON
(
int
tc1
;
char
*
tc2
);
};
int
main
(
int
argc
,
char
*
argv
[])
{
struct
int_container
icon
;
struct
charp_and_int_container
cicon
;
tcon_check
(
&
icon
,
tc
,
7
)
->
raw
.
p
=
NULL
;
tcon_check
(
&
cicon
,
tc1
,
7
)
->
raw
.
p
=
argv
[
0
];
tcon_check
(
&
cicon
,
tc2
,
argv
[
0
])
->
raw
.
p
=
argv
[
0
];
return
0
;
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment