nostrdb

an unfairly fast embedded nostr database backed by lmdb
git clone git://jb55.com/nostrdb
Log | Files | Refs | Submodules | README | LICENSE

commit dc1254eea5867bdf52d7618e2848c55324ed7516
parent a937eb3f12f80497a90a1f6f1c6dbc11a07b3c00
Author: Rusty Russell <rusty@rustcorp.com.au>
Date:   Sat, 17 Aug 2024 14:57:12 +0930

src: delete copies outside ccan/ dirs.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>


Diffstat:
Dsrc/bolt11/alignof.h | 20--------------------
Dsrc/bolt11/array_size.h | 26--------------------------
Dsrc/bolt11/build_assert.h | 40----------------------------------------
Dsrc/bolt11/check_type.h | 64----------------------------------------------------------------
Dsrc/bolt11/container_of.h | 145-------------------------------------------------------------------------------
Dsrc/bolt11/cppmagic.h | 191-------------------------------------------------------------------------------
Dsrc/bolt11/likely.h | 115-------------------------------------------------------------------------------
Dsrc/bolt11/list.c | 43-------------------------------------------
Dsrc/bolt11/list.h | 842-------------------------------------------------------------------------------
Dsrc/bolt11/mem.c | 128-------------------------------------------------------------------------------
Dsrc/bolt11/mem.h | 295-------------------------------------------------------------------------------
Dsrc/bolt11/short_types.h | 35-----------------------------------
Dsrc/bolt11/structeq.h | 46----------------------------------------------
Dsrc/bolt11/take.c | 126-------------------------------------------------------------------------------
Dsrc/bolt11/take.h | 136-------------------------------------------------------------------------------
Dsrc/bolt11/tal.c | 972-------------------------------------------------------------------------------
Dsrc/bolt11/tal.h | 553-------------------------------------------------------------------------------
Dsrc/bolt11/talstr.c | 315-------------------------------------------------------------------------------
Dsrc/bolt11/talstr.h | 225-------------------------------------------------------------------------------
Dsrc/bolt11/typesafe_cb.h | 134-------------------------------------------------------------------------------
Dsrc/bolt11/utf8.c | 199-------------------------------------------------------------------------------
Dsrc/bolt11/utf8.h | 55-------------------------------------------------------
Dsrc/compiler.h | 323-------------------------------------------------------------------------------
Msrc/cursor.h | 2+-
Dsrc/endian.h | 365-------------------------------------------------------------------------------
Dsrc/sha256.c | 302------------------------------------------------------------------------------
Dsrc/sha256.h | 155-------------------------------------------------------------------------------
27 files changed, 1 insertion(+), 5851 deletions(-)

