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
3a34aa1a
Commit
3a34aa1a
authored
Sep 23, 2011
by
Rusty Russell
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
jmap: use ccan/tcon and always be typesafe.
This handles both pointer and integer types using ccan/tcon.
parent
805ea067
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
676 additions
and
727 deletions
+676
-727
ccan/jmap/_info
ccan/jmap/_info
+36
-24
ccan/jmap/jmap.c
ccan/jmap/jmap.c
+5
-4
ccan/jmap/jmap.h
ccan/jmap/jmap.h
+367
-240
ccan/jmap/jmap_type.h
ccan/jmap/jmap_type.h
+0
-303
ccan/jmap/test/run-access-count.c
ccan/jmap/test/run-access-count.c
+6
-2
ccan/jmap/test/run-ptridx-int.c
ccan/jmap/test/run-ptridx-int.c
+99
-0
ccan/jmap/test/run-ptridx-type.c
ccan/jmap/test/run-ptridx-type.c
+40
-39
ccan/jmap/test/run-uintidx-type.c
ccan/jmap/test/run-uintidx-type.c
+82
-78
ccan/jmap/test/run.c
ccan/jmap/test/run.c
+39
-37
ccan/tcon/tcon.h
ccan/tcon/tcon.h
+2
-0
No files found.
ccan/jmap/_info
View file @
3a34aa1a
...
@@ -9,38 +9,46 @@
...
@@ -9,38 +9,46 @@
* integers or pointers as an index, Judy arrays provide an efficient
* integers or pointers as an index, Judy arrays provide an efficient
* map to integers or pointers.
* map to integers or pointers.
*
*
* jmap.h simply contains wrappers for a size_t-indexed size_t values, and
* You define a struct for your particular index and value types using
* jmap_type.h contain a wrapper macro for size_t->pointer maps and pointer
* the JMAP_MEMBERS macro, then use the jmap routines to manipulate
* ->pointer maps.
* the mapping.
*
* Note: if you use an integer type for the index or value types and
* your compiler doesn't support "typeof", you will get warnings about
* mixing pointers and integers.
*
*
* Example:
* Example:
* // Silly example of associating data with arguments by pointer and int.
* // Silly example of associating data with arguments by pointer and int.
* #include <string.h>
* #include <string.h>
* #include <stdio.h>
* #include <stdio.h>
* #include <ccan/jmap/jmap
_type
.h>
* #include <ccan/jmap/jmap.h>
*
*
* struct opt_detail {
* struct opt_detail {
* bool is_long;
* bool is_long;
* unsigned int length; // == 1 if !is_long.
* unsigned int length; // == 1 if !is_long.
* };
* };
*
*
* // Define jmap_arg_<op> and jmap_arg, for int -> argv.
* // Define map type for int -> argv.
* JMAP_DEFINE_UINTIDX_TYPE(char, arg);
* struct arg_map {
* // Define jmap_opt_<op> and jmap_opt, for argv -> struct opt_detail *.
* JMAP_MEMBERS(int, char *);
* JMAP_DEFINE_PTRIDX_TYPE(char, struct opt_detail, opt);
* };
* // Define map type for argv -> struct opt_detail *.
* struct opt_map {
* JMAP_MEMBERS(char *, struct opt_detail *);
* };
*
*
* int main(int argc, char *argv[])
* int main(int argc, char *argv[])
* {
* {
* int i;
* int i;
* // This map is equivalent to the argv[] array. Silly example.
* // This map is equivalent to the argv[] array. Silly example.
* struct
jmap_arg *arg = jmap_arg_new(
);
* struct
arg_map *arg = jmap_new(struct arg_map
);
* struct
jmap_opt *opt = jmap_opt_new(
);
* struct
opt_map *opt = jmap_new(struct opt_map
);
* struct opt_detail *d;
* struct opt_detail *d;
*
*
* // Note: this is not correct for real parsing!
* // Note: this is not correct for real parsing!
* for (i =
0
; i < argc; i++) {
* for (i =
1
; i < argc; i++) {
* jmap_a
rg_a
dd(arg, i, argv[i]);
* jmap_add(arg, i, argv[i]);
* if (
i < 1 ||
argv[i][0] != '-')
* if (argv[i][0] != '-')
* continue;
* continue;
* d = malloc(sizeof(*d));
* d = malloc(sizeof(*d));
* if (argv[i][1] == '-') {
* if (argv[i][1] == '-') {
...
@@ -52,27 +60,30 @@
...
@@ -52,27 +60,30 @@
* d->is_long = false;
* d->is_long = false;
* d->length = 1;
* d->length = 1;
* }
* }
* jmap_
opt_
add(opt, argv[i], d);
* jmap_add(opt, argv[i], d);
* }
* }
*
*
* printf("Found %lu options:\n", jmap_
opt_
count(opt));
* printf("Found %lu options:\n", jmap_count(opt));
* for (i = jmap_
arg_first(arg,-1); i!=-1; i = jmap_arg_next(arg,i,-1
)) {
* for (i = jmap_
first(arg); i; i = jmap_next(arg,i
)) {
* char *a = jmap_
arg_
get(arg, i);
* char *a = jmap_get(arg, i);
* d = jmap_
opt_
get(opt, a);
* d = jmap_get(opt, a);
* printf(" Arg %i ('%s') is a %s of %u chars\n",
* printf(" Arg %i ('%s') is a %s of %u chars\n",
* i, a,
* i, a,
* d == NULL ? "normal arg
ument
"
* d == NULL ? "normal arg"
* : d->is_long ? "long opt
ion
"
* : d->is_long ? "long opt"
* : "short opt
ion
",
* : "short opt",
* d == NULL ? strlen(a) : d->length);
* d == NULL ? strlen(a) : d->length);
* // We no longer need it, so free it here.
* // We no longer need it, so free it here.
* free(d);
* free(d);
* }
* }
* jmap_
opt_
free(opt);
* jmap_free(opt);
* jmap_
arg_
free(arg);
* jmap_free(arg);
* return 0;
* return 0;
* }
* }
*
* // Given "--help" output contains "Arg 1 ('--help') is a long opt of 4 chars"
* // Given "-h" output contains "Arg 1 ('-h') is a short opt of 1 chars"
* // Given "foo" output contains "Arg 1 ('foo') is a normal arg of 3 chars"
*
* License: LGPL (v2.1 or any later version)
* License: LGPL (v2.1 or any later version)
* Author: Rusty Russell <rusty@rustcorp.com.au>
* Author: Rusty Russell <rusty@rustcorp.com.au>
*/
*/
...
@@ -84,6 +95,7 @@ int main(int argc, char *argv[])
...
@@ -84,6 +95,7 @@ int main(int argc, char *argv[])
if (strcmp(argv[1], "depends") == 0) {
if (strcmp(argv[1], "depends") == 0) {
printf("ccan/build_assert\n");
printf("ccan/build_assert\n");
printf("ccan/compiler\n");
printf("ccan/compiler\n");
printf("ccan/tcon\n");
printf("Judy\n");
printf("Judy\n");
return 0;
return 0;
}
}
...
...
ccan/jmap/jmap.c
View file @
3a34aa1a
...
@@ -4,7 +4,7 @@
...
@@ -4,7 +4,7 @@
#include <stdlib.h>
#include <stdlib.h>
#include <string.h>
#include <string.h>
struct
jmap
*
jmap_new
(
void
)
struct
jmap
*
jmap_new
_
(
size_t
size
)
{
{
struct
jmap
*
map
;
struct
jmap
*
map
;
...
@@ -13,7 +13,8 @@ struct jmap *jmap_new(void)
...
@@ -13,7 +13,8 @@ struct jmap *jmap_new(void)
/* We also put pointers into Judy, in jmap_types.h */
/* We also put pointers into Judy, in jmap_types.h */
BUILD_ASSERT
(
sizeof
(
Word_t
)
>=
sizeof
(
void
*
));
BUILD_ASSERT
(
sizeof
(
Word_t
)
>=
sizeof
(
void
*
));
map
=
malloc
(
sizeof
(
*
map
));
assert
(
size
>=
sizeof
(
*
map
));
map
=
malloc
(
size
);
if
(
map
)
{
if
(
map
)
{
map
->
judy
=
NULL
;
map
->
judy
=
NULL
;
memset
(
&
map
->
err
,
0
,
sizeof
(
map
->
err
));
memset
(
&
map
->
err
,
0
,
sizeof
(
map
->
err
));
...
@@ -26,7 +27,7 @@ struct jmap *jmap_new(void)
...
@@ -26,7 +27,7 @@ struct jmap *jmap_new(void)
return
map
;
return
map
;
}
}
const
char
*
jmap_error_
(
struct
jmap
*
map
)
const
char
*
jmap_error_
str_
(
struct
jmap
*
map
)
{
{
char
*
str
;
char
*
str
;
free
((
char
*
)
map
->
errstr
);
free
((
char
*
)
map
->
errstr
);
...
@@ -40,7 +41,7 @@ const char *jmap_error_(struct jmap *map)
...
@@ -40,7 +41,7 @@ const char *jmap_error_(struct jmap *map)
return
str
;
return
str
;
}
}
void
jmap_free
(
const
struct
jmap
*
map
)
void
jmap_free
_
(
const
struct
jmap
*
map
)
{
{
free
((
char
*
)
map
->
errstr
);
free
((
char
*
)
map
->
errstr
);
JudyLFreeArray
((
PPvoid_t
)
&
map
->
judy
,
PJE0
);
JudyLFreeArray
((
PPvoid_t
)
&
map
->
judy
,
PJE0
);
...
...
ccan/jmap/jmap.h
View file @
3a34aa1a
/* Licensed under LGPLv2.1+ - see LICENSE file for details */
/* Licensed under LGPLv2.1+ - see LICENSE file for details */
#ifndef CCAN_JMAP_H
#ifndef CCAN_JMAP_H
#define CCAN_JMAP_H
#define CCAN_JMAP_H
#include <ccan/compiler/compiler.h>
#include <ccan/tcon/tcon.h>
#include <stddef.h>
#include <stddef.h>
#include <Judy.h>
#include <Judy.h>
#include <stdbool.h>
#include <stdbool.h>
#include <string.h>
#include <string.h>
#include <ccan/compiler/compiler.h>
#include <assert.h>
#include <assert.h>
#ifdef CCAN_JMAP_DEBUG
#ifdef CCAN_JMAP_DEBUG
#include <stdio.h>
#include <stdio.h>
#endif
#endif
/**
/**
*
jmap_new - create a new, empty
jmap.
*
struct map - private definition of a
jmap.
*
*
* See Also:
* It's exposed here so you can put it in your structures and so we can
* JMAP_DEFINE_TYPE()
* supply inline functions.
*
* Example:
* struct jmap *map = jmap_new();
* if (!map)
* errx(1, "Failed to allocate jmap");
*/
*/
struct
jmap
*
jmap_new
(
void
);
/**
* jmap_free - destroy a jmap.
* @map: the map returned from jmap_new.
*
* Example:
* jmap_free(map);
*/
void
jmap_free
(
const
struct
jmap
*
map
);
/* This is exposed in the header so we can inline. Treat it as private! */
struct
jmap
{
struct
jmap
{
Pvoid_t
judy
;
Pvoid_t
judy
;
JError_t
err
;
JError_t
err
;
...
@@ -45,47 +29,46 @@ struct jmap {
...
@@ -45,47 +29,46 @@ struct jmap {
unsigned
long
acc_index
;
unsigned
long
acc_index
;
const
char
*
funcname
;
const
char
*
funcname
;
};
};
const
char
*
COLD
jmap_error_
(
struct
jmap
*
map
);
/* Debugging checks. */
/**
static
inline
void
jmap_debug_add_access
(
const
struct
jmap
*
map
,
* JMAP_MEMBERS - declare members for a type-specific jmap.
unsigned
long
index
,
* @itype: index type for this map, or void * for any pointer.
unsigned
long
*
val
,
* @ctype: contents type for this map, or void * for any pointer.
const
char
*
funcname
)
*
{
* Example:
#ifdef CCAN_JMAP_DEBUG
* struct jmap_long_to_charp {
if
(
!
map
->
acc_value
)
{
* JMAP_MEMBERS(long, char *);
((
struct
jmap
*
)
map
)
->
acc_value
=
val
;
* };
((
struct
jmap
*
)
map
)
->
acc_index
=
index
;
*/
((
struct
jmap
*
)
map
)
->
funcname
=
funcname
;
#define JMAP_MEMBERS(itype, ctype) \
}
struct jmap raw; \
#endif
TCON(itype icanary; ctype ccanary)
if
(
val
)
assert
(
++
((
struct
jmap
*
)
map
)
->
num_accesses
);
}
static
inline
void
jmap_debug_del_access
(
struct
jmap
*
map
,
unsigned
long
**
val
)
/**
{
* jmap_new - create a new, empty jmap.
assert
(
--
map
->
num_accesses
>=
0
);
*
#ifdef CCAN_JMAP_DEBUG
* See Also:
if
(
map
->
acc_value
==
*
val
)
* JMAP_MEMBERS()
map
->
acc_value
=
NULL
;
*
#endif
* Example:
/* Set it to some invalid value. Not NULL, they might rely on that! */
* struct jmap_long_to_charp {
assert
(
memset
(
val
,
0x42
,
sizeof
(
*
val
)));
* JMAP_MEMBERS(long, char *);
}
* };
*
* struct jmap_long_to_charp *map = jmap_new(struct jmap_long_to_charp);
* if (!map)
* errx(1, "Failed to allocate jmap");
*/
#define jmap_new(type) ((type *)jmap_new_(sizeof(type)))
static
inline
void
jmap_debug_access
(
struct
jmap
*
map
)
/**
{
* jmap_free - destroy a jmap.
#ifdef CCAN_JMAP_DEBUG
* @map: the map returned from jmap_new.
if
(
map
->
num_accesses
&&
map
->
acc_value
)
*
fprintf
(
stderr
,
* Example:
"jmap: still got index %lu, val %lu (%p) from %s
\n
"
,
* jmap_free(map);
map
->
acc_index
,
*
map
->
acc_value
,
map
->
acc_value
,
*/
map
->
funcname
);
#define jmap_free(map) jmap_free_(&(map)->raw)
#endif
assert
(
!
map
->
num_accesses
);
}
/**
/**
* jmap_error - test for an error in the a previous jmap_ operation.
* jmap_error - test for an error in the a previous jmap_ operation.
...
@@ -99,21 +82,48 @@ static inline void jmap_debug_access(struct jmap *map)
...
@@ -99,21 +82,48 @@ static inline void jmap_debug_access(struct jmap *map)
* interface misuse.
* interface misuse.
*
*
* Example:
* Example:
* struct jmap *map = jmap_new();
* const char *errstr;
* const char *errstr;
*
*
* if (!map)
* err(1, "allocating jmap");
* errstr = jmap_error(map);
* errstr = jmap_error(map);
* if (errstr)
* if (errstr)
* errx(1, "Woah, error on newly created map?! %s", errstr);
* errx(1, "Woah, error on newly created map?! %s", errstr);
*/
*/
static
inline
const
char
*
jmap_error
(
struct
jmap
*
map
)
#define jmap_error(map) jmap_error_(&(map)->raw)
{
if
(
JU_ERRNO
(
&
map
->
err
)
<=
JU_ERRNO_NFMAX
)
/**
return
NULL
;
* jmap_rawi - unwrap the typed map and check the index type
return
jmap_error_
(
map
);
* @map: the typed jmap
}
* @expr: the expression to check the index type against (not evaluated)
*
* This macro usually causes the compiler to emit a warning if the
* variable is of an unexpected type. It is used internally where we
* need to access the raw underlying jmap.
*/
#define jmap_rawi(map, expr) (&tcon_check((map), icanary, (expr))->raw)
/**
* jmap_rawc - unwrap the typed map and check the contents type
* @map: the typed jmap
* @expr: the expression to check the content type against (not evaluated)
*
* This macro usually causes the compiler to emit a warning if the
* variable is of an unexpected type. It is used internally where we
* need to access the raw underlying jmap.
*/
#define jmap_rawc(map, expr) (&tcon_check((map), ccanary, (expr))->raw)
/**
* jmap_rawci - unwrap the typed map and check the index and contents types
* @map: the typed jmap
* @iexpr: the expression to check the index type against (not evaluated)
* @cexpr: the expression to check the contents type against (not evaluated)
*
* This macro usually causes the compiler to emit a warning if the
* variable is of an unexpected type. It is used internally where we
* need to access the raw underlying jmap.
*/
#define jmap_rawci(map, iexpr, cexpr) \
(&tcon_check(tcon_check((map), ccanary, (cexpr)), icanary, (iexpr))->raw)
/**
/**
* jmap_add - add or replace a value for a given index in the map.
* jmap_add - add or replace a value for a given index in the map.
...
@@ -125,20 +135,12 @@ static inline const char *jmap_error(struct jmap *map)
...
@@ -125,20 +135,12 @@ static inline const char *jmap_error(struct jmap *map)
* Returns false on error (out of memory).
* Returns false on error (out of memory).
*
*
* Example:
* Example:
* if (!jmap_add(map, 0,
1
))
* if (!jmap_add(map, 0,
"hello"
))
* err(1, "jmap_add failed!");
* err(1, "jmap_add failed!");
*/
*/
static
inline
bool
jmap_add
(
struct
jmap
*
map
,
#define jmap_add(map, index, value) \
unsigned
long
index
,
unsigned
long
value
)
jmap_add_(jmap_rawci((map), (index), (value)), \
{
(unsigned long)(index), (unsigned long)value)
unsigned
long
*
val
;
jmap_debug_access
(
map
);
val
=
(
unsigned
long
*
)
JudyLIns
(
&
map
->
judy
,
index
,
&
map
->
err
);
if
(
val
==
PJERR
)
return
false
;
*
val
=
value
;
return
true
;
}
/**
/**
* jmap_set - change a value for an existing index in the map.
* jmap_set - change a value for an existing index in the map.
...
@@ -150,21 +152,12 @@ static inline bool jmap_add(struct jmap *map,
...
@@ -150,21 +152,12 @@ static inline bool jmap_add(struct jmap *map,
* otherwise returns false and does nothing.
* otherwise returns false and does nothing.
*
*
* Example:
* Example:
* if (!jmap_set(map, 0,
2
))
* if (!jmap_set(map, 0,
"goodbye"
))
* err(1, "jmap_set: index 0 not found");
* err(1, "jmap_set: index 0 not found");
*/
*/
static
inline
bool
jmap_set
(
const
struct
jmap
*
map
,
#define jmap_set(map, index, value) \
unsigned
long
index
,
unsigned
long
value
)
jmap_set_(jmap_rawci((map), (index), (value)), \
{
(unsigned long)(index), (unsigned long)value)
unsigned
long
*
val
;
val
=
(
unsigned
long
*
)
JudyLGet
(
map
->
judy
,
index
,
(
JError_t
*
)
&
map
->
err
);
if
(
val
&&
val
!=
PJERR
)
{
*
val
=
value
;
return
true
;
}
return
false
;
}
/**
/**
* jmap_del - remove an index from the map.
* jmap_del - remove an index from the map.
...
@@ -175,11 +168,8 @@ static inline bool jmap_set(const struct jmap *map,
...
@@ -175,11 +168,8 @@ static inline bool jmap_set(const struct jmap *map,
* if (!jmap_del(map, 0))
* if (!jmap_del(map, 0))
* err(1, "jmap_del failed!");
* err(1, "jmap_del failed!");
*/
*/
static
inline
bool
jmap_del
(
struct
jmap
*
map
,
unsigned
long
index
)
#define jmap_del(map, index) \
{
jmap_del_(jmap_rawi((map), (index)), (unsigned long)(index))
jmap_debug_access
(
map
);
return
JudyLDel
(
&
map
->
judy
,
index
,
&
map
->
err
)
==
1
;
}
/**
/**
* jmap_test - test if a given index is defined.
* jmap_test - test if a given index is defined.
...
@@ -187,38 +177,40 @@ static inline bool jmap_del(struct jmap *map, unsigned long index)
...
@@ -187,38 +177,40 @@ static inline bool jmap_del(struct jmap *map, unsigned long index)
* @index: the index to find
* @index: the index to find
*
*
* Example:
* Example:
* jmap_add(map,
0, 1
);
* jmap_add(map,
1, "hello"
);
* assert(jmap_test(map,
0
));
* assert(jmap_test(map,
1
));
*/
*/
static
inline
bool
jmap_test
(
const
struct
jmap
*
map
,
unsigned
long
index
)
#define jmap_test(map, index) \
{
jmap_test_(jmap_rawi((map), (index)), (unsigned long)(index))
return
JudyLGet
(
map
->
judy
,
index
,
(
JError_t
*
)
&
map
->
err
)
!=
NULL
;
}
/**
/**
* jmap_get - get a value for a given index.
* jmap_get - get a value for a given index.
* @map: map from jmap_new
* @map: map from jmap_new
* @index: the index to find
* @index: the index to find
* @invalid: the value to return if the index isn't found.
*
* Returns 0 if !jmap_test(map, index).
*
*
* Example:
* Example:
* jmap_add(map, 0, 1);
* const char *str = "hello";
* assert(jmap_get(map, 0, -1) == 1);
* jmap_add(map, 2, str);
* assert(jmap_get(map, 0) == str);
*
*
* See Also:
* See Also:
* jmap_getval()
* jmap_getval()
*/
*/
static
inline
unsigned
long
jmap_get
(
const
struct
jmap
*
map
,
#define jmap_get(map, index) \
unsigned
long
index
,
tcon_cast((map), ccanary, \
unsigned
long
invalid
)
jmap_get_(jmap_rawi((map), (index)), (unsigned long)(index)))
{
unsigned
long
*
val
;
/**
val
=
(
unsigned
long
*
)
JudyLGet
(
map
->
judy
,
index
,
* jmap_count - get population of the map.
(
JError_t
*
)
&
map
->
err
);
* @map: map from jmap_new
if
(
!
val
||
val
==
PJERR
)
*
return
invalid
;
* Example:
return
*
val
;
* assert(jmap_count(map) < 1000);
}
*/
#define jmap_count(map) \
jmap_popcount_(&(map)->raw, 0, -1UL)
/**
/**
* jmap_popcount - get population of (some part of) the map.
* jmap_popcount - get population of (some part of) the map.
...
@@ -229,12 +221,9 @@ static inline unsigned long jmap_get(const struct jmap *map,
...
@@ -229,12 +221,9 @@ static inline unsigned long jmap_get(const struct jmap *map,
* Example:
* Example:
* assert(jmap_popcount(map, 0, 1000) <= jmap_popcount(map, 0, 2000));
* assert(jmap_popcount(map, 0, 1000) <= jmap_popcount(map, 0, 2000));
*/
*/
static
inline
unsigned
long
jmap_popcount
(
const
struct
jmap
*
map
,
#define jmap_popcount(map, start, end_incl) \
unsigned
long
start
,
jmap_popcount_(jmap_rawi((map), (start) ? (start) : (end_incl)), \
unsigned
long
end_incl
)
(unsigned long)(start), (unsigned long)(end_incl))
{
return
JudyLCount
(
map
->
judy
,
start
,
end_incl
,
(
JError_t
*
)
&
map
->
err
);
}
/**
/**
* jmap_nth - return the index of the nth value in the map.
* jmap_nth - return the index of the nth value in the map.
...
@@ -259,109 +248,74 @@ static inline unsigned long jmap_popcount(const struct jmap *map,
...
@@ -259,109 +248,74 @@ static inline unsigned long jmap_popcount(const struct jmap *map,
* See Also:
* See Also:
* jmap_nthval();
* jmap_nthval();
*/
*/
static
inline
unsigned
long
jmap_nth
(
const
struct
jmap
*
map
,
#define jmap_nth(map, n, invalid) \
unsigned
long
n
,
unsigned
long
invalid
)
tcon_cast((map), icanary, \
{
jmap_nth_(jmap_rawi((map), (invalid)), \
unsigned
long
index
;
(n), (unsigned long)(invalid)))
if
(
!
JudyLByCount
(
map
->
judy
,
n
+
1
,
&
index
,
(
JError_t
*
)
&
map
->
err
))
index
=
invalid
;
return
index
;
}
/**
/**
* jmap_first - return the first index in the map.
* jmap_first - return the first index in the map
(must not contain 0)
.
* @map: map from jmap_new
* @map: map from jmap_new
* @invalid: return value if jmap is empty.
*
*
* This is equivalent to jmap_nth(map, 0,
invalid
).
* This is equivalent to jmap_nth(map, 0,
0
).
*
*
* Example:
* Example:
* assert(!jmap_test(map, 0));
* assert(!jmap_test(map, 0));
* printf("Map indices (increasing order):");
* printf("Map indices (increasing order):");
* for (i = jmap_first(map
, 0); i; i = jmap_next(map, i, 0
))
* for (i = jmap_first(map
); i; i = jmap_next(map, i
))
* printf(" %lu", i);
* printf(" %lu", i);
* printf("\n");
* printf("\n");
*
*
* See Also:
* See Also:
* jmap_firstval()
* jmap_firstval()
*/
*/
static
inline
unsigned
long
jmap_first
(
const
struct
jmap
*
map
,
#define jmap_first(map) \
unsigned
long
invalid
)
tcon_cast((map), icanary, jmap_first_(&(map)->raw))
{
unsigned
long
index
=
0
;
if
(
!
JudyLFirst
(
map
->
judy
,
&
index
,
(
JError_t
*
)
&
map
->
err
))
index
=
invalid
;
else
assert
(
index
!=
invalid
);
return
index
;
}
/**
/**
* jmap_next - return the next index in the map.
* jmap_next - return the next index in the map.
* @map: map from jmap_new
* @map: map from jmap_new
* @prev: previous index
* @prev: previous index
* @invalid: return value if there prev was final index in map.
*
*
* This is usually used to find an adjacent index after jmap_first.
* This is usually used to find an adjacent index after jmap_first.
* See Also:
* See Also:
* jmap_nextval()
* jmap_nextval()
*/
*/
static
inline
unsigned
long
jmap_next
(
const
struct
jmap
*
map
,
#define jmap_next(map, prev) \
unsigned
long
prev
,
tcon_cast((map), icanary, jmap_next_(jmap_rawi((map), (prev)), \
unsigned
long
invalid
)
(unsigned long)(prev)))
{
if
(
!
JudyLNext
(
map
->
judy
,
&
prev
,
(
JError_t
*
)
&
map
->
err
))
prev
=
invalid
;
else
assert
(
prev
!=
invalid
);
return
prev
;
}
/**
/**
* jmap_last - return the last index in the map.
* jmap_last - return the last index in the map.
* @map: map from jmap_new
* @map: map from jmap_new
* @invalid: return value if map is empty.
*
* Returns 0 if map is empty.
*
*
* Example:
* Example:
* assert(!jmap_test(map, 0));
* assert(!jmap_test(map, 0));
* printf("Map indices (increasing order):");
* printf("Map indices (increasing order):");
* for (i = jmap_last(map
, 0); i; i = jmap_prev(map, i, 0
))
* for (i = jmap_last(map
); i; i = jmap_prev(map, i
))
* printf(" %lu", i);
* printf(" %lu", i);
* printf("\n");
* printf("\n");
* See Also:
* See Also:
* jmap_lastval()
* jmap_lastval()
*/
*/
static
inline
unsigned
long
jmap_last
(
const
struct
jmap
*
map
,
#define jmap_last(map) \
unsigned
long
invalid
)
tcon_cast((map), icanary, jmap_last_(&(map)->raw))
{
unsigned
long
index
=
-
1
;
if
(
!
JudyLLast
(
map
->
judy
,
&
index
,
(
JError_t
*
)
&
map
->
err
))
index
=
invalid
;
else
assert
(
index
!=
invalid
);
return
index
;
}
/**
/**
* jmap_prev - return the previous index in the map
.
* jmap_prev - return the previous index in the map
(must not contain 0)
* @map: map from jmap_new
* @map: map from jmap_new
* @prev: previous index
* @prev: previous index
* @invalid: return value if no previous indices are in the map.
*
*
* This is usually used to find an prior adjacent index after jmap_last.
* This is usually used to find an prior adjacent index after jmap_last.
* Returns 0 if no previous indices in map.
*
* See Also:
* See Also:
* jmap_prevval()
* jmap_prevval()
*/
*/
static
inline
unsigned
long
jmap_prev
(
const
struct
jmap
*
map
,
#define jmap_prev(map, prev) \
unsigned
long
prev
,
tcon_cast((map), icanary, jmap_prev_(jmap_rawi((map), (prev)), (prev)))
unsigned
long
invalid
)
{
if
(
!
JudyLPrev
(
map
->
judy
,
&
prev
,
(
JError_t
*
)
&
map
->
err
))
prev
=
invalid
;
else
assert
(
prev
!=
invalid
);
return
prev
;
}
/**
/**
* jmap_getval - access a value in-place for a given index.
* jmap_getval - access a value in-place for a given index.
...
@@ -377,28 +331,24 @@ static inline unsigned long jmap_prev(const struct jmap *map,
...
@@ -377,28 +331,24 @@ static inline unsigned long jmap_prev(const struct jmap *map,
* have called jmap_putval().
* have called jmap_putval().
*
*
* Example:
* Example:
*
unsigned long
*p;
*
char *
*p;
* jmap_add(map, 0,
1
);
* jmap_add(map, 0,
"hello"
);
* p = jmap_getval(map, 0);
* p = jmap_getval(map, 0);
* if (!p)
* if (!p)
* errx(1, "Could not find 0 in map!");
* errx(1, "Could not find 0 in map!");
* if (
*p != 1
)
* if (
strcmp(*p, "hello") != 0
)
* errx(1, "Value in map was not
0
?!");
* errx(1, "Value in map was not
correct
?!");
* *p =
7
;
* *p =
(char *)"goodbye"
;
* jmap_putval(map, &p);
* jmap_putval(map, &p);
* // Accessing p now would probably crash.
* // Accessing p now would probably crash.
*
*
* See Also:
* See Also:
* jmap_putval(), jmap_firstval()
* jmap_putval(), jmap_firstval()
*/
*/
static
inline
unsigned
long
*
jmap_getval
(
struct
jmap
*
map
,
unsigned
long
index
)
#define jmap_getval(map, index) \
{
tcon_cast_ptr((map), ccanary, \
unsigned
long
*
val
;
jmap_getval_(jmap_rawi((map), (index)), \
val
=
(
unsigned
long
*
)
JudyLGet
(
map
->
judy
,
index
,
(unsigned long)(index)))
(
JError_t
*
)
&
map
->
err
);
jmap_debug_add_access
(
map
,
index
,
val
,
"jmap_getval"
);
return
val
;
}
/**
/**
* jmap_putval - revoke access to a value.
* jmap_putval - revoke access to a value.
...
@@ -415,43 +365,36 @@ static inline unsigned long *jmap_getval(struct jmap *map, unsigned long index)
...
@@ -415,43 +365,36 @@ static inline unsigned long *jmap_getval(struct jmap *map, unsigned long index)
* jmap_getval(), jmap_nthval(), jmap_firstval(), jmap_nextval(),
* jmap_getval(), jmap_nthval(), jmap_firstval(), jmap_nextval(),
* jmap_lastval(), jmap_prevval().
* jmap_lastval(), jmap_prevval().
*/
*/
static
inline
void
jmap_putval
(
struct
jmap
*
map
,
unsigned
long
**
p
)
#define jmap_putval(map, p) \
{
jmap_putval_(jmap_rawc((map), **(p)), (p))
jmap_debug_del_access
(
map
,
p
);
}
/**
/**
* jmap_nthval - access the value of the nth value in the map.
* jmap_nthval - access the value of the nth value in the map.
* @map: map from jmap_new
* @map: map from jmap_new
* @n: which index we are interested in (0-based)
* @n: which index we are interested in (0-based)
* @index: set to the nth index in the map.
*
*
* This returns a pointer to the value at the nth index in the map,
* This returns a pointer to the value at the nth index in the map,
* or NULL if there are n is greater than the population of the map.
* or NULL if there are n is greater than the population of the map.
* You must use jmap_putval() on the pointer once you are done with it.
* You must use jmap_putval() on the pointer once you are done with it.
*
*
* Example:
* Example:
*
unsigned long
*val;
*
char *
*val;
*
*
* // We know 0 isn't in map.
* // We know 0 isn't in map.
* assert(!jmap_test(map, 0));
* assert(!jmap_test(map, 0));
* for (i = 0; (val = jmap_nthval(map, i, &index)) != NULL; i++) {
* for (i = 0; (val = jmap_nthval(map, i, &index)) != NULL; i++) {
* assert(jmap_popcount(map, 0, index) == i);
* assert(jmap_popcount(map, 0, index) == i);
* printf("Index %lu = %lu, value = %
lu
\n", i, index, *val);
* printf("Index %lu = %lu, value = %
s
\n", i, index, *val);
* jmap_putval(map, &val);
* jmap_putval(map, &val);
* }
* }
*
*
* See Also:
* See Also:
* jmap_nth();
* jmap_nth();
*/
*/
static
inline
unsigned
long
*
jmap_nthval
(
const
struct
jmap
*
map
,
#define jmap_nthval(map, n, index) \
unsigned
long
n
,
unsigned
long
*
index
)
tcon_cast_ptr((map), ccanary, \
{
jmap_nthval_(jmap_rawi((map), *(index)), (n), (index)))
unsigned
long
*
val
;
val
=
(
unsigned
long
*
)
JudyLByCount
(
map
->
judy
,
n
+
1
,
index
,
(
JError_t
*
)
&
map
->
err
);
jmap_debug_add_access
(
map
,
*
index
,
val
,
"jmap_nthval"
);
return
val
;
}
/**
/**
* jmap_firstval - access the first value in the map.
* jmap_firstval - access the first value in the map.
...
@@ -462,7 +405,7 @@ static inline unsigned long *jmap_nthval(const struct jmap *map,
...
@@ -462,7 +405,7 @@ static inline unsigned long *jmap_nthval(const struct jmap *map,
* the first value, which you must call jmap_putval() on!
* the first value, which you must call jmap_putval() on!
*
*
* Example:
* Example:
* // Add one to every value
.
* // Add one to every value
(ie. make it point into second char of string)
* for (val = jmap_firstval(map, &i); val; val = jmap_nextval(map, &i)) {
* for (val = jmap_firstval(map, &i); val; val = jmap_nextval(map, &i)) {
* (*val)++;
* (*val)++;
* jmap_putval(map, &val);
* jmap_putval(map, &val);
...
@@ -472,16 +415,10 @@ static inline unsigned long *jmap_nthval(const struct jmap *map,
...
@@ -472,16 +415,10 @@ static inline unsigned long *jmap_nthval(const struct jmap *map,
* See Also:
* See Also:
* jmap_first, jmap_nextval()
* jmap_first, jmap_nextval()
*/
*/
static
inline
unsigned
long
*
jmap_firstval
(
const
struct
jmap
*
map
,
#define jmap_firstval(map, index) \
unsigned
long
*
index
)
tcon_cast_ptr((map), ccanary, \
{
jmap_firstval_(jmap_rawi((map), *(index)), \
unsigned
long
*
val
;
(unsigned long *)(index)))
*
index
=
0
;
val
=
(
unsigned
long
*
)
JudyLFirst
(
map
->
judy
,
index
,
(
JError_t
*
)
&
map
->
err
);
jmap_debug_add_access
(
map
,
*
index
,
val
,
"jmap_firstval"
);
return
val
;
}
/**
/**
* jmap_nextval - access the next value in the map.
* jmap_nextval - access the next value in the map.
...
@@ -494,15 +431,11 @@ static inline unsigned long *jmap_firstval(const struct jmap *map,
...
@@ -494,15 +431,11 @@ static inline unsigned long *jmap_firstval(const struct jmap *map,
* See Also:
* See Also:
* jmap_firstval(), jmap_putval()
* jmap_firstval(), jmap_putval()
*/
*/
static
inline
unsigned
long
*
jmap_nextval
(
const
struct
jmap
*
map
,
#define jmap_nextval(map, index) \
unsigned
long
*
index
)
tcon_cast_ptr((map), ccanary, \
{
jmap_nextval_(jmap_rawi((map), *(index)), \
unsigned
long
*
val
;
(unsigned long *)(index)))
val
=
(
unsigned
long
*
)
JudyLNext
(
map
->
judy
,
index
,
(
JError_t
*
)
&
map
->
err
);
jmap_debug_add_access
(
map
,
*
index
,
val
,
"jmap_nextval"
);
return
val
;
}
/**
/**
* jmap_lastval - access the last value in the map.
* jmap_lastval - access the last value in the map.
...
@@ -512,16 +445,11 @@ static inline unsigned long *jmap_nextval(const struct jmap *map,
...
@@ -512,16 +445,11 @@ static inline unsigned long *jmap_nextval(const struct jmap *map,
* See Also:
* See Also:
* jmap_last(), jmap_putval()
* jmap_last(), jmap_putval()
*/
*/
static
inline
unsigned
long
*
jmap_lastval
(
const
struct
jmap
*
map
,
#define jmap_lastval(map, index) \
unsigned
long
*
index
)
tcon_cast_ptr((map), ccanary, \
{
jmap_lastval_(jmap_rawi((map), *(index)), \
unsigned
long
*
val
;
(unsigned long *)(index)))
*
index
=
-
1
;
val
=
(
unsigned
long
*
)
JudyLLast
(
map
->
judy
,
index
,
(
JError_t
*
)
&
map
->
err
);
jmap_debug_add_access
(
map
,
*
index
,
val
,
"jmap_lastval"
);
return
val
;
}
/**
/**
* jmap_prevval - access the previous value in the map.
* jmap_prevval - access the previous value in the map.
...
@@ -534,8 +462,207 @@ static inline unsigned long *jmap_lastval(const struct jmap *map,
...
@@ -534,8 +462,207 @@ static inline unsigned long *jmap_lastval(const struct jmap *map,
* See Also:
* See Also:
* jmap_lastval(), jmap_putval()
* jmap_lastval(), jmap_putval()
*/
*/
static
inline
unsigned
long
*
jmap_prevval
(
const
struct
jmap
*
map
,
#define jmap_prevval(map, index) \
tcon_cast_ptr((map), ccanary, \
jmap_prevval_(jmap_rawi((map), *(index)), \
(unsigned long *)(index)))
/* Debugging checks. */
static
inline
void
jmap_debug_add_access
(
const
struct
jmap
*
map
,
unsigned
long
index
,
unsigned
long
*
val
,
const
char
*
funcname
)
{
#ifdef CCAN_JMAP_DEBUG
if
(
!
map
->
acc_value
)
{
((
struct
jmap
*
)
map
)
->
acc_value
=
val
;
((
struct
jmap
*
)
map
)
->
acc_index
=
index
;
((
struct
jmap
*
)
map
)
->
funcname
=
funcname
;
}
#endif
if
(
val
)
assert
(
++
((
struct
jmap
*
)
map
)
->
num_accesses
);
}
static
inline
void
jmap_debug_del_access
(
struct
jmap
*
map
,
unsigned
long
**
val
)
{
assert
(
--
map
->
num_accesses
>=
0
);
#ifdef CCAN_JMAP_DEBUG
if
(
map
->
acc_value
==
*
val
)
map
->
acc_value
=
NULL
;
#endif
/* Set it to some invalid value. Not NULL, they might rely on that! */
assert
(
memset
(
val
,
0x42
,
sizeof
(
void
*
)));
}
static
inline
void
jmap_debug_access
(
struct
jmap
*
map
)
{
#ifdef CCAN_JMAP_DEBUG
if
(
map
->
num_accesses
&&
map
->
acc_value
)
fprintf
(
stderr
,
"jmap: still got index %lu, val %lu (%p) from %s
\n
"
,
map
->
acc_index
,
*
map
->
acc_value
,
map
->
acc_value
,
map
->
funcname
);
#endif
assert
(
!
map
->
num_accesses
);
}
/* Private functions */
struct
jmap
*
jmap_new_
(
size_t
size
);
void
jmap_free_
(
const
struct
jmap
*
map
);
const
char
*
COLD
jmap_error_str_
(
struct
jmap
*
map
);
static
inline
const
char
*
jmap_error_
(
struct
jmap
*
map
)
{
if
(
JU_ERRNO
(
&
map
->
err
)
<=
JU_ERRNO_NFMAX
)
return
NULL
;
return
jmap_error_str_
(
map
);
}
static
inline
bool
jmap_add_
(
struct
jmap
*
map
,
unsigned
long
index
,
unsigned
long
value
)
{
unsigned
long
*
val
;
jmap_debug_access
(
map
);
val
=
(
unsigned
long
*
)
JudyLIns
(
&
map
->
judy
,
index
,
&
map
->
err
);
if
(
val
==
PJERR
)
return
false
;
*
val
=
value
;
return
true
;
}
static
inline
bool
jmap_set_
(
const
struct
jmap
*
map
,
unsigned
long
index
,
unsigned
long
value
)
{
unsigned
long
*
val
;
val
=
(
unsigned
long
*
)
JudyLGet
(
map
->
judy
,
index
,
(
JError_t
*
)
&
map
->
err
);
if
(
val
&&
val
!=
PJERR
)
{
*
val
=
value
;
return
true
;
}
return
false
;
}
static
inline
bool
jmap_del_
(
struct
jmap
*
map
,
unsigned
long
index
)
{
jmap_debug_access
(
map
);
return
JudyLDel
(
&
map
->
judy
,
index
,
&
map
->
err
)
==
1
;
}
static
inline
bool
jmap_test_
(
const
struct
jmap
*
map
,
unsigned
long
index
)
{
return
JudyLGet
(
map
->
judy
,
index
,
(
JError_t
*
)
&
map
->
err
)
!=
NULL
;
}
static
inline
unsigned
long
jmap_get_
(
const
struct
jmap
*
map
,
unsigned
long
index
)
{
unsigned
long
*
val
;
val
=
(
unsigned
long
*
)
JudyLGet
(
map
->
judy
,
index
,
(
JError_t
*
)
&
map
->
err
);
if
(
!
val
||
val
==
PJERR
)
return
0
;
return
*
val
;
}
static
inline
unsigned
long
jmap_popcount_
(
const
struct
jmap
*
map
,
unsigned
long
start
,
unsigned
long
end_incl
)
{
return
JudyLCount
(
map
->
judy
,
start
,
end_incl
,
(
JError_t
*
)
&
map
->
err
);
}
static
inline
unsigned
long
jmap_nth_
(
const
struct
jmap
*
map
,
unsigned
long
n
,
unsigned
long
invalid
)
{
unsigned
long
index
;
if
(
!
JudyLByCount
(
map
->
judy
,
n
+
1
,
&
index
,
(
JError_t
*
)
&
map
->
err
))
index
=
invalid
;
return
index
;
}
static
inline
unsigned
long
jmap_first_
(
const
struct
jmap
*
map
)
{
unsigned
long
index
=
0
;
if
(
!
JudyLFirst
(
map
->
judy
,
&
index
,
(
JError_t
*
)
&
map
->
err
))
index
=
0
;
else
assert
(
index
!=
0
);
return
index
;
}
static
inline
unsigned
long
jmap_next_
(
const
struct
jmap
*
map
,
unsigned
long
prev
)
{
if
(
!
JudyLNext
(
map
->
judy
,
&
prev
,
(
JError_t
*
)
&
map
->
err
))
prev
=
0
;
else
assert
(
prev
!=
0
);
return
prev
;
}
static
inline
unsigned
long
jmap_last_
(
const
struct
jmap
*
map
)
{
unsigned
long
index
=
-
1
;
if
(
!
JudyLLast
(
map
->
judy
,
&
index
,
(
JError_t
*
)
&
map
->
err
))
index
=
0
;
else
assert
(
index
!=
0
);
return
index
;
}
static
inline
unsigned
long
jmap_prev_
(
const
struct
jmap
*
map
,
unsigned
long
prev
)
{
if
(
!
JudyLPrev
(
map
->
judy
,
&
prev
,
(
JError_t
*
)
&
map
->
err
))
prev
=
0
;
else
assert
(
prev
!=
0
);
return
prev
;
}
static
inline
void
*
jmap_getval_
(
struct
jmap
*
map
,
unsigned
long
index
)
{
unsigned
long
*
val
;
val
=
(
unsigned
long
*
)
JudyLGet
(
map
->
judy
,
index
,
(
JError_t
*
)
&
map
->
err
);
jmap_debug_add_access
(
map
,
index
,
val
,
"jmap_getval"
);
return
val
;
}
static
inline
void
jmap_putval_
(
struct
jmap
*
map
,
void
*
p
)
{
jmap_debug_del_access
(
map
,
p
);
}
static
inline
unsigned
long
*
jmap_nthval_
(
const
struct
jmap
*
map
,
unsigned
long
n
,
unsigned
long
*
index
)
unsigned
long
*
index
)
{
unsigned
long
*
val
;
val
=
(
unsigned
long
*
)
JudyLByCount
(
map
->
judy
,
n
+
1
,
index
,
(
JError_t
*
)
&
map
->
err
);
jmap_debug_add_access
(
map
,
*
index
,
val
,
"jmap_nthval"
);
return
val
;
}
static
inline
unsigned
long
*
jmap_firstval_
(
const
struct
jmap
*
map
,
unsigned
long
*
index
)
{
unsigned
long
*
val
;
*
index
=
0
;
val
=
(
unsigned
long
*
)
JudyLFirst
(
map
->
judy
,
index
,
(
JError_t
*
)
&
map
->
err
);
jmap_debug_add_access
(
map
,
*
index
,
val
,
"jmap_firstval"
);
return
val
;
}
static
inline
unsigned
long
*
jmap_nextval_
(
const
struct
jmap
*
map
,
unsigned
long
*
index
)
{
unsigned
long
*
val
;
val
=
(
unsigned
long
*
)
JudyLNext
(
map
->
judy
,
index
,
(
JError_t
*
)
&
map
->
err
);
jmap_debug_add_access
(
map
,
*
index
,
val
,
"jmap_nextval"
);
return
val
;
}
static
inline
unsigned
long
*
jmap_lastval_
(
const
struct
jmap
*
map
,
unsigned
long
*
index
)
{
unsigned
long
*
val
;
*
index
=
-
1
;
val
=
(
unsigned
long
*
)
JudyLLast
(
map
->
judy
,
index
,
(
JError_t
*
)
&
map
->
err
);
jmap_debug_add_access
(
map
,
*
index
,
val
,
"jmap_lastval"
);
return
val
;
}
static
inline
unsigned
long
*
jmap_prevval_
(
const
struct
jmap
*
map
,
unsigned
long
*
index
)
{
{
unsigned
long
*
val
;
unsigned
long
*
val
;
val
=
(
unsigned
long
*
)
JudyLPrev
(
map
->
judy
,
index
,
val
=
(
unsigned
long
*
)
JudyLPrev
(
map
->
judy
,
index
,
...
...
ccan/jmap/jmap_type.h
deleted
100644 → 0
View file @
805ea067
/* Licensed under LGPLv2.1+ - see LICENSE file for details */
#ifndef CCAN_JMAP_TYPE_H
#define CCAN_JMAP_TYPE_H
#include <ccan/jmap/jmap.h>
/**
* JMAP_DEFINE_UINTIDX_TYPE - create a set of jmap ops for integer->ptr map
* @type: a type whose pointers will be values in the map.
* @name: a name for all the functions to define (of form jmap_<name>_*)
*
* It's easiest if NULL values aren't placed in the map: jmap_@name_get will
* return NULL if an index isn't valid.
*
* The following wrapper functions are defined; each one is the same as
* the jmap.h generic equivalent except where noted:
*
* // Creating, errors and freeing.
* struct jmap_@name *jmap_@name_new(void);
* void jmap_@name_free(const struct jmap_@name *map);
* const char *jmap_@name_error(struct jmap_@name *map);
*
* // Add, set, delete, test and get.
* bool jmap_@name_add(struct jmap_@name *map,
* unsigned long idx, const type *value);
* bool jmap_@name_set(const struct jmap_@name *map,
* unsigned long idx, const type *value);
* bool jmap_@name_del(struct jmap_@name *map, unsigned long idx);
* bool jmap_@name_test(const struct jmap_@name *map, unsigned long idx);
* type *jmap_@name_get(const struct jmap_@name *map, unsigned long idx);
*
* // Counting and iteration.
* unsigned long jmap_@name_popcount(const struct jmap_@name *map,
* unsigned long start,
* unsigned long end_incl);
* unsigned long jmap_@name_nth(const struct jmap_@name *map,
* unsigned long n, unsigned long invalid);
* unsigned long jmap_@name_first(const struct jmap_@name *map,
* unsigned long invalid);
* unsigned long jmap_@name_next(const struct jmap_@name *map,
* unsigned long prev,
* unsigned long invalid);
* unsigned long jmap_@name_last(const struct jmap_@name *map,
* unsigned long invalid);
* unsigned long jmap_@name_prev(const struct jmap_@name *map,
* unsigned long prev,
* unsigned long invalid);
*
* // Get pointers to values to use.
* type **jmap_@name_getval(const struct jmap_@name *map,
* unsigned long idx);
* void jmap_@name_putval(struct jmap_@name *map, type ***p);
* type **jmap_@name_nthval(struct jmap_@name *map,
* unsigned long n, unsigned long *idx);
* type **jmap_@name_firstval(const struct jmap_@name *map,
* unsigned long *idx);
* type **jmap_@name_nextval(const struct jmap_@name *map,
* unsigned long *idx);
* type **jmap_@name_lastval(const struct jmap_@name *map,
* unsigned long *idx);
* type **jmap_@name_prevval(const struct jmap_@name *map,
* unsigned long *idx);
*/
#define JMAP_DEFINE_UINTIDX_TYPE(type, name) \
struct jmap_##name; \
static inline struct jmap_##name *jmap_##name##_new(void) \
{ \
return (struct jmap_##name *)jmap_new(); \
} \
static inline void jmap_##name##_free(const struct jmap_##name *map) \
{ \
jmap_free((const struct jmap *)map); \
} \
static inline const char *jmap_##name##_error(struct jmap_##name *map) \
{ \
return jmap_error((struct jmap *)map); \
} \
static inline bool jmap_##name##_add(struct jmap_##name *map, \
unsigned long idx, const type *value) \
{ \
return jmap_add((struct jmap *)map, idx, (unsigned long)value); \
} \
static inline bool jmap_##name##_set(const struct jmap_##name *map, \
unsigned long idx, const type *value) \
{ \
return jmap_set((const struct jmap *)map, idx, (unsigned long)value); \
} \
static inline bool jmap_##name##_del(struct jmap_##name *map, \
unsigned long idx) \
{ \
return jmap_del((struct jmap *)map, idx); \
} \
static inline bool jmap_##name##_test(const struct jmap_##name *map, \
unsigned long idx) \
{ \
return jmap_test((const struct jmap *)map, (unsigned long)idx); \
} \
static inline type *jmap_##name##_get(const struct jmap_##name *map, \
unsigned long idx) \
{ \
return (type *)jmap_get((const struct jmap *)map, idx, 0); \
} \
static inline unsigned long \
jmap_##name##_popcount(const struct jmap_##name *map, \
unsigned long start, unsigned long end_incl) \
{ \
return jmap_popcount((const struct jmap *)map, start, end_incl); \
} \
static inline unsigned long jmap_##name##_nth(const struct jmap_##name *map, \
unsigned long n, \
unsigned long invalid) \
{ \
return jmap_nth((const struct jmap *)map, n, invalid); \
} \
static inline unsigned long \
jmap_##name##_first(const struct jmap_##name *map, \
unsigned long invalid) \
{ \
return jmap_first((const struct jmap *)map, invalid); \
} \
static inline unsigned long \
jmap_##name##_next(const struct jmap_##name *map, \
unsigned long prev, unsigned long invalid) \
{ \
return jmap_next((const struct jmap *)map, prev, invalid); \
} \
static inline unsigned long \
jmap_##name##_last(const struct jmap_##name *map, \
unsigned long invalid) \
{ \
return jmap_last((const struct jmap *)map, invalid); \
} \
static inline unsigned long \
jmap_##name##_prev(const struct jmap_##name *map, \
unsigned long prev, unsigned long invalid) \
{ \
return jmap_prev((const struct jmap *)map, prev, invalid); \
} \
static inline type **jmap_##name##_getval(const struct jmap_##name *map, \
unsigned long idx) \
{ \
return (type **)jmap_getval((struct jmap *)map, idx); \
} \
static inline void jmap_##name##_putval(struct jmap_##name *map, \
type ***p) \
{ \
return jmap_putval((struct jmap *)map, (unsigned long **)p); \
} \
static inline type **jmap_##name##_nthval(struct jmap_##name *map, \
unsigned long n, \
unsigned long *idx) \
{ \
return (type **)jmap_nthval((struct jmap *)map, n, idx); \
} \
static inline type **jmap_##name##_firstval(const struct jmap_##name *map, \
unsigned long *idx) \
{ \
return (type **)jmap_firstval((const struct jmap *)map, idx); \
} \
static inline type **jmap_##name##_nextval(const struct jmap_##name *map, \
unsigned long *idx) \
{ \
return (type **)jmap_nextval((const struct jmap *)map, idx); \
} \
static inline type **jmap_##name##_lastval(const struct jmap_##name *map, \
unsigned long *idx) \
{ \
return (type **)jmap_lastval((const struct jmap *)map, idx); \
} \
static inline type **jmap_##name##_prevval(const struct jmap_##name *map, \
unsigned long *idx) \
{ \
return (type **)jmap_prevval((const struct jmap *)map, idx); \
}
/**
* JMAP_DEFINE_PTRIDX_TYPE - create a map of jmap ops for ptr->ptr map
* @itype: a type whose pointers will idx into the map.
* @type: a type whose pointers will be values in the map.
* @name: a name for all the functions to define (of form jmap_<name>_*)
*
* This macro defines a map of inline functions for typesafe and
* convenient usage of a pointer-idxed Judy map of pointers. It is
* assumed that a NULL pointer is never an idx in the map, as
* various functions return NULL for "invalid idx". Similarly,
* jmap_@name_get will return NULL if an idx isn't valid, so NULL indices
* are not recommended (though you can tell using jmap_@name_test).
*
* Since the ordering is by idx pointer value, it's generally quite useless.
* Thus we don't define order-specific functions, except first/next for
* traversal.
*
* The following wrapper functions are defined; each one is the same as
* the jmap.h generic equivalent:
*
* struct jmap_@name *jmap_@name_new(void);
* void jmap_@name_free(const struct jmap_@name *map);
* const char *jmap_@name_error(struct jmap_@name *map);
*
* bool jmap_@name_add(const struct jmap_@name *map,
* const itype *idx, const type *value);
* bool jmap_@name_set(const struct jmap_@name *map,
* const itype *idx, const type *value);
* bool jmap_@name_del(struct jmap_@name *map, const itype *idx);
* bool jmap_@name_test(const struct jmap_@name *map, const itype *idx);
*
* type *jmap_@name_get(const struct jmap_@name *map, const itype *idx);
* itype *jmap_@name_count(const struct jmap_@name *map);
* itype *jmap_@name_first(const struct jmap_@name *map);
* itype *jmap_@name_next(const struct jmap_@name *map,
* const itype *prev);
*
* type **jmap_@name_getval(const struct jmap_@name *map,
* const itype *idx);
* void jmap_@name_putval(struct jmap_@name *map, type ***p);
* type **jmap_@name_firstval(const struct jmap_@name *map,
* const itype **idx);
* type **jmap_@name_nextval(const struct jmap_@name *map,
* const itype **idx);
*/
#define JMAP_DEFINE_PTRIDX_TYPE(itype, type, name) \
struct jmap_##name; \
static inline struct jmap_##name *jmap_##name##_new(void) \
{ \
return (struct jmap_##name *)jmap_new(); \
} \
static inline void jmap_##name##_free(const struct jmap_##name *map) \
{ \
jmap_free((const struct jmap *)map); \
} \
static inline const char *jmap_##name##_error(struct jmap_##name *map) \
{ \
return jmap_error((struct jmap *)map); \
} \
static inline bool jmap_##name##_add(struct jmap_##name *map, \
const itype *idx, const type *value) \
{ \
return jmap_add((struct jmap *)map, (unsigned long)idx, \
(unsigned long)value); \
} \
static inline bool jmap_##name##_set(const struct jmap_##name *map, \
const itype *idx, const type *value) \
{ \
return jmap_set((const struct jmap *)map, (unsigned long)idx, \
(unsigned long)value); \
} \
static inline bool jmap_##name##_del(struct jmap_##name *map, \
const itype *idx) \
{ \
return jmap_del((struct jmap *)map, (unsigned long)idx); \
} \
static inline bool jmap_##name##_test(const struct jmap_##name *map, \
const itype *idx) \
{ \
return jmap_test((const struct jmap *)map, (unsigned long)idx); \
} \
static inline type *jmap_##name##_get(const struct jmap_##name *map, \
const itype *idx) \
{ \
return (type *)jmap_get((const struct jmap *)map, \
(unsigned long)idx, 0); \
} \
static inline unsigned long \
jmap_##name##_count(const struct jmap_##name *map) \
{ \
return jmap_popcount((const struct jmap *)map, 0, -1); \
} \
static inline itype *jmap_##name##_first(const struct jmap_##name *map) \
{ \
return (itype *)jmap_first((const struct jmap *)map, 0); \
} \
static inline itype *jmap_##name##_next(const struct jmap_##name *map, \
const itype *prev) \
{ \
return (itype *)jmap_next((const struct jmap *)map, \
(unsigned long)prev, 0); \
} \
static inline type **jmap_##name##_getval(const struct jmap_##name *map, \
const itype *idx) \
{ \
return (type **)jmap_getval((struct jmap *)map, \
(unsigned long)idx); \
} \
static inline void jmap_##name##_putval(struct jmap_##name *map, \
type ***p) \
{ \
return jmap_putval((struct jmap *)map, (unsigned long **)p); \
} \
static inline type **jmap_##name##_firstval(const struct jmap_##name *map, \
itype **idx) \
{ \
unsigned long i; \
type **ret; \
ret = (type **)jmap_firstval((const struct jmap *)map, &i); \
*idx = (void *)i; \
return ret; \
} \
static inline type **jmap_##name##_nextval(const struct jmap_##name *map, \
itype **idx) \
{ \
return (type **)jmap_nextval((const struct jmap *)map, \
(unsigned long *)idx); \
}
#endif
/* CCAN_JMAP_TYPE_H */
ccan/jmap/test/run-access-count.c
View file @
3a34aa1a
...
@@ -5,15 +5,19 @@
...
@@ -5,15 +5,19 @@
#include <sys/wait.h>
#include <sys/wait.h>
#include <unistd.h>
#include <unistd.h>
struct
map
{
JMAP_MEMBERS
(
unsigned
long
,
unsigned
long
);
};
int
main
(
int
argc
,
char
*
argv
[])
int
main
(
int
argc
,
char
*
argv
[])
{
{
struct
j
map
*
map
;
struct
map
*
map
;
unsigned
long
*
value
;
unsigned
long
*
value
;
int
status
;
int
status
;
plan_tests
(
9
);
plan_tests
(
9
);
map
=
jmap_new
();
map
=
jmap_new
(
struct
map
);
ok1
(
jmap_error
(
map
)
==
NULL
);
ok1
(
jmap_error
(
map
)
==
NULL
);
ok1
(
jmap_add
(
map
,
0
,
1
));
ok1
(
jmap_add
(
map
,
0
,
1
));
...
...
ccan/jmap/test/run-ptridx-int.c
0 → 100644
View file @
3a34aa1a
#include <ccan/tap/tap.h>
#include <ccan/jmap/jmap.c>
struct
idx
;
struct
map
{
JMAP_MEMBERS
(
struct
idx
*
,
int
);
};
#define NUM 100
static
int
cmp_ptr
(
const
void
*
a
,
const
void
*
b
)
{
return
*
(
char
**
)
a
-
*
(
char
**
)
b
;
}
int
main
(
int
argc
,
char
*
argv
[])
{
struct
map
*
map
;
struct
idx
*
idx
[
NUM
+
1
],
*
index
;
unsigned
int
i
;
int
*
intp
;
plan_tests
(
25
+
NUM
*
2
+
6
);
for
(
i
=
0
;
i
<
NUM
+
1
;
i
++
)
idx
[
i
]
=
malloc
(
20
);
qsort
(
idx
,
NUM
,
sizeof
(
idx
[
0
]),
cmp_ptr
);
map
=
jmap_new
(
struct
map
);
ok1
(
jmap_error
(
map
)
==
NULL
);
ok1
(
jmap_test
(
map
,
idx
[
NUM
])
==
false
);
ok1
(
jmap_get
(
map
,
idx
[
NUM
])
==
0
);
ok1
(
jmap_count
(
map
)
==
0
);
ok1
(
jmap_first
(
map
)
==
0
);
ok1
(
jmap_del
(
map
,
idx
[
0
])
==
false
);
/* Set only works on existing cases. */
ok1
(
jmap_set
(
map
,
idx
[
0
],
0
)
==
false
);
ok1
(
jmap_add
(
map
,
idx
[
0
],
1
)
==
true
);
ok1
(
jmap_get
(
map
,
idx
[
0
])
==
1
);
ok1
(
jmap_set
(
map
,
idx
[
0
],
-
1
)
==
true
);
ok1
(
jmap_get
(
map
,
idx
[
0
])
==
-
1
);
ok1
(
jmap_test
(
map
,
idx
[
0
])
==
true
);
ok1
(
jmap_count
(
map
)
==
1
);
ok1
(
jmap_first
(
map
)
==
idx
[
0
]);
ok1
(
jmap_next
(
map
,
idx
[
0
])
==
NULL
);
ok1
(
jmap_del
(
map
,
idx
[
0
])
==
true
);
ok1
(
jmap_test
(
map
,
idx
[
0
])
==
false
);
ok1
(
jmap_count
(
map
)
==
0
);
for
(
i
=
0
;
i
<
NUM
;
i
++
)
jmap_add
(
map
,
idx
[
i
],
i
+
1
);
ok1
(
jmap_count
(
map
)
==
NUM
);
ok1
(
jmap_first
(
map
)
==
idx
[
0
]);
ok1
(
jmap_next
(
map
,
idx
[
0
])
==
idx
[
1
]);
ok1
(
jmap_next
(
map
,
idx
[
NUM
-
1
])
==
NULL
);
ok1
(
jmap_get
(
map
,
idx
[
0
])
==
1
);
ok1
(
jmap_get
(
map
,
idx
[
NUM
-
1
])
==
NUM
);
ok1
(
jmap_get
(
map
,
(
void
*
)((
char
*
)
idx
[
NUM
-
1
]
+
1
))
==
0
);
/* Reverse values in map. */
for
(
i
=
0
;
i
<
NUM
;
i
++
)
{
intp
=
jmap_getval
(
map
,
idx
[
i
]);
ok1
(
*
intp
==
i
+
1
);
*
intp
=
NUM
-
i
;
jmap_putval
(
map
,
&
intp
);
}
for
(
i
=
0
;
i
<
NUM
;
i
++
)
ok1
(
jmap_get
(
map
,
idx
[
i
])
==
NUM
-
i
);
intp
=
jmap_firstval
(
map
,
&
index
);
ok1
(
index
==
idx
[
0
]);
ok1
(
*
intp
==
NUM
);
jmap_putval
(
map
,
&
intp
);
intp
=
jmap_nextval
(
map
,
&
index
);
ok1
(
index
==
idx
[
1
]);
ok1
(
*
intp
==
NUM
-
1
);
jmap_putval
(
map
,
&
intp
);
index
=
idx
[
NUM
-
1
];
intp
=
jmap_nextval
(
map
,
&
index
);
ok1
(
intp
==
NULL
);
ok1
(
jmap_error
(
map
)
==
NULL
);
jmap_free
(
map
);
for
(
i
=
0
;
i
<
NUM
+
1
;
i
++
)
free
(
idx
[
i
]);
return
exit_status
();
}
ccan/jmap/test/run-ptridx-type.c
View file @
3a34aa1a
#include <ccan/tap/tap.h>
#include <ccan/tap/tap.h>
#include <ccan/jmap/jmap_type.h>
#include <ccan/jmap/jmap.c>
#include <ccan/jmap/jmap.c>
struct
foo
;
struct
foo
;
struct
idx
;
struct
idx
;
JMAP_DEFINE_PTRIDX_TYPE
(
struct
idx
,
struct
foo
,
foo
);
struct
jmap_foo
{
JMAP_MEMBERS
(
struct
idx
*
,
struct
foo
*
);
};
#define NUM 100
#define NUM 100
...
@@ -32,70 +33,70 @@ int main(int argc, char *argv[])
...
@@ -32,70 +33,70 @@ int main(int argc, char *argv[])
for
(
i
=
0
;
i
<
NUM
+
1
;
i
++
)
for
(
i
=
0
;
i
<
NUM
+
1
;
i
++
)
idx
[
i
]
=
(
void
*
)((
char
*
)
foo
[
i
]
+
1
);
idx
[
i
]
=
(
void
*
)((
char
*
)
foo
[
i
]
+
1
);
map
=
jmap_
foo_new
(
);
map
=
jmap_
new
(
struct
jmap_foo
);
ok1
(
jmap_
foo_
error
(
map
)
==
NULL
);
ok1
(
jmap_error
(
map
)
==
NULL
);
ok1
(
jmap_
foo_
test
(
map
,
idx
[
NUM
])
==
false
);
ok1
(
jmap_test
(
map
,
idx
[
NUM
])
==
false
);
ok1
(
jmap_
foo_
get
(
map
,
idx
[
NUM
])
==
(
struct
foo
*
)
NULL
);
ok1
(
jmap_get
(
map
,
idx
[
NUM
])
==
(
struct
foo
*
)
NULL
);
ok1
(
jmap_
foo_
count
(
map
)
==
0
);
ok1
(
jmap_count
(
map
)
==
0
);
ok1
(
jmap_f
oo_f
irst
(
map
)
==
(
struct
idx
*
)
NULL
);
ok1
(
jmap_first
(
map
)
==
(
struct
idx
*
)
NULL
);
ok1
(
jmap_
foo_
del
(
map
,
idx
[
0
])
==
false
);
ok1
(
jmap_del
(
map
,
idx
[
0
])
==
false
);
/* Set only works on existing cases. */
/* Set only works on existing cases. */
ok1
(
jmap_
foo_
set
(
map
,
idx
[
0
],
foo
[
0
])
==
false
);
ok1
(
jmap_set
(
map
,
idx
[
0
],
foo
[
0
])
==
false
);
ok1
(
jmap_
foo_
add
(
map
,
idx
[
0
],
foo
[
1
])
==
true
);
ok1
(
jmap_add
(
map
,
idx
[
0
],
foo
[
1
])
==
true
);
ok1
(
jmap_
foo_
get
(
map
,
idx
[
0
])
==
foo
[
1
]);
ok1
(
jmap_get
(
map
,
idx
[
0
])
==
foo
[
1
]);
ok1
(
jmap_
foo_
set
(
map
,
idx
[
0
],
foo
[
0
])
==
true
);
ok1
(
jmap_set
(
map
,
idx
[
0
],
foo
[
0
])
==
true
);
ok1
(
jmap_
foo_
get
(
map
,
idx
[
0
])
==
foo
[
0
]);
ok1
(
jmap_get
(
map
,
idx
[
0
])
==
foo
[
0
]);
ok1
(
jmap_
foo_
test
(
map
,
idx
[
0
])
==
true
);
ok1
(
jmap_test
(
map
,
idx
[
0
])
==
true
);
ok1
(
jmap_
foo_
count
(
map
)
==
1
);
ok1
(
jmap_count
(
map
)
==
1
);
ok1
(
jmap_f
oo_f
irst
(
map
)
==
idx
[
0
]);
ok1
(
jmap_first
(
map
)
==
idx
[
0
]);
ok1
(
jmap_
foo_
next
(
map
,
idx
[
0
])
==
NULL
);
ok1
(
jmap_next
(
map
,
idx
[
0
])
==
NULL
);
ok1
(
jmap_
foo_
del
(
map
,
idx
[
0
])
==
true
);
ok1
(
jmap_del
(
map
,
idx
[
0
])
==
true
);
ok1
(
jmap_
foo_
test
(
map
,
idx
[
0
])
==
false
);
ok1
(
jmap_test
(
map
,
idx
[
0
])
==
false
);
ok1
(
jmap_
foo_
count
(
map
)
==
0
);
ok1
(
jmap_count
(
map
)
==
0
);
for
(
i
=
0
;
i
<
NUM
;
i
++
)
for
(
i
=
0
;
i
<
NUM
;
i
++
)
jmap_
foo_
add
(
map
,
idx
[
i
],
foo
[
i
]);
jmap_add
(
map
,
idx
[
i
],
foo
[
i
]);
ok1
(
jmap_
foo_
count
(
map
)
==
NUM
);
ok1
(
jmap_count
(
map
)
==
NUM
);
ok1
(
jmap_f
oo_f
irst
(
map
)
==
idx
[
0
]);
ok1
(
jmap_first
(
map
)
==
idx
[
0
]);
ok1
(
jmap_
foo_
next
(
map
,
idx
[
0
])
==
idx
[
1
]);
ok1
(
jmap_next
(
map
,
idx
[
0
])
==
idx
[
1
]);
ok1
(
jmap_
foo_
next
(
map
,
idx
[
NUM
-
1
])
==
NULL
);
ok1
(
jmap_next
(
map
,
idx
[
NUM
-
1
])
==
NULL
);
ok1
(
jmap_
foo_
get
(
map
,
idx
[
0
])
==
foo
[
0
]);
ok1
(
jmap_get
(
map
,
idx
[
0
])
==
foo
[
0
]);
ok1
(
jmap_
foo_
get
(
map
,
idx
[
NUM
-
1
])
==
foo
[
NUM
-
1
]);
ok1
(
jmap_get
(
map
,
idx
[
NUM
-
1
])
==
foo
[
NUM
-
1
]);
ok1
(
jmap_
foo_
get
(
map
,
(
void
*
)((
char
*
)
idx
[
NUM
-
1
]
+
1
))
==
NULL
);
ok1
(
jmap_get
(
map
,
(
void
*
)((
char
*
)
idx
[
NUM
-
1
]
+
1
))
==
NULL
);
/* Reverse values in map. */
/* Reverse values in map. */
for
(
i
=
0
;
i
<
NUM
;
i
++
)
{
for
(
i
=
0
;
i
<
NUM
;
i
++
)
{
foop
=
jmap_
foo_
getval
(
map
,
idx
[
i
]);
foop
=
jmap_getval
(
map
,
idx
[
i
]);
ok1
(
*
foop
==
foo
[
i
]);
ok1
(
*
foop
==
foo
[
i
]);
*
foop
=
foo
[
NUM
-
1
-
i
];
*
foop
=
foo
[
NUM
-
1
-
i
];
jmap_
foo_
putval
(
map
,
&
foop
);
jmap_putval
(
map
,
&
foop
);
}
}
for
(
i
=
0
;
i
<
NUM
;
i
++
)
for
(
i
=
0
;
i
<
NUM
;
i
++
)
ok1
(
jmap_
foo_
get
(
map
,
idx
[
i
])
==
foo
[
NUM
-
1
-
i
]);
ok1
(
jmap_get
(
map
,
idx
[
i
])
==
foo
[
NUM
-
1
-
i
]);
foop
=
jmap_f
oo_f
irstval
(
map
,
&
index
);
foop
=
jmap_firstval
(
map
,
&
index
);
ok1
(
index
==
idx
[
0
]);
ok1
(
index
==
idx
[
0
]);
ok1
(
*
foop
==
foo
[
NUM
-
1
]);
ok1
(
*
foop
==
foo
[
NUM
-
1
]);
jmap_
foo_
putval
(
map
,
&
foop
);
jmap_putval
(
map
,
&
foop
);
foop
=
jmap_
foo_
nextval
(
map
,
&
index
);
foop
=
jmap_nextval
(
map
,
&
index
);
ok1
(
index
==
idx
[
1
]);
ok1
(
index
==
idx
[
1
]);
ok1
(
*
foop
==
foo
[
NUM
-
2
]);
ok1
(
*
foop
==
foo
[
NUM
-
2
]);
jmap_
foo_
putval
(
map
,
&
foop
);
jmap_putval
(
map
,
&
foop
);
index
=
idx
[
NUM
-
1
];
index
=
idx
[
NUM
-
1
];
foop
=
jmap_
foo_
nextval
(
map
,
&
index
);
foop
=
jmap_nextval
(
map
,
&
index
);
ok1
(
foop
==
NULL
);
ok1
(
foop
==
NULL
);
ok1
(
jmap_
foo_
error
(
map
)
==
NULL
);
ok1
(
jmap_error
(
map
)
==
NULL
);
jmap_f
oo_f
ree
(
map
);
jmap_free
(
map
);
for
(
i
=
0
;
i
<
NUM
+
1
;
i
++
)
for
(
i
=
0
;
i
<
NUM
+
1
;
i
++
)
free
(
foo
[
i
]);
free
(
foo
[
i
]);
...
...
ccan/jmap/test/run-uintidx-type.c
View file @
3a34aa1a
#include <ccan/tap/tap.h>
#include <ccan/tap/tap.h>
#include <ccan/jmap/jmap_type.h>
#include <ccan/jmap/jmap.c>
#include <ccan/jmap/jmap.c>
struct
foo
;
struct
foo
;
JMAP_DEFINE_UINTIDX_TYPE
(
struct
foo
,
foo
);
struct
jmap_foo
{
JMAP_MEMBERS
(
unsigned
long
,
struct
foo
*
);
};
#define NUM 100
#define NUM 100
...
@@ -14,117 +15,120 @@ int main(int argc, char *argv[])
...
@@ -14,117 +15,120 @@ int main(int argc, char *argv[])
struct
foo
*
foo
[
NUM
],
**
foop
;
struct
foo
*
foo
[
NUM
],
**
foop
;
unsigned
long
i
;
unsigned
long
i
;
plan_tests
(
37
+
NUM
*
2
+
19
);
plan_tests
(
40
+
NUM
*
2
+
19
);
for
(
i
=
0
;
i
<
NUM
;
i
++
)
for
(
i
=
0
;
i
<
NUM
;
i
++
)
foo
[
i
]
=
malloc
(
20
);
foo
[
i
]
=
malloc
(
20
);
map
=
jmap_
foo_new
(
);
map
=
jmap_
new
(
struct
jmap_foo
);
ok1
(
jmap_
foo_
error
(
map
)
==
NULL
);
ok1
(
jmap_error
(
map
)
==
NULL
);
ok1
(
jmap_
foo_
test
(
map
,
0
)
==
false
);
ok1
(
jmap_test
(
map
,
0
)
==
false
);
ok1
(
jmap_
foo_
get
(
map
,
0
)
==
(
struct
foo
*
)
NULL
);
ok1
(
jmap_get
(
map
,
0
)
==
(
struct
foo
*
)
NULL
);
ok1
(
jmap_
foo_
popcount
(
map
,
0
,
-
1
)
==
0
);
ok1
(
jmap_popcount
(
map
,
0
,
-
1
)
==
0
);
ok1
(
jmap_f
oo_first
(
map
,
0
)
==
0
);
ok1
(
jmap_f
irst
(
map
)
==
0
);
ok1
(
jmap_
foo_last
(
map
,
0
)
==
0
);
ok1
(
jmap_
last
(
map
)
==
0
);
ok1
(
jmap_
foo_
del
(
map
,
0
)
==
false
);
ok1
(
jmap_del
(
map
,
0
)
==
false
);
/* Set only works on existing cases. */
/* Set only works on existing cases. */
ok1
(
jmap_foo_set
(
map
,
0
,
foo
[
0
])
==
false
);
ok1
(
jmap_set
(
map
,
1
,
foo
[
0
])
==
false
);
ok1
(
jmap_foo_add
(
map
,
0
,
foo
[
1
])
==
true
);
ok1
(
jmap_add
(
map
,
1
,
foo
[
1
])
==
true
);
ok1
(
jmap_foo_get
(
map
,
0
)
==
foo
[
1
]);
ok1
(
jmap_get
(
map
,
1
)
==
foo
[
1
]);
ok1
(
jmap_foo_set
(
map
,
0
,
foo
[
0
])
==
true
);
ok1
(
jmap_set
(
map
,
1
,
foo
[
0
])
==
true
);
ok1
(
jmap_foo_get
(
map
,
0
)
==
foo
[
0
]);
ok1
(
jmap_get
(
map
,
1
)
==
foo
[
0
]);
ok1
(
jmap_foo_test
(
map
,
0
)
==
true
);
ok1
(
jmap_test
(
map
,
1
)
==
true
);
ok1
(
jmap_foo_popcount
(
map
,
0
,
-
1
)
==
1
);
ok1
(
jmap_popcount
(
map
,
0
,
-
1
)
==
1
);
ok1
(
jmap_foo_first
(
map
,
-
1
)
==
0
);
ok1
(
jmap_first
(
map
)
==
1
);
ok1
(
jmap_foo_last
(
map
,
-
1
)
==
0
);
ok1
(
jmap_last
(
map
)
==
1
);
ok1
(
jmap_foo_next
(
map
,
0
,
-
1
)
==
(
size_t
)
-
1
);
ok1
(
jmap_next
(
map
,
0
)
==
1
);
ok1
(
jmap_foo_prev
(
map
,
0
,
-
1
)
==
(
size_t
)
-
1
);
ok1
(
jmap_next
(
map
,
1
)
==
0
);
ok1
(
jmap_prev
(
map
,
2
)
==
1
);
ok1
(
jmap_foo_del
(
map
,
0
)
==
true
);
ok1
(
jmap_prev
(
map
,
1
)
==
0
);
ok1
(
jmap_foo_test
(
map
,
0
)
==
false
);
ok1
(
jmap_foo_popcount
(
map
,
0
,
-
1
)
==
0
);
ok1
(
jmap_del
(
map
,
1
)
==
true
);
ok1
(
jmap_test
(
map
,
1
)
==
false
);
ok1
(
jmap_popcount
(
map
,
0
,
-
1
)
==
0
);
for
(
i
=
0
;
i
<
NUM
;
i
++
)
for
(
i
=
0
;
i
<
NUM
;
i
++
)
jmap_foo_add
(
map
,
i
,
foo
[
i
]);
jmap_add
(
map
,
i
+
1
,
foo
[
i
]);
ok1
(
jmap_foo_popcount
(
map
,
0
,
-
1
)
==
NUM
);
ok1
(
jmap_count
(
map
)
==
NUM
);
ok1
(
jmap_foo_popcount
(
map
,
0
,
NUM
-
1
)
==
NUM
);
ok1
(
jmap_popcount
(
map
,
0
,
-
1
)
==
NUM
);
ok1
(
jmap_foo_popcount
(
map
,
0
,
NUM
/
2
-
1
)
==
NUM
/
2
);
ok1
(
jmap_popcount
(
map
,
1
,
NUM
)
==
NUM
);
ok1
(
jmap_foo_popcount
(
map
,
NUM
/
2
,
NUM
)
==
NUM
-
NUM
/
2
);
ok1
(
jmap_popcount
(
map
,
1
,
NUM
/
2
)
==
NUM
/
2
);
ok1
(
jmap_popcount
(
map
,
NUM
/
2
+
1
,
NUM
)
==
NUM
-
NUM
/
2
);
ok1
(
jmap_foo_nth
(
map
,
0
,
-
1
)
==
0
);
ok1
(
jmap_foo_nth
(
map
,
NUM
-
1
,
-
1
)
==
NUM
-
1
);
ok1
(
jmap_nth
(
map
,
0
,
-
1
)
==
1
);
ok1
(
jmap_foo_nth
(
map
,
NUM
,
-
1
)
==
(
size_t
)
-
1
);
ok1
(
jmap_nth
(
map
,
NUM
-
1
,
-
1
)
==
NUM
);
ok1
(
jmap_foo_first
(
map
,
-
1
)
==
0
);
ok1
(
jmap_nth
(
map
,
NUM
,
-
1
)
==
(
size_t
)
-
1
);
ok1
(
jmap_foo_last
(
map
,
-
1
)
==
NUM
-
1
);
ok1
(
jmap_first
(
map
)
==
1
);
ok1
(
jmap_foo_next
(
map
,
0
,
-
1
)
==
1
);
ok1
(
jmap_last
(
map
)
==
NUM
);
ok1
(
jmap_foo_next
(
map
,
NUM
-
1
,
-
1
)
==
(
size_t
)
-
1
);
ok1
(
jmap_next
(
map
,
1
)
==
2
);
ok1
(
jmap_foo_prev
(
map
,
1
,
-
1
)
==
0
);
ok1
(
jmap_next
(
map
,
NUM
)
==
0
);
ok1
(
jmap_foo_prev
(
map
,
0
,
-
1
)
==
(
size_t
)
-
1
);
ok1
(
jmap_prev
(
map
,
2
)
==
1
);
ok1
(
jmap_prev
(
map
,
1
)
==
0
);
ok1
(
jmap_foo_get
(
map
,
0
)
==
foo
[
0
]);
ok1
(
jmap_foo_get
(
map
,
NUM
-
1
)
==
foo
[
NUM
-
1
]);
ok1
(
jmap_get
(
map
,
1
)
==
foo
[
0
]);
ok1
(
jmap_foo_get
(
map
,
NUM
)
==
NULL
);
ok1
(
jmap_get
(
map
,
NUM
)
==
foo
[
NUM
-
1
]);
ok1
(
jmap_get
(
map
,
NUM
+
1
)
==
NULL
);
/* Reverse values in map. */
/* Reverse values in map. */
for
(
i
=
0
;
i
<
NUM
;
i
++
)
{
for
(
i
=
0
;
i
<
NUM
;
i
++
)
{
foop
=
jmap_
foo_getval
(
map
,
i
);
foop
=
jmap_
getval
(
map
,
i
+
1
);
ok1
(
*
foop
==
foo
[
i
]);
ok1
(
*
foop
==
foo
[
i
]);
*
foop
=
foo
[
NUM
-
1
-
i
];
*
foop
=
foo
[
NUM
-
1
-
i
];
jmap_
foo_
putval
(
map
,
&
foop
);
jmap_putval
(
map
,
&
foop
);
}
}
for
(
i
=
0
;
i
<
NUM
;
i
++
)
for
(
i
=
0
;
i
<
NUM
;
i
++
)
ok1
(
jmap_
foo_get
(
map
,
i
)
==
foo
[
NUM
-
1
-
i
]);
ok1
(
jmap_
get
(
map
,
i
+
1
)
==
foo
[
NUM
-
1
-
i
]);
foop
=
jmap_
foo_
nthval
(
map
,
0
,
&
i
);
foop
=
jmap_nthval
(
map
,
0
,
&
i
);
ok1
(
i
==
0
);
ok1
(
i
==
1
);
ok1
(
*
foop
==
foo
[
NUM
-
1
]);
ok1
(
*
foop
==
foo
[
NUM
-
1
]);
jmap_
foo_
putval
(
map
,
&
foop
);
jmap_putval
(
map
,
&
foop
);
foop
=
jmap_
foo_
nthval
(
map
,
NUM
-
1
,
&
i
);
foop
=
jmap_nthval
(
map
,
NUM
-
1
,
&
i
);
ok1
(
i
==
NUM
-
1
);
ok1
(
i
==
NUM
);
ok1
(
*
foop
==
foo
[
0
]);
ok1
(
*
foop
==
foo
[
0
]);
jmap_
foo_
putval
(
map
,
&
foop
);
jmap_putval
(
map
,
&
foop
);
foop
=
jmap_f
oo_f
irstval
(
map
,
&
i
);
foop
=
jmap_firstval
(
map
,
&
i
);
ok1
(
i
==
0
);
ok1
(
i
==
1
);
ok1
(
*
foop
==
foo
[
NUM
-
1
]);
ok1
(
*
foop
==
foo
[
NUM
-
1
]);
jmap_
foo_
putval
(
map
,
&
foop
);
jmap_putval
(
map
,
&
foop
);
foop
=
jmap_
foo_
nextval
(
map
,
&
i
);
foop
=
jmap_nextval
(
map
,
&
i
);
ok1
(
i
==
1
);
ok1
(
i
==
2
);
ok1
(
*
foop
==
foo
[
NUM
-
2
]);
ok1
(
*
foop
==
foo
[
NUM
-
2
]);
jmap_
foo_
putval
(
map
,
&
foop
);
jmap_putval
(
map
,
&
foop
);
foop
=
jmap_
foo_
prevval
(
map
,
&
i
);
foop
=
jmap_prevval
(
map
,
&
i
);
ok1
(
i
==
0
);
ok1
(
i
==
1
);
ok1
(
*
foop
==
foo
[
NUM
-
1
]);
ok1
(
*
foop
==
foo
[
NUM
-
1
]);
jmap_
foo_
putval
(
map
,
&
foop
);
jmap_putval
(
map
,
&
foop
);
foop
=
jmap_
foo_
prevval
(
map
,
&
i
);
foop
=
jmap_prevval
(
map
,
&
i
);
ok1
(
foop
==
NULL
);
ok1
(
foop
==
NULL
);
foop
=
jmap_
foo_
lastval
(
map
,
&
i
);
foop
=
jmap_lastval
(
map
,
&
i
);
ok1
(
i
==
NUM
-
1
);
ok1
(
i
==
NUM
);
ok1
(
*
foop
==
foo
[
0
]);
ok1
(
*
foop
==
foo
[
0
]);
jmap_
foo_
putval
(
map
,
&
foop
);
jmap_putval
(
map
,
&
foop
);
foop
=
jmap_
foo_
prevval
(
map
,
&
i
);
foop
=
jmap_prevval
(
map
,
&
i
);
ok1
(
i
==
NUM
-
2
);
ok1
(
i
==
NUM
-
1
);
ok1
(
*
foop
==
foo
[
1
]);
ok1
(
*
foop
==
foo
[
1
]);
jmap_
foo_
putval
(
map
,
&
foop
);
jmap_putval
(
map
,
&
foop
);
foop
=
jmap_
foo_
nextval
(
map
,
&
i
);
foop
=
jmap_nextval
(
map
,
&
i
);
ok1
(
i
==
NUM
-
1
);
ok1
(
i
==
NUM
);
ok1
(
*
foop
==
foo
[
0
]);
ok1
(
*
foop
==
foo
[
0
]);
jmap_
foo_
putval
(
map
,
&
foop
);
jmap_putval
(
map
,
&
foop
);
foop
=
jmap_
foo_
nextval
(
map
,
&
i
);
foop
=
jmap_nextval
(
map
,
&
i
);
ok1
(
foop
==
NULL
);
ok1
(
foop
==
NULL
);
ok1
(
jmap_
foo_
error
(
map
)
==
NULL
);
ok1
(
jmap_error
(
map
)
==
NULL
);
jmap_f
oo_f
ree
(
map
);
jmap_free
(
map
);
for
(
i
=
0
;
i
<
NUM
;
i
++
)
for
(
i
=
0
;
i
<
NUM
;
i
++
)
free
(
foo
[
i
]);
free
(
foo
[
i
]);
...
...
ccan/jmap/test/run.c
View file @
3a34aa1a
...
@@ -2,111 +2,113 @@
...
@@ -2,111 +2,113 @@
#define CCAN_JMAP_DEBUG
#define CCAN_JMAP_DEBUG
#include <ccan/jmap/jmap.c>
#include <ccan/jmap/jmap.c>
struct
map
{
JMAP_MEMBERS
(
unsigned
long
,
unsigned
long
);
};
int
main
(
int
argc
,
char
*
argv
[])
int
main
(
int
argc
,
char
*
argv
[])
{
{
struct
j
map
*
map
;
struct
map
*
map
;
unsigned
long
i
,
*
value
;
unsigned
long
i
,
*
value
;
const
char
*
err
;
const
char
*
err
;
plan_tests
(
5
3
);
plan_tests
(
5
1
);
map
=
jmap_new
();
map
=
jmap_new
(
struct
map
);
ok1
(
jmap_error
(
map
)
==
NULL
);
ok1
(
jmap_error
(
map
)
==
NULL
);
ok1
(
jmap_test
(
map
,
0
)
==
false
);
ok1
(
jmap_test
(
map
,
0
)
==
false
);
ok1
(
jmap_del
(
map
,
0
)
==
false
);
ok1
(
jmap_del
(
map
,
0
)
==
false
);
ok1
(
jmap_add
(
map
,
0
,
1
)
==
true
);
ok1
(
jmap_add
(
map
,
0
,
1
)
==
true
);
ok1
(
jmap_test
(
map
,
0
)
==
true
);
ok1
(
jmap_test
(
map
,
0
)
==
true
);
ok1
(
jmap_get
(
map
,
0
,
-
1
)
==
1
);
ok1
(
jmap_get
(
map
,
0
)
==
1
);
ok1
(
jmap_get
(
map
,
1
,
-
1
)
==
(
size_t
)
-
1
);
ok1
(
jmap_get
(
map
,
1
)
==
0
);
ok1
(
jmap_del
(
map
,
0
)
==
true
);
ok1
(
jmap_del
(
map
,
0
)
==
true
);
ok1
(
jmap_popcount
(
map
,
0
,
-
1
)
==
0
);
ok1
(
jmap_popcount
(
map
,
0
,
-
1
)
==
0
);
ok1
(
jmap_nth
(
map
,
0
,
0
)
==
0
);
ok1
(
jmap_nth
(
map
,
0
,
0
)
==
0
);
ok1
(
jmap_nth
(
map
,
0
,
-
1
)
==
(
size_t
)
-
1
);
ok1
(
jmap_nth
(
map
,
0
,
-
1
)
==
(
size_t
)
-
1
);
ok1
(
jmap_first
(
map
,
0
)
==
0
);
ok1
(
jmap_first
(
map
)
==
0
);
ok1
(
jmap_first
(
map
,
-
1
)
==
(
size_t
)
-
1
);
ok1
(
jmap_last
(
map
)
==
0
);
ok1
(
jmap_last
(
map
,
0
)
==
0
);
ok1
(
jmap_last
(
map
,
-
1
)
==
(
size_t
)
-
1
);
ok1
(
jmap_getval
(
map
,
0
)
==
NULL
);
ok1
(
jmap_getval
(
map
,
0
)
==
NULL
);
/* Map a million indices, 16 apart. */
/* Map a million indices, 16 apart. */
for
(
i
=
0
;
i
<
1000000
;
i
++
)
for
(
i
=
0
;
i
<
1000000
;
i
++
)
jmap_add
(
map
,
i
<<
4
,
(
i
<<
5
)
+
1
);
jmap_add
(
map
,
(
i
<<
4
)
+
1
,
(
i
<<
5
)
+
1
);
/* This only take 6.3MB on my 32-bit system. */
/* This only take 6.3MB on my 32-bit system. */
diag
(
"%u bytes memory used
\n
"
,
(
unsigned
)
JudyLMemUsed
(
map
->
judy
));
diag
(
"%u bytes memory used
\n
"
,
(
unsigned
)
JudyLMemUsed
(
map
->
raw
.
judy
));
ok1
(
jmap_get
(
map
,
0
,
-
1
)
==
1
);
ok1
(
jmap_get
(
map
,
1
)
==
1
);
ok1
(
jmap_get
(
map
,
999999
<<
4
,
-
1
)
==
(
999999
<<
5
)
+
1
);
ok1
(
jmap_get
(
map
,
(
999999
<<
4
)
+
1
)
==
(
999999
<<
5
)
+
1
);
ok1
(
jmap_popcount
(
map
,
0
,
-
1
)
==
1000000
);
ok1
(
jmap_popcount
(
map
,
0
,
-
1
)
==
1000000
);
ok1
(
jmap_nth
(
map
,
0
,
-
1
)
==
0
);
ok1
(
jmap_nth
(
map
,
0
,
-
1
)
==
1
);
ok1
(
jmap_nth
(
map
,
999999
,
-
1
)
==
999999
<<
4
);
ok1
(
jmap_nth
(
map
,
999999
,
-
1
)
==
(
999999
<<
4
)
+
1
);
ok1
(
jmap_nth
(
map
,
1000000
,
-
1
)
==
(
size_t
)
-
1
);
ok1
(
jmap_nth
(
map
,
1000000
,
-
1
)
==
(
size_t
)
-
1
);
ok1
(
jmap_first
(
map
,
-
1
)
==
0
);
ok1
(
jmap_first
(
map
)
==
1
);
ok1
(
jmap_last
(
map
,
-
1
)
==
999999
<<
4
);
ok1
(
jmap_last
(
map
)
==
(
999999
<<
4
)
+
1
);
ok1
(
jmap_next
(
map
,
0
,
-
1
)
==
1
<<
4
);
ok1
(
jmap_next
(
map
,
1
)
==
(
1
<<
4
)
+
1
);
ok1
(
jmap_next
(
map
,
999999
<<
4
,
-
1
)
==
(
size_t
)
-
1
);
ok1
(
jmap_next
(
map
,
(
999999
<<
4
)
+
1
)
==
0
);
ok1
(
jmap_prev
(
map
,
1
,
-
1
)
==
0
);
ok1
(
jmap_prev
(
map
,
2
)
==
1
);
ok1
(
jmap_prev
(
map
,
0
,
-
1
)
==
(
size_t
)
-
1
);
ok1
(
jmap_prev
(
map
,
0
)
==
0
);
ok1
(
jmap_error
(
map
)
==
NULL
);
ok1
(
jmap_error
(
map
)
==
NULL
);
/* Accessors. */
/* Accessors. */
value
=
jmap_getval
(
map
,
0
);
value
=
jmap_getval
(
map
,
1
);
ok1
(
value
&&
*
value
==
1
);
ok1
(
value
&&
*
value
==
1
);
*
value
=
2
;
*
value
=
2
;
ok1
(
jmap_get
(
map
,
0
,
-
1
)
==
2
);
ok1
(
jmap_get
(
map
,
1
)
==
2
);
jmap_putval
(
map
,
&
value
);
jmap_putval
(
map
,
&
value
);
ok1
(
jmap_get
(
map
,
0
,
-
1
)
==
2
);
ok1
(
jmap_get
(
map
,
1
)
==
2
);
ok1
(
jmap_set
(
map
,
0
,
1
));
ok1
(
jmap_set
(
map
,
1
,
1
));
value
=
jmap_getval
(
map
,
999999
<<
4
);
value
=
jmap_getval
(
map
,
(
999999
<<
4
)
+
1
);
ok1
(
value
&&
*
value
==
(
999999
<<
5
)
+
1
);
ok1
(
value
&&
*
value
==
(
999999
<<
5
)
+
1
);
jmap_putval
(
map
,
&
value
);
jmap_putval
(
map
,
&
value
);
value
=
jmap_nthval
(
map
,
0
,
&
i
);
value
=
jmap_nthval
(
map
,
0
,
&
i
);
ok1
(
i
==
0
);
ok1
(
i
==
1
);
ok1
(
value
&&
*
value
==
1
);
ok1
(
value
&&
*
value
==
1
);
jmap_putval
(
map
,
&
value
);
jmap_putval
(
map
,
&
value
);
value
=
jmap_nthval
(
map
,
999999
,
&
i
);
value
=
jmap_nthval
(
map
,
999999
,
&
i
);
ok1
(
i
==
999999
<<
4
);
ok1
(
i
==
(
999999
<<
4
)
+
1
);
ok1
(
value
&&
*
value
==
(
999999
<<
5
)
+
1
);
ok1
(
value
&&
*
value
==
(
999999
<<
5
)
+
1
);
jmap_putval
(
map
,
&
value
);
jmap_putval
(
map
,
&
value
);
ok1
(
jmap_nthval
(
map
,
1000000
,
&
i
)
==
NULL
);
ok1
(
jmap_nthval
(
map
,
1000000
,
&
i
)
==
NULL
);
value
=
jmap_firstval
(
map
,
&
i
);
value
=
jmap_firstval
(
map
,
&
i
);
ok1
(
i
==
0
);
ok1
(
i
==
1
);
ok1
(
value
&&
*
value
==
1
);
ok1
(
value
&&
*
value
==
1
);
jmap_putval
(
map
,
&
value
);
jmap_putval
(
map
,
&
value
);
ok1
(
jmap_prevval
(
map
,
&
i
)
==
NULL
);
ok1
(
jmap_prevval
(
map
,
&
i
)
==
NULL
);
i
=
0
;
i
=
1
;
value
=
jmap_nextval
(
map
,
&
i
);
value
=
jmap_nextval
(
map
,
&
i
);
ok1
(
i
==
1
<<
4
);
ok1
(
i
==
(
1
<<
4
)
+
1
);
ok1
(
value
&&
*
value
==
(
1
<<
5
)
+
1
);
ok1
(
value
&&
*
value
==
(
1
<<
5
)
+
1
);
jmap_putval
(
map
,
&
value
);
jmap_putval
(
map
,
&
value
);
value
=
jmap_lastval
(
map
,
&
i
);
value
=
jmap_lastval
(
map
,
&
i
);
ok1
(
i
==
999999
<<
4
);
ok1
(
i
==
(
999999
<<
4
)
+
1
);
ok1
(
value
&&
*
value
==
(
999999
<<
5
)
+
1
);
ok1
(
value
&&
*
value
==
(
999999
<<
5
)
+
1
);
jmap_putval
(
map
,
&
value
);
jmap_putval
(
map
,
&
value
);
ok1
(
jmap_nextval
(
map
,
&
i
)
==
NULL
);
ok1
(
jmap_nextval
(
map
,
&
i
)
==
NULL
);
i
=
999999
<<
4
;
i
=
(
999999
<<
4
)
+
1
;
value
=
jmap_prevval
(
map
,
&
i
);
value
=
jmap_prevval
(
map
,
&
i
);
ok1
(
i
==
999998
<<
4
);
ok1
(
i
==
(
999998
<<
4
)
+
1
);
ok1
(
value
&&
*
value
==
(
999998
<<
5
)
+
1
);
ok1
(
value
&&
*
value
==
(
999998
<<
5
)
+
1
);
jmap_putval
(
map
,
&
value
);
jmap_putval
(
map
,
&
value
);
/* Test error handling */
/* Test error handling */
JU_ERRNO
(
&
map
->
err
)
=
100
;
JU_ERRNO
(
&
map
->
raw
.
err
)
=
100
;
JU_ERRID
(
&
map
->
err
)
=
991
;
JU_ERRID
(
&
map
->
raw
.
err
)
=
991
;
err
=
jmap_error
(
map
);
err
=
jmap_error
(
map
);
ok1
(
err
);
ok1
(
err
);
ok1
(
strstr
(
err
,
"100"
));
ok1
(
strstr
(
err
,
"100"
));
ok1
(
strstr
(
err
,
"991"
));
ok1
(
strstr
(
err
,
"991"
));
ok1
(
err
==
map
->
errstr
);
ok1
(
err
==
map
->
raw
.
errstr
);
jmap_free
(
map
);
jmap_free
(
map
);
return
exit_status
();
return
exit_status
();
...
...
ccan/tcon/tcon.h
View file @
3a34aa1a
...
@@ -74,8 +74,10 @@
...
@@ -74,8 +74,10 @@
*/
*/
#if HAVE_TYPEOF
#if HAVE_TYPEOF
#define tcon_cast(x, canary, expr) ((__typeof__((x)->_tcon[0].canary))(expr))
#define tcon_cast(x, canary, expr) ((__typeof__((x)->_tcon[0].canary))(expr))
#define tcon_cast_ptr(x, canary, expr) ((__typeof__(&(x)->_tcon[0].canary))(expr))
#else
#else
#define tcon_cast(x, canary, expr) ((void *)(expr))
#define tcon_cast(x, canary, expr) ((void *)(expr))
#define tcon_cast_ptr(x, canary, expr) ((void *)(expr))
#endif
#endif
#endif
/* CCAN_TCON_H */
#endif
/* CCAN_TCON_H */
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