GithubHelp home page GithubHelp logo

dcreager / libcork Goto Github PK

View Code? Open in Web Editor NEW
367.0 367.0 106.0 1.55 MB

A simple, easily embeddable cross-platform C library

Home Page: https://libcork.io/

License: BSD 3-Clause "New" or "Revised" License

Shell 1.12% Python 4.07% CMake 4.10% C 80.83% C++ 1.01% Perl 1.42% Terra 0.16% Makefile 2.02% M4 5.23% Raku 0.05%

libcork's People

Contributors

codeslinger avatar dcreager avatar ddosolitary avatar gregvirgin avatar johnzachary avatar jrtc27 avatar madeye avatar nathanfrench avatar rogers0 avatar rouge8 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

libcork's Issues

Stripped down dynamic array data structure

libcork is really awesome, but for me at least it is too difficult to keep including the entire source tree and build system just to use the dynamic array data structure in some of my projects.

I would really like to create a stripped down version consisting of just a few files, the license and a README. What’s your opinion on this?

No longer build with Cygwin 2.11.0 due to clearenv()

Cygwin has implemented clearenv() since v2.11.0 so now compiler complains about multiple declaration.

Making all in libcork
make[2]: Entering directory '/home/appveyor/shadowsocks-libev/libcork'
  CC       src/libcork/cli/libcork_la-commands.lo
  CC       src/libcork/core/libcork_la-allocator.lo
  CC       src/libcork/core/libcork_la-error.lo
  CC       src/libcork/core/libcork_la-gc.lo
  CC       src/libcork/core/libcork_la-hash.lo
  CC       src/libcork/core/libcork_la-ip-address.lo
  CC       src/libcork/core/libcork_la-mempool.lo
  CC       src/libcork/core/libcork_la-timestamp.lo
  CC       src/libcork/core/libcork_la-u128.lo
  CC       src/libcork/ds/libcork_la-array.lo
  CC       src/libcork/ds/libcork_la-bitset.lo
  CC       src/libcork/ds/libcork_la-buffer.lo
  CC       src/libcork/ds/libcork_la-dllist.lo
  CC       src/libcork/ds/libcork_la-file-stream.lo
  CC       src/libcork/ds/libcork_la-hash-table.lo
  CC       src/libcork/ds/libcork_la-managed-buffer.lo
  CC       src/libcork/ds/libcork_la-ring-buffer.lo
  CC       src/libcork/ds/libcork_la-slice.lo
  CC       src/libcork/posix/libcork_la-directory-walker.lo
  CC       src/libcork/posix/libcork_la-env.lo
src/libcork/posix/env.c:194:1: error: conflicting types for ‘clearenv’
 clearenv(void)
 ^~~~~~~~
In file included from /usr/include/stdlib.h:26:0,
                 from src/libcork/posix/env.c:10:
/usr/include/cygwin/stdlib.h:30:5: note: previous declaration of ‘clearenv’ was here
 int clearenv (void);
     ^~~~~~~~
make[2]: *** [Makefile:723: src/libcork/posix/libcork_la-env.lo] Error 1
make[2]: Leaving directory '/home/appveyor/shadowsocks-libev/libcork'

http://cygwin.1069669.n5.nabble.com/PATCH-v2-0-6-Implement-clearenv-td141025.html

Will not compile

CMake Warning:
No source or binary directory provided. Both will be assumed to be the
same as the current working directory, but note that this warning will
become a fatal error in future CMake releases.

-- The C compiler identification is GNU 10.1.0
-- The CXX compiler identification is GNU 10.1.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc - works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ - works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found PkgConfig: /usr/bin/pkg-config (found version "1.7.3")
-- Checking for module 'check'
-- Found check, version 0.14.0
fatal: not a git repository (or any of the parent directories): .git
CMake Error at CMakeLists.txt:42 (message):
Invalid version number:

-- Configuring incomplete, errors occurred!

is the output i get everytime i attempt to compile

Add managed ring-buffer (optionally thread-safe)

I use libcork in my arsenal of C libraries for various personal and professional projects which occasionally involve producer-consumer issues in which I can't malloc (typically due to 'producer' code invoked from interrupt which can't take an unbounded amount of time).

Ideally it would be thread safe but doesn't appear possible without adding to the threads directory which would, I presume, needs to be cross-platform. I'd have to investigate further to convince myself of what needs to be done.

Given some time I adapt and formalize what I've written in the past, assure it has a similar API to the existing ring-buffer, add it to dh.h and submit a pull request if others will find it useful.

Non local, non UTC timestamp display

Timezones are an unavoidable complexity in dealing with time. Libcork represents its timestamps internally as a 64bit fixed point number with the implied point between the 32 bit epoch time and a 32 bit fraction where a single bit represents 1/2^32 of a second. By convention, the internal representation is an UTC offset since the beginning of the epoch, but there is no technically feasible way to enforce this.

Time stamps can be displayed as UTC in any format supported by the underlying gmtime function for deconstructing the time and the strftime function for formatting. They can also be displayed as local time based on the TZ environment variable of the host system and the localtime function. Recent additions also support display in an ISO8601 format for both UTC and local times.

Missing is the ability to display times in an arbitrary time zone, neither UTC nor local. This is a convenience function, but can avoid analysis errors when data recorded in one time zone must be processed in another along with logs and other sources that only have local time in human readable format. While it can be argued that this is poor experimental methodology, it happens with astounding regularity.

Adding a function like

bool cork_timestamp_format_tz(const cork_timestamp ts, const tz_t zone, const char *format, char *buf, size_t size)

and its ISO equivalent would allow the time to be formatted for an arbitrary timezone.