diff --git a/src/bolt11/alignof.h b/src/bolt11/alignof.h @@ -1,20 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#ifndef CCAN_ALIGNOF_H -#define CCAN_ALIGNOF_H -#include "../config.h" - -/** - * ALIGNOF - get the alignment of a type - * @t: the type to test - * - * This returns a safe alignment for the given type. - */ -#if HAVE_ALIGNOF -/* A GCC extension. */ -#define ALIGNOF(t) __alignof__(t) -#else -/* Alignment by measuring structure padding. */ -#define ALIGNOF(t) ((char *)(&((struct { char c; t _h; } *)0)->_h) - (char *)0) -#endif - -#endif /* CCAN_ALIGNOF_H */ diff --git a/src/bolt11/array_size.h b/src/bolt11/array_size.h @@ -1,26 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#ifndef CCAN_ARRAY_SIZE_H -#define CCAN_ARRAY_SIZE_H -#include "../config.h" -#include "build_assert.h" - -/** - * ARRAY_SIZE - get the number of elements in a visible array - * @arr: the array whose size you want. - * - * This does not work on pointers, or arrays declared as [], or - * function parameters. With correct compiler support, such usage - * will cause a build error (see build_assert). - */ -#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + _array_size_chk(arr)) - -#if HAVE_BUILTIN_TYPES_COMPATIBLE_P && HAVE_TYPEOF -/* Two gcc extensions. - * &a[0] degrades to a pointer: a different type from an array */ -#define _array_size_chk(arr) \ - BUILD_ASSERT_OR_ZERO(!__builtin_types_compatible_p(typeof(arr), \ - typeof(&(arr)[0]))) -#else -#define _array_size_chk(arr) 0 -#endif -#endif /* CCAN_ALIGNOF_H */ diff --git a/src/bolt11/build_assert.h b/src/bolt11/build_assert.h @@ -1,40 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#ifndef CCAN_BUILD_ASSERT_H -#define CCAN_BUILD_ASSERT_H - -/** - * BUILD_ASSERT - assert a build-time dependency. - * @cond: the compile-time condition which must be true. - * - * Your compile will fail if the condition isn't true, or can't be evaluated - * by the compiler. This can only be used within a function. - * - * Example: - * #include <stddef.h> - * ... - * static char *foo_to_char(struct foo *foo) - * { - * // This code needs string to be at start of foo. - * BUILD_ASSERT(offsetof(struct foo, string) == 0); - * return (char *)foo; - * } - */ -#define BUILD_ASSERT(cond) \ - do { (void) sizeof(char [1 - 2*!(cond)]); } while(0) - -/** - * BUILD_ASSERT_OR_ZERO - assert a build-time dependency, as an expression. - * @cond: the compile-time condition which must be true. - * - * Your compile will fail if the condition isn't true, or can't be evaluated - * by the compiler. This can be used in an expression: its value is "0". - * - * Example: - * #define foo_to_char(foo) \ - * ((char *)(foo) \ - * + BUILD_ASSERT_OR_ZERO(offsetof(struct foo, string) == 0)) - */ -#define BUILD_ASSERT_OR_ZERO(cond) \ - (sizeof(char [1 - 2*!(cond)]) - 1) - -#endif /* CCAN_BUILD_ASSERT_H */ diff --git a/src/bolt11/check_type.h b/src/bolt11/check_type.h @@ -1,64 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#ifndef CCAN_CHECK_TYPE_H -#define CCAN_CHECK_TYPE_H -#include "../config.h" - -/** - * check_type - issue a warning or build failure if type is not correct. - * @expr: the expression whose type we should check (not evaluated). - * @type: the exact type we expect the expression to be. - * - * This macro is usually used within other macros to try to ensure that a macro - * argument is of the expected type. No type promotion of the expression is - * done: an unsigned int is not the same as an int! - * - * check_type() always evaluates to 0. - * - * If your compiler does not support typeof, then the best we can do is fail - * to compile if the sizes of the types are unequal (a less complete check). - * - * Example: - * // They should always pass a 64-bit value to _set_some_value! - * #define set_some_value(expr) \ - * _set_some_value((check_type((expr), uint64_t), (expr))) - */ - -/** - * check_types_match - issue a warning or build failure if types are not same. - * @expr1: the first expression (not evaluated). - * @expr2: the second expression (not evaluated). - * - * This macro is usually used within other macros to try to ensure that - * arguments are of identical types. No type promotion of the expressions is - * done: an unsigned int is not the same as an int! - * - * check_types_match() always evaluates to 0. - * - * If your compiler does not support typeof, then the best we can do is fail - * to compile if the sizes of the types are unequal (a less complete check). - * - * Example: - * // Do subtraction to get to enclosing type, but make sure that - * // pointer is of correct type for that member. - * #define container_of(mbr_ptr, encl_type, mbr) \ - * (check_types_match((mbr_ptr), &((encl_type *)0)->mbr), \ - * ((encl_type *) \ - * ((char *)(mbr_ptr) - offsetof(encl_type, mbr)))) - */ -#if HAVE_TYPEOF -#define check_type(expr, type) \ - ((typeof(expr) *)0 != (type *)0) - -#define check_types_match(expr1, expr2) \ - ((typeof(expr1) *)0 != (typeof(expr2) *)0) -#else -#include <ccan/build_assert/build_assert.h> -/* Without typeof, we can only test the sizes. */ -#define check_type(expr, type) \ - BUILD_ASSERT_OR_ZERO(sizeof(expr) == sizeof(type)) - -#define check_types_match(expr1, expr2) \ - BUILD_ASSERT_OR_ZERO(sizeof(expr1) == sizeof(expr2)) -#endif /* HAVE_TYPEOF */ - -#endif /* CCAN_CHECK_TYPE_H */ diff --git a/src/bolt11/container_of.h b/src/bolt11/container_of.h @@ -1,145 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#ifndef CCAN_CONTAINER_OF_H -#define CCAN_CONTAINER_OF_H -#include <stddef.h> - -#include "../config.h" -#include "check_type.h" - -/** - * container_of - get pointer to enclosing structure - * @member_ptr: pointer to the structure member - * @containing_type: the type this member is within - * @member: the name of this member within the structure. - * - * Given a pointer to a member of a structure, this macro does pointer - * subtraction to return the pointer to the enclosing type. - * - * Example: - * struct foo { - * int fielda, fieldb; - * // ... - * }; - * struct info { - * int some_other_field; - * struct foo my_foo; - * }; - * - * static struct info *foo_to_info(struct foo *foo) - * { - * return container_of(foo, struct info, my_foo); - * } - */ -#define container_of(member_ptr, containing_type, member) \ - ((containing_type *) \ - ((char *)(member_ptr) \ - - container_off(containing_type, member)) \ - + check_types_match(*(member_ptr), ((containing_type *)0)->member)) - - -/** - * container_of_or_null - get pointer to enclosing structure, or NULL - * @member_ptr: pointer to the structure member - * @containing_type: the type this member is within - * @member: the name of this member within the structure. - * - * Given a pointer to a member of a structure, this macro does pointer - * subtraction to return the pointer to the enclosing type, unless it - * is given NULL, in which case it also returns NULL. - * - * Example: - * struct foo { - * int fielda, fieldb; - * // ... - * }; - * struct info { - * int some_other_field; - * struct foo my_foo; - * }; - * - * static struct info *foo_to_info_allowing_null(struct foo *foo) - * { - * return container_of_or_null(foo, struct info, my_foo); - * } - */ -static inline char *container_of_or_null_(void *member_ptr, size_t offset) -{ - return member_ptr ? (char *)member_ptr - offset : NULL; -} -#define container_of_or_null(member_ptr, containing_type, member) \ - ((containing_type *) \ - container_of_or_null_(member_ptr, \ - container_off(containing_type, member)) \ - + check_types_match(*(member_ptr), ((containing_type *)0)->member)) - -/** - * container_off - get offset to enclosing structure - * @containing_type: the type this member is within - * @member: the name of this member within the structure. - * - * Given a pointer to a member of a structure, this macro does - * typechecking and figures out the offset to the enclosing type. - * - * Example: - * struct foo { - * int fielda, fieldb; - * // ... - * }; - * struct info { - * int some_other_field; - * struct foo my_foo; - * }; - * - * static struct info *foo_to_info(struct foo *foo) - * { - * size_t off = container_off(struct info, my_foo); - * return (void *)((char *)foo - off); - * } - */ -#define container_off(containing_type, member) \ - offsetof(containing_type, member) - -/** - * container_of_var - get pointer to enclosing structure using a variable - * @member_ptr: pointer to the structure member - * @container_var: a pointer of same type as this member's container - * @member: the name of this member within the structure. - * - * Given a pointer to a member of a structure, this macro does pointer - * subtraction to return the pointer to the enclosing type. - * - * Example: - * static struct info *foo_to_i(struct foo *foo) - * { - * struct info *i = container_of_var(foo, i, my_foo); - * return i; - * } - */ -#if HAVE_TYPEOF -#define container_of_var(member_ptr, container_var, member) \ - container_of(member_ptr, typeof(*container_var), member) -#else -#define container_of_var(member_ptr, container_var, member) \ - ((void *)((char *)(member_ptr) - \ - container_off_var(container_var, member))) -#endif - -/** - * container_off_var - get offset of a field in enclosing structure - * @container_var: a pointer to a container structure - * @member: the name of a member within the structure. - * - * Given (any) pointer to a structure and a its member name, this - * macro does pointer subtraction to return offset of member in a - * structure memory layout. - * - */ -#if HAVE_TYPEOF -#define container_off_var(var, member) \ - container_off(typeof(*var), member) -#else -#define container_off_var(var, member) \ - ((const char *)&(var)->member - (const char *)(var)) -#endif - -#endif /* CCAN_CONTAINER_OF_H */ diff --git a/src/bolt11/cppmagic.h b/src/bolt11/cppmagic.h @@ -1,191 +0,0 @@ -/* MIT (BSD) license - see LICENSE file for details */ -#ifndef CCAN_CPPMAGIC_H -#define CCAN_CPPMAGIC_H - -/** - * CPPMAGIC_NOTHING - expands to nothing - */ -#define CPPMAGIC_NOTHING() - -/** - * CPPMAGIC_STRINGIFY - convert arguments to a string literal - */ -#define _CPPMAGIC_STRINGIFY(...) #__VA_ARGS__ -#define CPPMAGIC_STRINGIFY(...) _CPPMAGIC_STRINGIFY(__VA_ARGS__) - -/** - * CPPMAGIC_GLUE2 - glue arguments together - * - * CPPMAGIC_GLUE2(@a_, @b_) - * expands to the expansion of @a_ followed immediately - * (combining tokens) by the expansion of @b_ - */ -#define _CPPMAGIC_GLUE2(a_, b_) a_##b_ -#define CPPMAGIC_GLUE2(a_, b_) _CPPMAGIC_GLUE2(a_, b_) - -/** - * CPPMAGIC_1ST - return 1st argument - * - * CPPMAGIC_1ST(@a_, ...) - * expands to the expansion of @a_ - */ -#define CPPMAGIC_1ST(a_, ...) a_ - -/** - * CPPMAGIC_2ND - return 2nd argument - * - * CPPMAGIC_2ST(@a_, @b_, ...) - * expands to the expansion of @b_ - */ -#define CPPMAGIC_2ND(a_, b_, ...) b_ - -/** - * CPPMAGIC_ISZERO - is argument '0' - * - * CPPMAGIC_ISZERO(@a) - * expands to '1' if @a is '0', otherwise expands to '0'. - */ -#define _CPPMAGIC_ISPROBE(...) CPPMAGIC_2ND(__VA_ARGS__, 0) -#define _CPPMAGIC_PROBE() $, 1 -#define _CPPMAGIC_ISZERO_0 _CPPMAGIC_PROBE() -#define CPPMAGIC_ISZERO(a_) \ - _CPPMAGIC_ISPROBE(CPPMAGIC_GLUE2(_CPPMAGIC_ISZERO_, a_)) - -/** - * CPPMAGIC_NONZERO - is argument not '0' - * - * CPPMAGIC_NONZERO(@a) - * expands to '0' if @a is '0', otherwise expands to '1'. - */ -#define CPPMAGIC_NONZERO(a_) CPPMAGIC_ISZERO(CPPMAGIC_ISZERO(a_)) - -/** - * CPPMAGIC_NONEMPTY - does the macro have any arguments? - * - * CPPMAGIC_NONEMPTY() - * expands to '0' - * CPPMAGIC_NONEMPTY(@a) - * CPPMAGIC_NONEMPTY(@a, ...) - * expand to '1' - */ -#define _CPPMAGIC_EOA() 0 -#define CPPMAGIC_NONEMPTY(...) \ - CPPMAGIC_NONZERO(CPPMAGIC_1ST(_CPPMAGIC_EOA __VA_ARGS__)()) - -/** - * CPPMAGIC_ISEMPTY - does the macro have no arguments? - * - * CPPMAGIC_ISEMPTY() - * expands to '1' - * CPPMAGIC_ISEMPTY(@a) - * CPPMAGIC_ISEMPTY(@a, ...) - * expand to '0' - */ -#define CPPMAGIC_ISEMPTY(...) \ - CPPMAGIC_ISZERO(CPPMAGIC_NONEMPTY(__VA_ARGS__)) - -/* - * CPPMAGIC_IFELSE - preprocessor conditional - * - * CPPMAGIC_IFELSE(@cond)(@if)(@else) - * expands to @else if @cond is '0', otherwise expands to @if - */ -#define _CPPMAGIC_IF_0(...) _CPPMAGIC_IF_0_ELSE -#define _CPPMAGIC_IF_1(...) __VA_ARGS__ _CPPMAGIC_IF_1_ELSE -#define _CPPMAGIC_IF_0_ELSE(...) __VA_ARGS__ -#define _CPPMAGIC_IF_1_ELSE(...) -#define _CPPMAGIC_IFELSE(cond_) CPPMAGIC_GLUE2(_CPPMAGIC_IF_, cond_) -#define CPPMAGIC_IFELSE(cond_) \ - _CPPMAGIC_IFELSE(CPPMAGIC_NONZERO(cond_)) - -/** - * CPPMAGIC_EVAL - force multiple expansion passes - * - * Forces macros in the arguments to be expanded repeatedly (up to - * 1024 times) even when CPP would usually stop expanding. - */ -#define CPPMAGIC_EVAL1(...) __VA_ARGS__ -#define CPPMAGIC_EVAL2(...) \ - CPPMAGIC_EVAL1(CPPMAGIC_EVAL1(__VA_ARGS__)) -#define CPPMAGIC_EVAL4(...) \ - CPPMAGIC_EVAL2(CPPMAGIC_EVAL2(__VA_ARGS__)) -#define CPPMAGIC_EVAL8(...) \ - CPPMAGIC_EVAL4(CPPMAGIC_EVAL4(__VA_ARGS__)) -#define CPPMAGIC_EVAL16(...) \ - CPPMAGIC_EVAL8(CPPMAGIC_EVAL8(__VA_ARGS__)) -#define CPPMAGIC_EVAL32(...) \ - CPPMAGIC_EVAL16(CPPMAGIC_EVAL16(__VA_ARGS__)) -#define CPPMAGIC_EVAL64(...) \ - CPPMAGIC_EVAL32(CPPMAGIC_EVAL32(__VA_ARGS__)) -#define CPPMAGIC_EVAL128(...) \ - CPPMAGIC_EVAL64(CPPMAGIC_EVAL64(__VA_ARGS__)) -#define CPPMAGIC_EVAL256(...) \ - CPPMAGIC_EVAL128(CPPMAGIC_EVAL128(__VA_ARGS__)) -#define CPPMAGIC_EVAL512(...) \ - CPPMAGIC_EVAL256(CPPMAGIC_EVAL256(__VA_ARGS__)) -#define CPPMAGIC_EVAL1024(...) \ - CPPMAGIC_EVAL512(CPPMAGIC_EVAL512(__VA_ARGS__)) -#define CPPMAGIC_EVAL(...) CPPMAGIC_EVAL1024(__VA_ARGS__) - -/** - * CPPMAGIC_DEFER1, CPPMAGIC_DEFER2 - defer expansion - */ -#define CPPMAGIC_DEFER1(a_) a_ CPPMAGIC_NOTHING() -#define CPPMAGIC_DEFER2(a_) a_ CPPMAGIC_NOTHING CPPMAGIC_NOTHING()() - -/** - * CPPMAGIC_MAP - iterate another macro across arguments - * @m: name of a one argument macro - * - * CPPMAGIC_MAP(@m, @a1, @a2, ... @an) - * expands to the expansion of @m(@a1) , @m(@a2) , ... , @m(@an) - */ -#define _CPPMAGIC_MAP_() _CPPMAGIC_MAP -#define _CPPMAGIC_MAP(m_, a_, ...) \ - m_(a_) \ - CPPMAGIC_IFELSE(CPPMAGIC_NONEMPTY(__VA_ARGS__)) \ - (, CPPMAGIC_DEFER2(_CPPMAGIC_MAP_)()(m_, __VA_ARGS__)) \ - () -#define CPPMAGIC_MAP(m_, ...) \ - CPPMAGIC_IFELSE(CPPMAGIC_NONEMPTY(__VA_ARGS__)) \ - (CPPMAGIC_EVAL(_CPPMAGIC_MAP(m_, __VA_ARGS__))) \ - () - -/** - * CPPMAGIC_2MAP - iterate another macro across pairs of arguments - * @m: name of a two argument macro - * - * CPPMAGIC_2MAP(@m, @a1, @b1, @a2, @b2, ..., @an, @bn) - * expands to the expansion of - * @m(@a1, @b1) , @m(@a2, @b2) , ... , @m(@an, @bn) - */ -#define _CPPMAGIC_2MAP_() _CPPMAGIC_2MAP -#define _CPPMAGIC_2MAP(m_, a_, b_, ...) \ - m_(a_, b_) \ - CPPMAGIC_IFELSE(CPPMAGIC_NONEMPTY(__VA_ARGS__)) \ - (, CPPMAGIC_DEFER2(_CPPMAGIC_2MAP_)()(m_, __VA_ARGS__)) \ - () -#define CPPMAGIC_2MAP(m_, ...) \ - CPPMAGIC_IFELSE(CPPMAGIC_NONEMPTY(__VA_ARGS__)) \ - (CPPMAGIC_EVAL(_CPPMAGIC_2MAP(m_, __VA_ARGS__))) \ - () - -/** - * CPPMAGIC_JOIN - separate arguments with given delimiter - * @d: delimiter - * - * CPPMAGIC_JOIN(@d, @a1, @a2, ..., @an) - * expands to the expansion of @a1 @d @a2 @d ... @d @an - */ -#define _CPPMAGIC_JOIN_() _CPPMAGIC_JOIN -#define _CPPMAGIC_JOIN(d_, a_, ...) \ - a_ \ - CPPMAGIC_IFELSE(CPPMAGIC_NONEMPTY(__VA_ARGS__)) \ - (d_ CPPMAGIC_DEFER2(_CPPMAGIC_JOIN_)()(d_, __VA_ARGS__)) \ - () -#define CPPMAGIC_JOIN(d_, ...) \ - CPPMAGIC_IFELSE(CPPMAGIC_NONEMPTY(__VA_ARGS__)) \ - (CPPMAGIC_EVAL(_CPPMAGIC_JOIN(d_, __VA_ARGS__))) \ - () - -#endif /* CCAN_CPPMAGIC_H */ diff --git a/src/bolt11/likely.h b/src/bolt11/likely.h @@ -1,115 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#ifndef CCAN_LIKELY_H -#define CCAN_LIKELY_H -#include "../config.h" -#include <stdbool.h> - -#ifndef CCAN_LIKELY_DEBUG -#if HAVE_BUILTIN_EXPECT -/** - * likely - indicate that a condition is likely to be true. - * @cond: the condition - * - * This uses a compiler extension where available to indicate a likely - * code path and optimize appropriately; it's also useful for readers - * to quickly identify exceptional paths through functions. The - * threshold for "likely" is usually considered to be between 90 and - * 99%; marginal cases should not be marked either way. - * - * See Also: - * unlikely(), likely_stats() - * - * Example: - * // Returns false if we overflow. - * static inline bool inc_int(unsigned int *val) - * { - * (*val)++; - * if (likely(*val)) - * return true; - * return false; - * } - */ -#define likely(cond) __builtin_expect(!!(cond), 1) - -/** - * unlikely - indicate that a condition is unlikely to be true. - * @cond: the condition - * - * This uses a compiler extension where available to indicate an unlikely - * code path and optimize appropriately; see likely() above. - * - * See Also: - * likely(), likely_stats(), COLD (compiler.h) - * - * Example: - * // Prints a warning if we overflow. - * static inline void inc_int(unsigned int *val) - * { - * (*val)++; - * if (unlikely(*val == 0)) - * fprintf(stderr, "Overflow!"); - * } - */ -#define unlikely(cond) __builtin_expect(!!(cond), 0) -#else -#ifndef likely -#define likely(cond) (!!(cond)) -#endif -#ifndef unlikely -#define unlikely(cond) (!!(cond)) -#endif -#endif -#else /* CCAN_LIKELY_DEBUG versions */ -#include <ccan/str/str.h> - -#define likely(cond) \ - (_likely_trace(!!(cond), 1, stringify(cond), __FILE__, __LINE__)) -#define unlikely(cond) \ - (_likely_trace(!!(cond), 0, stringify(cond), __FILE__, __LINE__)) - -long _likely_trace(bool cond, bool expect, - const char *condstr, - const char *file, unsigned int line); -/** - * likely_stats - return description of abused likely()/unlikely() - * @min_hits: minimum number of hits - * @percent: maximum percentage correct - * - * When CCAN_LIKELY_DEBUG is defined, likely() and unlikely() trace their - * results: this causes a significant slowdown, but allows analysis of - * whether the branches are labelled correctly. - * - * This function returns a malloc'ed description of the least-correct - * usage of likely() or unlikely(). It ignores places which have been - * called less than @min_hits times, and those which were predicted - * correctly more than @percent of the time. It returns NULL when - * nothing meets those criteria. - * - * Note that this call is destructive; the returned offender is - * removed from the trace so that the next call to likely_stats() will - * return the next-worst likely()/unlikely() usage. - * - * Example: - * // Print every place hit more than twice which was wrong > 5%. - * static void report_stats(void) - * { - * #ifdef CCAN_LIKELY_DEBUG - * const char *bad; - * - * while ((bad = likely_stats(2, 95)) != NULL) { - * printf("Suspicious likely: %s", bad); - * free(bad); - * } - * #endif - * } - */ -char *likely_stats(unsigned int min_hits, unsigned int percent); - -/** - * likely_stats_reset - free up memory of likely()/unlikely() branches. - * - * This can also plug memory leaks. - */ -void likely_stats_reset(void); -#endif /* CCAN_LIKELY_DEBUG */ -#endif /* CCAN_LIKELY_H */ diff --git a/src/bolt11/list.c b/src/bolt11/list.c @@ -1,43 +0,0 @@ -/* Licensed under BSD-MIT - see LICENSE file for details */ -#include <stdio.h> -#include <stdlib.h> -#include "list.h" - -static void *corrupt(const char *abortstr, - const struct list_node *head, - const struct list_node *node, - unsigned int count) -{ - if (abortstr) { - fprintf(stderr, - "%s: prev corrupt in node %p (%u) of %p\n", - abortstr, node, count, head); - abort(); - } - return NULL; -} - -struct list_node *list_check_node(const struct list_node *node, - const char *abortstr) -{ - const struct list_node *p, *n; - int count = 0; - - for (p = node, n = node->next; n != node; p = n, n = n->next) { - count++; - if (n->prev != p) - return corrupt(abortstr, node, n, count); - } - /* Check prev on head node. */ - if (node->prev != p) - return corrupt(abortstr, node, node, 0); - - return (struct list_node *)node; -} - -struct list_head *list_check(const struct list_head *h, const char *abortstr) -{ - if (!list_check_node(&h->n, abortstr)) - return NULL; - return (struct list_head *)h; -} diff --git a/src/bolt11/list.h b/src/bolt11/list.h @@ -1,842 +0,0 @@ -/* Licensed under BSD-MIT - see LICENSE file for details */ -#ifndef CCAN_LIST_H -#define CCAN_LIST_H -//#define CCAN_LIST_DEBUG 1 -#include <stdbool.h> -#include <assert.h> -#include "str.h" -#include "container_of.h" -#include "check_type.h" - -/** - * struct list_node - an entry in a doubly-linked list - * @next: next entry (self if empty) - * @prev: previous entry (self if empty) - * - * This is used as an entry in a linked list. - * Example: - * struct child { - * const char *name; - * // Linked list of all us children. - * struct list_node list; - * }; - */ -struct list_node -{ - struct list_node *next, *prev; -}; - -/** - * struct list_head - the head of a doubly-linked list - * @h: the list_head (containing next and prev pointers) - * - * This is used as the head of a linked list. - * Example: - * struct parent { - * const char *name; - * struct list_head children; - * unsigned int num_children; - * }; - */ -struct list_head -{ - struct list_node n; -}; - -/** - * list_check - check head of a list for consistency - * @h: the list_head - * @abortstr: the location to print on aborting, or NULL. - * - * Because list_nodes have redundant information, consistency checking between - * the back and forward links can be done. This is useful as a debugging check. - * If @abortstr is non-NULL, that will be printed in a diagnostic if the list - * is inconsistent, and the function will abort. - * - * Returns the list head if the list is consistent, NULL if not (it - * can never return NULL if @abortstr is set). - * - * See also: list_check_node() - * - * Example: - * static void dump_parent(struct parent *p) - * { - * struct child *c; - * - * printf("%s (%u children):\n", p->name, p->num_children); - * list_check(&p->children, "bad child list"); - * list_for_each(&p->children, c, list) - * printf(" -> %s\n", c->name); - * } - */ -struct list_head *list_check(const struct list_head *h, const char *abortstr); - -/** - * list_check_node - check node of a list for consistency - * @n: the list_node - * @abortstr: the location to print on aborting, or NULL. - * - * Check consistency of the list node is in (it must be in one). - * - * See also: list_check() - * - * Example: - * static void dump_child(const struct child *c) - * { - * list_check_node(&c->list, "bad child list"); - * printf("%s\n", c->name); - * } - */ -struct list_node *list_check_node(const struct list_node *n, - const char *abortstr); - -#define LIST_LOC __FILE__ ":" stringify(__LINE__) -#ifdef CCAN_LIST_DEBUG -#define list_debug(h, loc) list_check((h), loc) -#define list_debug_node(n, loc) list_check_node((n), loc) -#else -#define list_debug(h, loc) ((void)loc, h) -#define list_debug_node(n, loc) ((void)loc, n) -#endif - -/** - * LIST_HEAD_INIT - initializer for an empty list_head - * @name: the name of the list. - * - * Explicit initializer for an empty list. - * - * See also: - * LIST_HEAD, list_head_init() - * - * Example: - * static struct list_head my_list = LIST_HEAD_INIT(my_list); - */ -#define LIST_HEAD_INIT(name) { { &(name).n, &(name).n } } - -/** - * LIST_HEAD - define and initialize an empty list_head - * @name: the name of the list. - * - * The LIST_HEAD macro defines a list_head and initializes it to an empty - * list. It can be prepended by "static" to define a static list_head. - * - * See also: - * LIST_HEAD_INIT, list_head_init() - * - * Example: - * static LIST_HEAD(my_global_list); - */ -#define LIST_HEAD(name) \ - struct list_head name = LIST_HEAD_INIT(name) - -/** - * list_head_init - initialize a list_head - * @h: the list_head to set to the empty list - * - * Example: - * ... - * struct parent *parent = malloc(sizeof(*parent)); - * - * list_head_init(&parent->children); - * parent->num_children = 0; - */ -static inline void list_head_init(struct list_head *h) -{ - h->n.next = h->n.prev = &h->n; -} - -/** - * list_node_init - initialize a list_node - * @n: the list_node to link to itself. - * - * You don't need to use this normally! But it lets you list_del(@n) - * safely. - */ -static inline void list_node_init(struct list_node *n) -{ - n->next = n->prev = n; -} - -/** - * list_add_after - add an entry after an existing node in a linked list - * @h: the list_head to add the node to (for debugging) - * @p: the existing list_node to add the node after - * @n: the new list_node to add to the list. - * - * The existing list_node must already be a member of the list. - * The new list_node does not need to be initialized; it will be overwritten. - * - * Example: - * struct child c1, c2, c3; - * LIST_HEAD(h); - * - * list_add_tail(&h, &c1.list); - * list_add_tail(&h, &c3.list); - * list_add_after(&h, &c1.list, &c2.list); - */ -#define list_add_after(h, p, n) list_add_after_(h, p, n, LIST_LOC) -static inline void list_add_after_(struct list_head *h, - struct list_node *p, - struct list_node *n, - const char *abortstr) -{ - n->next = p->next; - n->prev = p; - p->next->prev = n; - p->next = n; - (void)list_debug(h, abortstr); -} - -/** - * list_add - add an entry at the start of a linked list. - * @h: the list_head to add the node to - * @n: the list_node to add to the list. - * - * The list_node does not need to be initialized; it will be overwritten. - * Example: - * struct child *child = malloc(sizeof(*child)); - * - * child->name = "marvin"; - * list_add(&parent->children, &child->list); - * parent->num_children++; - */ -#define list_add(h, n) list_add_(h, n, LIST_LOC) -static inline void list_add_(struct list_head *h, - struct list_node *n, - const char *abortstr) -{ - list_add_after_(h, &h->n, n, abortstr); -} - -/** - * list_add_before - add an entry before an existing node in a linked list - * @h: the list_head to add the node to (for debugging) - * @p: the existing list_node to add the node before - * @n: the new list_node to add to the list. - * - * The existing list_node must already be a member of the list. - * The new list_node does not need to be initialized; it will be overwritten. - * - * Example: - * list_head_init(&h); - * list_add_tail(&h, &c1.list); - * list_add_tail(&h, &c3.list); - * list_add_before(&h, &c3.list, &c2.list); - */ -#define list_add_before(h, p, n) list_add_before_(h, p, n, LIST_LOC) -static inline void list_add_before_(struct list_head *h, - struct list_node *p, - struct list_node *n, - const char *abortstr) -{ - n->next = p; - n->prev = p->prev; - p->prev->next = n; - p->prev = n; - (void)list_debug(h, abortstr); -} - -/** - * list_add_tail - add an entry at the end of a linked list. - * @h: the list_head to add the node to - * @n: the list_node to add to the list. - * - * The list_node does not need to be initialized; it will be overwritten. - * Example: - * list_add_tail(&parent->children, &child->list); - * parent->num_children++; - */ -#define list_add_tail(h, n) list_add_tail_(h, n, LIST_LOC) -static inline void list_add_tail_(struct list_head *h, - struct list_node *n, - const char *abortstr) -{ - list_add_before_(h, &h->n, n, abortstr); -} - -/** - * list_empty - is a list empty? - * @h: the list_head - * - * If the list is empty, returns true. - * - * Example: - * assert(list_empty(&parent->children) == (parent->num_children == 0)); - */ -#define list_empty(h) list_empty_(h, LIST_LOC) -static inline bool list_empty_(const struct list_head *h, const char* abortstr) -{ - (void)list_debug(h, abortstr); - return h->n.next == &h->n; -} - -/** - * list_empty_nodebug - is a list empty (and don't perform debug checks)? - * @h: the list_head - * - * If the list is empty, returns true. - * This differs from list_empty() in that if CCAN_LIST_DEBUG is set it - * will NOT perform debug checks. Only use this function if you REALLY - * know what you're doing. - * - * Example: - * assert(list_empty_nodebug(&parent->children) == (parent->num_children == 0)); - */ -#ifndef CCAN_LIST_DEBUG -#define list_empty_nodebug(h) list_empty(h) -#else -static inline bool list_empty_nodebug(const struct list_head *h) -{ - return h->n.next == &h->n; -} -#endif - -/** - * list_empty_nocheck - is a list empty? - * @h: the list_head - * - * If the list is empty, returns true. This doesn't perform any - * debug check for list consistency, so it can be called without - * locks, racing with the list being modified. This is ok for - * checks where an incorrect result is not an issue (optimized - * bail out path for example). - */ -static inline bool list_empty_nocheck(const struct list_head *h) -{ - return h->n.next == &h->n; -} - -/** - * list_del - delete an entry from an (unknown) linked list. - * @n: the list_node to delete from the list. - * - * Note that this leaves @n in an undefined state; it can be added to - * another list, but not deleted again. - * - * See also: - * list_del_from(), list_del_init() - * - * Example: - * list_del(&child->list); - * parent->num_children--; - */ -#define list_del(n) list_del_(n, LIST_LOC) -static inline void list_del_(struct list_node *n, const char* abortstr) -{ - (void)list_debug_node(n, abortstr); - n->next->prev = n->prev; - n->prev->next = n->next; -#ifdef CCAN_LIST_DEBUG - /* Catch use-after-del. */ - n->next = n->prev = NULL; -#endif -} - -/** - * list_del_init - delete a node, and reset it so it can be deleted again. - * @n: the list_node to be deleted. - * - * list_del(@n) or list_del_init() again after this will be safe, - * which can be useful in some cases. - * - * See also: - * list_del_from(), list_del() - * - * Example: - * list_del_init(&child->list); - * parent->num_children--; - */ -#define list_del_init(n) list_del_init_(n, LIST_LOC) -static inline void list_del_init_(struct list_node *n, const char *abortstr) -{ - list_del_(n, abortstr); - list_node_init(n); -} - -/** - * list_del_from - delete an entry from a known linked list. - * @h: the list_head the node is in. - * @n: the list_node to delete from the list. - * - * This explicitly indicates which list a node is expected to be in, - * which is better documentation and can catch more bugs. - * - * See also: list_del() - * - * Example: - * list_del_from(&parent->children, &child->list); - * parent->num_children--; - */ -static inline void list_del_from(struct list_head *h, struct list_node *n) -{ -#ifdef CCAN_LIST_DEBUG - { - /* Thorough check: make sure it was in list! */ - struct list_node *i; - for (i = h->n.next; i != n; i = i->next) - assert(i != &h->n); - } -#endif /* CCAN_LIST_DEBUG */ - - /* Quick test that catches a surprising number of bugs. */ - assert(!list_empty(h)); - list_del(n); -} - -/** - * list_swap - swap out an entry from an (unknown) linked list for a new one. - * @o: the list_node to replace from the list. - * @n: the list_node to insert in place of the old one. - * - * Note that this leaves @o in an undefined state; it can be added to - * another list, but not deleted/swapped again. - * - * See also: - * list_del() - * - * Example: - * struct child x1, x2; - * LIST_HEAD(xh); - * - * list_add(&xh, &x1.list); - * list_swap(&x1.list, &x2.list); - */ -#define list_swap(o, n) list_swap_(o, n, LIST_LOC) -static inline void list_swap_(struct list_node *o, - struct list_node *n, - const char* abortstr) -{ - (void)list_debug_node(o, abortstr); - *n = *o; - n->next->prev = n; - n->prev->next = n; -#ifdef CCAN_LIST_DEBUG - /* Catch use-after-del. */ - o->next = o->prev = NULL; -#endif -} - -/** - * list_entry - convert a list_node back into the structure containing it. - * @n: the list_node - * @type: the type of the entry - * @member: the list_node member of the type - * - * Example: - * // First list entry is children.next; convert back to child. - * child = list_entry(parent->children.n.next, struct child, list); - * - * See Also: - * list_top(), list_for_each() - */ -#define list_entry(n, type, member) container_of(n, type, member) - -/** - * list_top - get the first entry in a list - * @h: the list_head - * @type: the type of the entry - * @member: the list_node member of the type - * - * If the list is empty, returns NULL. - * - * Example: - * struct child *first; - * first = list_top(&parent->children, struct child, list); - * if (!first) - * printf("Empty list!\n"); - */ -#define list_top(h, type, member) \ - ((type *)list_top_((h), list_off_(type, member))) - -static inline const void *list_top_(const struct list_head *h, size_t off) -{ - if (list_empty(h)) - return NULL; - return (const char *)h->n.next - off; -} - -/** - * list_pop - remove the first entry in a list - * @h: the list_head - * @type: the type of the entry - * @member: the list_node member of the type - * - * If the list is empty, returns NULL. - * - * Example: - * struct child *one; - * one = list_pop(&parent->children, struct child, list); - * if (!one) - * printf("Empty list!\n"); - */ -#define list_pop(h, type, member) \ - ((type *)list_pop_((h), list_off_(type, member))) - -static inline const void *list_pop_(const struct list_head *h, size_t off) -{ - struct list_node *n; - - if (list_empty(h)) - return NULL; - n = h->n.next; - list_del(n); - return (const char *)n - off; -} - -/** - * list_tail - get the last entry in a list - * @h: the list_head - * @type: the type of the entry - * @member: the list_node member of the type - * - * If the list is empty, returns NULL. - * - * Example: - * struct child *last; - * last = list_tail(&parent->children, struct child, list); - * if (!last) - * printf("Empty list!\n"); - */ -#define list_tail(h, type, member) \ - ((type *)list_tail_((h), list_off_(type, member))) - -static inline const void *list_tail_(const struct list_head *h, size_t off) -{ - if (list_empty(h)) - return NULL; - return (const char *)h->n.prev - off; -} - -/** - * list_for_each - iterate through a list. - * @h: the list_head (warning: evaluated multiple times!) - * @i: the structure containing the list_node - * @member: the list_node member of the structure - * - * This is a convenient wrapper to iterate @i over the entire list. It's - * a for loop, so you can break and continue as normal. - * - * Example: - * list_for_each(&parent->children, child, list) - * printf("Name: %s\n", child->name); - */ -#define list_for_each(h, i, member) \ - list_for_each_off(h, i, list_off_var_(i, member)) - -/** - * list_for_each_rev - iterate through a list backwards. - * @h: the list_head - * @i: the structure containing the list_node - * @member: the list_node member of the structure - * - * This is a convenient wrapper to iterate @i over the entire list. It's - * a for loop, so you can break and continue as normal. - * - * Example: - * list_for_each_rev(&parent->children, child, list) - * printf("Name: %s\n", child->name); - */ -#define list_for_each_rev(h, i, member) \ - list_for_each_rev_off(h, i, list_off_var_(i, member)) - -/** - * list_for_each_rev_safe - iterate through a list backwards, - * maybe during deletion - * @h: the list_head - * @i: the structure containing the list_node - * @nxt: the structure containing the list_node - * @member: the list_node member of the structure - * - * This is a convenient wrapper to iterate @i over the entire list backwards. - * It's a for loop, so you can break and continue as normal. The extra - * variable * @nxt is used to hold the next element, so you can delete @i - * from the list. - * - * Example: - * struct child *next; - * list_for_each_rev_safe(&parent->children, child, next, list) { - * printf("Name: %s\n", child->name); - * } - */ -#define list_for_each_rev_safe(h, i, nxt, member) \ - list_for_each_rev_safe_off(h, i, nxt, list_off_var_(i, member)) - -/** - * list_for_each_safe - iterate through a list, maybe during deletion - * @h: the list_head - * @i: the structure containing the list_node - * @nxt: the structure containing the list_node - * @member: the list_node member of the structure - * - * This is a convenient wrapper to iterate @i over the entire list. It's - * a for loop, so you can break and continue as normal. The extra variable - * @nxt is used to hold the next element, so you can delete @i from the list. - * - * Example: - * list_for_each_safe(&parent->children, child, next, list) { - * list_del(&child->list); - * parent->num_children--; - * } - */ -#define list_for_each_safe(h, i, nxt, member) \ - list_for_each_safe_off(h, i, nxt, list_off_var_(i, member)) - -/** - * list_next - get the next entry in a list - * @h: the list_head - * @i: a pointer to an entry in the list. - * @member: the list_node member of the structure - * - * If @i was the last entry in the list, returns NULL. - * - * Example: - * struct child *second; - * second = list_next(&parent->children, first, list); - * if (!second) - * printf("No second child!\n"); - */ -#define list_next(h, i, member) \ - ((list_typeof(i))list_entry_or_null(list_debug(h, \ - __FILE__ ":" stringify(__LINE__)), \ - (i)->member.next, \ - list_off_var_((i), member))) - -/** - * list_prev - get the previous entry in a list - * @h: the list_head - * @i: a pointer to an entry in the list. - * @member: the list_node member of the structure - * - * If @i was the first entry in the list, returns NULL. - * - * Example: - * first = list_prev(&parent->children, second, list); - * if (!first) - * printf("Can't go back to first child?!\n"); - */ -#define list_prev(h, i, member) \ - ((list_typeof(i))list_entry_or_null(list_debug(h, \ - __FILE__ ":" stringify(__LINE__)), \ - (i)->member.prev, \ - list_off_var_((i), member))) - -/** - * list_append_list - empty one list onto the end of another. - * @to: the list to append into - * @from: the list to empty. - * - * This takes the entire contents of @from and moves it to the end of - * @to. After this @from will be empty. - * - * Example: - * struct list_head adopter; - * - * list_append_list(&adopter, &parent->children); - * assert(list_empty(&parent->children)); - * parent->num_children = 0; - */ -#define list_append_list(t, f) list_append_list_(t, f, \ - __FILE__ ":" stringify(__LINE__)) -static inline void list_append_list_(struct list_head *to, - struct list_head *from, - const char *abortstr) -{ - struct list_node *from_tail = list_debug(from, abortstr)->n.prev; - struct list_node *to_tail = list_debug(to, abortstr)->n.prev; - - /* Sew in head and entire list. */ - to->n.prev = from_tail; - from_tail->next = &to->n; - to_tail->next = &from->n; - from->n.prev = to_tail; - - /* Now remove head. */ - list_del(&from->n); - list_head_init(from); -} - -/** - * list_prepend_list - empty one list into the start of another. - * @to: the list to prepend into - * @from: the list to empty. - * - * This takes the entire contents of @from and moves it to the start - * of @to. After this @from will be empty. - * - * Example: - * list_prepend_list(&adopter, &parent->children); - * assert(list_empty(&parent->children)); - * parent->num_children = 0; - */ -#define list_prepend_list(t, f) list_prepend_list_(t, f, LIST_LOC) -static inline void list_prepend_list_(struct list_head *to, - struct list_head *from, - const char *abortstr) -{ - struct list_node *from_tail = list_debug(from, abortstr)->n.prev; - struct list_node *to_head = list_debug(to, abortstr)->n.next; - - /* Sew in head and entire list. */ - to->n.next = &from->n; - from->n.prev = &to->n; - to_head->prev = from_tail; - from_tail->next = to_head; - - /* Now remove head. */ - list_del(&from->n); - list_head_init(from); -} - -/* internal macros, do not use directly */ -#define list_for_each_off_dir_(h, i, off, dir) \ - for (i = list_node_to_off_(list_debug(h, LIST_LOC)->n.dir, \ - (off)); \ - list_node_from_off_((void *)i, (off)) != &(h)->n; \ - i = list_node_to_off_(list_node_from_off_((void *)i, (off))->dir, \ - (off))) - -#define list_for_each_safe_off_dir_(h, i, nxt, off, dir) \ - for (i = list_node_to_off_(list_debug(h, LIST_LOC)->n.dir, \ - (off)), \ - nxt = list_node_to_off_(list_node_from_off_(i, (off))->dir, \ - (off)); \ - list_node_from_off_(i, (off)) != &(h)->n; \ - i = nxt, \ - nxt = list_node_to_off_(list_node_from_off_(i, (off))->dir, \ - (off))) - -/** - * list_for_each_off - iterate through a list of memory regions. - * @h: the list_head - * @i: the pointer to a memory region which contains list node data. - * @off: offset(relative to @i) at which list node data resides. - * - * This is a low-level wrapper to iterate @i over the entire list, used to - * implement all oher, more high-level, for-each constructs. It's a for loop, - * so you can break and continue as normal. - * - * WARNING! Being the low-level macro that it is, this wrapper doesn't know - * nor care about the type of @i. The only assumption made is that @i points - * to a chunk of memory that at some @offset, relative to @i, contains a - * properly filled `struct list_node' which in turn contains pointers to - * memory chunks and it's turtles all the way down. With all that in mind - * remember that given the wrong pointer/offset couple this macro will - * happily churn all you memory until SEGFAULT stops it, in other words - * caveat emptor. - * - * It is worth mentioning that one of legitimate use-cases for that wrapper - * is operation on opaque types with known offset for `struct list_node' - * member(preferably 0), because it allows you not to disclose the type of - * @i. - * - * Example: - * list_for_each_off(&parent->children, child, - * offsetof(struct child, list)) - * printf("Name: %s\n", child->name); - */ -#define list_for_each_off(h, i, off) \ - list_for_each_off_dir_((h),(i),(off),next) - -/** - * list_for_each_rev_off - iterate through a list of memory regions backwards - * @h: the list_head - * @i: the pointer to a memory region which contains list node data. - * @off: offset(relative to @i) at which list node data resides. - * - * See list_for_each_off for details - */ -#define list_for_each_rev_off(h, i, off) \ - list_for_each_off_dir_((h),(i),(off),prev) - -/** - * list_for_each_safe_off - iterate through a list of memory regions, maybe - * during deletion - * @h: the list_head - * @i: the pointer to a memory region which contains list node data. - * @nxt: the structure containing the list_node - * @off: offset(relative to @i) at which list node data resides. - * - * For details see `list_for_each_off' and `list_for_each_safe' - * descriptions. - * - * Example: - * list_for_each_safe_off(&parent->children, child, - * next, offsetof(struct child, list)) - * printf("Name: %s\n", child->name); - */ -#define list_for_each_safe_off(h, i, nxt, off) \ - list_for_each_safe_off_dir_((h),(i),(nxt),(off),next) - -/** - * list_for_each_rev_safe_off - iterate backwards through a list of - * memory regions, maybe during deletion - * @h: the list_head - * @i: the pointer to a memory region which contains list node data. - * @nxt: the structure containing the list_node - * @off: offset(relative to @i) at which list node data resides. - * - * For details see `list_for_each_rev_off' and `list_for_each_rev_safe' - * descriptions. - * - * Example: - * list_for_each_rev_safe_off(&parent->children, child, - * next, offsetof(struct child, list)) - * printf("Name: %s\n", child->name); - */ -#define list_for_each_rev_safe_off(h, i, nxt, off) \ - list_for_each_safe_off_dir_((h),(i),(nxt),(off),prev) - -/* Other -off variants. */ -#define list_entry_off(n, type, off) \ - ((type *)list_node_from_off_((n), (off))) - -#define list_head_off(h, type, off) \ - ((type *)list_head_off((h), (off))) - -#define list_tail_off(h, type, off) \ - ((type *)list_tail_((h), (off))) - -#define list_add_off(h, n, off) \ - list_add((h), list_node_from_off_((n), (off))) - -#define list_del_off(n, off) \ - list_del(list_node_from_off_((n), (off))) - -#define list_del_from_off(h, n, off) \ - list_del_from(h, list_node_from_off_((n), (off))) - -/* Offset helper functions so we only single-evaluate. */ -static inline void *list_node_to_off_(struct list_node *node, size_t off) -{ - return (void *)((char *)node - off); -} -static inline struct list_node *list_node_from_off_(void *ptr, size_t off) -{ - return (struct list_node *)((char *)ptr + off); -} - -/* Get the offset of the member, but make sure it's a list_node. */ -#define list_off_(type, member) \ - (container_off(type, member) + \ - check_type(((type *)0)->member, struct list_node)) - -#define list_off_var_(var, member) \ - (container_off_var(var, member) + \ - check_type(var->member, struct list_node)) - -#if HAVE_TYPEOF -#define list_typeof(var) typeof(var) -#else -#define list_typeof(var) void * -#endif - -/* Returns member, or NULL if at end of list. */ -static inline void *list_entry_or_null(const struct list_head *h, - const struct list_node *n, - size_t off) -{ - if (n == &h->n) - return NULL; - return (char *)n - off; -} -#endif /* CCAN_LIST_H */ diff --git a/src/bolt11/mem.c b/src/bolt11/mem.c @@ -1,128 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ - -#include "config.h" - -#include <assert.h> -#include <string.h> -#include "mem.h" - -#if !HAVE_MEMMEM -void *memmem(const void *haystack, size_t haystacklen, - const void *needle, size_t needlelen) -{ - const char *p; - - if (needlelen > haystacklen) - return NULL; - - p = haystack; - - for (p = haystack; - (p + needlelen) <= ((const char *)haystack + haystacklen); - p++) - if (memcmp(p, needle, needlelen) == 0) - return (void *)p; - - return NULL; -} -#endif - -#if !HAVE_MEMRCHR -void *memrchr(const void *s, int c, size_t n) -{ - unsigned char *p = (unsigned char *)s; - - while (n) { - if (p[n-1] == c) - return p + n - 1; - n--; - } - - return NULL; -} -#endif - -void *mempbrkm(const void *data_, size_t len, const void *accept_, size_t accept_len) -{ - const char *data = data_, *accept = accept_; - size_t i, j; - - for (i = 0; i < len; i++) - for (j = 0; j < accept_len; j++) - if (accept[j] == data[i]) - return (void *)&data[i]; - return NULL; -} - -void *memcchr(void const *data, int c, size_t data_len) -{ - char const *p = data; - size_t i; - - for (i = 0; i < data_len; i++) - if (p[i] != c) - return (void *)&p[i]; - - return NULL; -} - -#define MEMSWAP_TMP_SIZE 256 - -void memswap(void *a, void *b, size_t n) -{ - char *ap = a; - char *bp = b; - char tmp[MEMSWAP_TMP_SIZE]; - - assert(!memoverlaps(a, n, b, n)); - - while (n) { - size_t m = n > MEMSWAP_TMP_SIZE ? MEMSWAP_TMP_SIZE : n; - - memcpy(tmp, bp, m); - memcpy(bp, ap, m); - memcpy(ap, tmp, m); - - ap += m; - bp += m; - n -= m; - } -} - -bool memeqzero(const void *data, size_t length) -{ - const unsigned char *p = data; - size_t len; - - /* Check first 16 bytes manually */ - for (len = 0; len < 16; len++) { - if (!length) - return true; - if (*p) - return false; - p++; - length--; - } - - /* Now we know that's zero, memcmp with self. */ - return memcmp(data, p, length) == 0; -} - -void memtaint(void *data, size_t len) -{ - /* Using 16 bytes is a bit quicker than 4 */ - const unsigned tainter[] - = { 0xdeadbeef, 0xdeadbeef, 0xdeadbeef, 0xdeadbeef }; - char *p = data; - - while (len >= sizeof(tainter)) { - memcpy(p, tainter, sizeof(tainter)); - p += sizeof(tainter); - len -= sizeof(tainter); - } - memcpy(p, tainter, len); - -#if HAVE_VALGRIND_MEMCHECK_H - VALGRIND_MAKE_MEM_UNDEFINED(data, len); -#endif -} diff --git a/src/bolt11/mem.h b/src/bolt11/mem.h @@ -1,295 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#ifndef CCAN_MEM_H -#define CCAN_MEM_H - -#include "../config.h" -#include "../compiler.h" - -#include <string.h> -#include <stdbool.h> - -#if !HAVE_MEMMEM -PURE_FUNCTION -void *memmem(const void *haystack, size_t haystacklen, - const void *needle, size_t needlelen); -#endif - -#if !HAVE_MEMRCHR -PURE_FUNCTION -void *memrchr(const void *s, int c, size_t n); -#endif - -/** - * mempbrkm - locates the first occurrence in @data of any bytes in @accept - * @data: where we search - * @len: length of data in bytes - * @accept: array of bytes we search for - * @accept_len: # of bytes in accept - * - * Returns a pointer to the byte in @data that matches one of the bytes in - * @accept, or NULL if no such byte is found. - * - * Example: - * char otherbytes[] = "Hello \0world"; - * size_t otherbytes_len = sizeof(otherbytes) - 1; - * char *r = mempbrkm(otherbytes, otherbytes_len, "\0b", 2); - * if (r) { - * printf("Found %c\n", *r); - * } else { - * printf("Nada\n"); - * } - * - */ -PURE_FUNCTION -void *mempbrkm(const void *data, size_t len, const void *accept, size_t accept_len); - -/** - * mempbrk - locates the first occurrence in @data of any bytes in @accept - * @data: where we search - * @len: length of data in bytes - * @accept: NUL terminated string containing the bytes we search for - * - * Returns a pointer to the byte in @data that matches one of the bytes in - * @accept, or NULL if no such byte is found. - * - * Example: - * - * r = mempbrk(otherbytes, otherbytes_len, "abcde"); - * if (r) { - * printf("Found %c\n", *r); - * } else { - * printf("Nada\n"); - * } - */ -PURE_FUNCTION -static inline char *mempbrk(const void *data, size_t len, const char *accept) -{ - return mempbrkm(data, len, accept, strlen(accept)); -} - -/** - * memcchr - scan memory until a character does _not_ match - * @data: pointer to memory to scan - * @data_len: length of data - * @c: character to scan for - * - * The complement of memchr(). - * - * Returns a pointer to the first character which is _not_ @c. If all memory in - * @data is @c, returns NULL. - * - * Example: - * char somebytes[] = "HI By\0e"; - * size_t bytes_len = sizeof(somebytes) - 1; - * r = memcchr(somebytes, ' ', bytes_len); - * if (r) { - * printf("Found %c after trimming spaces\n", *r); - * } - */ -PURE_FUNCTION -void *memcchr(void const *data, int c, size_t data_len); - -/** - * memeq - Are two byte arrays equal? - * @a: first array - * @al: bytes in first array - * @b: second array - * @bl: bytes in second array - * - * Example: - * if (memeq(somebytes, bytes_len, otherbytes, otherbytes_len)) { - * printf("memory blocks are the same!\n"); - * } - */ -PURE_FUNCTION -static inline bool memeq(const void *a, size_t al, const void *b, size_t bl) -{ - return al == bl && !memcmp(a, b, bl); -} - -/** - * memstarts - determine if @data starts with @prefix - * @data: does this begin with @prefix? - * @data_len: bytes in @data - * @prefix: does @data begin with these bytes? - * @prefix_len: bytes in @prefix - * - * Returns true if @data starts with @prefix, otherwise return false. - * - * Example: - * if (memstarts(somebytes, bytes_len, otherbytes, otherbytes_len)) { - * printf("somebytes starts with otherbytes!\n"); - * } - */ -PURE_FUNCTION -static inline bool memstarts(void const *data, size_t data_len, - void const *prefix, size_t prefix_len) -{ - if (prefix_len > data_len) - return false; - return memeq(data, prefix_len, prefix, prefix_len); -} - -/** - * memeqstr - Is a byte array equal to a NUL terminated string? - * @data: byte array - * @length: length of @data in bytes - * @string: NUL terminated string - * - * The '\0' byte is ignored when checking if @bytes == @string. - * - * Example: - * if (memeqstr(somebytes, bytes_len, "foo")) { - * printf("somebytes == 'foo'!\n"); - * } - */ -PURE_FUNCTION -static inline bool memeqstr(const void *data, size_t length, const char *string) -{ - return memeq(data, length, string, strlen(string)); -} - -/** - * memeqzero - Is a byte array all zeroes? - * @data: byte array - * @length: length of @data in bytes - * - * Example: - * if (memeqzero(somebytes, bytes_len)) { - * printf("somebytes == 0!\n"); - * } - */ -PURE_FUNCTION -bool memeqzero(const void *data, size_t length); - -/** - * memstarts_str - Does this byte array start with a string prefix? - * @a: byte array - * @al: length in bytes - * @s: string prefix - * - * Example: - * if (memstarts_str(somebytes, bytes_len, "It")) { - * printf("somebytes starts with 'It'\n"); - * } - */ -PURE_FUNCTION -static inline bool memstarts_str(const void *a, size_t al, const char *s) -{ - return memstarts(a, al, s, strlen(s)); -} - -/** - * memends - Does this byte array end with a given byte-array suffix? - * @s: byte array - * @s_len: length in bytes - * @suffix: byte array suffix - * @suffix_len: length of suffix in bytes - * - * Returns true if @suffix appears as a substring at the end of @s, - * false otherwise. - */ -PURE_FUNCTION -static inline bool memends(const void *s, size_t s_len, const void *suffix, size_t suffix_len) -{ - return (s_len >= suffix_len) && (memcmp((const char *)s + s_len - suffix_len, - suffix, suffix_len) == 0); -} - -/** - * memends_str - Does this byte array end with a string suffix? - * @a: byte array - * @al: length in bytes - * @s: string suffix - * - * Example: - * if (memends_str(somebytes, bytes_len, "It")) { - * printf("somebytes ends with with 'It'\n"); - * } - */ -PURE_FUNCTION -static inline bool memends_str(const void *a, size_t al, const char *s) -{ - return memends(a, al, s, strlen(s)); -} - -/** - * memoverlaps - Do two memory ranges overlap? - * @a: pointer to first memory range - * @al: length of first memory range - * @b: pointer to second memory range - * @al: length of second memory range - */ -CONST_FUNCTION -static inline bool memoverlaps(const void *a_, size_t al, - const void *b_, size_t bl) -{ - const char *a = a_; - const char *b = b_; - - return (a < (b + bl)) && (b < (a + al)); -} - -/* - * memswap - Exchange two memory regions - * @a: first region - * @b: second region - * @n: length of the regions - * - * Undefined results if the two memory regions overlap. - */ -void memswap(void *a, void *b, size_t n); - -#if HAVE_VALGRIND_MEMCHECK_H -#include <valgrind/memcheck.h> -static inline void *memcheck_(const void *data, size_t len) -{ - VALGRIND_CHECK_MEM_IS_DEFINED(data, len); - return (void *)data; -} -#else -static inline void *memcheck_(const void *data, size_t len) -{ - (void)len; - return (void *)data; -} -#endif - -#if HAVE_TYPEOF -/** - * memcheck - check that a memory region is initialized - * @data: start of region - * @len: length in bytes - * - * When running under valgrind, this causes an error to be printed - * if the entire region is not defined. Otherwise valgrind only - * reports an error when an undefined value is used for a branch, or - * written out. - * - * Example: - * // Search for space, but make sure it's all initialized. - * if (memchr(memcheck(somebytes, bytes_len), ' ', bytes_len)) { - * printf("space was found!\n"); - * } - */ -#define memcheck(data, len) ((__typeof__((data)+0))memcheck_((data), (len))) -#else -#define memcheck(data, len) memcheck_((data), (len)) -#endif - -/** - * memtaint - mark a memory region unused - * @data: start of region - * @len: length in bytes - * - * This writes an "0xdeadbeef" eyecatcher repeatedly to the memory. - * When running under valgrind, it also tells valgrind that the memory is - * uninitialized, triggering valgrind errors if it is used for branches - * or written out (or passed to memcheck!) in future. - * - * Example: - * // We'll reuse this buffer later, but be sure we don't access it. - * memtaint(somebytes, bytes_len); - */ -void memtaint(void *data, size_t len); -#endif /* CCAN_MEM_H */ diff --git a/src/bolt11/short_types.h b/src/bolt11/short_types.h @@ -1,35 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#ifndef CCAN_SHORT_TYPES_H -#define CCAN_SHORT_TYPES_H -#include <stdint.h> - -/** - * u64/s64/u32/s32/u16/s16/u8/s8 - short names for explicitly-sized types. - */ -typedef uint64_t u64; -typedef int64_t s64; -typedef uint32_t u32; -typedef int32_t s32; -typedef uint16_t u16; -typedef int16_t s16; -typedef uint8_t u8; -typedef int8_t s8; - -/* Whichever they include first, they get these definitions. */ -#ifdef CCAN_ENDIAN_H -/** - * be64/be32/be16 - 64/32/16 bit big-endian representation. - */ -typedef beint64_t be64; -typedef beint32_t be32; -typedef beint16_t be16; - -/** - * le64/le32/le16 - 64/32/16 bit little-endian representation. - */ -typedef leint64_t le64; -typedef leint32_t le32; -typedef leint16_t le16; -#endif - -#endif /* CCAN_SHORT_TYPES_H */ diff --git a/src/bolt11/structeq.h b/src/bolt11/structeq.h @@ -1,46 +0,0 @@ -/* MIT (BSD) license - see LICENSE file for details */ -#ifndef CCAN_STRUCTEQ_H -#define CCAN_STRUCTEQ_H -#include "build_assert.h" -#include "cppmagic.h" -#include <string.h> -#include <stdbool.h> - -/** - * STRUCTEQ_DEF - define an ..._eq function to compare two structures. - * @sname: name of the structure, and function (<sname>_eq) to define. - * @padbytes: number of bytes of expected padding, or negative "max". - * @...: name of every member of the structure. - * - * This generates a single memcmp() call in the common case where the - * structure contains no padding. Since it can't tell the difference between - * padding and a missing member, @padbytes can be used to assert that - * there isn't any, or how many we expect. A negative number means - * "up to or equal to that amount of padding", as padding can be - * platform dependent. - */ -#define STRUCTEQ_DEF(sname, padbytes, ...) \ -static inline bool CPPMAGIC_GLUE2(sname, _eq)(const struct sname *_a, \ - const struct sname *_b) \ -{ \ - BUILD_ASSERT(((padbytes) < 0 && \ - CPPMAGIC_JOIN(+, CPPMAGIC_MAP(STRUCTEQ_MEMBER_SIZE_, \ - __VA_ARGS__)) \ - - (padbytes) >= sizeof(*_a)) \ - || CPPMAGIC_JOIN(+, CPPMAGIC_MAP(STRUCTEQ_MEMBER_SIZE_, \ - __VA_ARGS__)) \ - + (padbytes) == sizeof(*_a)); \ - if (CPPMAGIC_JOIN(+, CPPMAGIC_MAP(STRUCTEQ_MEMBER_SIZE_, __VA_ARGS__)) \ - == sizeof(*_a)) \ - return memcmp(_a, _b, sizeof(*_a)) == 0; \ - else \ - return CPPMAGIC_JOIN(&&, \ - CPPMAGIC_MAP(STRUCTEQ_MEMBER_CMP_, \ - __VA_ARGS__)); \ -} - -/* Helpers */ -#define STRUCTEQ_MEMBER_SIZE_(m) sizeof((_a)->m) -#define STRUCTEQ_MEMBER_CMP_(m) memcmp(&_a->m, &_b->m, sizeof(_a->m)) == 0 - -#endif /* CCAN_STRUCTEQ_H */ diff --git a/src/bolt11/take.c b/src/bolt11/take.c @@ -1,126 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#include "take.h" -#include "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) { - const char **labelarr_new; - labelarr_new = realloc(labelarr, - sizeof(*labelarr) * (max_taken+1)); - if (labelarr_new) { - labelarr = labelarr_new; - } else { - /* num_taken will be out of sync with the size of - * labelarr after realloc failure. - * Just pretend that we never had labelarr allocated. */ - free(labelarr); - labelarr = NULL; - } - } - 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/src/bolt11/take.h b/src/bolt11/take.h @@ -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 "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/src/bolt11/tal.c b/src/bolt11/tal.c @@ -1,972 +0,0 @@ -/* Licensed under BSD-MIT - see LICENSE file for details */ -#include "tal.h" -#include "../compiler.h" -#include "list.h" -#include "alignof.h" - -#include <assert.h> -#include <stdio.h> -#include <stddef.h> -#include <string.h> -#include <limits.h> -#include <stdint.h> -#include <errno.h> - -//#define TAL_DEBUG 1 - -#define NOTIFY_IS_DESTRUCTOR 512 -#define NOTIFY_EXTRA_ARG 1024 - -/* This makes our parent_child ptr stand out for to_tal_hdr checks */ -#define TAL_PTR_OBFUSTICATOR ((intptr_t)0x1984200820142016ULL) - -/* 32-bit type field, first byte 0 in either endianness. */ -enum prop_type { - CHILDREN = 0x00c1d500, - NAME = 0x00111100, - NOTIFIER = 0x00071f00, -}; - -struct tal_hdr { - struct list_node list; - struct prop_hdr *prop; - /* XOR with TAL_PTR_OBFUSTICATOR */ - intptr_t parent_child; - size_t bytelen; -}; - -struct prop_hdr { - enum prop_type type; - struct prop_hdr *next; -}; - -struct children { - struct prop_hdr hdr; /* CHILDREN */ - struct tal_hdr *parent; - struct list_head children; /* Head of siblings. */ -}; - -struct name { - struct prop_hdr hdr; /* NAME */ - char name[]; -}; - -struct notifier { - struct prop_hdr hdr; /* NOTIFIER */ - enum tal_notify_type types; - union notifier_cb { - void (*notifyfn)(tal_t *, enum tal_notify_type, void *); - void (*destroy)(tal_t *); /* If NOTIFY_IS_DESTRUCTOR set */ - void (*destroy2)(tal_t *, void *); /* If NOTIFY_EXTRA_ARG */ - } u; -}; - -/* Extra arg */ -struct notifier_extra_arg { - struct notifier n; - void *arg; -}; - -#define EXTRA_ARG(n) (((struct notifier_extra_arg *)(n))->arg) - -static struct { - struct tal_hdr hdr; - struct children c; -} null_parent = { { { &null_parent.hdr.list, &null_parent.hdr.list }, - &null_parent.c.hdr, TAL_PTR_OBFUSTICATOR, 0 }, - { { CHILDREN, NULL }, - &null_parent.hdr, - { { &null_parent.c.children.n, - &null_parent.c.children.n } } - } -}; - - -static void *(*allocfn)(size_t size) = malloc; -static void *(*resizefn)(void *, size_t size) = realloc; -static void (*freefn)(void *) = free; -static void (*errorfn)(const char *msg) = (void *)abort; -/* Count on non-destrutor notifiers; often stays zero. */ -static size_t notifiers = 0; - -static inline void COLD call_error(const char *msg) -{ - errorfn(msg); -} - -static bool get_destroying_bit(intptr_t parent_child) -{ - return parent_child & 1; -} - -static void set_destroying_bit(intptr_t *parent_child) -{ - *parent_child |= 1; -} - -static struct children *ignore_destroying_bit(intptr_t parent_child) -{ - return (void *)((parent_child ^ TAL_PTR_OBFUSTICATOR) & ~(intptr_t)1); -} - -/* This means valgrind can see leaks. */ -void tal_cleanup(void) -{ - struct tal_hdr *i; - - while ((i = list_top(&null_parent.c.children, struct tal_hdr, list))) { - list_del(&i->list); - memset(i, 0, sizeof(*i)); - } - - /* Cleanup any taken pointers. */ - take_cleanup(); -} - -/* We carefully start all real properties with a zero byte. */ -static bool is_literal(const struct prop_hdr *prop) -{ - return ((char *)prop)[0] != 0; -} - -#ifndef NDEBUG -static const void *bounds_start, *bounds_end; - -static void update_bounds(const void *new, size_t size) -{ - if (unlikely(!bounds_start)) { - bounds_start = new; - bounds_end = (char *)new + size; - } else if (new < bounds_start) - bounds_start = new; - else if ((char *)new + size > (char *)bounds_end) - bounds_end = (char *)new + size; -} - -static bool in_bounds(const void *p) -{ - return !p - || (p >= (void *)&null_parent && p <= (void *)(&null_parent + 1)) - || (p >= bounds_start && p <= bounds_end); -} -#else -static void update_bounds(const void *new, size_t size) -{ -} - -static bool in_bounds(const void *p) -{ - return true; -} -#endif - -static void check_bounds(const void *p) -{ - if (!in_bounds(p)) - call_error("Not a valid header"); -} - -static struct tal_hdr *to_tal_hdr(const void *ctx) -{ - struct tal_hdr *t; - - t = (struct tal_hdr *)((char *)ctx - sizeof(struct tal_hdr)); - check_bounds(t); - check_bounds(ignore_destroying_bit(t->parent_child)); - check_bounds(t->list.next); - check_bounds(t->list.prev); - if (t->prop && !is_literal(t->prop)) - check_bounds(t->prop); - return t; -} - -static struct tal_hdr *to_tal_hdr_or_null(const void *ctx) -{ - if (!ctx) - return &null_parent.hdr; - return to_tal_hdr(ctx); -} - -static void *from_tal_hdr(const struct tal_hdr *hdr) -{ - return (void *)(hdr + 1); -} - -static void *from_tal_hdr_or_null(const struct tal_hdr *hdr) -{ - if (hdr == &null_parent.hdr) - return NULL; - return from_tal_hdr(hdr); -} - -#ifdef TAL_DEBUG -static struct tal_hdr *debug_tal(struct tal_hdr *tal) -{ - tal_check(from_tal_hdr_or_null(tal), "TAL_DEBUG "); - return tal; -} -#else -static struct tal_hdr *debug_tal(struct tal_hdr *tal) -{ - return tal; -} -#endif - -static void notify(const struct tal_hdr *ctx, - enum tal_notify_type type, const void *info, - int saved_errno) -{ - const struct prop_hdr *p; - - for (p = ctx->prop; p; p = p->next) { - struct notifier *n; - - if (is_literal(p)) - break; - if (p->type != NOTIFIER) - continue; - n = (struct notifier *)p; - if (n->types & type) { - errno = saved_errno; - if (n->types & NOTIFY_IS_DESTRUCTOR) { - /* Blatt this notifier in case it tries to - * tal_del_destructor() from inside */ - union notifier_cb cb = n->u; - /* It's a union, so this NULLs destroy2 too! */ - n->u.destroy = NULL; - if (n->types & NOTIFY_EXTRA_ARG) - cb.destroy2(from_tal_hdr(ctx), - EXTRA_ARG(n)); - else - cb.destroy(from_tal_hdr(ctx)); - } else - n->u.notifyfn(from_tal_hdr_or_null(ctx), type, - (void *)info); - } - } -} - -static void *allocate(size_t size) -{ - void *ret = allocfn(size); - if (!ret) - call_error("allocation failed"); - else - update_bounds(ret, size); - return ret; -} - -static struct prop_hdr **find_property_ptr(const struct tal_hdr *t, - enum prop_type type) -{ - struct prop_hdr **p; - - for (p = (struct prop_hdr **)&t->prop; *p; p = &(*p)->next) { - if (is_literal(*p)) { - if (type == NAME) - return p; - break; - } - if ((*p)->type == type) - return p; - } - return NULL; -} - -static void *find_property(const struct tal_hdr *parent, enum prop_type type) -{ - struct prop_hdr **p = find_property_ptr(parent, type); - - if (p) - return *p; - return NULL; -} - -static void init_property(struct prop_hdr *hdr, - struct tal_hdr *parent, - enum prop_type type) -{ - hdr->type = type; - hdr->next = parent->prop; - parent->prop = hdr; -} - -static struct notifier *add_notifier_property(struct tal_hdr *t, - enum tal_notify_type types, - void (*fn)(void *, - enum tal_notify_type, - void *), - void *extra_arg) -{ - struct notifier *prop; - - if (types & NOTIFY_EXTRA_ARG) - prop = allocate(sizeof(struct notifier_extra_arg)); - else - prop = allocate(sizeof(struct notifier)); - - if (prop) { - init_property(&prop->hdr, t, NOTIFIER); - prop->types = types; - prop->u.notifyfn = fn; - if (types & NOTIFY_EXTRA_ARG) - EXTRA_ARG(prop) = extra_arg; - } - return prop; -} - -static enum tal_notify_type del_notifier_property(struct tal_hdr *t, - void (*fn)(tal_t *, - enum tal_notify_type, - void *), - bool match_extra_arg, - void *extra_arg) -{ - struct prop_hdr **p; - - for (p = (struct prop_hdr **)&t->prop; *p; p = &(*p)->next) { - struct notifier *n; - enum tal_notify_type types; - - if (is_literal(*p)) - break; - if ((*p)->type != NOTIFIER) - continue; - n = (struct notifier *)*p; - if (n->u.notifyfn != fn) - continue; - - types = n->types; - if ((types & NOTIFY_EXTRA_ARG) - && match_extra_arg - && extra_arg != EXTRA_ARG(n)) - continue; - - *p = (*p)->next; - freefn(n); - return types & ~(NOTIFY_IS_DESTRUCTOR|NOTIFY_EXTRA_ARG); - } - return 0; -} - -static struct name *add_name_property(struct tal_hdr *t, const char *name) -{ - struct name *prop; - - prop = allocate(sizeof(*prop) + strlen(name) + 1); - if (prop) { - init_property(&prop->hdr, t, NAME); - strcpy(prop->name, name); - } - return prop; -} - -static struct children *add_child_property(struct tal_hdr *parent, - struct tal_hdr *child UNNEEDED) -{ - struct children *prop = allocate(sizeof(*prop)); - if (prop) { - init_property(&prop->hdr, parent, CHILDREN); - prop->parent = parent; - list_head_init(&prop->children); - } - return prop; -} - -static bool add_child(struct tal_hdr *parent, struct tal_hdr *child) -{ - struct children *children = find_property(parent, CHILDREN); - - if (!children) { - children = add_child_property(parent, child); - if (!children) - return false; - } - list_add(&children->children, &child->list); - child->parent_child = (intptr_t)children ^ TAL_PTR_OBFUSTICATOR; - return true; -} - -static void del_tree(struct tal_hdr *t, const tal_t *orig, int saved_errno) -{ - struct prop_hdr **prop, *p, *next; - - assert(!taken(from_tal_hdr(t))); - - /* Already being destroyed? Don't loop. */ - if (unlikely(get_destroying_bit(t->parent_child))) - return; - - set_destroying_bit(&t->parent_child); - - /* Call free notifiers. */ - notify(t, TAL_NOTIFY_FREE, (tal_t *)orig, saved_errno); - - /* Now free children and groups. */ - prop = find_property_ptr(t, CHILDREN); - if (prop) { - struct tal_hdr *i; - struct children *c = (struct children *)*prop; - - while ((i = list_top(&c->children, struct tal_hdr, list))) { - list_del(&i->list); - del_tree(i, orig, saved_errno); - } - } - - /* Finally free our properties. */ - for (p = t->prop; p && !is_literal(p); p = next) { - next = p->next; - freefn(p); - } - freefn(t); -} - -void *tal_alloc_(const tal_t *ctx, size_t size, bool clear, const char *label) -{ - struct tal_hdr *child, *parent = debug_tal(to_tal_hdr_or_null(ctx)); - - child = allocate(sizeof(struct tal_hdr) + size); - if (!child) - return NULL; - if (clear) - memset(from_tal_hdr(child), 0, size); - child->prop = (void *)label; - child->bytelen = size; - - if (!add_child(parent, child)) { - freefn(child); - return NULL; - } - debug_tal(parent); - if (notifiers) - notify(parent, TAL_NOTIFY_ADD_CHILD, from_tal_hdr(child), 0); - return from_tal_hdr(debug_tal(child)); -} - -static bool adjust_size(size_t *size, size_t count) -{ - const size_t extra = sizeof(struct tal_hdr); - - /* Multiplication wrap */ - if (count && unlikely(*size * count / *size != count)) - goto overflow; - - *size *= count; - - /* Make sure we don't wrap adding header. */ - if (*size + extra < extra) - goto overflow; - return true; -overflow: - call_error("allocation size overflow"); - return false; -} - -void *tal_alloc_arr_(const tal_t *ctx, size_t size, size_t count, bool clear, - const char *label) -{ - if (!adjust_size(&size, count)) - return NULL; - - return tal_alloc_(ctx, size, clear, label); -} - -void *tal_free(const tal_t *ctx) -{ - if (ctx) { - struct tal_hdr *t; - int saved_errno = errno; - t = debug_tal(to_tal_hdr(ctx)); - if (unlikely(get_destroying_bit(t->parent_child))) - return NULL; - if (notifiers) - notify(ignore_destroying_bit(t->parent_child)->parent, - TAL_NOTIFY_DEL_CHILD, ctx, saved_errno); - list_del(&t->list); - del_tree(t, ctx, saved_errno); - errno = saved_errno; - } - return NULL; -} - -void *tal_steal_(const tal_t *new_parent, const tal_t *ctx) -{ - if (ctx) { - struct tal_hdr *newpar, *t, *old_parent; - - newpar = debug_tal(to_tal_hdr_or_null(new_parent)); - t = debug_tal(to_tal_hdr(ctx)); - - /* Unlink it from old parent. */ - list_del(&t->list); - old_parent = ignore_destroying_bit(t->parent_child)->parent; - - if (unlikely(!add_child(newpar, t))) { - /* We can always add to old parent, because it has a - * children property already. */ - if (!add_child(old_parent, t)) - abort(); - return NULL; - } - debug_tal(newpar); - if (notifiers) - notify(t, TAL_NOTIFY_STEAL, new_parent, 0); - } - return (void *)ctx; -} - -bool tal_add_destructor_(const tal_t *ctx, void (*destroy)(void *me)) -{ - tal_t *t = debug_tal(to_tal_hdr(ctx)); - return add_notifier_property(t, TAL_NOTIFY_FREE|NOTIFY_IS_DESTRUCTOR, - (void *)destroy, NULL); -} - -bool tal_add_destructor2_(const tal_t *ctx, void (*destroy)(void *me, void *arg), - void *arg) -{ - tal_t *t = debug_tal(to_tal_hdr(ctx)); - return add_notifier_property(t, TAL_NOTIFY_FREE|NOTIFY_IS_DESTRUCTOR - |NOTIFY_EXTRA_ARG, - (void *)destroy, arg); -} - -/* We could support notifiers with an extra arg, but we didn't add to API */ -bool tal_add_notifier_(const tal_t *ctx, enum tal_notify_type types, - void (*callback)(tal_t *, enum tal_notify_type, void *)) -{ - struct tal_hdr *t = debug_tal(to_tal_hdr_or_null(ctx)); - struct notifier *n; - - assert(types); - assert((types & ~(TAL_NOTIFY_FREE | TAL_NOTIFY_STEAL | TAL_NOTIFY_MOVE - | TAL_NOTIFY_RESIZE | TAL_NOTIFY_RENAME - | TAL_NOTIFY_ADD_CHILD | TAL_NOTIFY_DEL_CHILD - | TAL_NOTIFY_ADD_NOTIFIER - | TAL_NOTIFY_DEL_NOTIFIER)) == 0); - - /* Don't call notifier about itself: set types after! */ - n = add_notifier_property(t, 0, callback, NULL); - if (unlikely(!n)) - return false; - - if (notifiers) - notify(t, TAL_NOTIFY_ADD_NOTIFIER, callback, 0); - - n->types = types; - if (types != TAL_NOTIFY_FREE) - notifiers++; - return true; -} - -bool tal_del_notifier_(const tal_t *ctx, - void (*callback)(tal_t *, enum tal_notify_type, void *), - bool match_extra_arg, void *extra_arg) -{ - struct tal_hdr *t = debug_tal(to_tal_hdr_or_null(ctx)); - enum tal_notify_type types; - - types = del_notifier_property(t, callback, match_extra_arg, extra_arg); - if (types) { - notify(t, TAL_NOTIFY_DEL_NOTIFIER, callback, 0); - if (types != TAL_NOTIFY_FREE) - notifiers--; - return true; - } - return false; -} - -bool tal_del_destructor_(const tal_t *ctx, void (*destroy)(void *me)) -{ - return tal_del_notifier_(ctx, (void *)destroy, false, NULL); -} - -bool tal_del_destructor2_(const tal_t *ctx, void (*destroy)(void *me, void *arg), - void *arg) -{ - return tal_del_notifier_(ctx, (void *)destroy, true, arg); -} - -bool tal_set_name_(tal_t *ctx, const char *name, bool literal) -{ - struct tal_hdr *t = debug_tal(to_tal_hdr(ctx)); - struct prop_hdr **prop = find_property_ptr(t, NAME); - - /* Get rid of any old name */ - if (prop) { - struct name *name = (struct name *)*prop; - if (is_literal(&name->hdr)) - *prop = NULL; - else { - *prop = name->hdr.next; - freefn(name); - } - } - - if (literal && name[0]) { - struct prop_hdr **p; - - /* Append literal. */ - for (p = &t->prop; *p && !is_literal(*p); p = &(*p)->next); - *p = (struct prop_hdr *)name; - } else if (!add_name_property(t, name)) - return false; - - debug_tal(t); - if (notifiers) - notify(t, TAL_NOTIFY_RENAME, name, 0); - return true; -} - -const char *tal_name(const tal_t *t) -{ - struct name *n; - - n = find_property(debug_tal(to_tal_hdr(t)), NAME); - if (!n) - return NULL; - - if (is_literal(&n->hdr)) - return (const char *)n; - return n->name; -} - -size_t tal_bytelen(const tal_t *ptr) -{ - /* NULL -> null_parent which has bytelen 0 */ - struct tal_hdr *t = debug_tal(to_tal_hdr_or_null(ptr)); - - return t->bytelen; -} - -/* Start one past first child: make stopping natural in circ. list. */ -static struct tal_hdr *first_child(struct tal_hdr *parent) -{ - struct children *child; - - child = find_property(parent, CHILDREN); - if (!child) - return NULL; - - return list_top(&child->children, struct tal_hdr, list); -} - -tal_t *tal_first(const tal_t *root) -{ - struct tal_hdr *c, *t = debug_tal(to_tal_hdr_or_null(root)); - - c = first_child(t); - if (!c) - return NULL; - return from_tal_hdr(c); -} - -tal_t *tal_next(const tal_t *prev) -{ - struct tal_hdr *next, *prevhdr = debug_tal(to_tal_hdr(prev)); - struct list_head *head; - - head = &ignore_destroying_bit(prevhdr->parent_child)->children; - next = list_next(head, prevhdr, list); - if (!next) - return NULL; - return from_tal_hdr(next); -} - -tal_t *tal_parent(const tal_t *ctx) -{ - struct tal_hdr *t; - - if (!ctx) - return NULL; - - t = debug_tal(to_tal_hdr(ctx)); - if (ignore_destroying_bit(t->parent_child)->parent == &null_parent.hdr) - return NULL; - return from_tal_hdr(ignore_destroying_bit(t->parent_child)->parent); -} - -bool tal_resize_(tal_t **ctxp, size_t size, size_t count, bool clear) -{ - struct tal_hdr *old_t, *t; - struct children *child; - - old_t = debug_tal(to_tal_hdr(*ctxp)); - - if (!adjust_size(&size, count)) - return false; - - t = resizefn(old_t, sizeof(struct tal_hdr) + size); - if (!t) { - call_error("Reallocation failure"); - return false; - } - - /* Clear between old end and new end. */ - if (clear && size > t->bytelen) { - char *old_end = (char *)(t + 1) + t->bytelen; - memset(old_end, 0, size - t->bytelen); - } - - /* Update length. */ - t->bytelen = size; - update_bounds(t, sizeof(struct tal_hdr) + size); - - /* If it didn't move, we're done! */ - if (t != old_t) { - /* Fix up linked list pointers. */ - t->list.next->prev = t->list.prev->next = &t->list; - - /* Copy take() property. */ - if (taken(from_tal_hdr(old_t))) - take(from_tal_hdr(t)); - - /* Fix up child property's parent pointer. */ - child = find_property(t, CHILDREN); - if (child) { - assert(child->parent == old_t); - child->parent = t; - } - *ctxp = from_tal_hdr(debug_tal(t)); - if (notifiers) - notify(t, TAL_NOTIFY_MOVE, from_tal_hdr(old_t), 0); - } - if (notifiers) - notify(t, TAL_NOTIFY_RESIZE, (void *)size, 0); - - return true; -} - -bool tal_expand_(tal_t **ctxp, const void *src, size_t size, size_t count) -{ - size_t old_len; - bool ret = false; - - old_len = debug_tal(to_tal_hdr(*ctxp))->bytelen; - - /* Check for additive overflow */ - if (old_len + count * size < old_len) { - call_error("dup size overflow"); - goto out; - } - - /* Don't point src inside thing we're expanding! */ - assert(src < *ctxp - || (char *)src >= (char *)(*ctxp) + old_len); - - if (!tal_resize_(ctxp, size, old_len/size + count, false)) - goto out; - - memcpy((char *)*ctxp + old_len, src, count * size); - ret = true; - -out: - if (taken(src)) - tal_free(src); - return ret; -} - -void *tal_dup_(const tal_t *ctx, const void *p, size_t size, - size_t n, size_t extra, bool nullok, const char *label) -{ - void *ret; - size_t nbytes = size; - - if (nullok && p == NULL) { - /* take(NULL) works. */ - (void)taken(p); - return NULL; - } - - if (!adjust_size(&nbytes, n)) { - if (taken(p)) - tal_free(p); - return NULL; - } - - /* Beware addition overflow! */ - if (n + extra < n) { - call_error("dup size overflow"); - if (taken(p)) - tal_free(p); - return NULL; - } - - if (taken(p)) { - if (unlikely(!p)) - return NULL; - if (unlikely(!tal_resize_((void **)&p, size, n + extra, false))) - return tal_free(p); - if (unlikely(!tal_steal(ctx, p))) - return tal_free(p); - return (void *)p; - } - - ret = tal_alloc_arr_(ctx, size, n + extra, false, label); - if (ret) - memcpy(ret, p, nbytes); - return ret; -} - -void *tal_dup_talarr_(const tal_t *ctx, const tal_t *src TAKES, const char *label) -{ - return tal_dup_(ctx, src, 1, tal_bytelen(src), 0, true, label); -} - -void tal_set_backend(void *(*alloc_fn)(size_t size), - void *(*resize_fn)(void *, size_t size), - void (*free_fn)(void *), - void (*error_fn)(const char *msg)) -{ - if (alloc_fn) - allocfn = alloc_fn; - if (resize_fn) - resizefn = resize_fn; - if (free_fn) - freefn = free_fn; - if (error_fn) - errorfn = error_fn; -} - -#ifdef CCAN_TAL_DEBUG -static void dump_node(unsigned int indent, const struct tal_hdr *t) -{ - unsigned int i; - const struct prop_hdr *p; - - for (i = 0; i < indent; i++) - fprintf(stderr, " "); - fprintf(stderr, "%p len=%zu", t, t->bytelen); - for (p = t->prop; p; p = p->next) { - struct children *c; - struct name *n; - struct notifier *no; - if (is_literal(p)) { - fprintf(stderr, " \"%s\"", (const char *)p); - break; - } - switch (p->type) { - case CHILDREN: - c = (struct children *)p; - fprintf(stderr, " CHILDREN(%p):parent=%p,children={%p,%p}", - p, c->parent, - c->children.n.prev, c->children.n.next); - break; - case NAME: - n = (struct name *)p; - fprintf(stderr, " NAME(%p):%s", p, n->name); - break; - case NOTIFIER: - no = (struct notifier *)p; - fprintf(stderr, " NOTIFIER(%p):fn=%p", p, no->u.notifyfn); - break; - default: - fprintf(stderr, " **UNKNOWN(%p):%i**", p, p->type); - } - } - fprintf(stderr, "\n"); -} - -static void tal_dump_(unsigned int level, const struct tal_hdr *t) -{ - struct children *children; - - dump_node(level, t); - - children = find_property(t, CHILDREN); - if (children) { - struct tal_hdr *i; - - list_for_each(&children->children, i, list) - tal_dump_(level + 1, i); - } -} - -void tal_dump(void) -{ - tal_dump_(0, &null_parent.hdr); -} -#endif /* CCAN_TAL_DEBUG */ - -#ifndef NDEBUG -static bool check_err(struct tal_hdr *t, const char *errorstr, - const char *errmsg) -{ - if (errorstr) { - /* Try not to malloc: it may be corrupted. */ - char msg[strlen(errorstr) + 20 + strlen(errmsg) + 1]; - sprintf(msg, "%s:%p %s", errorstr, from_tal_hdr(t), errmsg); - call_error(msg); - } - return false; -} - -static bool check_node(struct children *parent_child, - struct tal_hdr *t, const char *errorstr) -{ - struct prop_hdr *p; - struct name *name = NULL; - struct children *children = NULL; - - if (!in_bounds(t)) - return check_err(t, errorstr, "invalid pointer"); - - if (ignore_destroying_bit(t->parent_child) != parent_child) - return check_err(t, errorstr, "incorrect parent"); - - for (p = t->prop; p; p = p->next) { - if (is_literal(p)) { - if (name) - return check_err(t, errorstr, - "has extra literal"); - break; - } - if (!in_bounds(p)) - return check_err(t, errorstr, - "has bad property pointer"); - - switch (p->type) { - case CHILDREN: - if (children) - return check_err(t, errorstr, - "has two child nodes"); - children = (struct children *)p; - break; - case NOTIFIER: - break; - case NAME: - if (name) - return check_err(t, errorstr, - "has two names"); - name = (struct name *)p; - break; - default: - return check_err(t, errorstr, "has unknown property"); - } - } - if (children) { - struct tal_hdr *i; - - if (!list_check(&children->children, errorstr)) - return false; - list_for_each(&children->children, i, list) { - if (!check_node(children, i, errorstr)) - return false; - } - } - return true; -} - -bool tal_check(const tal_t *ctx, const char *errorstr) -{ - struct tal_hdr *t = to_tal_hdr_or_null(ctx); - - return check_node(ignore_destroying_bit(t->parent_child), t, errorstr); -} -#else /* NDEBUG */ -bool tal_check(const tal_t *ctx, const char *errorstr) -{ - return true; -} -#endif diff --git a/src/bolt11/tal.h b/src/bolt11/tal.h @@ -1,553 +0,0 @@ -/* Licensed under BSD-MIT - see LICENSE file for details */ -#ifndef CCAN_TAL_H -#define CCAN_TAL_H -#include "../config.h" -#include "../compiler.h" -#include "likely.h" -#include "typesafe_cb.h" -#include "str.h" -#include "take.h" - -#include <stdlib.h> -#include <stdbool.h> -#include <stdarg.h> - -/** - * tal_t - convenient alias for void to mark tal pointers. - * - * Since any pointer can be a tal-allocated pointer, it's often - * useful to use this typedef to mark them explicitly. - */ -typedef void tal_t; - -/** - * tal - basic allocator function - * @ctx: NULL, or tal allocated object to be parent. - * @type: the type to allocate. - * - * Allocates a specific type, with a given parent context. The name - * of the object is a string of the type, but if CCAN_TAL_DEBUG is - * defined it also contains the file and line which allocated it. - * - * tal_count() of the return will be 1. - * - * Example: - * int *p = tal(NULL, int); - * *p = 1; - */ -#define tal(ctx, type) \ - tal_label(ctx, type, TAL_LABEL(type, "")) - -/** - * talz - zeroing allocator function - * @ctx: NULL, or tal allocated object to be parent. - * @type: the type to allocate. - * - * Equivalent to tal() followed by memset() to zero. - * - * Example: - * p = talz(NULL, int); - * assert(*p == 0); - */ -#define talz(ctx, type) \ - talz_label(ctx, type, TAL_LABEL(type, "")) - -/** - * tal_free - free a tal-allocated pointer. - * @p: NULL, or tal allocated object to free. - * - * This calls the destructors for p (if any), then does the same for all its - * children (recursively) before finally freeing the memory. It returns - * NULL, for convenience. - * - * Note: errno is preserved by this call, and also saved and restored - * for any destructors or notifiers. - * - * Example: - * p = tal_free(p); - */ -void *tal_free(const tal_t *p); - -/** - * tal_arr - allocate an array of objects. - * @ctx: NULL, or tal allocated object to be parent. - * @type: the type to allocate. - * @count: the number to allocate. - * - * tal_count() of the returned pointer will be @count. - * - * Example: - * p = tal_arr(NULL, int, 2); - * p[0] = 0; - * p[1] = 1; - */ -#define tal_arr(ctx, type, count) \ - tal_arr_label(ctx, type, count, TAL_LABEL(type, "[]")) - -/** - * tal_arrz - allocate an array of zeroed objects. - * @ctx: NULL, or tal allocated object to be parent. - * @type: the type to allocate. - * @count: the number to allocate. - * - * Equivalent to tal_arr() followed by memset() to zero. - * - * Example: - * p = tal_arrz(NULL, int, 2); - * assert(p[0] == 0 && p[1] == 0); - */ -#define tal_arrz(ctx, type, count) \ - tal_arrz_label(ctx, type, count, TAL_LABEL(type, "[]")) - -/** - * tal_resize - enlarge or reduce a tal object. - * @p: A pointer to the tal allocated array to resize. - * @count: the number to allocate. - * - * This returns true on success (and may move *@p), or false on failure. - * On success, tal_count() of *@p will be @count. - * - * Note: if *p is take(), it will still be take() upon return, even if it - * has been moved. - * - * Example: - * tal_resize(&p, 100); - */ -#define tal_resize(p, count) \ - tal_resize_((void **)(p), sizeof**(p), (count), false) - -/** - * tal_resizez - enlarge or reduce a tal object; zero out extra. - * @p: A pointer to the tal allocated array to resize. - * @count: the number to allocate. - * - * This returns true on success (and may move *@p), or false on failure. - * - * Example: - * tal_resizez(&p, 200); - */ -#define tal_resizez(p, count) \ - tal_resize_((void **)(p), sizeof**(p), (count), true) - -/** - * tal_steal - change the parent of a tal-allocated pointer. - * @ctx: The new parent. - * @ptr: The tal allocated object to move, or NULL. - * - * This may need to perform an allocation, in which case it may fail; thus - * it can return NULL, otherwise returns @ptr. If @ptr is NULL, this function does - * nothing. - */ -#if HAVE_STATEMENT_EXPR -/* Weird macro avoids gcc's 'warning: value computed is not used'. */ -#define tal_steal(ctx, ptr) \ - ({ (tal_typeof(ptr) tal_steal_((ctx),(ptr))); }) -#else -#define tal_steal(ctx, ptr) \ - (tal_typeof(ptr) tal_steal_((ctx),(ptr))) -#endif - -/** - * tal_add_destructor - add a callback function when this context is destroyed. - * @ptr: The tal allocated object. - * @function: the function to call before it's freed. - * - * This is a more convenient form of tal_add_notifier(@ptr, - * TAL_NOTIFY_FREE, ...), in that the function prototype takes only @ptr. - * - * Note that this can only fail if your allocfn fails and your errorfn returns. - */ -#define tal_add_destructor(ptr, function) \ - tal_add_destructor_((ptr), typesafe_cb(void, void *, (function), (ptr))) - -/** - * tal_del_destructor - remove a destructor callback function. - * @ptr: The tal allocated object. - * @function: the function to call before it's freed. - * - * If @function has not been successfully added as a destructor, this returns - * false. Note that if we're inside the destructor call itself, this will - * return false. - */ -#define tal_del_destructor(ptr, function) \ - tal_del_destructor_((ptr), typesafe_cb(void, void *, (function), (ptr))) - -/** - * tal_add_destructor2 - add a 2-arg callback function when context is destroyed. - * @ptr: The tal allocated object. - * @function: the function to call before it's freed. - * @arg: the extra argument to the function. - * - * Sometimes an extra argument is required for a destructor; this - * saves the extra argument internally to avoid the caller having to - * do an extra allocation. - * - * Note that this can only fail if your allocfn fails and your errorfn returns. - */ -#define tal_add_destructor2(ptr, function, arg) \ - tal_add_destructor2_((ptr), \ - typesafe_cb_cast(void (*)(tal_t *, void *), \ - void (*)(__typeof__(ptr), \ - __typeof__(arg)), \ - (function)), \ - (arg)) - -/** - * tal_del_destructor - remove a destructor callback function. - * @ptr: The tal allocated object. - * @function: the function to call before it's freed. - * - * If @function has not been successfully added as a destructor, this returns - * false. Note that if we're inside the destructor call itself, this will - * return false. - */ -#define tal_del_destructor(ptr, function) \ - tal_del_destructor_((ptr), typesafe_cb(void, void *, (function), (ptr))) - -/** - * tal_del_destructor2 - remove 2-arg callback function. - * @ptr: The tal allocated object. - * @function: the function to call before it's freed. - * @arg: the extra argument to the function. - * - * If @function has not been successfully added as a destructor with - * @arg, this returns false. - */ -#define tal_del_destructor2(ptr, function, arg) \ - tal_del_destructor2_((ptr), \ - typesafe_cb_cast(void (*)(tal_t *, void *), \ - void (*)(__typeof__(ptr), \ - __typeof__(arg)), \ - (function)), \ - (arg)) -enum tal_notify_type { - TAL_NOTIFY_FREE = 1, - TAL_NOTIFY_STEAL = 2, - TAL_NOTIFY_MOVE = 4, - TAL_NOTIFY_RESIZE = 8, - TAL_NOTIFY_RENAME = 16, - TAL_NOTIFY_ADD_CHILD = 32, - TAL_NOTIFY_DEL_CHILD = 64, - TAL_NOTIFY_ADD_NOTIFIER = 128, - TAL_NOTIFY_DEL_NOTIFIER = 256 -}; - -/** - * tal_add_notifier - add a callback function when this context changes. - * @ptr: The tal allocated object, or NULL. - * @types: Bitwise OR of the types the callback is interested in. - * @callback: the function to call. - * - * Note that this can only fail if your allocfn fails and your errorfn - * returns. Also note that notifiers are not reliable in the case - * where an allocation fails, as they may be called before any - * allocation is actually done. - * - * TAL_NOTIFY_FREE is called when @ptr is freed, either directly or - * because an ancestor is freed: @info is the argument to tal_free(). - * It is exactly equivalent to a destructor, with more information. - * errno is set to the value it was at the call of tal_free(). - * - * TAL_NOTIFY_STEAL is called when @ptr's parent changes: @info is the - * new parent. - * - * TAL_NOTIFY_MOVE is called when @ptr is realloced (via tal_resize) - * and moved. In this case, @ptr arg here is the new memory, and - * @info is the old pointer. - * - * TAL_NOTIFY_RESIZE is called when @ptr is realloced via tal_resize: - * @info is the new size, in bytes. If the pointer has moved, - * TAL_NOTIFY_MOVE callbacks are called first. - * - * TAL_NOTIFY_ADD_CHILD/TAL_NOTIFY_DEL_CHILD are called when @ptr is - * the context for a tal() allocating call, or a direct child is - * tal_free()d: @info is the child. Note that TAL_NOTIFY_DEL_CHILD is - * not called when this context is tal_free()d: TAL_NOTIFY_FREE is - * considered sufficient for that case. - * - * TAL_NOTIFY_ADD_NOTIFIER/TAL_NOTIFIER_DEL_NOTIFIER are called when a - * notifier is added or removed (not for this notifier): @info is the - * callback. This is also called for tal_add_destructor and - * tal_del_destructor. - */ -#define tal_add_notifier(ptr, types, callback) \ - tal_add_notifier_((ptr), (types), \ - typesafe_cb_postargs(void, tal_t *, (callback), \ - (ptr), \ - enum tal_notify_type, void *)) - -/** - * tal_del_notifier - remove a notifier callback function. - * @ptr: The tal allocated object. - * @callback: the function to call. - */ -#define tal_del_notifier(ptr, callback) \ - tal_del_notifier_((ptr), \ - typesafe_cb_postargs(void, void *, (callback), \ - (ptr), \ - enum tal_notify_type, void *), \ - false, NULL) - -/** - * tal_set_name - attach a name to a tal pointer. - * @ptr: The tal allocated object. - * @name: The name to use. - * - * The name is copied, unless we're certain it's a string literal. - */ -#define tal_set_name(ptr, name) \ - tal_set_name_((ptr), (name), TAL_IS_LITERAL(name)) - -/** - * tal_name - get the name for a tal pointer. - * @ptr: The tal allocated object. - * - * Returns NULL if no name has been set. - */ -const char *tal_name(const tal_t *ptr); - -/** - * tal_count - get the count of objects in a tal object. - * @ptr: The tal allocated object (or NULL) - * - * Returns 0 if @ptr is NULL. Note that if the allocation was done as a - * different type to @ptr, the result may not match the @count argument - * (or implied 1) of that allocation! - */ -#define tal_count(p) (tal_bytelen(p) / sizeof(*p)) - -/** - * tal_bytelen - get the count of bytes in a tal object. - * @ptr: The tal allocated object (or NULL) - * - * Returns 0 if @ptr is NULL. - */ -size_t tal_bytelen(const tal_t *ptr); - -/** - * tal_first - get the first immediate tal object child. - * @root: The tal allocated object to start with, or NULL. - * - * Returns NULL if there are no children. - */ -tal_t *tal_first(const tal_t *root); - -/** - * tal_next - get the next immediate tal object child. - * @prev: The return value from tal_first or tal_next. - * - * Returns NULL if there are no more immediate children. This should be safe to - * call on an altering tree unless @prev is no longer valid. - */ -tal_t *tal_next(const tal_t *prev); - -/** - * tal_parent - get the parent of a tal object. - * @ctx: The tal allocated object. - * - * Returns the parent, which may be NULL. Returns NULL if @ctx is NULL. - */ -tal_t *tal_parent(const tal_t *ctx); - -/** - * tal_dup - duplicate an object. - * @ctx: The tal allocated object to be parent of the result (may be NULL). - * @type: the type (should match type of @p!) - * @p: the object to copy (or reparented if take()). Must not be NULL. - */ -#define tal_dup(ctx, type, p) \ - tal_dup_label(ctx, type, p, TAL_LABEL(type, ""), false) - -/** - * tal_dup_or_null - duplicate an object, or just pass NULL. - * @ctx: The tal allocated object to be parent of the result (may be NULL). - * @type: the type (should match type of @p!) - * @p: the object to copy (or reparented if take()) - * - * if @p is NULL, just return NULL, otherwise to tal_dup(). - */ -#define tal_dup_or_null(ctx, type, p) \ - tal_dup_label(ctx, type, p, TAL_LABEL(type, ""), true) - -/** - * tal_dup_arr - duplicate an array. - * @ctx: The tal allocated object to be parent of the result (may be NULL). - * @type: the type (should match type of @p!) - * @p: the array to copy (or resized & reparented if take()) - * @n: the number of sizeof(type) entries to copy. - * @extra: the number of extra sizeof(type) entries to allocate. - */ -#define tal_dup_arr(ctx, type, p, n, extra) \ - tal_dup_arr_label(ctx, type, p, n, extra, TAL_LABEL(type, "[]")) - - -/** - * tal_dup_arr - duplicate a tal array. - * @ctx: The tal allocated object to be parent of the result (may be NULL). - * @type: the type (should match type of @p!) - * @p: the tal array to copy (or resized & reparented if take()) - * - * The common case of duplicating an entire tal array. - */ -#define tal_dup_talarr(ctx, type, p) \ - ((type *)tal_dup_talarr_((ctx), tal_typechk_(p, type *), \ - TAL_LABEL(type, "[]"))) -/* Lower-level interfaces, where you want to supply your own label string. */ -#define tal_label(ctx, type, label) \ - ((type *)tal_alloc_((ctx), sizeof(type), false, label)) -#define talz_label(ctx, type, label) \ - ((type *)tal_alloc_((ctx), sizeof(type), true, label)) -#define tal_arr_label(ctx, type, count, label) \ - ((type *)tal_alloc_arr_((ctx), sizeof(type), (count), false, label)) -#define tal_arrz_label(ctx, type, count, label) \ - ((type *)tal_alloc_arr_((ctx), sizeof(type), (count), true, label)) -#define tal_dup_label(ctx, type, p, label, nullok) \ - ((type *)tal_dup_((ctx), tal_typechk_(p, type *), \ - sizeof(type), 1, 0, nullok, \ - label)) -#define tal_dup_arr_label(ctx, type, p, n, extra, label) \ - ((type *)tal_dup_((ctx), tal_typechk_(p, type *), \ - sizeof(type), (n), (extra), false, \ - label)) - -/** - * tal_set_backend - set the allocation or error functions to use - * @alloc_fn: allocator or NULL (default is malloc) - * @resize_fn: re-allocator or NULL (default is realloc) - * @free_fn: free function or NULL (default is free) - * @error_fn: called on errors or NULL (default is abort) - * - * The defaults are set up so tal functions never return NULL, but you - * can override error_fn to change that. error_fn can return, and is - * called if alloc_fn or resize_fn fail. - * - * If any parameter is NULL, that function is unchanged. - */ -void tal_set_backend(void *(*alloc_fn)(size_t size), - void *(*resize_fn)(void *, size_t size), - void (*free_fn)(void *), - void (*error_fn)(const char *msg)); - -/** - * tal_expand - expand a tal array with contents. - * @a1p: a pointer to the tal array to expand. - * @a2: the second array (can be take()). - * @num2: the number of elements in the second array. - * - * Note that *@a1 and @a2 should be the same type. tal_count(@a1) will - * be increased by @num2. - * - * Example: - * int *arr1 = tal_arrz(NULL, int, 2); - * int arr2[2] = { 1, 3 }; - * - * tal_expand(&arr1, arr2, 2); - * assert(tal_count(arr1) == 4); - * assert(arr1[2] == 1); - * assert(arr1[3] == 3); - */ -#define tal_expand(a1p, a2, num2) \ - tal_expand_((void **)(a1p), (a2), sizeof**(a1p), \ - (num2) + 0*sizeof(*(a1p) == (a2))) - -/** - * tal_cleanup - remove pointers from NULL node - * - * Internally, tal keeps a list of nodes allocated from @ctx NULL; this - * prevents valgrind from noticing memory leaks. This re-initializes - * that list to empty. - * - * It also calls take_cleanup() for you. - */ -void tal_cleanup(void); - - -/** - * tal_check - sanity check a tal context and its children. - * @ctx: a tal context, or NULL. - * @errorstr: a string to prepend calls to error_fn, or NULL. - * - * This sanity-checks a tal tree (unless NDEBUG is defined, in which case - * it simply returns true). If errorstr is not null, error_fn is called - * when a problem is found, otherwise it is not. - * - * See also: - * tal_set_backend() - */ -bool tal_check(const tal_t *ctx, const char *errorstr); - -#ifdef CCAN_TAL_DEBUG -/** - * tal_dump - dump entire tal tree to stderr. - * - * This is a helper for debugging tal itself, which dumps all the tal internal - * state. - */ -void tal_dump(void); -#endif - -/* Internal support functions */ -#ifndef TAL_LABEL -#ifdef CCAN_TAL_NO_LABELS -#define TAL_LABEL(type, arr) NULL -#else -#ifdef CCAN_TAL_DEBUG -#define TAL_LABEL(type, arr) \ - __FILE__ ":" stringify(__LINE__) ":" stringify(type) arr -#else -#define TAL_LABEL(type, arr) stringify(type) arr -#endif /* CCAN_TAL_DEBUG */ -#endif -#endif - -#if HAVE_BUILTIN_CONSTANT_P -#define TAL_IS_LITERAL(str) __builtin_constant_p(str) -#else -#define TAL_IS_LITERAL(str) (sizeof(&*(str)) != sizeof(char *)) -#endif - -bool tal_set_name_(tal_t *ctx, const char *name, bool literal); - -#if HAVE_TYPEOF -#define tal_typeof(ptr) (__typeof__(ptr)) -#if HAVE_STATEMENT_EXPR -/* Careful: ptr can be const foo *, ptype is foo *. Also, ptr could - * be an array, eg "hello". */ -#define tal_typechk_(ptr, ptype) ({ __typeof__((ptr)+0) _p = (ptype)(ptr); _p; }) -#else -#define tal_typechk_(ptr, ptype) (ptr) -#endif -#else /* !HAVE_TYPEOF */ -#define tal_typeof(ptr) -#define tal_typechk_(ptr, ptype) (ptr) -#endif - -void *tal_alloc_(const tal_t *ctx, size_t bytes, bool clear, const char *label); -void *tal_alloc_arr_(const tal_t *ctx, size_t bytes, size_t count, bool clear, - const char *label); - -void *tal_dup_(const tal_t *ctx, const void *p TAKES, size_t size, - size_t n, size_t extra, bool nullok, const char *label); -void *tal_dup_talarr_(const tal_t *ctx, const tal_t *src TAKES, - const char *label); - -tal_t *tal_steal_(const tal_t *new_parent, const tal_t *t); - -bool tal_resize_(tal_t **ctxp, size_t size, size_t count, bool clear); -bool tal_expand_(tal_t **ctxp, const void *src TAKES, size_t size, size_t count); - -bool tal_add_destructor_(const tal_t *ctx, void (*destroy)(void *me)); -bool tal_add_destructor2_(const tal_t *ctx, void (*destroy)(void *me, void *arg), - void *arg); -bool tal_del_destructor_(const tal_t *ctx, void (*destroy)(void *me)); -bool tal_del_destructor2_(const tal_t *ctx, void (*destroy)(void *me, void *arg), - void *arg); - -bool tal_add_notifier_(const tal_t *ctx, enum tal_notify_type types, - void (*notify)(tal_t *ctx, enum tal_notify_type, - void *info)); -bool tal_del_notifier_(const tal_t *ctx, - void (*notify)(tal_t *ctx, enum tal_notify_type, - void *info), - bool match_extra_arg, void *arg); -#endif /* CCAN_TAL_H */ diff --git a/src/bolt11/talstr.c b/src/bolt11/talstr.c @@ -1,315 +0,0 @@ -/* Licensed under BSD-MIT - see LICENSE file for details */ -#include <unistd.h> -#include <stdint.h> -#include <string.h> -#include <limits.h> -#include <stdlib.h> -#include "talstr.h" -#include <sys/types.h> -#include <regex.h> -#include <stdarg.h> -#include <unistd.h> -#include <stdio.h> -#include "str.h" - -char *tal_strdup_(const tal_t *ctx, const char *p, const char *label) -{ - /* We have to let through NULL for take(). */ - return tal_dup_arr_label(ctx, char, p, p ? strlen(p) + 1: 1, 0, label); -} - -char *tal_strndup_(const tal_t *ctx, const char *p, size_t n, const char *label) -{ - size_t len; - char *ret; - - /* We have to let through NULL for take(). */ - if (likely(p)) - len = strnlen(p, n); - else - len = n; - - ret = tal_dup_arr_label(ctx, char, p, len, 1, label); - if (ret) - ret[len] = '\0'; - return ret; -} - -char *tal_fmt_(const tal_t *ctx, const char *label, const char *fmt, ...) -{ - va_list ap; - char *ret; - - va_start(ap, fmt); - ret = tal_vfmt_(ctx, fmt, ap, label); - va_end(ap); - - return ret; -} - -static bool do_vfmt(char **buf, size_t off, const char *fmt, va_list ap) -{ - /* A decent guess to start. */ - size_t max = strlen(fmt) * 2 + 1; - bool ok; - - for (;;) { - va_list ap2; - int ret; - - if (!tal_resize(buf, off + max)) { - ok = false; - break; - } - - va_copy(ap2, ap); - ret = vsnprintf(*buf + off, max, fmt, ap2); - va_end(ap2); - - if (ret < max) { - ok = true; - /* Make sure tal_count() is correct! */ - tal_resize(buf, off + ret + 1); - break; - } - max *= 2; - } - - if (taken(fmt)) - tal_free(fmt); - return ok; -} - -char *tal_vfmt_(const tal_t *ctx, const char *fmt, va_list ap, const char *label) -{ - char *buf; - - if (!fmt && taken(fmt)) - return NULL; - - /* A decent guess to start. */ - buf = tal_arr_label(ctx, char, strlen(fmt) * 2, label); - if (!do_vfmt(&buf, 0, fmt, ap)) - buf = tal_free(buf); - return buf; -} - -bool tal_append_vfmt(char **baseptr, const char *fmt, va_list ap) -{ - if (!fmt && taken(fmt)) - return false; - - return do_vfmt(baseptr, strlen(*baseptr), fmt, ap); -} - -bool tal_append_fmt(char **baseptr, const char *fmt, ...) -{ - va_list ap; - bool ret; - - va_start(ap, fmt); - ret = tal_append_vfmt(baseptr, fmt, ap); - va_end(ap); - - return ret; -} - -char *tal_strcat_(const tal_t *ctx, const char *s1, const char *s2, - const char *label) -{ - size_t len1, len2; - char *ret; - - if (unlikely(!s2) && taken(s2)) { - if (taken(s1)) - tal_free(s1); - return NULL; - } - /* We have to let through NULL for take(). */ - len1 = s1 ? strlen(s1) : 0; - len2 = strlen(s2); - - ret = tal_dup_arr_label(ctx, char, s1, len1, len2 + 1, label); - if (likely(ret)) - memcpy(ret + len1, s2, len2 + 1); - - if (taken(s2)) - tal_free(s2); - return ret; -} - -char **tal_strsplit_(const tal_t *ctx, - const char *string, const char *delims, enum strsplit flags, - const char *label) -{ - char **parts, *str; - size_t max = 64, num = 0; - - parts = tal_arr(ctx, char *, max + 1); - if (unlikely(!parts)) { - if (taken(string)) - tal_free(string); - if (taken(delims)) - tal_free(delims); - return NULL; - } - str = tal_strdup(parts, string); - if (unlikely(!str)) - goto fail; - if (unlikely(!delims) && is_taken(delims)) - goto fail; - - if (flags == STR_NO_EMPTY) - str += strspn(str, delims); - - while (*str != '\0') { - size_t len = strcspn(str, delims), dlen; - - parts[num] = str; - dlen = strspn(str + len, delims); - parts[num][len] = '\0'; - if (flags == STR_EMPTY_OK && dlen) - dlen = 1; - str += len + dlen; - if (++num == max && !tal_resize(&parts, max*=2 + 1)) - goto fail; - } - parts[num] = NULL; - - /* Ensure that tal_count() is correct. */ - if (unlikely(!tal_resize(&parts, num+1))) - goto fail; - - if (taken(delims)) - tal_free(delims); - return parts; - -fail: - tal_free(parts); - if (taken(delims)) - tal_free(delims); - return NULL; -} - -char *tal_strjoin_(const tal_t *ctx, - char *strings[], const char *delim, enum strjoin flags, - const char *label) -{ - unsigned int i; - char *ret = NULL; - size_t totlen = 0, dlen; - - if (unlikely(!strings) && is_taken(strings)) - goto fail; - - if (unlikely(!delim) && is_taken(delim)) - goto fail; - - dlen = strlen(delim); - ret = tal_arr_label(ctx, char, dlen*2+1, label); - if (!ret) - goto fail; - - ret[0] = '\0'; - for (i = 0; strings[i]; i++) { - size_t len = strlen(strings[i]); - - if (flags == STR_NO_TRAIL && !strings[i+1]) - dlen = 0; - if (!tal_resize(&ret, totlen + len + dlen + 1)) - goto fail; - memcpy(ret + totlen, strings[i], len); - totlen += len; - memcpy(ret + totlen, delim, dlen); - totlen += dlen; - } - ret[totlen] = '\0'; - /* Make sure tal_count() is correct! */ - tal_resize(&ret, totlen+1); -out: - if (taken(strings)) - tal_free(strings); - if (taken(delim)) - tal_free(delim); - return ret; -fail: - ret = tal_free(ret); - goto out; -} - -static size_t count_open_braces(const char *string) -{ -#if 1 - size_t num = 0, esc = 0; - - while (*string) { - if (*string == '\\') - esc++; - else { - /* An odd number of \ means it's escaped. */ - if (*string == '(' && (esc & 1) == 0) - num++; - esc = 0; - } - string++; - } - return num; -#else - return strcount(string, "("); -#endif -} - -bool tal_strreg_(const tal_t *ctx, const char *string, const char *label, - const char *regex, ...) -{ - size_t nmatch = 1 + count_open_braces(regex); - regmatch_t matches[nmatch]; - regex_t r; - bool ret = false; - unsigned int i; - va_list ap; - - if (unlikely(!regex) && is_taken(regex)) - goto fail_no_re; - - if (regcomp(&r, regex, REG_EXTENDED) != 0) - goto fail_no_re; - - if (unlikely(!string) && is_taken(string)) - goto fail; - - if (regexec(&r, string, nmatch, matches, 0) != 0) - goto fail; - - ret = true; - va_start(ap, regex); - for (i = 1; i < nmatch; i++) { - char **arg = va_arg(ap, char **); - if (arg) { - /* eg. ([a-z])? can give "no match". */ - if (matches[i].rm_so == -1) - *arg = NULL; - else { - *arg = tal_strndup_(ctx, - string + matches[i].rm_so, - matches[i].rm_eo - - matches[i].rm_so, - label); - /* FIXME: If we fail, we set some and leak! */ - if (!*arg) { - ret = false; - break; - } - } - } - } - va_end(ap); -fail: - regfree(&r); -fail_no_re: - if (taken(regex)) - tal_free(regex); - if (taken(string)) - tal_free(string); - return ret; -} diff --git a/src/bolt11/talstr.h b/src/bolt11/talstr.h @@ -1,225 +0,0 @@ -/* Licensed under BSD-MIT - see LICENSE file for details */ -#ifndef CCAN_STR_TAL_H -#define CCAN_STR_TAL_H -#ifdef TAL_USE_TALLOC -#include <ccan/tal/talloc/talloc.h> -#else -#include "tal.h" -#endif -#include <string.h> -#include <stdbool.h> - -/** - * tal_strdup - duplicate a string - * @ctx: NULL, or tal allocated object to be parent. - * @p: the string to copy (can be take()). - * - * The returned string will have tal_count() == strlen() + 1. - */ -#define tal_strdup(ctx, p) tal_strdup_(ctx, p, TAL_LABEL(char, "[]")) -char *tal_strdup_(const tal_t *ctx, const char *p TAKES, const char *label); - -/** - * tal_strndup - duplicate a limited amount of a string. - * @ctx: NULL, or tal allocated object to be parent. - * @p: the string to copy (can be take()). - * @n: the maximum length to copy. - * - * Always gives a nul-terminated string, with strlen() <= @n. - * The returned string will have tal_count() == strlen() + 1. - */ -#define tal_strndup(ctx, p, n) tal_strndup_(ctx, p, n, TAL_LABEL(char, "[]")) -char *tal_strndup_(const tal_t *ctx, const char *p TAKES, size_t n, - const char *label); - -/** - * tal_fmt - allocate a formatted string - * @ctx: NULL, or tal allocated object to be parent. - * @fmt: the printf-style format (can be take()). - * - * The returned string will have tal_count() == strlen() + 1. - */ -#define tal_fmt(ctx, ...) \ - tal_fmt_(ctx, TAL_LABEL(char, "[]"), __VA_ARGS__) -char *tal_fmt_(const tal_t *ctx, const char *label, const char *fmt TAKES, - ...) PRINTF_FMT(3,4); - -/** - * tal_vfmt - allocate a formatted string (va_list version) - * @ctx: NULL, or tal allocated object to be parent. - * @fmt: the printf-style format (can be take()). - * @va: the va_list containing the format args. - * - * The returned string will have tal_count() == strlen() + 1. - */ -#define tal_vfmt(ctx, fmt, va) \ - tal_vfmt_(ctx, fmt, va, TAL_LABEL(char, "[]")) -char *tal_vfmt_(const tal_t *ctx, const char *fmt TAKES, va_list ap, - const char *label) - PRINTF_FMT(2,0); - -/** - * tal_append_fmt - append a formatted string to a talloc string. - * @baseptr: a pointer to the tal string to be appended to. - * @fmt: the printf-style format (can be take()). - * - * Returns false on allocation failure. - * Otherwise tal_count(*@baseptr) == strlen(*@baseptr) + 1. - */ -bool tal_append_fmt(char **baseptr, const char *fmt TAKES, ...) PRINTF_FMT(2,3); - -/** - * tal_append_vfmt - append a formatted string to a talloc string (va_list) - * @baseptr: a pointer to the tal string to be appended to. - * @fmt: the printf-style format (can be take()). - * @va: the va_list containing the format args. - * - * Returns false on allocation failure. - * Otherwise tal_count(*@baseptr) == strlen(*@baseptr) + 1. - */ -bool tal_append_vfmt(char **baseptr, const char *fmt TAKES, va_list ap); - -/** - * tal_strcat - join two strings together - * @ctx: NULL, or tal allocated object to be parent. - * @s1: the first string (can be take()). - * @s2: the second string (can be take()). - * - * The returned string will have tal_count() == strlen() + 1. - */ -#define tal_strcat(ctx, s1, s2) tal_strcat_(ctx, s1, s2, TAL_LABEL(char, "[]")) -char *tal_strcat_(const tal_t *ctx, const char *s1 TAKES, const char *s2 TAKES, - const char *label); - -enum strsplit { - STR_EMPTY_OK, - STR_NO_EMPTY -}; - -/** - * tal_strsplit - Split string into an array of substrings - * @ctx: the context to tal from (often NULL). - * @string: the string to split (can be take()). - * @delims: delimiters where lines should be split (can be take()). - * @flags: whether to include empty substrings. - * - * This function splits a single string into multiple strings. - * - * If @string is take(), the returned array will point into the - * mangled @string. - * - * Multiple delimiters result in empty substrings. By definition, no - * delimiters will appear in the substrings. - * - * The final char * in the array will be NULL, and tal_count() will - * return the number of elements plus 1 (for that NULL). - * - * Example: - * #include <ccan/tal/str/str.h> - * ... - * static unsigned int count_long_lines(const char *string) - * { - * char **lines; - * unsigned int i, long_lines = 0; - * - * // Can only fail on out-of-memory. - * lines = tal_strsplit(NULL, string, "\n", STR_NO_EMPTY); - * for (i = 0; lines[i] != NULL; i++) - * if (strlen(lines[i]) > 80) - * long_lines++; - * tal_free(lines); - * return long_lines; - * } - */ -#define tal_strsplit(ctx, string, delims, flag) \ - tal_strsplit_(ctx, string, delims, flag, TAL_LABEL(char *, "[]")) -char **tal_strsplit_(const tal_t *ctx, - const char *string TAKES, - const char *delims TAKES, - enum strsplit flag, - const char *label); - -enum strjoin { - STR_TRAIL, - STR_NO_TRAIL -}; - -/** - * tal_strjoin - Join an array of substrings into one long string - * @ctx: the context to tal from (often NULL). - * @strings: the NULL-terminated array of strings to join (can be take()) - * @delim: the delimiter to insert between the strings (can be take()) - * @flags: whether to add a delimieter to the end - * - * This function joins an array of strings into a single string. The - * return value is allocated using tal. Each string in @strings is - * followed by a copy of @delim. - * - * The returned string will have tal_count() == strlen() + 1. - * - * Example: - * // Append the string "--EOL" to each line. - * static char *append_to_all_lines(const char *string) - * { - * char **lines, *ret; - * - * lines = tal_strsplit(NULL, string, "\n", STR_EMPTY_OK); - * ret = tal_strjoin(NULL, lines, "-- EOL\n", STR_TRAIL); - * tal_free(lines); - * return ret; - * } - */ -#define tal_strjoin(ctx, strings, delim, flags) \ - tal_strjoin_(ctx, strings, delim, flags, TAL_LABEL(char, "[]")) -char *tal_strjoin_(const void *ctx, - char *strings[] TAKES, - const char *delim TAKES, - enum strjoin flags, - const char *label); - -/** - * tal_strreg - match/extract from a string via (extended) regular expressions. - * @ctx: the context to tal from (often NULL) - * @string: the string to try to match (can be take()) - * @regex: the regular expression to match (can be take()) - * ...: pointers to strings to allocate for subexpressions. - * - * Returns true if we matched, in which case any parenthesized - * expressions in @regex are allocated and placed in the char ** - * arguments following @regex. NULL arguments mean the match is not - * saved. The order of the strings is the order - * of opening braces in the expression: in the case of repeated - * expressions (eg "([a-z])*") the last one is saved, in the case of - * non-existent matches (eg "([a-z]*)?") the pointer is set to NULL. - * - * Allocation failures or malformed regular expressions return false. - * The allocated strings will have tal_count() == strlen() + 1. - * - * See Also: - * regcomp(3), regex(3). - * - * Example: - * // Given "My name is Rusty" outputs "Hello Rusty!\n" - * // Given "my first name is Rusty Russell" outputs "Hello Rusty Russell!\n" - * // Given "My name isnt Rusty Russell" outputs "Hello there!\n" - * int main(int argc, char *argv[]) - * { - * char *person, *input; - * - * (void)argc; - * // Join args and trim trailing space. - * input = tal_strjoin(NULL, argv+1, " ", STR_NO_TRAIL); - * if (tal_strreg(NULL, input, - * "[Mm]y (first )?name is ([A-Za-z ]+)", - * NULL, &person)) - * printf("Hello %s!\n", person); - * else - * printf("Hello there!\n"); - * return 0; - * } - */ -#define tal_strreg(ctx, string, ...) \ - tal_strreg_(ctx, string, TAL_LABEL(char, "[]"), __VA_ARGS__) -bool tal_strreg_(const void *ctx, const char *string TAKES, - const char *label, const char *regex, ...); -#endif /* CCAN_STR_TAL_H */ diff --git a/src/bolt11/typesafe_cb.h b/src/bolt11/typesafe_cb.h @@ -1,134 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#ifndef CCAN_TYPESAFE_CB_H -#define CCAN_TYPESAFE_CB_H -#include "../config.h" - -#if HAVE_TYPEOF && HAVE_BUILTIN_CHOOSE_EXPR && HAVE_BUILTIN_TYPES_COMPATIBLE_P -/** - * typesafe_cb_cast - only cast an expression if it matches a given type - * @desttype: the type to cast to - * @oktype: the type we allow - * @expr: the expression to cast - * - * This macro is used to create functions which allow multiple types. - * The result of this macro is used somewhere that a @desttype type is - * expected: if @expr is exactly of type @oktype, then it will be - * cast to @desttype type, otherwise left alone. - * - * This macro can be used in static initializers. - * - * This is merely useful for warnings: if the compiler does not - * support the primitives required for typesafe_cb_cast(), it becomes an - * unconditional cast, and the @oktype argument is not used. In - * particular, this means that @oktype can be a type which uses the - * "typeof": it will not be evaluated if typeof is not supported. - * - * Example: - * // We can take either an unsigned long or a void *. - * void _set_some_value(void *val); - * #define set_some_value(e) \ - * _set_some_value(typesafe_cb_cast(void *, unsigned long, (e))) - */ -#define typesafe_cb_cast(desttype, oktype, expr) \ - __builtin_choose_expr( \ - __builtin_types_compatible_p(__typeof__(0?(expr):(expr)), \ - oktype), \ - (desttype)(expr), (expr)) -#else -#define typesafe_cb_cast(desttype, oktype, expr) ((desttype)(expr)) -#endif - -/** - * typesafe_cb_cast3 - only cast an expression if it matches given types - * @desttype: the type to cast to - * @ok1: the first type we allow - * @ok2: the second type we allow - * @ok3: the third type we allow - * @expr: the expression to cast - * - * This is a convenient wrapper for multiple typesafe_cb_cast() calls. - * You can chain them inside each other (ie. use typesafe_cb_cast() - * for expr) if you need more than 3 arguments. - * - * Example: - * // We can take either a long, unsigned long, void * or a const void *. - * void _set_some_value(void *val); - * #define set_some_value(expr) \ - * _set_some_value(typesafe_cb_cast3(void *,, \ - * long, unsigned long, const void *,\ - * (expr))) - */ -#define typesafe_cb_cast3(desttype, ok1, ok2, ok3, expr) \ - typesafe_cb_cast(desttype, ok1, \ - typesafe_cb_cast(desttype, ok2, \ - typesafe_cb_cast(desttype, ok3, \ - (expr)))) - -/** - * typesafe_cb - cast a callback function if it matches the arg - * @rtype: the return type of the callback function - * @atype: the (pointer) type which the callback function expects. - * @fn: the callback function to cast - * @arg: the (pointer) argument to hand to the callback function. - * - * If a callback function takes a single argument, this macro does - * appropriate casts to a function which takes a single atype argument if the - * callback provided matches the @arg. - * - * It is assumed that @arg is of pointer type: usually @arg is passed - * or assigned to a void * elsewhere anyway. - * - * Example: - * void _register_callback(void (*fn)(void *arg), void *arg); - * #define register_callback(fn, arg) \ - * _register_callback(typesafe_cb(void, (fn), void*, (arg)), (arg)) - */ -#define typesafe_cb(rtype, atype, fn, arg) \ - typesafe_cb_cast(rtype (*)(atype), \ - rtype (*)(__typeof__(arg)), \ - (fn)) - -/** - * typesafe_cb_preargs - cast a callback function if it matches the arg - * @rtype: the return type of the callback function - * @atype: the (pointer) type which the callback function expects. - * @fn: the callback function to cast - * @arg: the (pointer) argument to hand to the callback function. - * - * This is a version of typesafe_cb() for callbacks that take other arguments - * before the @arg. - * - * Example: - * void _register_callback(void (*fn)(int, void *arg), void *arg); - * #define register_callback(fn, arg) \ - * _register_callback(typesafe_cb_preargs(void, void *, \ - * (fn), (arg), int), \ - * (arg)) - */ -#define typesafe_cb_preargs(rtype, atype, fn, arg, ...) \ - typesafe_cb_cast(rtype (*)(__VA_ARGS__, atype), \ - rtype (*)(__VA_ARGS__, __typeof__(arg)), \ - (fn)) - -/** - * typesafe_cb_postargs - cast a callback function if it matches the arg - * @rtype: the return type of the callback function - * @atype: the (pointer) type which the callback function expects. - * @fn: the callback function to cast - * @arg: the (pointer) argument to hand to the callback function. - * - * This is a version of typesafe_cb() for callbacks that take other arguments - * after the @arg. - * - * Example: - * void _register_callback(void (*fn)(void *arg, int), void *arg); - * #define register_callback(fn, arg) \ - * _register_callback(typesafe_cb_postargs(void, (fn), void *, \ - * (arg), int), \ - * (arg)) - */ -#define typesafe_cb_postargs(rtype, atype, fn, arg, ...) \ - typesafe_cb_cast(rtype (*)(atype, __VA_ARGS__), \ - rtype (*)(__typeof__(arg), __VA_ARGS__), \ - (fn)) -#endif /* CCAN_CAST_IF_TYPE_H */ diff --git a/src/bolt11/utf8.c b/src/bolt11/utf8.c @@ -1,199 +0,0 @@ -/* MIT (BSD) license - see LICENSE file for details - taken from ccan. thanks rusty! */ - -#include "utf8.h" -#include <errno.h> -#include <stdlib.h> - -/* I loved this table, so I stole it: */ -/* - * Copyright (c) 2017 Christian Hansen <chansen@cpan.org> - * <https://github.com/chansen/c-utf8-valid> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * UTF-8 Encoding Form - * - * U+0000..U+007F 0xxxxxxx <= 7 bits - * U+0080..U+07FF 110xxxxx 10xxxxxx <= 11 bits - * U+0800..U+FFFF 1110xxxx 10xxxxxx 10xxxxxx <= 16 bits - * U+10000..U+10FFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx <= 21 bits - * - * - * U+0000..U+007F 00..7F - * N C0..C1 80..BF 1100000x 10xxxxxx - * U+0080..U+07FF C2..DF 80..BF - * N E0 80..9F 80..BF 11100000 100xxxxx - * U+0800..U+0FFF E0 A0..BF 80..BF - * U+1000..U+CFFF E1..EC 80..BF 80..BF - * U+D000..U+D7FF ED 80..9F 80..BF - * S ED A0..BF 80..BF 11101101 101xxxxx - * U+E000..U+FFFF EE..EF 80..BF 80..BF - * N F0 80..8F 80..BF 80..BF 11110000 1000xxxx - * U+10000..U+3FFFF F0 90..BF 80..BF 80..BF - * U+40000..U+FFFFF F1..F3 80..BF 80..BF 80..BF - * U+100000..U+10FFFF F4 80..8F 80..BF 80..BF 11110100 1000xxxx - * - * Legend: - * N = Non-shortest form - * S = Surrogates - */ -bool utf8_decode(struct utf8_state *utf8_state, char c) -{ - if (utf8_state->used_len == utf8_state->total_len) { - utf8_state->used_len = 1; - /* First character in sequence. */ - if (((unsigned char)c & 0x80) == 0) { - /* ASCII, easy. */ - if (c == 0) - goto bad_encoding; - utf8_state->total_len = 1; - utf8_state->c = c; - goto finished_decoding; - } else if (((unsigned char)c & 0xE0) == 0xC0) { - utf8_state->total_len = 2; - utf8_state->c = ((unsigned char)c & 0x1F); - return false; - } else if (((unsigned char)c & 0xF0) == 0xE0) { - utf8_state->total_len = 3; - utf8_state->c = ((unsigned char)c & 0x0F); - return false; - } else if (((unsigned char)c & 0xF8) == 0xF0) { - utf8_state->total_len = 4; - utf8_state->c = ((unsigned char)c & 0x07); - return false; - } - goto bad_encoding; - } - - if (((unsigned char)c & 0xC0) != 0x80) - goto bad_encoding; - - utf8_state->c <<= 6; - utf8_state->c |= ((unsigned char)c & 0x3F); - - utf8_state->used_len++; - if (utf8_state->used_len == utf8_state->total_len) - goto finished_decoding; - return false; - -finished_decoding: - if (utf8_state->c == 0 || utf8_state->c > 0x10FFFF) - errno = ERANGE; - /* The UTF-16 "surrogate range": illegal in UTF-8 */ - else if (utf8_state->total_len == 3 - && (utf8_state->c & 0xFFFFF800) == 0x0000D800) - errno = ERANGE; - else { - int min_bits; - switch (utf8_state->total_len) { - case 1: - min_bits = 0; - break; - case 2: - min_bits = 7; - break; - case 3: - min_bits = 11; - break; - case 4: - min_bits = 16; - break; - default: - abort(); - } - if ((utf8_state->c >> min_bits) == 0) - errno = EFBIG; - else - errno = 0; - } - return true; - -bad_encoding: - utf8_state->total_len = utf8_state->used_len; - errno = EINVAL; - return true; -} - -size_t utf8_encode(uint32_t point, char dest[UTF8_MAX_LEN]) -{ - if ((point >> 7) == 0) { - if (point == 0) { - errno = ERANGE; - return 0; - } - /* 0xxxxxxx */ - dest[0] = point; - return 1; - } - - if ((point >> 11) == 0) { - /* 110xxxxx 10xxxxxx */ - dest[1] = 0x80 | (point & 0x3F); - dest[0] = 0xC0 | (point >> 6); - return 2; - } - - if ((point >> 16) == 0) { - if (point >= 0xD800 && point <= 0xDFFF) { - errno = ERANGE; - return 0; - } - /* 1110xxxx 10xxxxxx 10xxxxxx */ - dest[2] = 0x80 | (point & 0x3F); - dest[1] = 0x80 | ((point >> 6) & 0x3F); - dest[0] = 0xE0 | (point >> 12); - return 3; - } - - if (point > 0x10FFFF) { - errno = ERANGE; - return 0; - } - - /* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ - dest[3] = 0x80 | (point & 0x3F); - dest[2] = 0x80 | ((point >> 6) & 0x3F); - dest[1] = 0x80 | ((point >> 12) & 0x3F); - dest[0] = 0xF0 | (point >> 18); - return 4; -} - -/* Check for valid UTF-8 */ -bool utf8_check(const void *vbuf, size_t buflen) -{ - const unsigned char *buf = vbuf; - struct utf8_state utf8_state = UTF8_STATE_INIT; - bool need_more = false; - - for (size_t i = 0; i < buflen; i++) { - if (!utf8_decode(&utf8_state, buf[i])) { - need_more = true; - continue; - } - need_more = false; - if (errno != 0) - return false; - } - return !need_more; -} - diff --git a/src/bolt11/utf8.h b/src/bolt11/utf8.h @@ -1,55 +0,0 @@ -/* MIT (BSD) license - see LICENSE file for details */ -#ifndef CCAN_UTF8_H -#define CCAN_UTF8_H -#include <inttypes.h> -#include <stdbool.h> -#include <string.h> - -/* Unicode is limited to 21 bits. */ -#define UTF8_MAX_LEN 4 - -struct utf8_state { - /* How many characters we are expecting as part of this Unicode point */ - uint16_t total_len; - /* How many characters we've already seen. */ - uint16_t used_len; - /* Compound character, aka Unicode point. */ - uint32_t c; -}; - -#define UTF8_STATE_INIT { 0, 0, 0 } - -static inline void utf8_state_init(struct utf8_state *utf8_state) -{ - memset(utf8_state, 0, sizeof(*utf8_state)); -} - -/** - * utf8_decode - continue UTF8 decoding with this character. - * @utf8_state - initialized UTF8 state. - * @c - the character. - * - * Returns false if it needs another character to give results. - * Otherwise returns true, @utf8_state can be reused without initializeation, - * and sets errno: - * 0: success - * EINVAL: bad encoding (including a NUL character). - * EFBIG: not a minimal encoding. - * ERANGE: encoding of invalid character. - * - * You can extract the character from @utf8_state->c; @utf8_state->used_len - * indicates how many characters have been consumed. - */ -bool utf8_decode(struct utf8_state *utf8_state, char c); - -/** - * utf8_encode - encode a point into UTF8. - * @point - Unicode point to include. - * @dest - buffer to fill. - * - * Returns 0 if point was invalid, otherwise bytes of dest used. - * Sets errno to ERANGE if point was invalid. - */ -size_t utf8_encode(uint32_t point, char dest[UTF8_MAX_LEN]); - -#endif /* CCAN_UTF8_H */ diff --git a/src/compiler.h b/src/compiler.h @@ -1,323 +0,0 @@ -/* CC0 (Public domain) - see LICENSE file for details */ -#ifndef CCAN_COMPILER_H -#define CCAN_COMPILER_H -#include "config.h" - -#if HAVE_UNALIGNED_ACCESS -#define alignment_ok(p, n) 1 -#else -#define alignment_ok(p, n) ((size_t)(p) % (n) == 0) -#endif - -#ifndef COLD -#if HAVE_ATTRIBUTE_COLD -/** - * COLD - a function is unlikely to be called. - * - * Used to mark an unlikely code path and optimize appropriately. - * It is usually used on logging or error routines. - * - * Example: - * static void COLD moan(const char *reason) - * { - * fprintf(stderr, "Error: %s (%s)\n", reason, strerror(errno)); - * } - */ -#define COLD __attribute__((__cold__)) -#else -#define COLD -#endif -#endif - -#ifndef NORETURN -#if HAVE_ATTRIBUTE_NORETURN -/** - * NORETURN - a function does not return - * - * Used to mark a function which exits; useful for suppressing warnings. - * - * Example: - * static void NORETURN fail(const char *reason) - * { - * fprintf(stderr, "Error: %s (%s)\n", reason, strerror(errno)); - * exit(1); - * } - */ -#define NORETURN __attribute__((__noreturn__)) -#else -#define NORETURN -#endif -#endif - -#ifndef PRINTF_FMT -#if HAVE_ATTRIBUTE_PRINTF -/** - * PRINTF_FMT - a function takes printf-style arguments - * @nfmt: the 1-based number of the function's format argument. - * @narg: the 1-based number of the function's first variable argument. - * - * This allows the compiler to check your parameters as it does for printf(). - * - * Example: - * void PRINTF_FMT(2,3) my_printf(const char *prefix, const char *fmt, ...); - */ -#define PRINTF_FMT(nfmt, narg) \ - __attribute__((format(__printf__, nfmt, narg))) -#else -#define PRINTF_FMT(nfmt, narg) -#endif -#endif - -#ifndef CONST_FUNCTION -#if HAVE_ATTRIBUTE_CONST -/** - * CONST_FUNCTION - a function's return depends only on its argument - * - * This allows the compiler to assume that the function will return the exact - * same value for the exact same arguments. This implies that the function - * must not use global variables, or dereference pointer arguments. - */ -#define CONST_FUNCTION __attribute__((__const__)) -#else -#define CONST_FUNCTION -#endif - -#ifndef PURE_FUNCTION -#if HAVE_ATTRIBUTE_PURE -/** - * PURE_FUNCTION - a function is pure - * - * A pure function is one that has no side effects other than it's return value - * and uses no inputs other than it's arguments and global variables. - */ -#define PURE_FUNCTION __attribute__((__pure__)) -#else -#define PURE_FUNCTION -#endif -#endif -#endif - -#if HAVE_ATTRIBUTE_UNUSED -#ifndef UNNEEDED -/** - * UNNEEDED - a variable/function may not be needed - * - * This suppresses warnings about unused variables or functions, but tells - * the compiler that if it is unused it need not emit it into the source code. - * - * Example: - * // With some preprocessor options, this is unnecessary. - * static UNNEEDED int counter; - * - * // With some preprocessor options, this is unnecessary. - * static UNNEEDED void add_to_counter(int add) - * { - * counter += add; - * } - */ -#define UNNEEDED __attribute__((__unused__)) -#endif - -#ifndef NEEDED -#if HAVE_ATTRIBUTE_USED -/** - * NEEDED - a variable/function is needed - * - * This suppresses warnings about unused variables or functions, but tells - * the compiler that it must exist even if it (seems) unused. - * - * Example: - * // Even if this is unused, these are vital for debugging. - * static NEEDED int counter; - * static NEEDED void dump_counter(void) - * { - * printf("Counter is %i\n", counter); - * } - */ -#define NEEDED __attribute__((__used__)) -#else -/* Before used, unused functions and vars were always emitted. */ -#define NEEDED __attribute__((__unused__)) -#endif -#endif - -#ifndef UNUSED -/** - * UNUSED - a parameter is unused - * - * Some compilers (eg. gcc with -W or -Wunused) warn about unused - * function parameters. This suppresses such warnings and indicates - * to the reader that it's deliberate. - * - * Example: - * // This is used as a callback, so needs to have this prototype. - * static int some_callback(void *unused UNUSED) - * { - * return 0; - * } - */ -#define UNUSED __attribute__((__unused__)) -#endif -#else -#ifndef UNNEEDED -#define UNNEEDED -#endif -#ifndef NEEDED -#define NEEDED -#endif -#ifndef UNUSED -#define UNUSED -#endif -#endif - -#ifndef IS_COMPILE_CONSTANT -#if HAVE_BUILTIN_CONSTANT_P -/** - * IS_COMPILE_CONSTANT - does the compiler know the value of this expression? - * @expr: the expression to evaluate - * - * When an expression manipulation is complicated, it is usually better to - * implement it in a function. However, if the expression being manipulated is - * known at compile time, it is better to have the compiler see the entire - * expression so it can simply substitute the result. - * - * This can be done using the IS_COMPILE_CONSTANT() macro. - * - * Example: - * enum greek { ALPHA, BETA, GAMMA, DELTA, EPSILON }; - * - * // Out-of-line version. - * const char *greek_name(enum greek greek); - * - * // Inline version. - * static inline const char *_greek_name(enum greek greek) - * { - * switch (greek) { - * case ALPHA: return "alpha"; - * case BETA: return "beta"; - * case GAMMA: return "gamma"; - * case DELTA: return "delta"; - * case EPSILON: return "epsilon"; - * default: return "**INVALID**"; - * } - * } - * - * // Use inline if compiler knows answer. Otherwise call function - * // to avoid copies of the same code everywhere. - * #define greek_name(g) \ - * (IS_COMPILE_CONSTANT(greek) ? _greek_name(g) : greek_name(g)) - */ -#define IS_COMPILE_CONSTANT(expr) __builtin_constant_p(expr) -#else -/* If we don't know, assume it's not. */ -#define IS_COMPILE_CONSTANT(expr) 0 -#endif -#endif - -#ifndef WARN_UNUSED_RESULT -#if HAVE_WARN_UNUSED_RESULT -/** - * WARN_UNUSED_RESULT - warn if a function return value is unused. - * - * Used to mark a function where it is extremely unlikely that the caller - * can ignore the result, eg realloc(). - * - * Example: - * // buf param may be freed by this; need return value! - * static char *WARN_UNUSED_RESULT enlarge(char *buf, unsigned *size) - * { - * return realloc(buf, (*size) *= 2); - * } - */ -#define WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) -#else -#define WARN_UNUSED_RESULT -#endif -#endif - - -#if HAVE_ATTRIBUTE_DEPRECATED -/** - * WARN_DEPRECATED - warn that a function/type/variable is deprecated when used. - * - * Used to mark a function, type or variable should not be used. - * - * Example: - * WARN_DEPRECATED char *oldfunc(char *buf); - */ -#define WARN_DEPRECATED __attribute__((__deprecated__)) -#else -#define WARN_DEPRECATED -#endif - - -#if HAVE_ATTRIBUTE_NONNULL -/** - * NO_NULL_ARGS - specify that no arguments to this function can be NULL. - * - * The compiler will warn if any pointer args are NULL. - * - * Example: - * NO_NULL_ARGS char *my_copy(char *buf); - */ -#define NO_NULL_ARGS __attribute__((__nonnull__)) - -/** - * NON_NULL_ARGS - specify that some arguments to this function can't be NULL. - * @...: 1-based argument numbers for which args can't be NULL. - * - * The compiler will warn if any of the specified pointer args are NULL. - * - * Example: - * char *my_copy2(char *buf, char *maybenull) NON_NULL_ARGS(1); - */ -#define NON_NULL_ARGS(...) __attribute__((__nonnull__(__VA_ARGS__))) -#else -#define NO_NULL_ARGS -#define NON_NULL_ARGS(...) -#endif - -#if HAVE_ATTRIBUTE_RETURNS_NONNULL -/** - * RETURNS_NONNULL - specify that this function cannot return NULL. - * - * Mainly an optimization opportunity, but can also suppress warnings. - * - * Example: - * RETURNS_NONNULL char *my_copy(char *buf); - */ -#define RETURNS_NONNULL __attribute__((__returns_nonnull__)) -#else -#define RETURNS_NONNULL -#endif - -#if HAVE_ATTRIBUTE_SENTINEL -/** - * LAST_ARG_NULL - specify the last argument of a variadic function must be NULL. - * - * The compiler will warn if the last argument isn't NULL. - * - * Example: - * char *join_string(char *buf, ...) LAST_ARG_NULL; - */ -#define LAST_ARG_NULL __attribute__((__sentinel__)) -#else -#define LAST_ARG_NULL -#endif - -#if HAVE_BUILTIN_CPU_SUPPORTS -/** - * cpu_supports - test if current CPU supports the named feature. - * - * This takes a literal string, and currently only works on glibc platforms. - * - * Example: - * if (cpu_supports("mmx")) - * printf("MMX support engaged!\n"); - */ -#define cpu_supports(x) __builtin_cpu_supports(x) -#else -#define cpu_supports(x) 0 -#endif /* HAVE_BUILTIN_CPU_SUPPORTS */ - -#endif /* CCAN_COMPILER_H */ diff --git a/src/cursor.h b/src/cursor.h @@ -2,7 +2,7 @@ #ifndef JB55_CURSOR_H #define JB55_CURSOR_H -#include "bolt11/likely.h" +#include "ccan/likely/likely.h" #include <stdio.h> #include <inttypes.h> diff --git a/src/endian.h b/src/endian.h @@ -1,365 +0,0 @@ -/* CC0 (Public domain) */ -#ifndef CCAN_ENDIAN_H -#define CCAN_ENDIAN_H -#include <stdint.h> - -#include "config.h" -#include "cursor.h" - -/** - * BSWAP_16 - reverse bytes in a constant uint16_t value. - * @val: constant value whose bytes to swap. - * - * Designed to be usable in constant-requiring initializers. - * - * Example: - * struct mystruct { - * char buf[BSWAP_16(0x1234)]; - * }; - */ -#define BSWAP_16(val) \ - ((((uint16_t)(val) & 0x00ff) << 8) \ - | (((uint16_t)(val) & 0xff00) >> 8)) - -/** - * BSWAP_32 - reverse bytes in a constant uint32_t value. - * @val: constant value whose bytes to swap. - * - * Designed to be usable in constant-requiring initializers. - * - * Example: - * struct mystruct { - * char buf[BSWAP_32(0xff000000)]; - * }; - */ -#define BSWAP_32(val) \ - ((((uint32_t)(val) & 0x000000ff) << 24) \ - | (((uint32_t)(val) & 0x0000ff00) << 8) \ - | (((uint32_t)(val) & 0x00ff0000) >> 8) \ - | (((uint32_t)(val) & 0xff000000) >> 24)) - -/** - * BSWAP_64 - reverse bytes in a constant uint64_t value. - * @val: constantvalue whose bytes to swap. - * - * Designed to be usable in constant-requiring initializers. - * - * Example: - * struct mystruct { - * char buf[BSWAP_64(0xff00000000000000ULL)]; - * }; - */ -#define BSWAP_64(val) \ - ((((uint64_t)(val) & 0x00000000000000ffULL) << 56) \ - | (((uint64_t)(val) & 0x000000000000ff00ULL) << 40) \ - | (((uint64_t)(val) & 0x0000000000ff0000ULL) << 24) \ - | (((uint64_t)(val) & 0x00000000ff000000ULL) << 8) \ - | (((uint64_t)(val) & 0x000000ff00000000ULL) >> 8) \ - | (((uint64_t)(val) & 0x0000ff0000000000ULL) >> 24) \ - | (((uint64_t)(val) & 0x00ff000000000000ULL) >> 40) \ - | (((uint64_t)(val) & 0xff00000000000000ULL) >> 56)) - -#if HAVE_BYTESWAP_H -#include <byteswap.h> -#else -/** - * bswap_16 - reverse bytes in a uint16_t value. - * @val: value whose bytes to swap. - * - * Example: - * // Output contains "1024 is 4 as two bytes reversed" - * printf("1024 is %u as two bytes reversed\n", bswap_16(1024)); - */ -static inline uint16_t bswap_16(uint16_t val) -{ - return BSWAP_16(val); -} - -/** - * bswap_32 - reverse bytes in a uint32_t value. - * @val: value whose bytes to swap. - * - * Example: - * // Output contains "1024 is 262144 as four bytes reversed" - * printf("1024 is %u as four bytes reversed\n", bswap_32(1024)); - */ -static inline uint32_t bswap_32(uint32_t val) -{ - return BSWAP_32(val); -} -#endif /* !HAVE_BYTESWAP_H */ - -#if !HAVE_BSWAP_64 -/** - * bswap_64 - reverse bytes in a uint64_t value. - * @val: value whose bytes to swap. - * - * Example: - * // Output contains "1024 is 1125899906842624 as eight bytes reversed" - * printf("1024 is %llu as eight bytes reversed\n", - * (unsigned long long)bswap_64(1024)); - */ -static inline uint64_t bswap_64(uint64_t val) -{ - return BSWAP_64(val); -} -#endif - -/* Needed for Glibc like endiness check */ -#define __LITTLE_ENDIAN 1234 -#define __BIG_ENDIAN 4321 - -/* Sanity check the defines. We don't handle weird endianness. */ -#if !HAVE_LITTLE_ENDIAN && !HAVE_BIG_ENDIAN -#error "Unknown endian" -#elif HAVE_LITTLE_ENDIAN && HAVE_BIG_ENDIAN -#error "Can't compile for both big and little endian." -#elif HAVE_LITTLE_ENDIAN -#ifndef __BYTE_ORDER -#define __BYTE_ORDER __LITTLE_ENDIAN -#elif __BYTE_ORDER != __LITTLE_ENDIAN -#error "__BYTE_ORDER already defined, but not equal to __LITTLE_ENDIAN" -#endif -#elif HAVE_BIG_ENDIAN -#ifndef __BYTE_ORDER -#define __BYTE_ORDER __BIG_ENDIAN -#elif __BYTE_ORDER != __BIG_ENDIAN -#error "__BYTE_ORDER already defined, but not equal to __BIG_ENDIAN" -#endif -#endif - - -#ifdef __CHECKER__ -/* sparse needs forcing to remove bitwise attribute from ccan/short_types */ -#define ENDIAN_CAST __attribute__((force)) -#define ENDIAN_TYPE __attribute__((bitwise)) -#else -#define ENDIAN_CAST -#define ENDIAN_TYPE -#endif - -typedef uint64_t ENDIAN_TYPE leint64_t; -typedef uint64_t ENDIAN_TYPE beint64_t; -typedef uint32_t ENDIAN_TYPE leint32_t; -typedef uint32_t ENDIAN_TYPE beint32_t; -typedef uint16_t ENDIAN_TYPE leint16_t; -typedef uint16_t ENDIAN_TYPE beint16_t; - -#if HAVE_LITTLE_ENDIAN -/** - * CPU_TO_LE64 - convert a constant uint64_t value to little-endian - * @native: constant to convert - */ -#define CPU_TO_LE64(native) ((ENDIAN_CAST leint64_t)(native)) - -/** - * CPU_TO_LE32 - convert a constant uint32_t value to little-endian - * @native: constant to convert - */ -#define CPU_TO_LE32(native) ((ENDIAN_CAST leint32_t)(native)) - -/** - * CPU_TO_LE16 - convert a constant uint16_t value to little-endian - * @native: constant to convert - */ -#define CPU_TO_LE16(native) ((ENDIAN_CAST leint16_t)(native)) - -/** - * LE64_TO_CPU - convert a little-endian uint64_t constant - * @le_val: little-endian constant to convert - */ -#define LE64_TO_CPU(le_val) ((ENDIAN_CAST uint64_t)(le_val)) - -/** - * LE32_TO_CPU - convert a little-endian uint32_t constant - * @le_val: little-endian constant to convert - */ -#define LE32_TO_CPU(le_val) ((ENDIAN_CAST uint32_t)(le_val)) - -/** - * LE16_TO_CPU - convert a little-endian uint16_t constant - * @le_val: little-endian constant to convert - */ -#define LE16_TO_CPU(le_val) ((ENDIAN_CAST uint16_t)(le_val)) - -#else /* ... HAVE_BIG_ENDIAN */ -#define CPU_TO_LE64(native) ((ENDIAN_CAST leint64_t)BSWAP_64(native)) -#define CPU_TO_LE32(native) ((ENDIAN_CAST leint32_t)BSWAP_32(native)) -#define CPU_TO_LE16(native) ((ENDIAN_CAST leint16_t)BSWAP_16(native)) -#define LE64_TO_CPU(le_val) BSWAP_64((ENDIAN_CAST uint64_t)le_val) -#define LE32_TO_CPU(le_val) BSWAP_32((ENDIAN_CAST uint32_t)le_val) -#define LE16_TO_CPU(le_val) BSWAP_16((ENDIAN_CAST uint16_t)le_val) -#endif /* HAVE_BIG_ENDIAN */ - -#if HAVE_BIG_ENDIAN -/** - * CPU_TO_BE64 - convert a constant uint64_t value to big-endian - * @native: constant to convert - */ -#define CPU_TO_BE64(native) ((ENDIAN_CAST beint64_t)(native)) - -/** - * CPU_TO_BE32 - convert a constant uint32_t value to big-endian - * @native: constant to convert - */ -#define CPU_TO_BE32(native) ((ENDIAN_CAST beint32_t)(native)) - -/** - * CPU_TO_BE16 - convert a constant uint16_t value to big-endian - * @native: constant to convert - */ -#define CPU_TO_BE16(native) ((ENDIAN_CAST beint16_t)(native)) - -/** - * BE64_TO_CPU - convert a big-endian uint64_t constant - * @le_val: big-endian constant to convert - */ -#define BE64_TO_CPU(le_val) ((ENDIAN_CAST uint64_t)(le_val)) - -/** - * BE32_TO_CPU - convert a big-endian uint32_t constant - * @le_val: big-endian constant to convert - */ -#define BE32_TO_CPU(le_val) ((ENDIAN_CAST uint32_t)(le_val)) - -/** - * BE16_TO_CPU - convert a big-endian uint16_t constant - * @le_val: big-endian constant to convert - */ -#define BE16_TO_CPU(le_val) ((ENDIAN_CAST uint16_t)(le_val)) - -#else /* ... HAVE_LITTLE_ENDIAN */ -#define CPU_TO_BE64(native) ((ENDIAN_CAST beint64_t)BSWAP_64(native)) -#define CPU_TO_BE32(native) ((ENDIAN_CAST beint32_t)BSWAP_32(native)) -#define CPU_TO_BE16(native) ((ENDIAN_CAST beint16_t)BSWAP_16(native)) -#define BE64_TO_CPU(le_val) BSWAP_64((ENDIAN_CAST uint64_t)le_val) -#define BE32_TO_CPU(le_val) BSWAP_32((ENDIAN_CAST uint32_t)le_val) -#define BE16_TO_CPU(le_val) BSWAP_16((ENDIAN_CAST uint16_t)le_val) -#endif /* HAVE_LITTE_ENDIAN */ - - -/** - * cpu_to_le64 - convert a uint64_t value to little-endian - * @native: value to convert - */ -static inline leint64_t cpu_to_le64(uint64_t native) -{ - return CPU_TO_LE64(native); -} - -/** - * cpu_to_le32 - convert a uint32_t value to little-endian - * @native: value to convert - */ -static inline leint32_t cpu_to_le32(uint32_t native) -{ - return CPU_TO_LE32(native); -} - -/** - * cpu_to_le16 - convert a uint16_t value to little-endian - * @native: value to convert - */ -static inline leint16_t cpu_to_le16(uint16_t native) -{ - return CPU_TO_LE16(native); -} - -/** - * le64_to_cpu - convert a little-endian uint64_t value - * @le_val: little-endian value to convert - */ -static inline uint64_t le64_to_cpu(leint64_t le_val) -{ - return LE64_TO_CPU(le_val); -} - -/** - * le32_to_cpu - convert a little-endian uint32_t value - * @le_val: little-endian value to convert - */ -static inline uint32_t le32_to_cpu(leint32_t le_val) -{ - return LE32_TO_CPU(le_val); -} - -/** - * le16_to_cpu - convert a little-endian uint16_t value - * @le_val: little-endian value to convert - */ -static inline uint16_t le16_to_cpu(leint16_t le_val) -{ - return LE16_TO_CPU(le_val); -} - -/** - * cpu_to_be64 - convert a uint64_t value to big endian. - * @native: value to convert - */ -static inline beint64_t cpu_to_be64(uint64_t native) -{ - return CPU_TO_BE64(native); -} - -/** - * cpu_to_be32 - convert a uint32_t value to big endian. - * @native: value to convert - */ -static inline beint32_t cpu_to_be32(uint32_t native) -{ - return CPU_TO_BE32(native); -} - -/** - * cpu_to_be16 - convert a uint16_t value to big endian. - * @native: value to convert - */ -static inline beint16_t cpu_to_be16(uint16_t native) -{ - return CPU_TO_BE16(native); -} - -/** - * be64_to_cpu - convert a big-endian uint64_t value - * @be_val: big-endian value to convert - */ -static inline uint64_t be64_to_cpu(beint64_t be_val) -{ - return BE64_TO_CPU(be_val); -} - -/** - * be32_to_cpu - convert a big-endian uint32_t value - * @be_val: big-endian value to convert - */ -static inline uint32_t be32_to_cpu(beint32_t be_val) -{ - return BE32_TO_CPU(be_val); -} - -/** - * be16_to_cpu - convert a big-endian uint16_t value - * @be_val: big-endian value to convert - */ -static inline uint16_t be16_to_cpu(beint16_t be_val) -{ - return BE16_TO_CPU(be_val); -} - -/** - * be64/be32/be16 - 64/32/16 bit big-endian representation. - */ -typedef beint64_t be64; -typedef beint32_t be32; -typedef beint16_t be16; - -/** - * le64/le32/le16 - 64/32/16 bit little-endian representation. - */ -typedef leint64_t le64; -typedef leint32_t le32; -typedef leint16_t le16; - - -#endif /* CCAN_ENDIAN_H */ - diff --git a/src/sha256.c b/src/sha256.c @@ -1,302 +0,0 @@ -/* MIT (BSD) license - see LICENSE file for details */ -/* SHA256 core code translated from the Bitcoin project's C++: - * - * src/crypto/sha256.cpp commit 417532c8acb93c36c2b6fd052b7c11b6a2906aa2 - * Copyright (c) 2014 The Bitcoin Core developers - * Distributed under the MIT software license, see the accompanying - * file COPYING or http://www.opensource.org/licenses/mit-license.php. - */ -#include "sha256.h" -#include "endian.h" -#include "compiler.h" -#include <stdbool.h> -#include <assert.h> -#include <string.h> - -static void invalidate_sha256(struct sha256_ctx *ctx) -{ -#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL - ctx->c.md_len = 0; -#else - ctx->bytes = (size_t)-1; -#endif -} - -static void check_sha256(struct sha256_ctx *ctx) -{ -#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL - assert(ctx->c.md_len != 0); -#else - assert(ctx->bytes != (size_t)-1); -#endif -} - -#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL -void sha256_init(struct sha256_ctx *ctx) -{ - SHA256_Init(&ctx->c); -} - -void sha256_update(struct sha256_ctx *ctx, const void *p, size_t size) -{ - check_sha256(ctx); - SHA256_Update(&ctx->c, p, size); -} - -void sha256_done(struct sha256_ctx *ctx, struct sha256 *res) -{ - SHA256_Final(res->u.u8, &ctx->c); - invalidate_sha256(ctx); -} -#else -static uint32_t Ch(uint32_t x, uint32_t y, uint32_t z) -{ - return z ^ (x & (y ^ z)); -} -static uint32_t Maj(uint32_t x, uint32_t y, uint32_t z) -{ - return (x & y) | (z & (x | y)); -} -static uint32_t Sigma0(uint32_t x) -{ - return (x >> 2 | x << 30) ^ (x >> 13 | x << 19) ^ (x >> 22 | x << 10); -} -static uint32_t Sigma1(uint32_t x) -{ - return (x >> 6 | x << 26) ^ (x >> 11 | x << 21) ^ (x >> 25 | x << 7); -} -static uint32_t sigma0(uint32_t x) -{ - return (x >> 7 | x << 25) ^ (x >> 18 | x << 14) ^ (x >> 3); -} -static uint32_t sigma1(uint32_t x) -{ - return (x >> 17 | x << 15) ^ (x >> 19 | x << 13) ^ (x >> 10); -} - -/** One round of SHA-256. */ -static void Round(uint32_t a, uint32_t b, uint32_t c, uint32_t *d, uint32_t e, uint32_t f, uint32_t g, uint32_t *h, uint32_t k, uint32_t w) -{ - uint32_t t1 = *h + Sigma1(e) + Ch(e, f, g) + k + w; - uint32_t t2 = Sigma0(a) + Maj(a, b, c); - *d += t1; - *h = t1 + t2; -} - -/** Perform one SHA-256 transformation, processing a 64-byte chunk. */ -static void Transform(uint32_t *s, const uint32_t *chunk) -{ - uint32_t a = s[0], b = s[1], c = s[2], d = s[3], e = s[4], f = s[5], g = s[6], h = s[7]; - uint32_t w0, w1, w2, w3, w4, w5, w6, w7, w8, w9, w10, w11, w12, w13, w14, w15; - - Round(a, b, c, &d, e, f, g, &h, 0x428a2f98, w0 = be32_to_cpu(chunk[0])); - Round(h, a, b, &c, d, e, f, &g, 0x71374491, w1 = be32_to_cpu(chunk[1])); - Round(g, h, a, &b, c, d, e, &f, 0xb5c0fbcf, w2 = be32_to_cpu(chunk[2])); - Round(f, g, h, &a, b, c, d, &e, 0xe9b5dba5, w3 = be32_to_cpu(chunk[3])); - Round(e, f, g, &h, a, b, c, &d, 0x3956c25b, w4 = be32_to_cpu(chunk[4])); - Round(d, e, f, &g, h, a, b, &c, 0x59f111f1, w5 = be32_to_cpu(chunk[5])); - Round(c, d, e, &f, g, h, a, &b, 0x923f82a4, w6 = be32_to_cpu(chunk[6])); - Round(b, c, d, &e, f, g, h, &a, 0xab1c5ed5, w7 = be32_to_cpu(chunk[7])); - Round(a, b, c, &d, e, f, g, &h, 0xd807aa98, w8 = be32_to_cpu(chunk[8])); - Round(h, a, b, &c, d, e, f, &g, 0x12835b01, w9 = be32_to_cpu(chunk[9])); - Round(g, h, a, &b, c, d, e, &f, 0x243185be, w10 = be32_to_cpu(chunk[10])); - Round(f, g, h, &a, b, c, d, &e, 0x550c7dc3, w11 = be32_to_cpu(chunk[11])); - Round(e, f, g, &h, a, b, c, &d, 0x72be5d74, w12 = be32_to_cpu(chunk[12])); - Round(d, e, f, &g, h, a, b, &c, 0x80deb1fe, w13 = be32_to_cpu(chunk[13])); - Round(c, d, e, &f, g, h, a, &b, 0x9bdc06a7, w14 = be32_to_cpu(chunk[14])); - Round(b, c, d, &e, f, g, h, &a, 0xc19bf174, w15 = be32_to_cpu(chunk[15])); - - Round(a, b, c, &d, e, f, g, &h, 0xe49b69c1, w0 += sigma1(w14) + w9 + sigma0(w1)); - Round(h, a, b, &c, d, e, f, &g, 0xefbe4786, w1 += sigma1(w15) + w10 + sigma0(w2)); - Round(g, h, a, &b, c, d, e, &f, 0x0fc19dc6, w2 += sigma1(w0) + w11 + sigma0(w3)); - Round(f, g, h, &a, b, c, d, &e, 0x240ca1cc, w3 += sigma1(w1) + w12 + sigma0(w4)); - Round(e, f, g, &h, a, b, c, &d, 0x2de92c6f, w4 += sigma1(w2) + w13 + sigma0(w5)); - Round(d, e, f, &g, h, a, b, &c, 0x4a7484aa, w5 += sigma1(w3) + w14 + sigma0(w6)); - Round(c, d, e, &f, g, h, a, &b, 0x5cb0a9dc, w6 += sigma1(w4) + w15 + sigma0(w7)); - Round(b, c, d, &e, f, g, h, &a, 0x76f988da, w7 += sigma1(w5) + w0 + sigma0(w8)); - Round(a, b, c, &d, e, f, g, &h, 0x983e5152, w8 += sigma1(w6) + w1 + sigma0(w9)); - Round(h, a, b, &c, d, e, f, &g, 0xa831c66d, w9 += sigma1(w7) + w2 + sigma0(w10)); - Round(g, h, a, &b, c, d, e, &f, 0xb00327c8, w10 += sigma1(w8) + w3 + sigma0(w11)); - Round(f, g, h, &a, b, c, d, &e, 0xbf597fc7, w11 += sigma1(w9) + w4 + sigma0(w12)); - Round(e, f, g, &h, a, b, c, &d, 0xc6e00bf3, w12 += sigma1(w10) + w5 + sigma0(w13)); - Round(d, e, f, &g, h, a, b, &c, 0xd5a79147, w13 += sigma1(w11) + w6 + sigma0(w14)); - Round(c, d, e, &f, g, h, a, &b, 0x06ca6351, w14 += sigma1(w12) + w7 + sigma0(w15)); - Round(b, c, d, &e, f, g, h, &a, 0x14292967, w15 += sigma1(w13) + w8 + sigma0(w0)); - - Round(a, b, c, &d, e, f, g, &h, 0x27b70a85, w0 += sigma1(w14) + w9 + sigma0(w1)); - Round(h, a, b, &c, d, e, f, &g, 0x2e1b2138, w1 += sigma1(w15) + w10 + sigma0(w2)); - Round(g, h, a, &b, c, d, e, &f, 0x4d2c6dfc, w2 += sigma1(w0) + w11 + sigma0(w3)); - Round(f, g, h, &a, b, c, d, &e, 0x53380d13, w3 += sigma1(w1) + w12 + sigma0(w4)); - Round(e, f, g, &h, a, b, c, &d, 0x650a7354, w4 += sigma1(w2) + w13 + sigma0(w5)); - Round(d, e, f, &g, h, a, b, &c, 0x766a0abb, w5 += sigma1(w3) + w14 + sigma0(w6)); - Round(c, d, e, &f, g, h, a, &b, 0x81c2c92e, w6 += sigma1(w4) + w15 + sigma0(w7)); - Round(b, c, d, &e, f, g, h, &a, 0x92722c85, w7 += sigma1(w5) + w0 + sigma0(w8)); - Round(a, b, c, &d, e, f, g, &h, 0xa2bfe8a1, w8 += sigma1(w6) + w1 + sigma0(w9)); - Round(h, a, b, &c, d, e, f, &g, 0xa81a664b, w9 += sigma1(w7) + w2 + sigma0(w10)); - Round(g, h, a, &b, c, d, e, &f, 0xc24b8b70, w10 += sigma1(w8) + w3 + sigma0(w11)); - Round(f, g, h, &a, b, c, d, &e, 0xc76c51a3, w11 += sigma1(w9) + w4 + sigma0(w12)); - Round(e, f, g, &h, a, b, c, &d, 0xd192e819, w12 += sigma1(w10) + w5 + sigma0(w13)); - Round(d, e, f, &g, h, a, b, &c, 0xd6990624, w13 += sigma1(w11) + w6 + sigma0(w14)); - Round(c, d, e, &f, g, h, a, &b, 0xf40e3585, w14 += sigma1(w12) + w7 + sigma0(w15)); - Round(b, c, d, &e, f, g, h, &a, 0x106aa070, w15 += sigma1(w13) + w8 + sigma0(w0)); - - Round(a, b, c, &d, e, f, g, &h, 0x19a4c116, w0 += sigma1(w14) + w9 + sigma0(w1)); - Round(h, a, b, &c, d, e, f, &g, 0x1e376c08, w1 += sigma1(w15) + w10 + sigma0(w2)); - Round(g, h, a, &b, c, d, e, &f, 0x2748774c, w2 += sigma1(w0) + w11 + sigma0(w3)); - Round(f, g, h, &a, b, c, d, &e, 0x34b0bcb5, w3 += sigma1(w1) + w12 + sigma0(w4)); - Round(e, f, g, &h, a, b, c, &d, 0x391c0cb3, w4 += sigma1(w2) + w13 + sigma0(w5)); - Round(d, e, f, &g, h, a, b, &c, 0x4ed8aa4a, w5 += sigma1(w3) + w14 + sigma0(w6)); - Round(c, d, e, &f, g, h, a, &b, 0x5b9cca4f, w6 += sigma1(w4) + w15 + sigma0(w7)); - Round(b, c, d, &e, f, g, h, &a, 0x682e6ff3, w7 += sigma1(w5) + w0 + sigma0(w8)); - Round(a, b, c, &d, e, f, g, &h, 0x748f82ee, w8 += sigma1(w6) + w1 + sigma0(w9)); - Round(h, a, b, &c, d, e, f, &g, 0x78a5636f, w9 += sigma1(w7) + w2 + sigma0(w10)); - Round(g, h, a, &b, c, d, e, &f, 0x84c87814, w10 += sigma1(w8) + w3 + sigma0(w11)); - Round(f, g, h, &a, b, c, d, &e, 0x8cc70208, w11 += sigma1(w9) + w4 + sigma0(w12)); - Round(e, f, g, &h, a, b, c, &d, 0x90befffa, w12 += sigma1(w10) + w5 + sigma0(w13)); - Round(d, e, f, &g, h, a, b, &c, 0xa4506ceb, w13 += sigma1(w11) + w6 + sigma0(w14)); - Round(c, d, e, &f, g, h, a, &b, 0xbef9a3f7, w14 + sigma1(w12) + w7 + sigma0(w15)); - Round(b, c, d, &e, f, g, h, &a, 0xc67178f2, w15 + sigma1(w13) + w8 + sigma0(w0)); - - s[0] += a; - s[1] += b; - s[2] += c; - s[3] += d; - s[4] += e; - s[5] += f; - s[6] += g; - s[7] += h; -} - - -static void add(struct sha256_ctx *ctx, const void *p, size_t len) -{ - const unsigned char *data = p; - size_t bufsize = ctx->bytes % 64; - - if (bufsize + len >= 64) { - /* Fill the buffer, and process it. */ - memcpy(ctx->buf.u8 + bufsize, data, 64 - bufsize); - ctx->bytes += 64 - bufsize; - data += 64 - bufsize; - len -= 64 - bufsize; - Transform(ctx->s, ctx->buf.u32); - bufsize = 0; - } - - while (len >= 64) { - /* Process full chunks directly from the source. */ - if (alignment_ok(data, sizeof(uint32_t))) - Transform(ctx->s, (const uint32_t *)data); - else { - memcpy(ctx->buf.u8, data, sizeof(ctx->buf)); - Transform(ctx->s, ctx->buf.u32); - } - ctx->bytes += 64; - data += 64; - len -= 64; - } - - if (len) { - /* Fill the buffer with what remains. */ - memcpy(ctx->buf.u8 + bufsize, data, len); - ctx->bytes += len; - } -} - -void sha256_init(struct sha256_ctx *ctx) -{ - struct sha256_ctx init = SHA256_INIT; - *ctx = init; -} - -void sha256_update(struct sha256_ctx *ctx, const void *p, size_t size) -{ - check_sha256(ctx); - add(ctx, p, size); -} - -void sha256_done(struct sha256_ctx *ctx, struct sha256 *res) -{ - static const unsigned char pad[64] = {0x80}; - uint64_t sizedesc; - size_t i; - - sizedesc = cpu_to_be64((uint64_t)ctx->bytes << 3); - /* Add '1' bit to terminate, then all 0 bits, up to next block - 8. */ - add(ctx, pad, 1 + ((128 - 8 - (ctx->bytes % 64) - 1) % 64)); - /* Add number of bits of data (big endian) */ - add(ctx, &sizedesc, 8); - for (i = 0; i < sizeof(ctx->s) / sizeof(ctx->s[0]); i++) - res->u.u32[i] = cpu_to_be32(ctx->s[i]); - invalidate_sha256(ctx); -} -#endif - -void sha256(struct sha256 *sha, const void *p, size_t size) -{ - struct sha256_ctx ctx; - - sha256_init(&ctx); - sha256_update(&ctx, p, size); - sha256_done(&ctx, sha); -} - -void sha256_u8(struct sha256_ctx *ctx, uint8_t v) -{ - sha256_update(ctx, &v, sizeof(v)); -} - -void sha256_u16(struct sha256_ctx *ctx, uint16_t v) -{ - sha256_update(ctx, &v, sizeof(v)); -} - -void sha256_u32(struct sha256_ctx *ctx, uint32_t v) -{ - sha256_update(ctx, &v, sizeof(v)); -} - -void sha256_u64(struct sha256_ctx *ctx, uint64_t v) -{ - sha256_update(ctx, &v, sizeof(v)); -} - -/* Add as little-endian */ -void sha256_le16(struct sha256_ctx *ctx, uint16_t v) -{ - leint16_t lev = cpu_to_le16(v); - sha256_update(ctx, &lev, sizeof(lev)); -} - -void sha256_le32(struct sha256_ctx *ctx, uint32_t v) -{ - leint32_t lev = cpu_to_le32(v); - sha256_update(ctx, &lev, sizeof(lev)); -} - -void sha256_le64(struct sha256_ctx *ctx, uint64_t v) -{ - leint64_t lev = cpu_to_le64(v); - sha256_update(ctx, &lev, sizeof(lev)); -} - -/* Add as big-endian */ -void sha256_be16(struct sha256_ctx *ctx, uint16_t v) -{ - beint16_t bev = cpu_to_be16(v); - sha256_update(ctx, &bev, sizeof(bev)); -} - -void sha256_be32(struct sha256_ctx *ctx, uint32_t v) -{ - beint32_t bev = cpu_to_be32(v); - sha256_update(ctx, &bev, sizeof(bev)); -} - -void sha256_be64(struct sha256_ctx *ctx, uint64_t v) -{ - beint64_t bev = cpu_to_be64(v); - sha256_update(ctx, &bev, sizeof(bev)); -} - - diff --git a/src/sha256.h b/src/sha256.h @@ -1,155 +0,0 @@ - -#ifndef CCAN_CRYPTO_SHA256_H -#define CCAN_CRYPTO_SHA256_H - - -/** Output length for `wally_sha256` */ -#define SHA256_LEN 32 - - -/* BSD-MIT - see LICENSE file for details */ -/* #include "config.h" */ -#include <stdint.h> -#include <stdlib.h> - -/* Uncomment this to use openssl's SHA256 routines (and link with -lcrypto) */ -/*#define CCAN_CRYPTO_SHA256_USE_OPENSSL 1*/ - -#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL -#include <openssl/sha.h> -#endif - -/** - * struct sha256 - structure representing a completed SHA256. - * @u.u8: an unsigned char array. - * @u.u32: a 32-bit integer array. - * - * Other fields may be added to the union in future. - */ -struct sha256 { - union { - uint32_t u32[8]; - unsigned char u8[32]; - } u; -}; - -/** - * sha256 - return sha256 of an object. - * @sha256: the sha256 to fill in - * @p: pointer to memory, - * @size: the number of bytes pointed to by @p - * - * The bytes pointed to by @p is SHA256 hashed into @sha256. This is - * equivalent to sha256_init(), sha256_update() then sha256_done(). - */ -void sha256(struct sha256 *sha, const void *p, size_t size); - -/** - * struct sha256_ctx - structure to store running context for sha256 - */ -struct sha256_ctx { -#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL - SHA256_CTX c; -#else - uint32_t s[8]; - union { - uint32_t u32[16]; - unsigned char u8[64]; - } buf; - size_t bytes; -#endif -}; - -/** - * sha256_init - initialize an SHA256 context. - * @ctx: the sha256_ctx to initialize - * - * This must be called before sha256_update or sha256_done, or - * alternately you can assign SHA256_INIT. - * - * If it was already initialized, this forgets anything which was - * hashed before. - * - * Example: - * static void hash_all(const char **arr, struct sha256 *hash) - * { - * size_t i; - * struct sha256_ctx ctx; - * - * sha256_init(&ctx); - * for (i = 0; arr[i]; i++) - * sha256_update(&ctx, arr[i], strlen(arr[i])); - * sha256_done(&ctx, hash); - * } - */ -void sha256_init(struct sha256_ctx *ctx); - -/** - * SHA256_INIT - initializer for an SHA256 context. - * - * This can be used to statically initialize an SHA256 context (instead - * of sha256_init()). - * - * Example: - * static void hash_all(const char **arr, struct sha256 *hash) - * { - * size_t i; - * struct sha256_ctx ctx = SHA256_INIT; - * - * for (i = 0; arr[i]; i++) - * sha256_update(&ctx, arr[i], strlen(arr[i])); - * sha256_done(&ctx, hash); - * } - */ -#ifdef CCAN_CRYPTO_SHA256_USE_OPENSSL -#define SHA256_INIT \ - { { { 0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, \ - 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul }, \ - 0x0, 0x0, \ - { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, \ - 0x0, 0x20 } } -#else -#define SHA256_INIT \ - { { 0x6a09e667ul, 0xbb67ae85ul, 0x3c6ef372ul, 0xa54ff53aul, \ - 0x510e527ful, 0x9b05688cul, 0x1f83d9abul, 0x5be0cd19ul }, \ - { { 0 } }, 0 } -#endif - -/** - * sha256_update - include some memory in the hash. - * @ctx: the sha256_ctx to use - * @p: pointer to memory, - * @size: the number of bytes pointed to by @p - * - * You can call this multiple times to hash more data, before calling - * sha256_done(). - */ -void sha256_update(struct sha256_ctx *ctx, const void *p, size_t size); - -/** - * sha256_done - finish SHA256 and return the hash - * @ctx: the sha256_ctx to complete - * @res: the hash to return. - * - * Note that @ctx is *destroyed* by this, and must be reinitialized. - * To avoid that, pass a copy instead. - */ -void sha256_done(struct sha256_ctx *sha256, struct sha256 *res); - -/* Add various types to an SHA256 hash */ -void sha256_u8(struct sha256_ctx *ctx, uint8_t v); -void sha256_u16(struct sha256_ctx *ctx, uint16_t v); -void sha256_u32(struct sha256_ctx *ctx, uint32_t v); -void sha256_u64(struct sha256_ctx *ctx, uint64_t v); - -/* Add as little-endian */ -void sha256_le16(struct sha256_ctx *ctx, uint16_t v); -void sha256_le32(struct sha256_ctx *ctx, uint32_t v); -void sha256_le64(struct sha256_ctx *ctx, uint64_t v); - -/* Add as big-endian */ -void sha256_be16(struct sha256_ctx *ctx, uint16_t v); -void sha256_be32(struct sha256_ctx *ctx, uint32_t v); -void sha256_be64(struct sha256_ctx *ctx, uint64_t v); - -#endif /* CCAN_CRYPTO_SHA256_H */