summaryrefslogtreecommitdiff
path: root/ccan/take
diff options
context:
space:
mode:
Diffstat (limited to 'ccan/take')
l---------ccan/take/LICENSE1
-rw-r--r--ccan/take/_info61
-rw-r--r--ccan/take/take.c115
-rw-r--r--ccan/take/take.h136
-rw-r--r--ccan/take/test/run-debug.c34
-rw-r--r--ccan/take/test/run.c102
6 files changed, 0 insertions, 449 deletions
diff --git a/ccan/take/LICENSE b/ccan/take/LICENSE
deleted file mode 120000
index b7951da..0000000
--- a/ccan/take/LICENSE
+++ /dev/null
@@ -1 +0,0 @@
-../../licenses/CC0 \ No newline at end of file
diff --git a/ccan/take/_info b/ccan/take/_info
deleted file mode 100644
index c8cc4ac..0000000
--- a/ccan/take/_info
+++ /dev/null
@@ -1,61 +0,0 @@
-#include "config.h"
-#include <stdio.h>
-#include <string.h>
-
-/**
- * take - routines to mark pointers to be consumed by called functions.
- *
- * This code helps to implement ownership transfer on a per-arg basis:
- * the caller wraps the pointer argument in take() and the callee checks
- * taken() to see if it should consume it.
- *
- * Author: Rusty Russell <rusty@rustcorp.com.au>
- * License: CC0 (Public domain)
- *
- * Example:
- * // Given "foo/bar.c" outputs basename is bar.c
- * #include <ccan/take/take.h>
- * #include <string.h>
- *
- * // Dumb basename program and driver.
- * static char *base(const char *file TAKES)
- * {
- * const char *p = strrchr(file, '/');
- * if (!p)
- * p = file;
- * else
- * p++;
- *
- * // Use arg in place if we're allowed.
- * if (taken(file))
- * return memmove((char *)file, p, strlen(p)+1);
- * else
- * return strdup(p);
- * }
- *
- * int main(int argc, char *argv[])
- * {
- * char *b;
- *
- * if (argc > 1) // Mangle in place.
- * b = base(take(argv[1]));
- * else
- * b = base("test/string");
- *
- * printf("basename is %s\n", b);
- * return 0;
- * }
- */
-int main(int argc, char *argv[])
-{
- if (argc != 2)
- return 1;
-
- if (strcmp(argv[1], "depends") == 0) {
- printf("ccan/likely\n");
- printf("ccan/str\n");
- return 0;
- }
-
- return 1;
-}
diff --git a/ccan/take/take.c b/ccan/take/take.c
deleted file mode 100644
index c628aac..0000000
--- a/ccan/take/take.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/* CC0 (Public domain) - see LICENSE file for details */
-#include <ccan/take/take.h>
-#include <ccan/likely/likely.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-static const void **takenarr;
-static const char **labelarr;
-static size_t max_taken, num_taken;
-static size_t allocfail;
-static void (*allocfailfn)(const void *p);
-
-void *take_(const void *p, const char *label)
-{
- /* Overallocate: it's better than risking calloc returning NULL! */
- if (unlikely(label && !labelarr))
- labelarr = calloc(max_taken+1, sizeof(*labelarr));
-
- if (unlikely(num_taken == max_taken)) {
- const void **new;
-
- new = realloc(takenarr, sizeof(*takenarr) * (max_taken+1));
- if (unlikely(!new)) {
- if (allocfailfn) {
- allocfail++;
- allocfailfn(p);
- return NULL;
- }
- /* Otherwise we leak p. */
- return (void *)p;
- }
- takenarr = new;
- /* Once labelarr is set, we maintain it. */
- if (labelarr)
- labelarr = realloc(labelarr,
- sizeof(*labelarr) * (max_taken+1));
- max_taken++;
- }
- if (unlikely(labelarr))
- labelarr[num_taken] = label;
- takenarr[num_taken++] = p;
-
- return (void *)p;
-}
-
-static size_t find_taken(const void *p)
-{
- size_t i;
-
- for (i = 0; i < num_taken; i++) {
- if (takenarr[i] == p)
- return i+1;
- }
- return 0;
-}
-
-bool taken(const void *p)
-{
- size_t i;
-
- if (!p && unlikely(allocfail)) {
- allocfail--;
- return true;
- }
-
- i = find_taken(p);
- if (!i)
- return false;
-
- memmove(&takenarr[i-1], &takenarr[i],
- (--num_taken - (i - 1))*sizeof(takenarr[0]));
- return true;
-}
-
-bool is_taken(const void *p)
-{
- if (!p && unlikely(allocfail))
- return true;
-
- return find_taken(p) > 0;
-}
-
-const char *taken_any(void)
-{
- static char pointer_buf[32];
-
- if (num_taken == 0)
- return NULL;
-
- /* We're *allowed* to have some with labels, some without. */
- if (labelarr) {
- size_t i;
- for (i = 0; i < num_taken; i++)
- if (labelarr[i])
- return labelarr[i];
- }
-
- sprintf(pointer_buf, "%p", takenarr[0]);
- return pointer_buf;
-}
-
-void take_cleanup(void)
-{
- max_taken = num_taken = 0;
- free(takenarr);
- takenarr = NULL;
- free(labelarr);
- labelarr = NULL;
-}
-
-void take_allocfail(void (*fn)(const void *p))
-{
- allocfailfn = fn;
-}
diff --git a/ccan/take/take.h b/ccan/take/take.h
deleted file mode 100644
index 8950c6b..0000000
--- a/ccan/take/take.h
+++ /dev/null
@@ -1,136 +0,0 @@
-/* CC0 (Public domain) - see LICENSE file for details */
-#ifndef CCAN_TAKE_H
-#define CCAN_TAKE_H
-#include "config.h"
-#include <stdbool.h>
-#include <ccan/str/str.h>
-
-#ifdef CCAN_TAKE_DEBUG
-#define TAKE_LABEL(p) __FILE__ ":" stringify(__LINE__) ":" stringify(p)
-#else
-#define TAKE_LABEL(p) NULL
-#endif
-
-/**
- * TAKES - annotate a formal parameter as being take()-able
- *
- * This doesn't do anything, but useful for documentation.
- *
- * Example:
- * void print_string(const char *str TAKES);
- *
- */
-#define TAKES
-
-/**
- * take - record a pointer to be consumed by the function its handed to.
- * @p: the pointer to mark, or NULL.
- *
- * This marks a pointer object to be freed by the called function,
- * which is extremely useful for chaining functions. It works on
- * NULL, for pass-through error handling.
- */
-#define take(p) (take_typeof(p) take_((p), TAKE_LABEL(p)))
-
-/**
- * taken - check (and un-take) a pointer was passed with take()
- * @p: the pointer to check.
- *
- * A function which accepts take() arguments uses this to see if it
- * should own the pointer; it will be removed from the take list, so
- * this only returns true once.
- *
- * Example:
- * // Silly routine to add 1
- * static int *add_one(const int *num TAKES)
- * {
- * int *ret;
- * if (taken(num))
- * ret = (int *)num;
- * else
- * ret = malloc(sizeof(int));
- * if (ret)
- * *ret = (*num) + 1;
- * return ret;
- * }
- */
-bool taken(const void *p);
-
-/**
- * is_taken - check if a pointer was passed with take()
- * @p: the pointer to check.
- *
- * This is like the above, but doesn't remove it from the taken list.
- *
- * Example:
- * // Silly routine to add 1: doesn't handle taken args!
- * static int *add_one_notake(const int *num)
- * {
- * int *ret = malloc(sizeof(int));
- * assert(!is_taken(num));
- * if (ret)
- * *ret = (*num) + 1;
- * return ret;
- * }
- */
-bool is_taken(const void *p);
-
-/**
- * taken_any - are there any taken pointers?
- *
- * Mainly useful for debugging take() leaks. With CCAN_TAKE_DEBUG, returns
- * the label where the pointer was passed to take(), otherwise returns
- * a static char buffer with the pointer value in it. NULL if none are taken.
- *
- * Example:
- * static void cleanup(void)
- * {
- * assert(!taken_any());
- * }
- */
-const char *taken_any(void);
-
-/**
- * take_cleanup - remove all taken pointers from list.
- *
- * This is useful in atexit() handlers for valgrind-style leak detection.
- *
- * Example:
- * static void cleanup2(void)
- * {
- * take_cleanup();
- * }
- */
-void take_cleanup(void);
-
-/**
- * take_allocfail - set function to call if we can't reallocated taken array.
- * @fn: the function.
- *
- * If this is not set, then if the array reallocation fails, the
- * pointer won't be marked taken(). If @fn returns, it is expected to
- * free the pointer; we return NULL from take() and the function handles
- * it like any allocation failure.
- *
- * Example:
- * static void free_on_fail(const void *p)
- * {
- * free((void *)p);
- * }
- *
- * static void init(void)
- * {
- * take_allocfail(free_on_fail);
- * }
- */
-void take_allocfail(void (*fn)(const void *p));
-
-/* Private functions */
-#if HAVE_TYPEOF
-#define take_typeof(ptr) (__typeof__(ptr))
-#else
-#define take_typeof(ptr)
-#endif
-
-void *take_(const void *p, const char *label);
-#endif /* CCAN_TAKE_H */
diff --git a/ccan/take/test/run-debug.c b/ccan/take/test/run-debug.c
deleted file mode 100644
index a9dda6e..0000000
--- a/ccan/take/test/run-debug.c
+++ /dev/null
@@ -1,34 +0,0 @@
-#include <stdlib.h>
-#include <stdbool.h>
-
-#define CCAN_TAKE_DEBUG 1
-#include <ccan/take/take.h>
-#include <ccan/take/take.c>
-#include <ccan/tap/tap.h>
-
-int main(void)
-{
- const char *p = "hi";
-
- plan_tests(14);
-
- /* We can take NULL. */
- ok1(take(NULL) == NULL);
- ok1(is_taken(NULL));
- ok1(strstr(taken_any(), "run-debug.c:16:"));
- ok1(taken(NULL)); /* Undoes take() */
- ok1(!is_taken(NULL));
- ok1(!taken(NULL));
- ok1(!taken_any());
-
- /* We can take a real pointer. */
- ok1(take(p) == p);
- ok1(is_taken(p));
- ok1(strends(taken_any(), "run-debug.c:25:p"));
- ok1(taken(p)); /* Undoes take() */
- ok1(!is_taken(p));
- ok1(!taken(p));
- ok1(!taken_any());
-
- return exit_status();
-}
diff --git a/ccan/take/test/run.c b/ccan/take/test/run.c
deleted file mode 100644
index ba170fb..0000000
--- a/ccan/take/test/run.c
+++ /dev/null
@@ -1,102 +0,0 @@
-#include <stdlib.h>
-#include <stdbool.h>
-
-static bool fail_realloc;
-static void *my_realloc(void *p, size_t len)
-{
- if (fail_realloc)
- return NULL;
- return realloc(p, len);
-}
-#define realloc my_realloc
-
-#include <ccan/take/take.h>
-#include <ccan/take/take.c>
-#include <ccan/tap/tap.h>
-
-static int my_allocfail_called;
-static void my_allocfail(const void *p UNNEEDED)
-{
- my_allocfail_called++;
-}
-
-static void recurse(const char *takeme, int count)
-{
- if (count < 1000)
- recurse(take(strdup(takeme)), count+1);
- if (taken(takeme))
- free((char *)takeme);
-}
-
-int main(void)
-{
- const char *p = "hi";
-
- plan_tests(43);
-
- /* We can take NULL. */
- ok1(take(NULL) == NULL);
- ok1(is_taken(NULL));
- ok1(taken_any());
- ok1(taken(NULL)); /* Undoes take() */
- ok1(!is_taken(NULL));
- ok1(!taken(NULL));
-
- /* We can take NULL twice! */
- ok1(take(NULL) == NULL);
- ok1(take(NULL) == NULL);
- ok1(is_taken(NULL));
- ok1(taken_any());
- ok1(taken(NULL)); /* Undoes take() */
- ok1(is_taken(NULL));
- ok1(taken_any());
- ok1(taken(NULL)); /* Undoes take() */
- ok1(!is_taken(NULL));
- ok1(!taken(NULL));
- ok1(!taken_any());
-
- /* We can take a real pointer. */
- ok1(take(p) == p);
- ok1(is_taken(p));
- ok1(taken_any());
- ok1(taken(p)); /* Undoes take() */
- ok1(!is_taken(p));
- ok1(!taken(p));
- ok1(!taken_any());
-
- /* Force a failure. */
- ok1(!my_allocfail_called);
- ok1(take(p) == p);
- ok1(take(p+1) == p+1);
-
- fail_realloc = true;
- /* Without a handler, must pass through and leak. */
- ok1(take(p+2) == p+2);
- ok1(!taken(p+2));
-
- /* Now, with a handler. */
- take_allocfail(my_allocfail);
- ok1(take(p+2) == NULL);
-
- ok1(my_allocfail_called == 1);
- ok1(taken_any());
- ok1(taken(p));
- ok1(taken(p+1));
- ok1(is_taken(NULL));
- ok1(taken(NULL));
- ok1(!taken(NULL));
- ok1(!taken_any());
-
- /* Test some deep nesting. */
- fail_realloc = false;
- recurse("hello", 0);
- ok1(max_taken == 1000);
- ok1(!taken_any());
-
- take_cleanup();
- ok1(num_taken == 0);
- ok1(max_taken == 0);
- ok1(takenarr == NULL);
-
- return exit_status();
-}