The choice of a representation for tz_t is not as simple as it might seem. The easy out for the developer is to make tz_t an alias for another cork_timestamp (or an epoch time or an integer value) with the requirement that the fraction must be zero and the epoch time must represent a legitimate time zone offset that can be printed either as +hh, -hh, +hh:30 or -hh:30. This leaves it up to the programmer to determine the proper offset, including coping with all the DST rules, etc., in effect at the UTC time
represented by ts. The easy out for the programmer is to make tz_t a string that can be looked up with the functions associated with the timezone database (see http://www.twinsun.com/tz/tz-link.htm - top of page) to determine the offset needed for the given time. A compromise would be to create a function that takes a timezone string and returns a tz_t containing the offset.

In any case, if it is desired to represent the time zone in the formatted output in any form other than the actual offset, additional computation may be needed.

It may be possible to wrap the localtime and strftime functions in such a way that the TZ environment variable is reset locally for the duration of the conversion in which case, tz_t could be any representation that can be assigned to this variable.

Non local, non UTC timestamp display

Timezones are an unavoidable complexity in dealing with time. Libcork represents its timestamps internally as a 64bit fixed point number with the implied point between the 32 bit epoch time and a 32 bit fraction where a single bit represents 1/2^32 of a second. By convention, the internal representation is an UTC offset since the beginning of the epoch, but there is no technically feasible way to enforce this.

Time stamps can be displayed as UTC in any format supported by the underlying gmtime function for deconstructing the time and the strftime function for formatting. They can also be displayed as local time based on the TZ environment variable of the host system and the localtime function. Recent additions also support display in an ISO8601 format for both UTC and local times.

Missing is the ability to display times in an arbitrary time zone, neither UTC nor local. This is a convenience function, but can avoid analysis errors when data recorded in one time zone must be processed in another along with logs and other sources that only have local time in human readable format. While it can be argued that this is poor experimental methodology, it happens with astounding regularity.

Adding a function like

bool cork_timestamp_format_tz(const cork_timestamp ts, const tz_t zone, const char *format, char *buf, size_t size)

and its ISO equivalent would allow the time to be formatted for an arbitrary timezone.

The choice of a representation for tz_t is not as simple as it might seem. The easy out for the developer is to make tz_t an alias for another cork_timestamp (or an epoch time or an integer value) with the requirement that the fraction must be zero and the epoch time must represent a legitimate time zone offset that can be printed either as +hh, -hh, +hh:30 or -hh:30. This leaves it up to the programmer to determine the proper offset, including coping with all the DST rules, etc., in effect at the UTC time
represented by ts. The easy out for the programmer is to make tz_t a string that can be looked up with the functions associated with the timezone database (see http://www.twinsun.com/tz/tz-link.htm - top of page) to determine the offset needed for the given time. A compromise would be to create a function that takes a timezone string and returns a tz_t containing the offset.

In any case, if it is desired to represent the time zone in the formatted output in any form other than the actual offset, additional computation may be needed.

It may be possible to wrap the localtime and strftime functions in such a way that the TZ environment variable is reset locally for the duration of the conversion in which case, tz_t could be any representation that can be assigned to this variable.

pkg-config file is broken when CMAKE_INSTALL_{DOC,INCLUDE,LIB}DIR is absolute

As per title: cmake/FindCTargets.cmake has

set(prefix ${CMAKE_INSTALL_PREFIX})
set(exec_prefix "\${prefix}")
# [snip]
set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")

and so can’t handle absolute paths in CMAKE_INSTALL_{INCLUDE,LIB}DIR. The handling of CMAKE_INSTALL_DOCDIR is more complex but similarly faulty. This leads to broken .pc files on NixOS in particular.

See “Concatenating paths when building pkg-config files” for a thorough discussion of the problem and a suggested fix, or KDE’s extra-cmake-modules for a simpler approach.

Explicit support for ISO 8601 representations

Both the cork_timestamp_format_utc() and cork_timestamp_format_local() functions are capable of producing time strings in the ISO 8601 format given the appropriate "const char *format" parameters. It would be useful if the libcork.h file included #defines to support and standardize this usage.

Adding definitions such as

define ISO_8601_BASIC_TIME "%Y%m%dT%H%M%S" and

define ISO_8601_EXTENDED_TIME "%Y-%m-%dT%H:%M:%S"

would support this. If it is desired to explicitly include the local time zone or UTC designator in the time string, the character "Z" or the string "+00" can be appended to the conversion buffer before it is returned for the UTC case.

Adding "%z" to the format string will give the offset from UTC as +/-hhmm which works for the basic format, but would need to be edited to "+/-hh:mm in the extended case.

In addition to standard time representations, ISO 8601 defined a standard form for reporting durations. CORK timestamps can be interpreted as durations (with the value representing seconds since the start of an event rather than seconds since the epoch beginning), but these cannot be explicitly created under the strftime rules. In addition, the standard sanctions using months and years in the duration representations but gives no guide on how these are to be computed. Were we to add explicit support for a CORK duration string, it should probably have weeks as its largest component since the length of months (and subsequently larger units ) is nominal. If the duration is computed by subtracting two timestamp values, the presence of a leap second can make even the day and week components of a duration nominal although ISO 31-1 defines a day as 84600 seconds.

Non local, non UTC timestamp display

Timezones are an unavoidable complexity in dealing with time. Libcork represents its timestamps internally as a 64bit fixed point number with the implied point between the 32 bit epoch time and a 32 bit fraction where a single bit represents 1/2^32 of a second. By convention, the internal representation is an UTC offset since the beginning of the epoch, but there is no technically feasible way to enforce this.

Time stamps can be displayed as UTC in any format supported by the underlying gmtime function for deconstructing the time and the strftime function for formatting. They can also be displayed as local time based on the TZ environment variable of the host system and the localtime function. Recent additions also support display in an ISO8601 format for both UTC and local times.

Missing is the ability to display times in an arbitrary time zone, neither UTC nor local. This is a convenience function, but can avoid analysis errors when data recorded in one time zone must be processed in another along with logs and other sources that only have local time in human readable format. While it can be argued that this is poor experimental methodology, it happens with astounding regularity.

Adding a function like

bool cork_timestamp_format_tz(const cork_timestamp ts, const tz_t zone, const char *format, char *buf, size_t size)

and its ISO equivalent would allow the time to be formatted for an arbitrary timezone.

The choice of a representation for tz_t is not as simple as it might seem. The easy out for the developer is to make tz_t an alias for another cork_timestamp (or an epoch time or an integer value) with the requirement that the fraction must be zero and the epoch time must represent a legitimate time zone offset that can be printed either as +hh, -hh, +hh:30 or -hh:30. This leaves it up to the programmer to determine the proper offset, including coping with all the DST rules, etc., in effect at the UTC time
represented by ts. The easy out for the programmer is to make tz_t a string that can be looked up with the functions associated with the timezone database (see http://www.twinsun.com/tz/tz-link.htm - top of page) to determine the offset needed for the given time. A compromise would be to create a function that takes a timezone string and returns a tz_t containing the offset.

In any case, if it is desired to represent the time zone in the formatted output in any form other than the actual offset, additional computation may be needed.

It may be possible to wrap the localtime and strftime functions in such a way that the TZ environment variable is reset locally for the duration of the conversion in which case, tz_t could be any representation that can be assigned to this variable.

Mempool callback setting problem

Callback functions can be added to mempools for initializing objects and for freeing objects and user data. If the routine called to do this is called after objects have been created, There will be uninitialized objects that have either been allocated or are on the free list awaiting allocation. This might lead to obscure errors when the objects are operated on by user code or are when they are freed.

Several possible fixes are possible:

  1. Merge callback specification into the mempool constructor operations, precluding the error. This would remove the visible cork_mempool_set_callbacks function from the interface and might break existing, arguably correct, uses. It also could lead to a proliferation of interfaces if options with and without callbacks are supplied along with the present variations on element size / type and block size.
  2. Introduce a test into cork_mempool_set_callbacks that will raise an error and abort the program if it is called after any entities have been allocated, i.e. after the block chain pointer is non NULL. This would change the behavior of potentially erroneous programs, but would provide a clear indication of the problem to the user.
  3. Change the documentation to warn that calling cork_mempool_set_callbacks after a block has been allocated creates an undefined behavior and possible program failures during execution. This is the easiest to do, but provides the least protection for the user, expecially users who do not regularly RTFM or check it for updates.

Hash Table Instrumentation

When monitoring the performance of a program that uses dynamic hash tables, it is useful to track the space allocated to the table by catching table reallocations. Since reallocations occur when a new item is entered into a table which cannot find room for it, the tracking could be a side effect of the entry and size setting actions.

For the cork hash tables, these are calls on

cork_hash_table_get_or_create()
cork_hash_table_put()

for adding entries and the size setting operations

cork_string_hash_table_init()
cork_pointer_hash_table_init()
cork_hash_table_ensure_size()

By adding an optional "in/out" parameter, say

size_t * actual_size

to these operations, the actual size of the hash array (as opposed to the number of entries currently present in the table) could be returned whenever the table is allocated or reallocated. If the call time value is set to 0, a simple test for a non-zero return value identifies a reallocation point. In addition, by tracking the number of entries in the table when reallocation occurs, the typical table capacity (or load factor) for a given size can be tracked, as well.

Although I have not inspected the current hash code, reallocation typically involves doubling the size of the store for the table and rehashing all of the current entries since their index in the table will go from N to N+1 bits as the size of the table is increased from 2^N to 2^(N+1) entries. Instrumenting the reallocation process is a first step in evaluating the performance of algorithms that use the hash table facilities.

Deprecate the garbage collector?

Is anyone using the garbage collector? I've never used it in anger, and to be honest, I'm not sure if it belongs in this kind of low-level library. If not, I'd like to remove it before cutting a stable 1.0.0 release.

Misplaced parentheses in cork_ipv6_is_valid_network

When using ipsetbuild from libcorkipset, I found that all IPv6 addresses with a CIDR were being reported as errors (unless --loose-cidr was used). I eventually found the error in cork_ipv6_is_valid_network in libcork/core/ip-address.c : two closing parentheses have been misplaced. Lines 455 and 456 should be:

return (CORK_UINT64_BIG_TO_HOST(addr->_.u64[0]) & cidr_mask[0] == 0) &&
       (CORK_UINT64_BIG_TO_HOST(addr->_.u64[1]) & cidr_mask[1] == 0);

(The error would not be apparent in a big-endian architecture.)

I have tested this change by building a local version, and I am satisfied that it works.

As an aside, I also changed lines 441 and 442 to

return true;

since I regard a /128 on an IPv6 address (and /32 on an IPv4 address) as a no-operation.

Seg fault on OS X

There is an intermittent segmentation fault on OS X. It appears to happen in the new cork_size_atomic_add function in libcork.

unaligned access when unit test cork-hash

libcork has unit test error on cork-hash on sparc64 Arch [0].
I though it might be sparc64's issue, but debian sparc maintainer told me it's because of unaligned access [1], which also mentioned the possible fix [2].

[0] https://buildd.debian.org/status/logs.php?pkg=libcork&arch=sparc64
[1] https://lists.debian.org/debian-sparc/2016/08/msg00016.html
[2] https://github.com/systemd/systemd/blob/master/src/basic/unaligned.h

What do you think of this issue?

Documentation about cork_delete

The API docs have this signature for cork_delete:

type *cork_delete(void *ptr, TYPE type)

However, the source code defines the parameters differently:

#define cork_delete(type, ptr)  cork_free((ptr), sizeof(type))

Should the parameters in the documentation not be swapped?

Also, if cork_delete is an alias for cork_free which returns void *, shouldn't the return type be void * too?

Non local, non UTC timestamp display

Timezones are an unavoidable complexity in dealing with time. Libcork represents its timestamps internally as a 64bit fixed point number with the implied point between the 32 bit epoch time and a 32 bit fraction where a single bit represents 1/2^32 of a second. By convention, the internal representation is an UTC offset since the beginning of the epoch, but there is no technically feasible way to enforce this.

Time stamps can be displayed as UTC in any format supported by the underlying gmtime function for deconstructing the time and the strftime function for formatting. They can also be displayed as local time based on the TZ environment variable of the host system and the localtime function. Recent additions also support display in an ISO8601 format for both UTC and local times.

Missing is the ability to display times in an arbitrary time zone, neither UTC nor local. This is a convenience function, but can avoid analysis errors when data recorded in one time zone must be processed in another along with logs and other sources that only have local time in human readable format. While it can be argued that this is poor experimental methodology, it happens with astounding regularity.

Adding a function like

bool cork_timestamp_format_tz(const cork_timestamp ts, const tz_t zone, const char *format, char *buf, size_t size)

and its ISO equivalent would allow the time to be formatted for an arbitrary timezone.

The choice of a representation for tz_t is not as simple as it might seem. The easy out for the developer is to make tz_t an alias for another cork_timestamp (or an epoch time or an integer value) with the requirement that the fraction must be zero and the epoch time must represent a legitimate time zone offset that can be printed either as +hh, -hh, +hh:30 or -hh:30. This leaves it up to the programmer to determine the proper offset, including coping with all the DST rules, etc., in effect at the UTC time
represented by ts. The easy out for the programmer is to make tz_t a string that can be looked up with the functions associated with the timezone database (see http://www.twinsun.com/tz/tz-link.htm - top of page) to determine the offset needed for the given time. A compromise would be to create a function that takes a timezone string and returns a tz_t containing the offset.

In any case, if it is desired to represent the time zone in the formatted output in any form other than the actual offset, additional computation may be needed.

It may be possible to wrap the localtime and strftime functions in such a way that the TZ environment variable is reset locally for the duration of the conversion in which case, tz_t could be any representation that can be assigned to this variable.

Incorrect size report after `cork_array_ensure_size`

To reproduce:

  • Reallocate space in an array with cork_array_ensure_size
  • Assign a value manually to the expanded elements of the array (probably optional but usefult to test the reallocation)
  • Call cork_array_size(array) or array->size (undocumented by the way, but seems to work exactly the same)

Expected result: the number of elements including the ones inserted manually.

Actual result: the number of element prior to expansion.

Example program:

#include <libcork/ds.h>

typedef cork_array(int) Array;

int main()
{
    Array _a;
    Array *a = &_a;

    cork_array_init(a);
    printf("%lu\n", a->size);

    cork_array_append(a, 8);
    printf("%lu\n", a->size);

    cork_array_ensure_size(a, 2);
    cork_array_at(a, 1) = 36;
    printf("array->size: %lu\n", cork_array_size(a));
    printf("cork_array_size: %lu\n", cork_array_size(a));
    printf("At 1: %d\n", cork_array_at(a, 1));

    return(0);
}

Output:

0
1
array->size: 1
cork_array_size: 1
At 1: 36

Is this is the expected behavior?

Updated Github Release

It looks like the last release on Github was a in 2015. It almost makes the library seem dead, except there are still more commits. Also, my team wants to create a package for this library for the Conan package manager. We'd rather pin to a more recent release if possible.

Non local, non UTC timestamp display

Timezones are an unavoidable complexity in dealing with time. Libcork represents its timestamps internally as a 64bit fixed point number with the implied point between the 32 bit epoch time and a 32 bit fraction where a single bit represents 1/2^32 of a second. By convention, the internal representation is an UTC offset since the beginning of the epoch, but there is no technically feasible way to enforce this.

Time stamps can be displayed as UTC in any format supported by the underlying gmtime function for deconstructing the time and the strftime function for formatting. They can also be displayed as local time based on the TZ environment variable of the host system and the localtime function. Recent additions also support display in an ISO8601 format for both UTC and local times.

Missing is the ability to display times in an arbitrary time zone, neither UTC nor local. This is a convenience function, but can avoid analysis errors when data recorded in one time zone must be processed in another along with logs and other sources that only have local time in human readable format. While it can be argued that this is poor experimental methodology, it happens with astounding regularity.

Adding a function like

bool cork_timestamp_format_tz(const cork_timestamp ts, const tz_t zone, const char *format, char *buf, size_t size)

and its ISO equivalent would allow the time to be formatted for an arbitrary timezone.

The choice of a representation for tz_t is not as simple as it might seem. The easy out for the developer is to make tz_t an alias for another cork_timestamp (or an epoch time or an integer value) with the requirement that the fraction must be zero and the epoch time must represent a legitimate time zone offset that can be printed either as +hh, -hh, +hh:30 or -hh:30. This leaves it up to the programmer to determine the proper offset, including coping with all the DST rules, etc., in effect at the UTC time
represented by ts. The easy out for the programmer is to make tz_t a string that can be looked up with the functions associated with the timezone database (see http://www.twinsun.com/tz/tz-link.htm - top of page) to determine the offset needed for the given time. A compromise would be to create a function that takes a timezone string and returns a tz_t containing the offset.

In any case, if it is desired to represent the time zone in the formatted output in any form other than the actual offset, additional computation may be needed.

It may be possible to wrap the localtime and strftime functions in such a way that the TZ environment variable is reset locally for the duration of the conversion in which case, tz_t could be any representation that can be assigned to this variable.

mempool element and block size pathology

It appears to be possible to specify mempool elements that are larger than the blocks which should contain them.

The place where these come together is in the mempool creation routine cork_mempool_new_size_ex. At the very least, the problem could be diagnosed there, taking into account the need to provide both block and element headers. Possible solutions include:

  1. Modifying the documentation to call attention to the erroneous usage. This, alone, leaves open the possibility of difficult to diagnose segmentation faults at run time. It also requires exposing the block and element structures with their otherwise invisible header / link fields.
  2. Including a test in cork_mempool_new_size_ex that will abort the computation if the pathology occurs. If this is done, the diagnostic should specify the minimum block size required to hold a single element of the desired size.
  3. Allowing the code to adjust the block size, if necessary, so that a block will hold at least one element with the necessary header / link fields. Note that this might be extended so that a block will always hold an integral number of elements. It is not clear that this offers other than aesthetic benefits, although, a user naively specifying a block that is an integral multiple of the user's element size ensures a, possibly significant, waste of space due to the header / link space required.
  4. Introduce an incompatible change that replaces the block size specification with an element count specification. With this change, a default element count would replace the current default block size specification.

Rendering IPv6 containing an IPv4 address

cork_ipv6_to_raw_string() is incomplete in its handling of IPv6 addresses that contain IPv4 addresses as their low order 32 bits. The RFCs that I have found address a total of 5 cases, the first 2 of which are covered by the existing code:

  1. Prefix of ::/96 IPv4-compatible (RFC 1933)

  2. Prefix of ::ffff:0:0/96 IPv4-mapped (RFC 2765)

  3. Prefix of ::ffff:0:0:0/96 IPv4-translated (RFC 2765)

  4. Prefix of 64:ff9b::\96 IPv4-embeded (RFC 6052)
    5: Automatic tunneling per RFC 5214. This starts with an arbitrary 64 bit routing prefix followed by :X:00:5efe: and the IPv4 address, where X has the hex representation of

    a. 0 indicating a local, individual IPv4 address
    b. 100 indicating a local, group IPv4 address
    c. 200 indicating a global, individual IPv4 address
    d. 300 indicating a global, group IPv4 address

The code should be extended to cover the additional forms. It may be useful to make the presentation of the IPv4 address in dotted form optional given the advice of RFC 5952 which covers the representation of IPv6 addresses as text.

Addresses such as IPv4-Mapped IPv6 addresses, ISATAP [RFC5214], and
IPv4-translatable addresses [ADDR-FORMAT] have IPv4 addresses
embedded in the low-order 32 bits of the address. These addresses
have a special representation that may mix hexadecimal and dot
decimal notations. The decimal notation may be used only for the
last 32 bits of the address. For these addresses, mixed notation is
RECOMMENDED if the following condition is met: the address can be
distinguished as having IPv4 addresses embedded in the lower 32 bits
solely from the address field through the use of a well-known prefix.
Such prefixes are defined in [RFC4291] and [RFC2765] at the time of
this writing. If it is known by some external method that a given
prefix is used to embed IPv4, it MAY be represented as mixed
notation. Tools that provide options to specify prefixes that are
(or are not) to be represented as mixed notation may be useful.

There is a trade-off here where a recommendation to achieve an exact
match in a search (no dot decimals whatsoever) and a recommendation
to help the readability of an address (dot decimal whenever possible)
does not result in the same solution. The above recommendation is
aimed at fixing the representation as much as possible while leaving
the opportunity for future well-known prefixes to be represented in a
human-friendly manner as tools adjust to newly assigned prefixes.

Error in Build!

$ make VERBOSE=1

/usr/bin/cmake -H/home/check/Repository/github.com/dcreager/libcork -B/home/check/Repository/github.com/dcreager/libcork/build --check-build-system CMakeFiles/Makefile.cmake 0
/usr/bin/cmake -E cmake_progress_start /home/check/Repository/github.com/dcreager/libcork/build/CMakeFiles /home/check/Repository/github.com/dcreager/libcork/build/CMakeFiles/progress.marks
make -f CMakeFiles/Makefile2 all
make[1]: Entering directory '/home/check/Repository/github.com/dcreager/libcork/build'
make -f src/CMakeFiles/libcork-static.dir/build.make src/CMakeFiles/libcork-static.dir/depend
make[2]: Entering directory '/home/check/Repository/github.com/dcreager/libcork/build'
cd /home/check/Repository/github.com/dcreager/libcork/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/check/Repository/github.com/dcreager/libcork /home/check/Repository/github.com/dcreager/libcork/src /home/check/Repository/github.com/dcreager/libcork/build /home/check/Repository/github.com/dcreager/libcork/build/src /home/check/Repository/github.com/dcreager/libcork/build/src/CMakeFiles/libcork-static.dir/DependInfo.cmake --color=
make[2]: Leaving directory '/home/check/Repository/github.com/dcreager/libcork/build'
make -f src/CMakeFiles/libcork-static.dir/build.make src/CMakeFiles/libcork-static.dir/build
make[2]: Entering directory '/home/check/Repository/github.com/dcreager/libcork/build'
make[2]: Nothing to be done for 'src/CMakeFiles/libcork-static.dir/build'.
make[2]: Leaving directory '/home/check/Repository/github.com/dcreager/libcork/build'
[ 21%] Built target libcork-static
make -f src/CMakeFiles/libcork-shared.dir/build.make src/CMakeFiles/libcork-shared.dir/depend
make[2]: Entering directory '/home/check/Repository/github.com/dcreager/libcork/build'
cd /home/check/Repository/github.com/dcreager/libcork/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/check/Repository/github.com/dcreager/libcork /home/check/Repository/github.com/dcreager/libcork/src /home/check/Repository/github.com/dcreager/libcork/build /home/check/Repository/github.com/dcreager/libcork/build/src /home/check/Repository/github.com/dcreager/libcork/build/src/CMakeFiles/libcork-shared.dir/DependInfo.cmake --color=
make[2]: Leaving directory '/home/check/Repository/github.com/dcreager/libcork/build'
make -f src/CMakeFiles/libcork-shared.dir/build.make src/CMakeFiles/libcork-shared.dir/build
make[2]: Entering directory '/home/check/Repository/github.com/dcreager/libcork/build'
make[2]: Nothing to be done for 'src/CMakeFiles/libcork-shared.dir/build'.
make[2]: Leaving directory '/home/check/Repository/github.com/dcreager/libcork/build'
[ 41%] Built target libcork-shared
make -f src/CMakeFiles/cork-hash.dir/build.make src/CMakeFiles/cork-hash.dir/depend
make[2]: Entering directory '/home/check/Repository/github.com/dcreager/libcork/build'
cd /home/check/Repository/github.com/dcreager/libcork/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/check/Repository/github.com/dcreager/libcork /home/check/Repository/github.com/dcreager/libcork/src /home/check/Repository/github.com/dcreager/libcork/build /home/check/Repository/github.com/dcreager/libcork/build/src /home/check/Repository/github.com/dcreager/libcork/build/src/CMakeFiles/cork-hash.dir/DependInfo.cmake --color=
make[2]: Leaving directory '/home/check/Repository/github.com/dcreager/libcork/build'
make -f src/CMakeFiles/cork-hash.dir/build.make src/CMakeFiles/cork-hash.dir/build
make[2]: Entering directory '/home/check/Repository/github.com/dcreager/libcork/build'
make[2]: Nothing to be done for 'src/CMakeFiles/cork-hash.dir/build'.
make[2]: Leaving directory '/home/check/Repository/github.com/dcreager/libcork/build'
[ 42%] Built target cork-hash
make -f src/CMakeFiles/cork-initializer.dir/build.make src/CMakeFiles/cork-initializer.dir/depend
make[2]: Entering directory '/home/check/Repository/github.com/dcreager/libcork/build'
cd /home/check/Repository/github.com/dcreager/libcork/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/check/Repository/github.com/dcreager/libcork /home/check/Repository/github.com/dcreager/libcork/src /home/check/Repository/github.com/dcreager/libcork/build /home/check/Repository/github.com/dcreager/libcork/build/src /home/check/Repository/github.com/dcreager/libcork/build/src/CMakeFiles/cork-initializer.dir/DependInfo.cmake --color=
make[2]: Leaving directory '/home/check/Repository/github.com/dcreager/libcork/build'
make -f src/CMakeFiles/cork-initializer.dir/build.make src/CMakeFiles/cork-initializer.dir/build
make[2]: Entering directory '/home/check/Repository/github.com/dcreager/libcork/build'
make[2]: Nothing to be done for 'src/CMakeFiles/cork-initializer.dir/build'.
make[2]: Leaving directory '/home/check/Repository/github.com/dcreager/libcork/build'
[ 45%] Built target cork-initializer
make -f src/CMakeFiles/cork-test.dir/build.make src/CMakeFiles/cork-test.dir/depend
make[2]: Entering directory '/home/check/Repository/github.com/dcreager/libcork/build'
cd /home/check/Repository/github.com/dcreager/libcork/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/check/Repository/github.com/dcreager/libcork /home/check/Repository/github.com/dcreager/libcork/src /home/check/Repository/github.com/dcreager/libcork/build /home/check/Repository/github.com/dcreager/libcork/build/src /home/check/Repository/github.com/dcreager/libcork/build/src/CMakeFiles/cork-test.dir/DependInfo.cmake --color=
make[2]: Leaving directory '/home/check/Repository/github.com/dcreager/libcork/build'
make -f src/CMakeFiles/cork-test.dir/build.make src/CMakeFiles/cork-test.dir/build
make[2]: Entering directory '/home/check/Repository/github.com/dcreager/libcork/build'
make[2]: Nothing to be done for 'src/CMakeFiles/cork-test.dir/build'.
make[2]: Leaving directory '/home/check/Repository/github.com/dcreager/libcork/build'
[ 47%] Built target cork-test
make -f tests/CMakeFiles/embedded-test-hash-table.dir/build.make tests/CMakeFiles/embedded-test-hash-table.dir/depend
make[2]: Entering directory '/home/check/Repository/github.com/dcreager/libcork/build'
cd /home/check/Repository/github.com/dcreager/libcork/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/check/Repository/github.com/dcreager/libcork /home/check/Repository/github.com/dcreager/libcork/tests /home/check/Repository/github.com/dcreager/libcork/build /home/check/Repository/github.com/dcreager/libcork/build/tests /home/check/Repository/github.com/dcreager/libcork/build/tests/CMakeFiles/embedded-test-hash-table.dir/DependInfo.cmake --color=
make[2]: Leaving directory '/home/check/Repository/github.com/dcreager/libcork/build'
make -f tests/CMakeFiles/embedded-test-hash-table.dir/build.make tests/CMakeFiles/embedded-test-hash-table.dir/build
make[2]: Entering directory '/home/check/Repository/github.com/dcreager/libcork/build'
[ 48%] Linking C executable embedded-test-hash-table
cd /home/check/Repository/github.com/dcreager/libcork/build/tests && /usr/bin/cmake -E cmake_link_script CMakeFiles/embedded-test-hash-table.dir/link.txt --verbose=1
/usr/bin/cc -O3 -DNDEBUG  -rdynamic CMakeFiles/embedded-test-hash-table.dir/test-hash-table.c.o  -o embedded-test-hash-table ../src/libcork.a -lpthread 
CMakeFiles/embedded-test-hash-table.dir/test-hash-table.c.o: In function `test_pointer_hash_table':
test-hash-table.c:(.text+0x7d): undefined reference to `tcase_fn_start'
test-hash-table.c:(.text+0xd1): undefined reference to `_mark_point'
test-hash-table.c:(.text+0xf9): undefined reference to `_mark_point'
test-hash-table.c:(.text+0x114): undefined reference to `_mark_point'
test-hash-table.c:(.text+0x137): undefined reference to `_mark_point'
test-hash-table.c:(.text+0x182): undefined reference to `_ck_assert_failed'
test-hash-table.c:(.text+0x1ab): undefined reference to `_ck_assert_failed'
test-hash-table.c:(.text+0x1cf): undefined reference to `_ck_assert_failed'
test-hash-table.c:(.text+0x1f3): undefined reference to `_ck_assert_failed'
test-hash-table.c:(.text+0x217): undefined reference to `_ck_assert_failed'
CMakeFiles/embedded-test-hash-table.dir/test-hash-table.c.o: In function `test_string_hash_table':
test-hash-table.c:(.text+0x252): undefined reference to `tcase_fn_start'
test-hash-table.c:(.text+0x2ad): undefined reference to `_mark_point'
test-hash-table.c:(.text+0x34d): undefined reference to `_mark_point'
test-hash-table.c:(.text+0x368): undefined reference to `_mark_point'
test-hash-table.c:(.text+0x3f0): undefined reference to `_mark_point'
test-hash-table.c:(.text+0x443): undefined reference to `_ck_assert_failed'
test-hash-table.c:(.text+0x46c): undefined reference to `_ck_assert_failed'
test-hash-table.c:(.text+0x490): undefined reference to `_ck_assert_failed'
test-hash-table.c:(.text+0x4b4): undefined reference to `_ck_assert_failed'
test-hash-table.c:(.text+0x4d8): undefined reference to `_ck_assert_failed'
CMakeFiles/embedded-test-hash-table.dir/test-hash-table.c.o: In function `test_map_to_string':
test-hash-table.c:(.text+0x56c): undefined reference to `_mark_point'
test-hash-table.c:(.text+0x5bc): undefined reference to `_ck_assert_failed'
CMakeFiles/embedded-test-hash-table.dir/test-hash-table.c.o: In function `test_iterator_to_string':
test-hash-table.c:(.text+0x709): undefined reference to `_mark_point'
test-hash-table.c:(.text+0x75e): undefined reference to `_ck_assert_failed'
CMakeFiles/embedded-test-hash-table.dir/test-hash-table.c.o: In function `test_uint64_hash_table':
test-hash-table.c:(.text+0x7a2): undefined reference to `tcase_fn_start'
test-hash-table.c:(.text+0x811): undefined reference to `_mark_point'
test-hash-table.c:(.text+0x844): undefined reference to `_mark_point'
test-hash-table.c:(.text+0x87e): undefined reference to `_mark_point'
test-hash-table.c:(.text+0x8cf): undefined reference to `_mark_point'
test-hash-table.c:(.text+0x963): undefined reference to `_mark_point'
CMakeFiles/embedded-test-hash-table.dir/test-hash-table.c.o:test-hash-table.c:(.text+0x985): more undefined references to `_mark_point' follow
CMakeFiles/embedded-test-hash-table.dir/test-hash-table.c.o: In function `test_uint64_hash_table':
test-hash-table.c:(.text+0xdab): undefined reference to `_ck_assert_failed'
test-hash-table.c:(.text+0xdd4): undefined reference to `_ck_assert_failed'
test-hash-table.c:(.text+0xdf8): undefined reference to `_ck_assert_failed'
test-hash-table.c:(.text+0xe24): undefined reference to `_ck_assert_failed'
test-hash-table.c:(.text+0xe48): undefined reference to `_ck_assert_failed'
CMakeFiles/embedded-test-hash-table.dir/test-hash-table.c.o:test-hash-table.c:(.text+0xe74): more undefined references to `_ck_assert_failed' follow
CMakeFiles/embedded-test-hash-table.dir/test-hash-table.c.o: In function `test_suite':
test-hash-table.c:(.text+0x117e): undefined reference to `suite_create'
test-hash-table.c:(.text+0x118d): undefined reference to `tcase_create'
test-hash-table.c:(.text+0x11b4): undefined reference to `_tcase_add_test'
test-hash-table.c:(.text+0x11d9): undefined reference to `_tcase_add_test'
test-hash-table.c:(.text+0x11fe): undefined reference to `_tcase_add_test'
test-hash-table.c:(.text+0x1209): undefined reference to `suite_add_tcase'
CMakeFiles/embedded-test-hash-table.dir/test-hash-table.c.o: In function `main':
test-hash-table.c:(.text.startup+0x11): undefined reference to `srunner_create'
test-hash-table.c:(.text.startup+0x35): undefined reference to `srunner_run_all'
test-hash-table.c:(.text.startup+0x3d): undefined reference to `srunner_ntests_failed'
test-hash-table.c:(.text.startup+0x47): undefined reference to `srunner_free'
collect2: error: ld returned 1 exit status
make[2]: *** [tests/CMakeFiles/embedded-test-hash-table.dir/build.make:85: tests/embedded-test-hash-table] Error 1
make[2]: Leaving directory '/home/check/Repository/github.com/dcreager/libcork/build'
make[1]: *** [CMakeFiles/Makefile2:432: tests/CMakeFiles/embedded-test-hash-table.dir/all] Error 2
make[1]: Leaving directory '/home/check/Repository/github.com/dcreager/libcork/build'
make: *** [Makefile:141: all] Error 2

Can't get tests passed on Alpine Linux

shared-test-core and embedded-test-core complains: Unexpectedly formatted local time (got " 1992-03-07 20:26:40 ", expected " 1992-03-07 12:26:40 ". Any ideas please?

Hash test fails on 64-bit big endian CPU architecture

Hash test fails on 64-bit big endian CPU architecture, such as s390x, ppc64 and sparc64:
/«BUILDDIR»/libcork-0.15.0+ds/tests/test-core.c:341:F:hash:test_hash:0: Unexpected hash value 0xac7d28cc (expected 0x74bde19d)

Build log can be referenced:
https://buildd.debian.org/status/fetch.php?pkg=libcork&arch=s390x&ver=0.15.0%2Bds-1&stamp=1464961690
https://buildd.debian.org/status/fetch.php?pkg=libcork&arch=ppc64&ver=0.15.0%2Bds-1&stamp=1464961396
https://buildd.debian.org/status/fetch.php?pkg=libcork&arch=sparc64&ver=0.15.0%2Bds-1&stamp=1465008367

Additional IP support

libcork's support for the IP address types is limited. Additional operations are needed. Wherever the generic ip is used, assume ipv4,6 specific versions, as well, if appropriate.

Internal (cork, cork)

int cork_ip_cmp(const struct cork_ip *addr1, const struct cork_ip *addr2)

returns -1, 0, 1 for <, ==, >

void cork_ip_and_mask(struct cork_ip *addr1, const struct cork_ip *mask)
void cork_ip_or_mask(struct cork_ip *addr1, const struct cork_ip *mask)

and or or the specified mask to the address. The generic version could be created, but would need to raise an error if the versions of the operands were different. In addition to masking by address form masks, masking by cidr prefix would be useful.

int cork_ip_to_prefix(struct cork_ip *addr1, const int cidr_prefix) 

This returns error codes if the prefix is out of range for the ip or if the masking removed bits from the address. Whether the later is an error or informative depends on the intended use. If one is testing to see if the address is a legitimate prefix for the given cidr size, removing bits is an error. If one is trying to create a prefix address, it is not. Might want to separate this into 2 families
the form above that only checks to see if the prefix is appropriate and another, say

bool cork_ip_is_prefix(const struct cork_ip *addr1, const int cidr_prefix)

interface (cork <-> other)

void cork_ipv4_from_int( struct cork_ipv4 *addr1,  const uint32_t ip_int)
void cork_ipv4_to_int( const struct cork_ipv4 *addr1,  uint32_t  *ip_int)

Yes, these can be composed from the existing functions, but burying the endianess is desirable. As 128 bit machines become available similar, ipv6 versions will be desirable. We often find data files with ips represented as integers for a variety of reasons.

Other operations may also be desirable, for example, in building the bitset version of the ipset code, I needed operations that would split an ipv4 address treated as a 32 bit string with bit 0 on the right, bit 31 on the left into 4 integer fields, bits 31-23 (/9 prefix), bits 22-14 (/18 within a given /9), 13-5 (/27 within a given /18), and 4-0 (address within a /27). I did this accessing the individual bytes of the cork_ipv4 array, but a general mechanism might be useful. Note that all but the last require accessing 2 bytes, possibly masking and shifting each one, then combining the results. For IPv4, the computation would be simpler if performed on the native int representation of the address, but some careful performance analysis might be required to determine whether the time saved this way would pay for conversion to native order each time.

A potential null pointer bug

A potential bug is in the function "cork_slice_slice" of the file "libcork/ds/slice.c". See the bug report screenshot below:

image

When it goes to the else branch, variable "slice == nullptr" and it cannot be used directly at line 166.

We checked this piece of code is still exists in current develop branch of libcork.

1 test fails under ARCH=arm

I build with no problem on x64 machine, however on ARM/armel device, the following error occurs during unit test stage:

29/70 Test #29: cork-hash ........................***Failed    0.56 sec
!
--- cork-hash.t
+++ cork-hash.t.err
@@ -5,6 +5,6 @@
   $ cork-hash bar
   0x450e998d
   $ cork-hash tests.h
-  0x0b0628ee
+  0xb81fbba6
   $ cork-hash "A longer string"
-  0x53a2c885
+  0x2735f99f

...

99% tests passed, 1 tests failed out of 70
Total Test time (real) =  56.87 sec
The following tests FAILED:
         29 - cork-hash (Failed)

undefined reference to _cork_buffer_append_copy on macOS

Hi,

Trying the latest Git version and compiled all the C files using compiler defaults, on macOS the binary buffer interface fails with the following message:

cc -o main main.o libcork.a
Undefined symbols for architecture x86_64:
  "_cork_buffer_append_copy", referenced from:
      _cork_error_prefix_printf in libcork.a(error.o)
      _cork_error_prefix_string in libcork.a(error.o)
      _cork_error_prefix_vprintf in libcork.a(error.o)
ld: symbol(s) not found for architecture x86_64

The code that generates the error is as simple:

#include <libcork/ds.h>

int
main(void)
{
	struct cork_buffer buf;

	cork_buffer_init(&buf);
	cork_buffer_printf(&buf, "Hello %s", "David");
}

I suspect the CORK_INLINE does something that the compiler dislike because in the libcork.a static library the symbols are not visible.

$ nm libcork.a | grep append_copy
                 U _cork_buffer_append_copy
                 U _cork_buffer_append_copy

I think that's also why most C people recommend to not use inline functions in headers. According to the code, CORK_INLINE is correctly set to inline rather than static in line 158 from attributes.h

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.