Full Code of dcreager/libcork for AI

master a89596ce2244 cached
212 files
881.4 KB
233.2k tokens
1287 symbols
1 requests
Download .txt
Showing preview only (939K chars total). Download the full file or copy to clipboard to get everything.
Repository: dcreager/libcork
Branch: master
Commit: a89596ce2244
Files: 212
Total size: 881.4 KB

Directory structure:
gitextract_iakl50pb/

├── .buzzy/
│   ├── links.yaml
│   └── package.yaml
├── .clang-format
├── .github/
│   └── workflows/
│       └── ci.yml
├── .gitignore
├── AUTHORS
├── CMakeLists.txt
├── COPYING
├── INSTALL
├── Makefile.am
├── README.markdown
├── autogen.sh
├── build-aux/
│   └── calculate
├── cmake/
│   ├── FindCTargets.cmake
│   ├── FindParseArguments.cmake
│   └── FindPrereqs.cmake
├── configure.ac
├── docs/
│   ├── .gitattributes
│   ├── CMakeLists.txt
│   └── old/
│       ├── CMakeLists.txt
│       ├── _static/
│       │   ├── .keep
│       │   ├── docco-sphinx.css
│       │   └── pygments.css
│       ├── _templates/
│       │   └── .keep
│       ├── allocation.rst
│       ├── array.rst
│       ├── attributes.rst
│       ├── basic-types.rst
│       ├── bitset.rst
│       ├── buffer.rst
│       ├── byte-order.rst
│       ├── cli.rst
│       ├── conf.py
│       ├── config.rst
│       ├── dllist.rst
│       ├── ds.rst
│       ├── errors.rst
│       ├── files.rst
│       ├── gc.rst
│       ├── hash-table.rst
│       ├── hash-values.rst
│       ├── index.rst
│       ├── int128.rst
│       ├── managed-buffer.rst
│       ├── mempool.rst
│       ├── net-addresses.rst
│       ├── process.rst
│       ├── ring-buffer.rst
│       ├── slice.rst
│       ├── stream.rst
│       ├── subprocess.rst
│       ├── threads.rst
│       ├── timestamps.rst
│       ├── unique-ids.rst
│       ├── versions.rst
│       └── visibility.rst
├── extras/
│   └── hashstring.py
├── include/
│   ├── CMakeLists.txt
│   └── libcork/
│       ├── cli/
│       │   └── commands.h
│       ├── cli.h
│       ├── config/
│       │   ├── arch.h
│       │   ├── bsd.h
│       │   ├── config.h
│       │   ├── gcc.h
│       │   ├── linux.h
│       │   ├── macosx.h
│       │   └── version.h.in
│       ├── config.h
│       ├── core/
│       │   ├── allocator.h
│       │   ├── api.h
│       │   ├── attributes.h
│       │   ├── byte-order.h
│       │   ├── callbacks.h
│       │   ├── error.h
│       │   ├── gc.h
│       │   ├── hash.h
│       │   ├── id.h
│       │   ├── mempool.h
│       │   ├── net-addresses.h
│       │   ├── timestamp.h
│       │   ├── types.h
│       │   └── u128.h
│       ├── core.h
│       ├── ds/
│       │   ├── array.h
│       │   ├── bitset.h
│       │   ├── buffer.h
│       │   ├── dllist.h
│       │   ├── hash-table.h
│       │   ├── managed-buffer.h
│       │   ├── ring-buffer.h
│       │   ├── slice.h
│       │   └── stream.h
│       ├── ds.h
│       ├── helpers/
│       │   ├── errors.h
│       │   ├── gc.h
│       │   └── posix.h
│       ├── os/
│       │   ├── files.h
│       │   ├── process.h
│       │   └── subprocess.h
│       ├── os.h
│       ├── threads/
│       │   ├── atomics.h
│       │   └── basics.h
│       └── threads.h
├── m4/
│   ├── ax_pthread.m4
│   └── ax_valgrind_check.m4
├── make-dist.sh
├── run.sh
├── scripts/
│   ├── install
│   └── test
├── share/
│   ├── CMakeLists.txt
│   └── valgrind/
│       └── libcork.supp
├── src/
│   ├── APPNAME.pc.in
│   ├── CMakeLists.txt
│   ├── cork-hash/
│   │   └── cork-hash.c
│   ├── cork-initializer/
│   │   ├── init1.c
│   │   ├── init2.c
│   │   └── main.c
│   ├── cork-test/
│   │   └── cork-test.c
│   ├── libcork/
│   │   ├── cli/
│   │   │   └── commands.c
│   │   ├── core/
│   │   │   ├── allocator.c
│   │   │   ├── error.c
│   │   │   ├── gc.c
│   │   │   ├── hash.c
│   │   │   ├── id.c
│   │   │   ├── ip-address.c
│   │   │   ├── mempool.c
│   │   │   ├── timestamp.c
│   │   │   ├── u128.c
│   │   │   └── version.c
│   │   ├── ds/
│   │   │   ├── array.c
│   │   │   ├── bitset.c
│   │   │   ├── buffer.c
│   │   │   ├── dllist.c
│   │   │   ├── file-stream.c
│   │   │   ├── hash-table.c
│   │   │   ├── managed-buffer.c
│   │   │   ├── ring-buffer.c
│   │   │   ├── slice.c
│   │   │   └── stream.c
│   │   ├── posix/
│   │   │   ├── directory-walker.c
│   │   │   ├── env.c
│   │   │   ├── exec.c
│   │   │   ├── files.c
│   │   │   ├── process.c
│   │   │   └── subprocess.c
│   │   └── pthreads/
│   │       └── thread.c
│   └── libcork.pc.in
└── tests/
    ├── .gitattributes
    ├── .gitignore
    ├── CMakeLists.txt
    ├── COPYING.cram.txt
    ├── ccram
    ├── cork-hash.t
    ├── cork-initializer.t
    ├── cork-test/
    │   ├── cleanup.t
    │   ├── directory-watcher.t
    │   ├── help1-c1-s1.t
    │   ├── help1-c1-s2.t
    │   ├── help1-c1.t
    │   ├── help1-c2.t
    │   ├── help1-root.t
    │   ├── help2-c1-s1.t
    │   ├── help2-c1-s2.t
    │   ├── help2-c1.t
    │   ├── help2-c2.t
    │   ├── help2-root.t
    │   ├── help3-c1-s1.t
    │   ├── help3-c1-s2.t
    │   ├── help3-c1.t
    │   ├── help3-c2.t
    │   ├── help3-root.t
    │   ├── no-command-c1.t
    │   ├── no-command-root.t
    │   ├── run-c1-s1-f-t.t
    │   ├── run-c1-s1-f.t
    │   ├── run-c1-s1-t.t
    │   ├── run-c1-s1-test.t
    │   ├── run-c1-s1.t
    │   ├── run-c1-s2-f.t
    │   ├── run-c1-s2-file.t
    │   ├── run-c1-s2.t
    │   ├── run-c2.t
    │   ├── run-find-01.t
    │   ├── run-find-all-01.t
    │   ├── run-mkdir-01.t
    │   ├── run-paths-01.t
    │   ├── run-pwd-01.t
    │   ├── run-rm-01.t
    │   ├── run-sub-01.t
    │   ├── run-sub-02.t
    │   ├── run-sub-03.t
    │   ├── run-sub-04.t
    │   ├── run-sub-05.t
    │   └── run-sub-06.t
    ├── cram.py
    ├── create-u128-test-cases.py
    ├── helpers.h
    ├── test-array.c
    ├── test-bitset.c
    ├── test-buffer.c
    ├── test-core.c
    ├── test-dllist.c
    ├── test-files.c
    ├── test-gc.c
    ├── test-hash-table.c
    ├── test-managed-buffer.c
    ├── test-mempool.c
    ├── test-ring-buffer.c
    ├── test-slice.c
    ├── test-subprocess.c
    ├── test-threads.c
    └── test-u128.c

================================================
FILE CONTENTS
================================================

================================================
FILE: .buzzy/links.yaml
================================================
- git://github.com/dcreager/buzzy-core.git


================================================
FILE: .buzzy/package.yaml
================================================
name: libcork
build_dependencies:
  - pkg-config
  - check >= 0.9.4
license: BSD


================================================
FILE: .clang-format
================================================
Language: Cpp
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: TopLevel
AlwaysBreakAfterReturnType: TopLevel
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: true
BinPackArguments: true
BinPackParameters: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: WebKit
BreakBeforeTernaryOperators: false
BreakStringLiterals: false
ColumnLimit: 80
ContinuationIndentWidth: 8
ConstructorInitializerAllOnOneLineOrOnePerLine: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
IncludeCategories:
  - Regex:    '^<.*\.h>'
    Priority: 1
  - Regex:    '^<.*'
    Priority: 2
  - Regex:    '.*'
    Priority: 3
IncludeIsMainRegex: '([-_](test|unittest))?$'
IndentCaseLabels: true
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: false
MacroBlockBegin: ''
MacroBlockEnd:   ''
MaxEmptyLinesToKeep: 2
NamespaceIndentation: None
PenaltyBreakBeforeFirstCallParameter: 1
PenaltyBreakComment: 300
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 0
PointerAlignment: Left
ReflowComments: false
SortIncludes: true
SpaceAfterCStyleCast: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 2
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
TabWidth: 8
UseTab: Never


================================================
FILE: .github/workflows/ci.yml
================================================
name: Continuous integration
on:
  push:
    branches:
      - master
  pull_request:
  schedule:
    - cron: "0 0 1,15 * *"

jobs:
  test:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest]
        arch: [amd64, i386]
        compiler: [clang, gcc]
        flavor:
          - autotools
          - cmake
          - shared-cmake
          - fallback-u128
          - cmake-from-dist

    env:
      ARCH: ${{ matrix.arch }}
      COMPILER: ${{ matrix.compiler }}
      FLAVOR: ${{ matrix.flavor }}
      OS_NAME: ${{ matrix.os }}

    steps:
      - name: Checkout code
        uses: actions/checkout@v2

      - name: Fetch everything (for automatic version detection)
        run: git fetch --prune --unshallow

      - name: Install dependencies
        run: scripts/install

      - name: Test harness
        run: scripts/test


================================================
FILE: .gitignore
================================================
# autotools stuff
/aclocal.m4
/autom4te.cache/
/build-aux/compile
/build-aux/config.guess
/build-aux/config.sub
/build-aux/depcomp
/build-aux/install-sh
/build-aux/ltmain.sh
/build-aux/missing
/build-aux/test-driver
/config.h.in
/configure
/Makefile.in
/m4/libtool.m4
/m4/lt*.m4

# Dist tarballs
libcork-*.tar.xz

# In-source build artefacts
*.a
*.o
*.la
*.lo
.deps
.dirstamp
.libs/
/config.h
/config.log
/config.status
/cork-*
/libcork.la
/libtool
/Makefile
/stamp-h1
test*.log
test*.trs
/tests/test-*
!/tests/test-*.c

# Common out-of-source build locations
/.build*
/build*
!/build-aux


================================================
FILE: AUTHORS
================================================
# This is the list of libcork authors for copyright purposes.
#
# This does not necessarily list everyone who has contributed code, since in
# some cases, their employer may be the copyright holder.  To see the full list
# of contributors, see the revision history in source control.
DDoSolitary <DDoSolitary@gmail.com>
Google Inc.
Jan Weiß <jan@geheimwerk.de>
Nathan French <nate@cl0d.com>
Redjack, LLC
Roger Shimizu <rogershimizu@gmail.com>
Toby DiPasquale <toby@cbcg.net>


================================================
FILE: CMakeLists.txt
================================================
# -*- coding: utf-8 -*-
# ----------------------------------------------------------------------
# Copyright © 2011, libcork authors
# Please see the COPYING file in this distribution for license details.
# ----------------------------------------------------------------------

cmake_minimum_required(VERSION 2.6)
set(PROJECT_NAME libcork)
set(RELEASE_DATE 2015-09-03)
project(${PROJECT_NAME})
enable_testing()

set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
find_package(ParseArguments)
find_package(Prereqs)
find_package(CTargets)

#-----------------------------------------------------------------------
# Retrieve the current version number

execute_process(
    COMMAND
      ${CMAKE_SOURCE_DIR}/build-aux/calculate version
        ${CMAKE_SOURCE_DIR} .version-stamp
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
    RESULT_VARIABLE VERSION_RESULT
    OUTPUT_VARIABLE VERSION
    OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(VERSION_RESULT)
    message(FATAL_ERROR
            "Cannot determine version number: " ${VERSION_RESULT})
endif(VERSION_RESULT)
message(STATUS "Current version: " ${VERSION})

string(REGEX REPLACE "-.*" "-dev" BASE_VERSION "${VERSION}")

if(BASE_VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)(-dev)?$")
    set(CORK_VERSION_MAJOR "${CMAKE_MATCH_1}")
    set(CORK_VERSION_MINOR "${CMAKE_MATCH_2}")
    set(CORK_VERSION_PATCH "${CMAKE_MATCH_3}")
else(BASE_VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)(-dev)?$")
    message(FATAL_ERROR "Invalid version number: ${VERSION}")
endif(BASE_VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)(-dev)?$")
set(CORK_VERSION "${VERSION}")

execute_process(
    COMMAND
      ${CMAKE_SOURCE_DIR}/build-aux/calculate commit
        ${CMAKE_SOURCE_DIR} .commit-stamp
    WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
    RESULT_VARIABLE GIT_SHA1_RESULT
    OUTPUT_VARIABLE CORK_GIT_SHA1
    OUTPUT_STRIP_TRAILING_WHITESPACE
)
if(GIT_SHA1_RESULT)
    message(FATAL_ERROR
            "Cannot determine git commit: " ${GIT_SHA1_RESULT})
endif(GIT_SHA1_RESULT)
message(STATUS "Current revision: " ${CORK_GIT_SHA1})

include(GNUInstallDirs)

#-----------------------------------------------------------------------
# Set some options

if(APPLE)
    if (NOT CMAKE_INSTALL_NAME_DIR)
        set(CMAKE_INSTALL_NAME_DIR "${CMAKE_INSTALL_PREFIX}/lib")
    endif (NOT CMAKE_INSTALL_NAME_DIR)
endif(APPLE)

if(NOT CMAKE_BUILD_TYPE)
    set(CMAKE_BUILD_TYPE Release CACHE STRING
        "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
        FORCE)
endif(NOT CMAKE_BUILD_TYPE)

set(ENABLE_SHARED YES CACHE BOOL "Whether to build a shared library")
set(ENABLE_SHARED_EXECUTABLES NO CACHE BOOL
    "Whether to link executables using shared libraries")
set(ENABLE_SHARED_TESTS NO CACHE BOOL
    "Whether to link test cases using shared libraries")
set(ENABLE_STATIC YES CACHE BOOL "Whether to build a static library")

if(NOT CMAKE_INSTALL_LIBDIR)
    set(CMAKE_INSTALL_LIBDIR lib CACHE STRING
        "The base name of the installation directory for libraries")
endif(NOT CMAKE_INSTALL_LIBDIR)

if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
    add_definitions(-Wall -Werror)
elseif(CMAKE_C_COMPILER_ID STREQUAL "Clang")
    add_definitions(-Wall -Werror)
elseif(CMAKE_C_COMPILER_ID STREQUAL "Intel")
    add_definitions(-Wall -Werror)
endif(CMAKE_C_COMPILER_ID STREQUAL "GNU")

#-----------------------------------------------------------------------
# Check for prerequisite libraries

find_package(Threads)
set(THREADS_LDFLAGS "${CMAKE_THREAD_LIBS_INIT}")
set(THREADS_STATIC_LDFLAGS "${CMAKE_THREAD_LIBS_INIT}")
set(PTHREAD_LIBS "${CMAKE_THREAD_LIBS_INIT}")

#-----------------------------------------------------------------------
# Include our subdirectories

add_subdirectory(include)
add_subdirectory(share)
add_subdirectory(src)
add_subdirectory(tests)
add_subdirectory(docs/old)


================================================
FILE: COPYING
================================================
Copyright © 2011-2017, libcork authors
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

  • Redistributions of source code must retain the above copyright
    notice, this list of conditions and the following disclaimer.

  • 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.

  • Neither the names of the libcork authors nor the names of its
    contributors may be used to endorse or promote products derived
    from this software without specific prior written permission.

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
HOLDER 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.


================================================
FILE: INSTALL
================================================
Installation instructions
=========================

The libcork library is written in ANSI C.  It uses cmake as its build
manager.


Prerequisite libraries
----------------------

To build libcork, you need the following libraries installed on your
system:

  * pkg-config
  * check (http://libcheck.github.io/check)


Building from source
--------------------

The libcork library uses cmake as its build manager.  In most cases, you
should be able to build the source code using the following:

    $ mkdir build
    $ cd build
    $ cmake .. -DCMAKE_INSTALL_PREFIX=$PREFIX
    $ make
    $ make test
    $ make install

You might have to run the last command using sudo, if you need
administrative privileges to write to the $PREFIX directory.


Shared and static libraries
---------------------------

You can use the `ENABLE_SHARED` and `ENABLE_STATIC` cmake options to control
whether or not to install shared and static versions of libcork, respectively.
By default, both are installed.

You can use the `ENABLE_SHARED_EXECUTABLE` cmake option to control whether the
programs that we install link with libcork's shared library or static library.
(Note that this can override the value of `ENABLE_SHARED`; if you ask for the
programs to link with the shared library, then we have to install that shared
library for the programs to work properly.)  By default, we link with libcork
statically.

So, as an example, if you wanted to only build and install the shared library,
and to have our programs link with that shared library, you'd replace the cmake
command with the following:

    $ cmake .. \
        -DCMAKE_INSTALL_PREFIX=$PREFIX \
        -DENABLE_SHARED=YES \
        -DENABLE_STATIC=NO \
        -DENABLE_SHARED_EXECUTABLES=YES


================================================
FILE: Makefile.am
================================================
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------
# Copyright © 2018, libcork authors
# Please see the COPYING file in this distribution for license details.
# ------------------------------------------------------------------------------

#-------------------------------------------------------------------------------
# Dist hooks

dist-hook: dist-check-git-version dist-stamps

#-------------------------------------------------------------------------------
# .commit-stamp and .version-stamp

dist-check-git-version:
	: # Verify that the version that configure.ac recorded matches the
	: # current calculated version.
	@git_ver=`$(top_srcdir)/build-aux/calculate version $(top_srcdir) $(top_srcdir)/.version-stamp`; \
	if test "x$${git_ver}" != "x$(PACKAGE_VERSION)"; then \
	    echo "ERROR: PACKAGE_VERSION and 'git describe' version do not match:"; \
	    echo "     current 'git describe' version: $${git_ver}"; \
	    echo "     current PACKAGE_VERSION:        $(PACKAGE_VERSION)"; \
	    echo "Update PACKAGE_VERSION by running $(top_srcdir)/autogen.sh."; \
	    rm -rf "$(top_srcdir)/autom4te.cache"; \
	    exit 1; \
	fi

dist-stamps:
	@: # Generate version stamps for dist tarball.
	@echo $(CORK_GIT_SHA1) > $(distdir)/.commit-stamp
	@echo $(VERSION) > $(distdir)/.version-stamp

#-------------------------------------------------------------------------------
# Preliminaries

ACLOCAL_AMFLAGS = -I m4
AM_CPPFLAGS = \
    -I$(srcdir)/include \
    -I$(builddir)/include

lib_LTLIBRARIES = libcork.la
bin_PROGRAMS = cork-hash
check_PROGRAMS =
CLEANFILES =
EXTRA_DIST =
EXTRA_PROGRAMS =
TESTS =

#-------------------------------------------------------------------------------
# Extras

EXTRA_DIST += \
    CMakeLists.txt \
    README.markdown \
    build-aux/calculate \
    cmake \
    docs \
    extras \
    share \
    include/CMakeLists.txt \
    src/CMakeLists.txt \
    src/libcork.pc.in \
    tests/CMakeLists.txt

#-------------------------------------------------------------------------------
# libcork

libcork_includedir = $(includedir)/libcork
cli_includedir = $(includedir)/libcork/cli
config_includedir = $(includedir)/libcork/config
core_includedir = $(includedir)/libcork/core
ds_includedir = $(includedir)/libcork/ds
helpers_includedir = $(includedir)/libcork/helpers
os_includedir = $(includedir)/libcork/os
threads_includedir = $(includedir)/libcork/threads

libcork_include_HEADERS = \
    include/libcork/cli.h \
    include/libcork/config.h \
    include/libcork/core.h \
    include/libcork/ds.h \
    include/libcork/os.h \
    include/libcork/threads.h

cli_include_HEADERS = \
    include/libcork/cli/commands.h

config_include_HEADERS = \
    include/libcork/config/arch.h \
    include/libcork/config/gcc.h \
    include/libcork/config/macosx.h \
    include/libcork/config/bsd.h \
    include/libcork/config/linux.h \
    include/libcork/config/config.h \
    include/libcork/config/version.h

core_include_HEADERS = \
    include/libcork/core/hash.h \
    include/libcork/core/error.h \
    include/libcork/core/allocator.h \
    include/libcork/core/u128.h \
    include/libcork/core/attributes.h \
    include/libcork/core/byte-order.h \
    include/libcork/core/callbacks.h \
    include/libcork/core/timestamp.h \
    include/libcork/core/gc.h \
    include/libcork/core/net-addresses.h \
    include/libcork/core/types.h \
    include/libcork/core/id.h \
    include/libcork/core/api.h \
    include/libcork/core/mempool.h

ds_include_HEADERS = \
    include/libcork/ds/hash-table.h \
    include/libcork/ds/array.h \
    include/libcork/ds/managed-buffer.h \
    include/libcork/ds/ring-buffer.h \
    include/libcork/ds/stream.h \
    include/libcork/ds/bitset.h \
    include/libcork/ds/buffer.h \
    include/libcork/ds/slice.h \
    include/libcork/ds/dllist.h

helpers_include_HEADERS = \
    include/libcork/helpers/posix.h \
    include/libcork/helpers/errors.h \
    include/libcork/helpers/gc.h

os_include_HEADERS = \
    include/libcork/os/files.h \
    include/libcork/os/process.h \
    include/libcork/os/subprocess.h

threads_include_HEADERS = \
    include/libcork/threads/atomics.h \
    include/libcork/threads/basics.h

libcork_la_SOURCES = \
    src/libcork/cli/commands.c \
    src/libcork/core/allocator.c \
    src/libcork/core/error.c \
    src/libcork/core/gc.c \
    src/libcork/core/hash.c \
    src/libcork/core/id.c \
    src/libcork/core/ip-address.c \
    src/libcork/core/mempool.c \
    src/libcork/core/timestamp.c \
    src/libcork/core/u128.c \
    src/libcork/core/version.c \
    src/libcork/ds/array.c \
    src/libcork/ds/bitset.c \
    src/libcork/ds/buffer.c \
    src/libcork/ds/dllist.c \
    src/libcork/ds/file-stream.c \
    src/libcork/ds/hash-table.c \
    src/libcork/ds/managed-buffer.c \
    src/libcork/ds/ring-buffer.c \
    src/libcork/ds/slice.c \
    src/libcork/ds/stream.c \
    src/libcork/posix/directory-walker.c \
    src/libcork/posix/env.c \
    src/libcork/posix/exec.c \
    src/libcork/posix/files.c \
    src/libcork/posix/process.c \
    src/libcork/posix/subprocess.c \
    src/libcork/pthreads/thread.c

pkgconfig_DATA = src/libcork.pc

libcork_la_CPPFLAGS = $(AM_CPPFLAGS) $(CPPFLAGS) -DCORK_API=CORK_EXPORT
libcork_la_CFLAGS = $(AM_CFLAGS) $(CFLAGS) -DCORK_API=CORK_EXPORT
libcork_la_LDFLAGS = $(AM_LDFLAGS) $(LDFLAGS) -version-info 17:0:1

#-----------------------------------------------------------------------
# Utility commands

cork_hash_SOURCES = src/cork-hash/cork-hash.c
cork_hash_LDADD = libcork.la

#-----------------------------------------------------------------------
# Tests

# Standalone tests

standalone_tests = \
    test-array \
    test-bitset \
    test-buffer \
    test-core \
    test-dllist \
    test-files \
    test-gc \
    test-hash-table \
    test-managed-buffer \
    test-mempool \
    test-ring-buffer \
    test-slice \
    test-subprocess \
    test-threads \
    test-u128

EXTRA_DIST += tests/create-u128-test-cases.py
EXTRA_PROGRAMS += $(standalone_tests)

if RUN_TESTS

check_PROGRAMS += $(standalone_tests)
TESTS += $(standalone_tests)

tests_LDADD_ = libcork.la $(CHECK_LIBS)
tests_LDFLAGS_ = $(LDFLAGS) -static

test_array_SOURCES = tests/test-array.c tests/helpers.h
test_array_LDADD = $(tests_LDADD_)
test_array_LDFLAGS = $(tests_LDFLAGS_)

test_bitset_SOURCES = tests/test-bitset.c tests/helpers.h
test_bitset_LDADD = $(tests_LDADD_)
test_bitset_LDFLAGS = $(tests_LDFLAGS_)

test_buffer_SOURCES = tests/test-buffer.c tests/helpers.h
test_buffer_LDADD = $(tests_LDADD_)
test_buffer_LDFLAGS = $(tests_LDFLAGS_)

test_core_SOURCES = tests/test-core.c tests/helpers.h
test_core_LDADD = $(tests_LDADD_)
test_core_LDFLAGS = $(tests_LDFLAGS_)

test_dllist_SOURCES = tests/test-dllist.c tests/helpers.h
test_dllist_LDADD = $(tests_LDADD_)
test_dllist_LDFLAGS = $(tests_LDFLAGS_)

test_files_SOURCES = tests/test-files.c tests/helpers.h
test_files_LDADD = $(tests_LDADD_)
test_files_LDFLAGS = $(tests_LDFLAGS_)

test_gc_SOURCES = tests/test-gc.c tests/helpers.h
test_gc_LDADD = $(tests_LDADD_)
test_gc_LDFLAGS = $(tests_LDFLAGS_)

test_hash_table_SOURCES = tests/test-hash-table.c tests/helpers.h
test_hash_table_LDADD = $(tests_LDADD_)
test_hash_table_LDFLAGS = $(tests_LDFLAGS_)

test_managed_buffer_SOURCES = tests/test-managed-buffer.c tests/helpers.h
test_managed_buffer_LDADD = $(tests_LDADD_)
test_managed_buffer_LDFLAGS = $(tests_LDFLAGS_)

test_mempool_SOURCES = tests/test-mempool.c tests/helpers.h
test_mempool_LDADD = $(tests_LDADD_)
test_mempool_LDFLAGS = $(tests_LDFLAGS_)

test_ring_buffer_SOURCES = tests/test-ring-buffer.c tests/helpers.h
test_ring_buffer_LDADD = $(tests_LDADD_)
test_ring_buffer_LDFLAGS = $(tests_LDFLAGS_)

test_slice_SOURCES = tests/test-slice.c tests/helpers.h
test_slice_LDADD = $(tests_LDADD_)
test_slice_LDFLAGS = $(tests_LDFLAGS_)

test_subprocess_SOURCES = tests/test-subprocess.c tests/helpers.h
test_subprocess_LDADD = $(tests_LDADD_)
test_subprocess_LDFLAGS = $(tests_LDFLAGS_)

test_threads_SOURCES = tests/test-threads.c tests/helpers.h
test_threads_LDADD = $(tests_LDADD_)
test_threads_LDFLAGS = $(tests_LDFLAGS_)

test_u128_SOURCES = tests/test-u128.c tests/helpers.h
test_u128_CPPFLAGS = -I$(builddir)/tests $(AM_CPPFLAGS)
test_u128_LDADD = $(tests_LDADD_)
test_u128_LDFLAGS = $(tests_LDFLAGS_)

u128_tests = \
    tests/u128-tests-eq.c.in \
    tests/u128-tests-ne.c.in \
    tests/u128-tests-lt.c.in \
    tests/u128-tests-le.c.in \
    tests/u128-tests-gt.c.in \
    tests/u128-tests-ge.c.in \
    tests/u128-tests-shl.c.in \
    tests/u128-tests-shr.c.in \
    tests/u128-tests-add.c.in \
    tests/u128-tests-sub.c.in

CLEANFILES += $(u128_tests)

tests/u128-tests-eq.c.in: tests/create-u128-test-cases.py
	$(AM_V_GEN) $(PYTHON) $< eq $@
tests/u128-tests-ne.c.in: tests/create-u128-test-cases.py
	$(AM_V_GEN) $(PYTHON) $< ne $@
tests/u128-tests-lt.c.in: tests/create-u128-test-cases.py
	$(AM_V_GEN) $(PYTHON) $< lt $@
tests/u128-tests-le.c.in: tests/create-u128-test-cases.py
	$(AM_V_GEN) $(PYTHON) $< le $@
tests/u128-tests-gt.c.in: tests/create-u128-test-cases.py
	$(AM_V_GEN) $(PYTHON) $< gt $@
tests/u128-tests-ge.c.in: tests/create-u128-test-cases.py
	$(AM_V_GEN) $(PYTHON) $< ge $@
tests/u128-tests-shl.c.in: tests/create-u128-test-cases.py
	$(AM_V_GEN) $(PYTHON) $< shl $@
tests/u128-tests-shr.c.in: tests/create-u128-test-cases.py
	$(AM_V_GEN) $(PYTHON) $< shr $@
tests/u128-tests-add.c.in: tests/create-u128-test-cases.py
	$(AM_V_GEN) $(PYTHON) $< add $@
tests/u128-tests-sub.c.in: tests/create-u128-test-cases.py
	$(AM_V_GEN) $(PYTHON) $< sub $@

tests/test-u128.c: $(u128_tests)

endif RUN_TESTS

# Cram tests

TEST_EXTENSIONS = .t
EXTRA_DIST += \
    tests/ccram \
    tests/cram.py \
    tests/test-input.txt

cram_tests = \
    tests/cork-hash.t \
    tests/cork-initializer.t \
    tests/cork-test/cleanup.t \
    tests/cork-test/directory-watcher.t \
    tests/cork-test/help1-c1-s1.t \
    tests/cork-test/help1-c1-s2.t \
    tests/cork-test/help1-c1.t \
    tests/cork-test/help1-c2.t \
    tests/cork-test/help1-root.t \
    tests/cork-test/help2-c1-s1.t \
    tests/cork-test/help2-c1-s2.t \
    tests/cork-test/help2-c1.t \
    tests/cork-test/help2-c2.t \
    tests/cork-test/help2-root.t \
    tests/cork-test/help3-c1-s1.t \
    tests/cork-test/help3-c1-s2.t \
    tests/cork-test/help3-c1.t \
    tests/cork-test/help3-c2.t \
    tests/cork-test/help3-root.t \
    tests/cork-test/no-command-c1.t \
    tests/cork-test/no-command-root.t \
    tests/cork-test/run-c1-s1-f.t \
    tests/cork-test/run-c1-s1-f-t.t \
    tests/cork-test/run-c1-s1.t \
    tests/cork-test/run-c1-s1-test.t \
    tests/cork-test/run-c1-s1-t.t \
    tests/cork-test/run-c1-s2-file.t \
    tests/cork-test/run-c1-s2-f.t \
    tests/cork-test/run-c1-s2.t \
    tests/cork-test/run-c2.t \
    tests/cork-test/run-find-01.t \
    tests/cork-test/run-find-all-01.t \
    tests/cork-test/run-mkdir-01.t \
    tests/cork-test/run-paths-01.t \
    tests/cork-test/run-pwd-01.t \
    tests/cork-test/run-rm-01.t \
    tests/cork-test/run-sub-01.t \
    tests/cork-test/run-sub-02.t \
    tests/cork-test/run-sub-03.t \
    tests/cork-test/run-sub-04.t \
    tests/cork-test/run-sub-05.t \
    tests/cork-test/run-sub-06.t

EXTRA_DIST += $(cram_tests)

if RUN_TESTS

TESTS += $(cram_tests)

T_LOG_COMPILER = $(srcdir)/tests/ccram
AM_T_LOG_FLAGS = \
    --python $(PYTHON) \
    --root $(srcdir) \
    --cram $(srcdir)/tests/cram.py \
    --tests

check_PROGRAMS += cork-initializer
cork_initializer_SOURCES = \
    src/cork-initializer/init1.c \
    src/cork-initializer/init2.c \
    src/cork-initializer/main.c
cork_initializer_LDADD = libcork.la

check_PROGRAMS += cork-test
cork_test_SOURCES = src/cork-test/cork-test.c
cork_test_LDADD = libcork.la

endif

# If you have test failures during distcheck, cram won't be able to print out
# the diff, since `make distcheck` causes the unpacked distribution tarball to
# be read-only.  Uncomment the following to (temporarily) make the unpacked
# tests directory writeable, so that you can see what caused the test failure.
#distcheck-hook:
#	chmod -R ug+w $(distdir)/tests

# Test harness

@VALGRIND_CHECK_RULES@

if !RUN_TESTS
check-local:
	$(error Cannot run test suite without check and Python installed!)
endif


================================================
FILE: README.markdown
================================================
# libcork

[![Build Status](https://travis-ci.org/dcreager/libcork.svg?branch=master)](https://travis-ci.org/dcreager/libcork)

So what is libcork, exactly?  It's a “simple, easily embeddable,
cross-platform C library”.  It falls roughly into the same category as
[glib](http://library.gnome.org/devel/glib/) or
[APR](http://apr.apache.org/) in the C world; the STL,
[POCO](http://pocoproject.org/), or [QtCore](http://qt.nokia.com/)
in the C++ world; or the standard libraries of any decent dynamic
language.

So if libcork has all of these comparables, why a new library?  Well,
none of the C++ options are really applicable here.  And none of the C
options work, because one of the main goals is to have the library be
highly modular, and useful in resource-constrained systems.  Once we
describe some of the design decisions that we've made in libcork, you'll
hopefully see how this fits into an interesting niche of its own.

## Using libcork

There are two primary ways to use libcork in your own software project:
as a _shared library_, or _embedded_.

When you use libcork as a shared library, you install it just like you
would any other C library.  We happen to use CMake as our build system,
so you follow the usual CMake recipe to install the library.  (See the
[INSTALL](INSTALL) file for details.)  All of the libcork code is
contained within a single shared library (called libcork.so,
libcork.dylib, or cork.dll, depending on the system).  We also install a
pkg-config file that makes it easy to add the appropriate compiler flags
in your own build scripts.  So, you use pkg-config to find libcork's
include and library files, link with libcork, and you're good to go.

The alternative is to embed libcork into your own software project's
directory structure.  In this case, your build scripts compile the
libcork source along with the rest of your code.  This has some
advantages for resource-constrained systems, since (assuming your
compiler and linker are any good), you only include the libcork routines
that you actually use.  And if your toolchain supports link-time
optimization, the libcork routines can be optimized into the rest of
your code.

Which should you use?  That's really up to you.  Linking against the
shared library adds a runtime dependency, but gives you the usual
benefits of shared libraries: the library in memory is shared across
each program that uses it; you can install a single bug-fix update and
all libcork programs automatically take advantage of the new release;
etc.  The embedding option is great if you really need to make your
library as small as possible, or if you don't want to add that runtime
dependency.

## Design decisions

Note that having libcork be **easily** embeddable has some ramifications
on the library's design.  In particular, we don't want to make any
assumptions about which build system you're embedding libcork into.  We
happen to use CMake, but you might be using autotools, waf, scons, or
any number of others.  Most cross-platform libraries follow the
autotools model of performing some checks at compile time (maybe during
a separate “configure” phase, maybe not) to choose the right API
implementation for the current platform.  Since we can't assume a build
system, we have to take a different approach, and do as many checks as
we can using the C preprocessor.  Any check that we can't make in the
preprocessor has to be driven by a C preprocessor macro definition,
which you (the libcork user) are responsible for checking for and
defining.  So we need to have as few of those as possible.


================================================
FILE: autogen.sh
================================================
#!/bin/sh
# ------------------------------------------------------------------------------
# Copyright © 2020, libcork authors.
# Please see the COPYING file in this distribution for license details.
# ------------------------------------------------------------------------------

set -e

cd "$(dirname "$0")"

AUTORECONF=${AUTORECONF:-autoreconf}
ACLOCAL=${ACLOCAL:-aclocal}
AUTOCONF=${AUTOCONF:-autoconf}
AUTOHEADER=${AUTOHEADER:-autoheader}
AUTOMAKE=${AUTOMAKE:-automake}

"${AUTORECONF}" --verbose --install --force -I m4


================================================
FILE: build-aux/calculate
================================================
#!/bin/sh
# ----------------------------------------------------------------------
# Copyright © 2011, libcork authors
# All rights reserved.
#
# Please see the COPYING file in this distribution for license details.
# ----------------------------------------------------------------------

# Usage:
#   calculate version|commit [top_srcdir] [path to stamp file]
#
# Calculates the current version number.  When run from a distribution tarball,
# we get the version number from the .version-stamp file (that our `make dist`
# target ensures that it creates).  When run from a local git repository, we get
# the version number via `git describe`.

set -e

WHAT="$1"
case "$WHAT" in
  version) ;;
  commit) ;;
  *) echo "Unknown option $WHAT" >&2; exit 1;;
esac

top_srcdir="${2-.}"
export GIT_DIR="${top_srcdir}/.git"

# First try the stamp file
STAMP_FILE="$3"
if [ -f "$STAMP_FILE" ]; then
  version=$(cat "$STAMP_FILE")
  if [ -z "$version" ]; then
    echo "Invalid stamp file" >&2
    exit 1
  fi
  printf "%s" "$version"
  exit 0
fi

# Fall back on `git describe`
case "$WHAT" in
  version)
    closest_tag=$(git describe --abbrev=0)
    full_version=$(git describe --abbrev=7 --dirty)
    if test "$closest_tag" = "$full_version"; then
        version="$closest_tag"
    else
        version="$closest_tag-git"
    fi
    ;;
  commit)
    version=$(git rev-parse HEAD);;
esac
if [ -z "$version" ]; then
  echo "Cannot find the version from git" >&2
  exit 1
fi
printf "%s" "$version"


================================================
FILE: cmake/FindCTargets.cmake
================================================
# -*- coding: utf-8 -*-
# ----------------------------------------------------------------------
# Copyright © 2015, libcork authors
# Please see the COPYING file in this distribution for license details.
# ----------------------------------------------------------------------


#-----------------------------------------------------------------------
# Configuration options that control all of the below

set(ENABLE_SHARED YES CACHE BOOL "Whether to build a shared library")
set(ENABLE_SHARED_EXECUTABLES YES CACHE BOOL
    "Whether to link executables using shared libraries")
set(ENABLE_STATIC YES CACHE BOOL "Whether to build a static library")


#-----------------------------------------------------------------------
# Library, with options to build both shared and static versions

function(target_add_shared_libraries TARGET_NAME LIBRARIES LOCAL_LIBRARIES)
    foreach(lib ${LIBRARIES})
        string(REPLACE "-" "_" lib ${lib})
        string(TOUPPER ${lib} upperlib)
        target_link_libraries(
            ${TARGET_NAME}
            ${${upperlib}_LDFLAGS}
        )
    endforeach(lib)
    foreach(lib ${LOCAL_LIBRARIES})
        target_link_libraries(${TARGET_NAME} ${lib}-shared)
    endforeach(lib)
endfunction(target_add_shared_libraries)

function(target_add_static_libraries TARGET_NAME LIBRARIES LOCAL_LIBRARIES)
    foreach(lib ${LIBRARIES})
        string(REPLACE "-" "_" lib ${lib})
        string(TOUPPER ${lib} upperlib)
        target_link_libraries(
            ${TARGET_NAME}
            ${${upperlib}_STATIC_LDFLAGS}
        )
    endforeach(lib)
    foreach(lib ${LOCAL_LIBRARIES})
        target_link_libraries(${TARGET_NAME} ${lib}-static)
    endforeach(lib)
endfunction(target_add_static_libraries)

set_property(GLOBAL PROPERTY ALL_LOCAL_LIBRARIES "")

function(add_c_library __TARGET_NAME)
    set(options)
    set(one_args OUTPUT_NAME PKGCONFIG_NAME VERSION_INFO)
    set(multi_args LIBRARIES LOCAL_LIBRARIES SOURCES)
    cmake_parse_arguments(_ "${options}" "${one_args}" "${multi_args}" ${ARGN})

    if (__VERSION_INFO MATCHES "^([0-9]+):([0-9]+):([0-9]+)(-dev)?$")
        set(__VERSION_CURRENT  "${CMAKE_MATCH_1}")
        set(__VERSION_REVISION "${CMAKE_MATCH_2}")
        set(__VERSION_AGE      "${CMAKE_MATCH_3}")
    else (__VERSION_INFO MATCHES "^([0-9]+):([0-9]+):([0-9]+)(-dev)?$")
        message(FATAL_ERROR "Invalid library version info: ${__VERSION_INFO}")
    endif (__VERSION_INFO MATCHES "^([0-9]+):([0-9]+):([0-9]+)(-dev)?$")

    # Mimic libtool's behavior in calculating SONAME and VERSION from
    # version-info.
    # http://git.savannah.gnu.org/cgit/libtool.git/tree/build-aux/ltmain.in?id=722b6af0fad19b3d9f21924ae5aa6dfae5957378#n7042
    math(EXPR __SOVERSION "${__VERSION_CURRENT} - ${__VERSION_AGE}")
    set(__VERSION "${__SOVERSION}.${__VERSION_AGE}.${__VERSION_REVISION}")

    get_property(ALL_LOCAL_LIBRARIES GLOBAL PROPERTY ALL_LOCAL_LIBRARIES)
    list(APPEND ALL_LOCAL_LIBRARIES ${__TARGET_NAME})
    set_property(GLOBAL PROPERTY ALL_LOCAL_LIBRARIES "${ALL_LOCAL_LIBRARIES}")

    if (ENABLE_SHARED OR ENABLE_SHARED_EXECUTABLES)
        add_library(${__TARGET_NAME}-shared SHARED ${__SOURCES})
        set_target_properties(
            ${__TARGET_NAME}-shared PROPERTIES
            OUTPUT_NAME ${__OUTPUT_NAME}
            CLEAN_DIRECT_OUTPUT 1
            VERSION ${__VERSION}
            SOVERSION ${__SOVERSION}
        )

        if (CMAKE_VERSION VERSION_GREATER "2.8.11")
            target_include_directories(
                ${__TARGET_NAME}-shared PUBLIC
                ${CMAKE_SOURCE_DIR}/include
                ${CMAKE_BINARY_DIR}/include
            )
        else (CMAKE_VERSION VERSION_GREATER "2.8.11")
            include_directories(
                ${CMAKE_SOURCE_DIR}/include
                ${CMAKE_BINARY_DIR}/include
            )
        endif (CMAKE_VERSION VERSION_GREATER "2.8.11")

        target_add_shared_libraries(
            ${__TARGET_NAME}-shared
            "${__LIBRARIES}"
            "${__LOCAL_LIBRARIES}"
        )

        # We have to install the shared library if the user asked us to, or if
        # the user asked us to link our programs with the shared library.
        install(TARGETS ${__TARGET_NAME}-shared
                LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})
    endif (ENABLE_SHARED OR ENABLE_SHARED_EXECUTABLES)

    if (ENABLE_STATIC OR NOT ENABLE_SHARED_EXECUTABLES)
        add_library(${__TARGET_NAME}-static STATIC ${__SOURCES})
        set_target_properties(
            ${__TARGET_NAME}-static PROPERTIES
            OUTPUT_NAME ${__OUTPUT_NAME}
            CLEAN_DIRECT_OUTPUT 1
        )

        if (CMAKE_VERSION VERSION_GREATER "2.8.11")
            target_include_directories(
                ${__TARGET_NAME}-static PUBLIC
                ${CMAKE_SOURCE_DIR}/include
                ${CMAKE_BINARY_DIR}/include
            )
        else (CMAKE_VERSION VERSION_GREATER "2.8.11")
            include_directories(
                ${CMAKE_SOURCE_DIR}/include
                ${CMAKE_BINARY_DIR}/include
            )
        endif (CMAKE_VERSION VERSION_GREATER "2.8.11")

        target_add_static_libraries(
            ${__TARGET_NAME}-static
            "${__LIBRARIES}"
            "${__LOCAL_LIBRARIES}"
        )
    endif (ENABLE_STATIC OR NOT ENABLE_SHARED_EXECUTABLES)

    if (ENABLE_STATIC)
        # We DON'T have to install the static library if the user asked us to
        # link our programs statically.
        install(TARGETS ${__TARGET_NAME}-static
                ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
    endif (ENABLE_STATIC)

    set(PACKAGE_TARNAME "${PROJECT_NAME}")
    set(prefix ${CMAKE_INSTALL_PREFIX})
    set(exec_prefix "\${prefix}")
    set(datarootdir "\${prefix}/share")
    set(includedir "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}")
    set(libdir "\${exec_prefix}/${CMAKE_INSTALL_LIBDIR}")
    string(REPLACE
      "${CMAKE_INSTALL_DATAROOTDIR}/" ""
      base_docdir
      "${CMAKE_INSTALL_DOCDIR}")
    set(docdir "\${datarootdir}/${base_docdir}")
    configure_file(
        ${CMAKE_CURRENT_SOURCE_DIR}/${__PKGCONFIG_NAME}.pc.in
        ${CMAKE_CURRENT_BINARY_DIR}/${__PKGCONFIG_NAME}.pc
        @ONLY
    )
    install(
        FILES ${CMAKE_CURRENT_BINARY_DIR}/${__PKGCONFIG_NAME}.pc
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig
    )
endfunction(add_c_library)


#-----------------------------------------------------------------------
# Executable

function(add_c_executable __TARGET_NAME)
    set(options SKIP_INSTALL)
    set(one_args OUTPUT_NAME)
    set(multi_args LIBRARIES LOCAL_LIBRARIES SOURCES)
    cmake_parse_arguments(_ "${options}" "${one_args}" "${multi_args}" ${ARGN})

    add_executable(${__TARGET_NAME} ${__SOURCES})

    if (CMAKE_VERSION VERSION_GREATER "2.8.11")
        target_include_directories(
            ${__TARGET_NAME} PUBLIC
            ${CMAKE_SOURCE_DIR}/include
            ${CMAKE_BINARY_DIR}/include
        )
    else (CMAKE_VERSION VERSION_GREATER "2.8.11")
        include_directories(
            ${CMAKE_SOURCE_DIR}/include
            ${CMAKE_BINARY_DIR}/include
        )
    endif (CMAKE_VERSION VERSION_GREATER "2.8.11")

    if (ENABLE_SHARED_EXECUTABLES)
        target_add_shared_libraries(
            ${__TARGET_NAME}
            "${__LIBRARIES}"
            "${__LOCAL_LIBRARIES}"
        )
    else (ENABLE_SHARED_EXECUTABLES)
        target_add_static_libraries(
            ${__TARGET_NAME}
            "${__LIBRARIES}"
            "${__LOCAL_LIBRARIES}"
        )
    endif (ENABLE_SHARED_EXECUTABLES)

    if (NOT __SKIP_INSTALL)
        install(TARGETS ${__TARGET_NAME} RUNTIME DESTINATION bin)
    endif (NOT __SKIP_INSTALL)
endfunction(add_c_executable)


#-----------------------------------------------------------------------
# Test case

pkgconfig_prereq(check OPTIONAL)

function(add_c_test TEST_NAME)
    get_property(ALL_LOCAL_LIBRARIES GLOBAL PROPERTY ALL_LOCAL_LIBRARIES)
    add_c_executable(
        ${TEST_NAME}
        SKIP_INSTALL
        OUTPUT_NAME ${TEST_NAME}
        SOURCES ${TEST_NAME}.c
        LIBRARIES check
        LOCAL_LIBRARIES ${ALL_LOCAL_LIBRARIES}
    )
    add_test(${TEST_NAME} ${TEST_NAME})
endfunction(add_c_test)


================================================
FILE: cmake/FindParseArguments.cmake
================================================
# -*- coding: utf-8 -*-
# ----------------------------------------------------------------------
# Copyright © 2015, libcork authors
# Please see the COPYING file in this distribution for license details.
# ----------------------------------------------------------------------


# CMake 2.8.4 and higher gives us cmake_parse_arguments out of the box.  For
# earlier versions (RHEL5!) we have to define it ourselves.  (The definition
# comes from <http://www.cmake.org/Wiki/CMakeMacroParseArguments>.)

if (CMAKE_VERSION VERSION_LESS "2.8.4")

MACRO(CMAKE_PARSE_ARGUMENTS prefix arg_names option_names)
  SET(DEFAULT_ARGS)
  FOREACH(arg_name ${arg_names})
    SET(${prefix}_${arg_name})
  ENDFOREACH(arg_name)
  FOREACH(option ${option_names})
    SET(${prefix}_${option} FALSE)
  ENDFOREACH(option)

  SET(current_arg_name DEFAULT_ARGS)
  SET(current_arg_list)
  FOREACH(arg ${ARGN})
    SET(larg_names ${arg_names})
    LIST(FIND larg_names "${arg}" is_arg_name)
    IF (is_arg_name GREATER -1)
      SET(${prefix}_${current_arg_name} ${current_arg_list})
      SET(current_arg_name ${arg})
      SET(current_arg_list)
    ELSE (is_arg_name GREATER -1)
      SET(loption_names ${option_names})
      LIST(FIND loption_names "${arg}" is_option)
      IF (is_option GREATER -1)
          SET(${prefix}_${arg} TRUE)
      ELSE (is_option GREATER -1)
          SET(current_arg_list ${current_arg_list} ${arg})
      ENDIF (is_option GREATER -1)
    ENDIF (is_arg_name GREATER -1)
  ENDFOREACH(arg)
  SET(${prefix}_${current_arg_name} ${current_arg_list})
ENDMACRO(CMAKE_PARSE_ARGUMENTS)

else (CMAKE_VERSION VERSION_LESS "2.8.4")

    include(CMakeParseArguments)

endif (CMAKE_VERSION VERSION_LESS "2.8.4")


================================================
FILE: cmake/FindPrereqs.cmake
================================================
# -*- coding: utf-8 -*-
# ----------------------------------------------------------------------
# Copyright © 2015, libcork authors
# Please see the COPYING file in this distribution for license details.
# ----------------------------------------------------------------------


#-----------------------------------------------------------------------
# Configuration options that control all of the below

set(PKG_CONFIG_PATH CACHE STRING "pkg-config search path")
if (PKG_CONFIG_PATH)
    set(ENV{PKG_CONFIG_PATH} "${PKG_CONFIG_PATH}:$ENV{PKG_CONFIG_PATH}")
endif (PKG_CONFIG_PATH)


#-----------------------------------------------------------------------
# pkg-config prerequisites

find_package(PkgConfig)

function(pkgconfig_prereq DEP)
    set(options OPTIONAL)
    set(one_args)
    set(multi_args)
    cmake_parse_arguments(_ "${options}" "${one_args}" "${multi_args}" ${ARGN})

    string(REGEX REPLACE "[<>=].*" "" SHORT_NAME "${DEP}")
    string(REPLACE "-" "_" SHORT_NAME "${SHORT_NAME}")
    string(TOUPPER ${SHORT_NAME} UPPER_SHORT_NAME)
    string(TOLOWER ${SHORT_NAME} LOWER_SHORT_NAME)

    set(USE_CUSTOM_${UPPER_SHORT_NAME} NO CACHE BOOL
        "Whether you want to provide custom details for ${LOWER_SHORT_NAME}")

    if (NOT USE_CUSTOM_${UPPER_SHORT_NAME})
        set(PKG_CHECK_ARGS)
        if (NOT __OPTIONAL)
            list(APPEND PKG_CHECK_ARGS REQUIRED)
        endif (NOT __OPTIONAL)
        list(APPEND PKG_CHECK_ARGS ${DEP})

        pkg_check_modules(${UPPER_SHORT_NAME} ${PKG_CHECK_ARGS})
    endif (NOT USE_CUSTOM_${UPPER_SHORT_NAME})

    include_directories(${${UPPER_SHORT_NAME}_INCLUDE_DIRS})
    link_directories(${${UPPER_SHORT_NAME}_LIBRARY_DIRS})
endfunction(pkgconfig_prereq)


#-----------------------------------------------------------------------
# find_library prerequisites

function(library_prereq LIB_NAME)
    set(options OPTIONAL)
    set(one_args)
    set(multi_args)
    cmake_parse_arguments(_ "${options}" "${one_args}" "${multi_args}" ${ARGN})

    string(REPLACE "-" "_" SHORT_NAME "${LIB_NAME}")
    string(TOUPPER ${SHORT_NAME} UPPER_SHORT_NAME)
    string(TOLOWER ${SHORT_NAME} LOWER_SHORT_NAME)

    set(USE_CUSTOM_${UPPER_SHORT_NAME} NO CACHE BOOL
        "Whether you want to provide custom details for ${LOWER_SHORT_NAME}")

    if (USE_CUSTOM_${UPPER_SHORT_NAME})
        include_directories(${${UPPER_SHORT_NAME}_INCLUDE_DIRS})
        link_directories(${${UPPER_SHORT_NAME}_LIBRARY_DIRS})
        if (NOT ${UPPER_SHORT_NAME}_STATIC_LDFLAGS)
            set(${UPPER_SHORT_NAME}_STATIC_LDFLAGS
                ${${UPPER_SHORT_NAME}_LDFLAGS}
                PARENT_SCOPE)
        endif (NOT ${UPPER_SHORT_NAME}_STATIC_LDFLAGS)
    else (USE_CUSTOM_${UPPER_SHORT_NAME})
        find_library(${UPPER_SHORT_NAME}_LDFLAGS ${LIB_NAME})
        set(${UPPER_SHORT_NAME}_STATIC_LDFLAGS
            ${${UPPER_SHORT_NAME}_LDFLAGS}
            PARENT_SCOPE)
    endif (USE_CUSTOM_${UPPER_SHORT_NAME})

endfunction(library_prereq)


================================================
FILE: configure.ac
================================================
# -*- coding: utf-8 -*-
# ------------------------------------------------------------------------------
# Copyright © 2018, libcork authors
# Please see the COPYING file in this distribution for license details.
# ------------------------------------------------------------------------------

AC_INIT([libcork],
        m4_esyscmd([build-aux/calculate version . .version-stamp]),
        [info@libcork.io])
AC_CONFIG_AUX_DIR([build-aux])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([src/libcork/core/version.c])
AM_INIT_AUTOMAKE([foreign no-dist-gzip dist-xz subdir-objects])
AM_MAINTAINER_MODE([enable])  # Allow packagers to disable if they want
AM_SILENT_RULES([yes])
LT_INIT

# Generating version-stamp files
AC_PATH_PROG(GIT, [git])
if test -z "$GIT" ; then
  AC_MSG_FAILURE([cannot find 'git'])
fi

# Versions
AC_PROG_AWK
AC_PROG_SED
BASE_VERSION=`AS_ECHO([$VERSION]) | sed -e 's/\-.*//'`
AC_SUBST(CORK_VERSION_MAJOR, [`AS_ECHO([$BASE_VERSION]) | $AWK -F. '{print $1}'`])
AC_SUBST(CORK_VERSION_MINOR, [`AS_ECHO([$BASE_VERSION]) | $AWK -F. '{print $2}'`])
AC_SUBST(CORK_VERSION_PATCH, [`AS_ECHO([$BASE_VERSION]) | $AWK -F. '{print $3}'`])
AC_SUBST(CORK_VERSION, ["$VERSION"])
AC_SUBST(CORK_GIT_SHA1, m4_esyscmd([build-aux/calculate commit . .commit-stamp]))
AC_CONFIG_FILES([include/libcork/config/version.h])
AC_PROG_CC
AC_PROG_CC_C99

# TAP support
AC_PROG_AWK

# Threads
AX_PTHREAD
LIBS="$PTHREAD_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
CC="$PTHREAD_CC"

# pkg-config
PKG_INSTALLDIR
AC_CONFIG_FILES([src/libcork.pc])

# Tests
AM_PATH_PYTHON([2.3], , [:])
PKG_CHECK_MODULES(CHECK, [check], [check=yes], [check=no])
AM_CONDITIONAL(RUN_TESTS, [test "$PYTHON" != : -a $check = yes])

# Valgrind support
AX_VALGRIND_DFLT([memcheck], [on])
AX_VALGRIND_DFLT([helgrind], [off])
AX_VALGRIND_DFLT([drd], [off])
AX_VALGRIND_DFLT([sgcheck], [off])
AX_VALGRIND_CHECK()

# Turn on fatal warnings by default; you can override this by setting CPPFLAGS
# to something else when running configure.
: ${CPPFLAGS="-Wall -Werror"}

AC_OUTPUT([Makefile])

cat <<EOF

------------------ Summary ------------------
 $PACKAGE_NAME version $PACKAGE_VERSION
  Prefix.........: $prefix
  C Compiler.....: $CC $CFLAGS $CPPFLAGS
  Linker.........: $LD $LDFLAGS $LIBS
---------------------------------------------

Check the above options and compile with:
 ${MAKE-make}

EOF


================================================
FILE: docs/.gitattributes
================================================
*.graffle      -diff -whitespace
/*.[1-9]       -diff -whitespace


================================================
FILE: docs/CMakeLists.txt
================================================
# -*- coding: utf-8 -*-
# ----------------------------------------------------------------------
# Copyright © 2011, libcork authors
# Please see the COPYING file in this distribution for license details.
# ----------------------------------------------------------------------

# Fill in this with the text that you want to include in the header and footer
# of each man page.

set(MAN_HEADER "${PROJECT_NAME} documentation")
set(MAN_FOOTER "${PROJECT_NAME}")

# Fill this in with any man pages that should be built from a pandoc source
# file.  For a man page called foo.5, there should be a pandoc source file
# called foo.5.md.

set(MAN_PAGES
)

#-----------------------------------------------------------------------
# Everything below is boilerplate!

find_program(
    PANDOC_EXECUTABLE
    NAMES pandoc
    HINTS ENV PANDOC_DIR
    PATH_SUFFIXES bin
    DOC "Pandoc man page generator"
)

set(GENERATE_DOC TRUE CACHE BOOL
    "Whether to rebuild documentation")

if (NOT PANDOC_EXECUTABLE)
    message(WARNING "Unable to find pandoc documentation generator")
    set(GENERATE_DOC FALSE)
endif (NOT PANDOC_EXECUTABLE)


# Link man pages go in docs/links

macro(install_links section)
    file(GLOB links "links/*.${section}")
    if (links)
        install(
            FILES ${links}
            DESTINATION "share/man/man${section}"
        )
    endif (links)
endmacro(install_links section)

install_links(1)   # commands
install_links(3)   # library API
install_links(4)   # special files and drivers
install_links(5)   # file formats and conventions
install_links(7)   # miscellaneous
install_links(8)   # system commands


# Man pages with actual content go in docs

set(ALL_MANS)

macro(pandocify name)
    set(src "${CMAKE_CURRENT_SOURCE_DIR}/${name}.md")
    set(dest "${CMAKE_CURRENT_SOURCE_DIR}/${name}")
    get_filename_component(section "${name}" EXT)
    string(REPLACE "." "" section "${section}")

    # Only compile the markdown source into groff man pages if requested.
    if (GENERATE_DOC)
        add_custom_command(
            OUTPUT ${dest}
            COMMAND ${PANDOC_EXECUTABLE}
                -f markdown -t man -s --smart
                -V header="${MAN_HEADER}"
                -V footer="${MAN_FOOTER}"
                -V date=${RELEASE_DATE}
                -o ${dest} ${src}
            MAIN_DEPENDENCY ${src}
            COMMENT "Building ${name}"
        )
        list(APPEND ALL_MANS ${dest})
    endif (GENERATE_DOC)

    # We should always have an already-compiled copy of each man page in the
    # source tree, which we can install even if we didn't build fresh new
    # copies.
    install(
        FILES ${dest}
        DESTINATION "share/man/man${section}"
    )
endmacro(pandocify)

foreach(MAN_PAGE ${MAN_PAGES})
    pandocify(${MAN_PAGE})
endforeach(MAN_PAGE)

add_custom_target(doc ALL DEPENDS ${ALL_MANS})


================================================
FILE: docs/old/CMakeLists.txt
================================================
# -*- coding: utf-8 -*-
# ----------------------------------------------------------------------
# Copyright © 2011, libcork authors
# Please see the COPYING file in this distribution for license details.
# ----------------------------------------------------------------------

find_program(
  SPHINX_EXECUTABLE
  NAMES sphinx-build
  HINTS ENV SPHINX_DIR
  PATH_SUFFIXES bin
  DOC "Sphinx documentation generator"
)

set(GENERATE_DOC TRUE)

if (NOT SPHINX_EXECUTABLE)
  message(WARNING "Unable to find Sphinx documentation generator")
  set(GENERATE_DOC FALSE)
endif (NOT SPHINX_EXECUTABLE)

set(INTERSPHINX_OVERRIDES "")

macro(find_prereq_doc LIB_NAME)
  execute_process(
    COMMAND ${PKG_CONFIG_EXECUTABLE} --variable=sphinxdir ${LIB_NAME}
    OUTPUT_VARIABLE LIB_SPHINX_DIR
    OUTPUT_STRIP_TRAILING_WHITESPACE
  )

  if (LIB_SPHINX_DIR)
    message(STATUS "Using ${LIB_NAME} docs in ${LIB_SPHINX_DIR}")
    set(
      INTERSPHINX_OVERRIDES
      "${INTERSPHINX_OVERRIDES}\nintersphinx_mapping['${LIB_NAME}'] = ('${LIB_SPHINX_DIR}', None)"
    )
  endif (LIB_SPHINX_DIR)
endmacro(find_prereq_doc)

if (GENERATE_DOC)
  set(SPHINX_SRC_CONF_FILE "${CMAKE_CURRENT_SOURCE_DIR}/conf.py")
  set(SPHINX_CONF_FILE "${CMAKE_CURRENT_BINARY_DIR}/conf.py")
  set(SPHINX_CACHE_DIR "${CMAKE_CURRENT_BINARY_DIR}/_doctrees")
  set(SPHINX_HTML_DIR "${CMAKE_CURRENT_BINARY_DIR}/html")

  # If your Sphinx documentation references the Sphinx documentation of
  # any of your prerequisite libraries, add some calls to
  # find_prereq_doc here:
  #
  # find_prereq_doc(libcork)

  set(
    VERSION_FOR_CONF_PY
    "\nrelease=\"${VERSION}\"\nversion=\"${BASE_VERSION}\""
  )
  configure_file(${SPHINX_SRC_CONF_FILE} ${SPHINX_CONF_FILE} @ONLY)
  file(COPY _static DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
  file(COPY _templates DESTINATION ${CMAKE_CURRENT_BINARY_DIR})

  add_custom_target(old-doc ALL
    ${SPHINX_EXECUTABLE}
      -b html
      -d "${SPHINX_CACHE_DIR}"
      -c "${CMAKE_CURRENT_BINARY_DIR}"
      "${CMAKE_CURRENT_SOURCE_DIR}"
      "${SPHINX_HTML_DIR}"
    COMMENT "Building HTML documentation with Sphinx"
  )

  list(APPEND CLEAN_FILES "${SPHINX_CACHE_DIR}" "${SPHINX_HTML_DIR}")
  set_directory_properties(
    PROPERTIES
    ADDITIONAL_MAKE_CLEAN_FILES "${CLEAN_FILES}"
  )

  install(
    DIRECTORY "${SPHINX_HTML_DIR}"
    DESTINATION "${CMAKE_INSTALL_DOCDIR}"
  )
endif (GENERATE_DOC)


================================================
FILE: docs/old/_static/.keep
================================================


================================================
FILE: docs/old/_static/docco-sphinx.css
================================================
@import url("basic.css");

/* -- page layout ----------------------------------------------------------- */

body {
    font-family: 'Palatino Linotype', Palatino, 'URW Palladio L', 'Book Antiqua', FreeSerif, serif;
    /*font-size: 95%;*/
    font-size: 95%;
    color: #252519;
    margin: 0;
    padding: 0;
}

div.document {
}

div.documentwrapper {
    float: left;
    width: 100%;
}

div.bodywrapper {
    margin: 0 0 0 19em;
    background-color: #ffffff;
}

div.body {
    color: #252519;
    padding: 30px 0px 30px 60px;
    width: 40em;
}

div.footer {
    width: 100%;
    padding: 9px 0 9px 0;
    text-align: center;
    font-size: 75%;
}

div.footer a {
    color: #261a3b;
    text-decoration: underline;
}

div.related {
    background-color: #eee;
    border: 1px solid #ccc;
    line-height: 30px;
}

div.related a {
    color: #261a3b;
}

div.sphinxsidebar {
    padding: 30px 0px 0 20px;
    width: 19em;
    color: #555;
}

div.sphinxsidebar a {
    color: #555;
}

div.sphinxsidebar h3 {
    font-size: 1.4em;
    margin: 0;
    padding: 0;
}

div.sphinxsidebar h4 {
    font-size: 1.3em;
    margin: 5px 0 0 0;
    padding: 0;
}

div.sphinxsidebar p {
}

div.sphinxsidebar p.topless {
    margin: 5px 10px 10px 10px;
}

div.sphinxsidebar ul {
    margin: 10px;
    padding: 0;
    color: #ffffff;
}

div.sphinxsidebar li {
    padding-top: 5px;
    line-height: 115%;
}

div.sphinxsidebar input {
    border: 1px solid #ccc;
    font-family: sans-serif;
    font-size: 1em;
}



/* -- hyperlink styles ------------------------------------------------------ */

a {
    color: #306060;
    text-decoration: none;
}

a:visited {
    color: #306060;
    text-decoration: none;
}

a:hover {
    text-decoration: underline;
}



/* -- body styles ----------------------------------------------------------- */

div.body h1,
div.body h2 {
    border-top: 1px solid #ccc;
    margin: 40px -20px 10px -20px;
    padding: 3px 0 3px 0;
}

div.body h3,
div.body h4,
div.body h5,
div.body h6 {
    margin: 20px 0px -10px 0px;
}

div.body h1 { margin-top: 0; font-size: 200%; border: 0px; }
div.body h2 { font-size: 160%; }
div.body h3 { font-size: 140%; }
div.body h4 { font-size: 120%; }
div.body h5 { font-size: 110%; }
div.body h6 { font-size: 100%; }

a.headerlink {
    color: #c60f0f;
    font-size: 0.8em;
    padding: 0 4px 0 4px;
    text-decoration: none;
}

a.headerlink:hover {
    background-color: #c60f0f;
    color: white;
}

div.body p, div.body dd, div.body li {
    line-height: 130%;
}

p.admonition-title {
    margin-right: 0.3em;
}

div.admonition p.admonition-title + p {
    display: inline;
}

div.admonition p {
    margin-bottom: 5px;
}

div.admonition pre {
    margin-bottom: 5px;
}

div.admonition ul, div.admonition ol {
    margin-bottom: 5px;
}

div.note {
    background-color: #eee;
    border: 1px solid #ccc;
}

div.seealso {
    background-color: #ffc;
    border: 1px solid #ff6;
}

div.tip {
    background-color: #e4e4ff;
    border: 1px solid #ccc;
}

div.topic {
    background-color: #eee;
}

div.warning {
    background-color: #ffe4e4;
    border: 1px solid #f66;
}

p.admonition-title {
    display: inline;
}

p.admonition-title:after {
    content: ":";
}

pre {
    font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace;
    font-size: 80%;
    padding: 5px;
    background-color: #f5f5ff;
    color: #333333;
    line-height: 130%;
    border: 1px solid #e5e5ee;
    border-left: none;
    border-right: none;
}

tt {
    font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace;
    background-color: #f8f8ff;
    border: 1px solid #dedede;
    padding: 0 0.2em;
    font-size: 85%;
}

a tt {
    background-color: transparent;
    border: 0px;
}

dt {
    font-family: Menlo, Monaco, Consolas, "Lucida Console", monospace;
    font-size: 90%;
    line-height: 130%;
}

table.indextable dt {
    font-family: 'Palatino Linotype', Palatino, 'URW Palladio L', 'Book Antiqua', FreeSerif, serif;
    font-size: 100%;
}

em.property {
    font-size: 90%;
}

tt.descclassname {
    background-color: transparent;
    border: 0px;
    padding: 0px;
}

tt.descname {
    background-color: transparent;
    border: 0px;
    font-size: 100%;
    padding: 0px;
}

dt big {
    font-family: 'Palatino Linotype', Palatino, 'URW Palladio L', 'Book Antiqua', FreeSerif, serif;
    font-size: 140%;
    padding: 0 2px;
}

dt big.param_start_brace {
    padding: 0 6px;
}

dt big.param_end_brace {
    padding: 0 6px;
}

dt span.optional {
    font-family: 'Palatino Linotype', Palatino, 'URW Palladio L', 'Book Antiqua', FreeSerif, serif;
    font-size: 140%;
    padding: 0 2px;
}

th {
    background-color: #ede;
}

.warning tt {
    background: #efc2c2;
}

.note tt {
    background: #d6d6d6;
}

.viewcode-back {
    font-family: sans-serif;
}

div.viewcode-block:target {
    background-color: #f4debf;
    border-top: 1px solid #ac9;
    border-bottom: 1px solid #ac9;
}


================================================
FILE: docs/old/_static/pygments.css
================================================
.highlight .hll { background-color: #ffffcc }
.highlight .c { color: #408080; font-style: italic }  /* Comment */
.highlight .err { border: 1px solid #FF0000 }         /* Error */
.highlight .k { color: #954121 }                      /* Keyword */
.highlight .o { color: #666666 }                      /* Operator */
.highlight .cm { color: #408080; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #BC7A00 }                     /* Comment.Preproc */
.highlight .c1 { color: #408080; font-style: italic } /* Comment.Single */
.highlight .cs { color: #408080; font-style: italic } /* Comment.Special */
.highlight .gd { color: #A00000 }                     /* Generic.Deleted */
.highlight .ge { font-style: italic }                 /* Generic.Emph */
.highlight .gr { color: #FF0000 }                     /* Generic.Error */
.highlight .gh { color: #000080; font-weight: bold }  /* Generic.Heading */
.highlight .gi { color: #00A000 }                     /* Generic.Inserted */
.highlight .go { color: #808080 }                     /* Generic.Output */
.highlight .gp { color: #000080; font-weight: bold }  /* Generic.Prompt */
.highlight .gs { font-weight: bold }                  /* Generic.Strong */
.highlight .gu { color: #800080; font-weight: bold }  /* Generic.Subheading */
.highlight .gt { color: #0040D0 }                     /* Generic.Traceback */
.highlight .kc { color: #954121 }                     /* Keyword.Constant */
.highlight .kd { color: #954121; font-weight: bold }  /* Keyword.Declaration */
.highlight .kn { color: #954121; font-weight: bold }  /* Keyword.Namespace */
.highlight .kp { color: #954121 }                     /* Keyword.Pseudo */
.highlight .kr { color: #954121; font-weight: bold }  /* Keyword.Reserved */
.highlight .kt { color: #B00040 }                     /* Keyword.Type */
.highlight .m { color: #666666 }                      /* Literal.Number */
.highlight .s { color: #219161 }                      /* Literal.String */
.highlight .na { color: #7D9029 }                     /* Name.Attribute */
.highlight .nb { color: #954121 }                     /* Name.Builtin */
.highlight .nc { color: #0000FF; font-weight: bold }  /* Name.Class */
.highlight .no { color: #880000 }                     /* Name.Constant */
.highlight .nd { color: #AA22FF }                     /* Name.Decorator */
.highlight .ni { color: #999999; font-weight: bold }  /* Name.Entity */
.highlight .ne { color: #D2413A; font-weight: bold }  /* Name.Exception */
.highlight .nf { color: #0000FF }                     /* Name.Function */
.highlight .nl { color: #A0A000 }                     /* Name.Label */
.highlight .nn { color: #0000FF; font-weight: bold }  /* Name.Namespace */
.highlight .nt { color: #954121; font-weight: bold }  /* Name.Tag */
.highlight .nv { color: #19469D }                     /* Name.Variable */
.highlight .ow { color: #AA22FF; font-weight: bold }  /* Operator.Word */
.highlight .w { color: #bbbbbb }                      /* Text.Whitespace */
.highlight .mf { color: #666666 }                     /* Literal.Number.Float */
.highlight .mh { color: #666666 }                     /* Literal.Number.Hex */
.highlight .mi { color: #666666 }                     /* Literal.Number.Integer */
.highlight .mo { color: #666666 }                     /* Literal.Number.Oct */
.highlight .sb { color: #219161 }                     /* Literal.String.Backtick */
.highlight .sc { color: #219161 }                     /* Literal.String.Char */
.highlight .sd { color: #219161; font-style: italic } /* Literal.String.Doc */
.highlight .s2 { color: #219161 }                     /* Literal.String.Double */
.highlight .se { color: #BB6622; font-weight: bold }  /* Literal.String.Escape */
.highlight .sh { color: #219161 }                     /* Literal.String.Heredoc */
.highlight .si { color: #BB6688; font-weight: bold }  /* Literal.String.Interpol */
.highlight .sx { color: #954121 }                     /* Literal.String.Other */
.highlight .sr { color: #BB6688 }                     /* Literal.String.Regex */
.highlight .s1 { color: #219161 }                     /* Literal.String.Single */
.highlight .ss { color: #19469D }                     /* Literal.String.Symbol */
.highlight .bp { color: #954121 }                     /* Name.Builtin.Pseudo */
.highlight .vc { color: #19469D }                     /* Name.Variable.Class */
.highlight .vg { color: #19469D }                     /* Name.Variable.Global */
.highlight .vi { color: #19469D }                     /* Name.Variable.Instance */
.highlight .il { color: #666666 }                     /* Literal.Number.Integer.Long */


================================================
FILE: docs/old/_templates/.keep
================================================


================================================
FILE: docs/old/allocation.rst
================================================
.. _allocation:

*****************
Memory allocation
*****************

.. highlight:: c

::

  #include <libcork/core.h>

One of the biggest hassles in writing C code is memory management.  libcork's
memory allocation API tries to simplify this task as much as possible.  This is
still C, so you still have to manage allocated memory manually — for instance,
by keeping careful track of which section of code "owns" any memory that you've
allocated from heap, and is therefore responsible for freeing it.  But we *can*
make it easier to handle memory allocation failures, and provide helper macros
for certain common allocation tasks.

There is another `important use case`_ that we also want to support: giving
application writers complete control over how the libraries they use allocate
and deallocate memory.  libcork :ref:`provides <libcork-allocators>` this
capability, giving you control over how, for instance, a hash table allocates
its internal buckets.  If you're writing a library that links with libcork as a
shared library, you'll get this behavior for free; if the application writer
customizes how libcork allocates memory, your library will pick up that
customization as well.  If you're embedding libcork, so that your library's
clients can't tell (or care) that you're using libcork, then you'll want to
expose your own similar customization interface.

.. _important use case: https://blog.mozilla.org/nnethercote/2013/11/08/libraries-should-permit-custom-allocators/


.. _allocation-api:

Allocating memory
=================

The simplest part of the API is the part responsible for actually allocating and
deallocating memory.  When using this part of the API, you don't have to worry
about customization at all; the functions described here will automatically "do
the right thing" based on how your library or application is configured.  The
biggest thing to worry about is how to handle memory allocation failures.  We
provide two strategies, "guaranteed" and "recoverable".

The most common use case is that running out of memory is a Really Bad Thing,
and there's nothing we can do to recover.  In this case, it doesn't make sense
to check for memory allocation failures throughout your code, since you can't
really do anything if it does happen.  The "guaranteed" family of functions
handles that error checking for you, and guarantees that if the allocation
function returns, it will return a valid piece of memory.  If the allocation
fails, the function will never return.  That allows you to right simple and safe
code like the following::

    struct my_type  *instance = cork_new(struct my_type);
    /* Just start using instance; don't worry about verifying that it's
     * not NULL! */

On the other hand, you might be writing some code that can gracefully handle a
memory allocation failure.  You might try to allocate a super-huge cache, for
instance; if you can't allocate the cache, your code will still work, it will
just be a bit slower.  In this case, you *want* to be able to detect memory
allocation failures, and handle them in whatever way is appropriate.  The
"recoverable" family of functions will return a ``NULL`` pointer if allocation
fails.

.. note::

   libcork itself uses the guaranteed functions for all internal memory
   allocation.


Guaranteed allocation
---------------------

The functions in this section are guaranteed to return a valid newly allocated
pointer.  If memory allocation fails, the functions will not return.

.. function:: void \*cork_malloc(size_t size)
              void \*cork_calloc(size_t count, size_t size)
              void \*cork_realloc(void \*ptr, size_t old_size, size_t new_size)
              type \*cork_new(TYPE type)

   The first three functions mimic the standard ``malloc``, ``calloc``, and
   ``realloc`` functions to allocate (or reallocate) some memory, with the added
   guarantee that they will always return a valid newly allocated pointer.
   ``cork_new`` is a convenience function for allocating an instance of a
   particular type; it is exactly equivalent to::

       cork_malloc(sizeof(type))

   Note that with ``cork_realloc``, unlike the standard ``realloc`` function,
   you must provide the old size of the memory region, in addition to the
   requested new size.

   Each allocation function has a corresponding deallocation function that you
   must use to free the memory when you are done with it: use
   :c:func:`cork_free` to free memory allocated using ``cork_malloc`` or
   ``cork_realloc``; use :c:func:`cork_cfree` to free memory allocated using
   ``cork_calloc``; and use :c:func:`cork_delete` to free memory allocated using
   ``cork_new``.

   .. note::

      Note that the possible memory leak in the standard ``realloc``
      function doesn't apply here, since we're going to abort the whole
      program if the reallocation fails.


Recoverable allocation
----------------------

The functions in this section will return a ``NULL`` pointer if any memory
allocation fails, allowing you to recover from the error condition, if possible.

.. function:: void \*cork_xmalloc(size_t size)
              void \*cork_xcalloc(size_t count, size_t size)
              void \*cork_xrealloc(void \*ptr, size_t old_size, size_t new_size)
              void \*cork_xreallocf(void \*ptr, size_t old_size, size_t new_size)
              type \*cork_xnew(TYPE type)

   The first three functions mimic the standard ``malloc``, ``calloc``,
   ``realloc`` functions.  ``cork_xreallocf`` mimics the common ``reallocf``
   function from BSD.  These functions return ``NULL`` if the memory allocation
   fails.  (Note that unlike the standard functions, they do **not** set
   ``errno`` to ``ENOMEM``; the only indication you have of an error condition
   is a ``NULL`` return value.)

   Note that with ``cork_xrealloc`` and ``cork_xreallocf``, unlike the standard
   ``realloc`` function, you must provide the old size of the memory region, in
   addition to the requested new size.

   ``cork_xreallocf`` is more safe than the standard ``realloc`` function.  A
   common idiom when calling ``realloc`` is::

       void  *ptr = /* from somewhere */;
       /* UNSAFE!  Do not do this! */
       ptr = realloc(ptr, new_size);

   This is unsafe!  The ``realloc`` function returns a ``NULL`` pointer if the
   reallocation fails.  By assigning directly into *ptr*, you'll get a memory
   leak in these situations.  The ``cork_xreallocf`` function, on the other
   hand, will automatically free the existing pointer if the reallocation fails,
   eliminating the memory leak::

       void  *ptr = /* from somewhere */;
       /* This is safe.  Do this. */
       ptr = cork_xreallocf(ptr, new_size);
       /* Check whether ptr is NULL before using it! */

   Each allocation function has a corresponding deallocation function that you
   must use to free the memory when you are done with it: use
   :c:func:`cork_free` to free memory allocated using ``cork_xmalloc``,
   ``cork_xrealloc``, or ``cork_xreallocf``; use :c:func:`cork_cfree` to free
   memory allocated using ``cork_xcalloc``; and use :c:func:`cork_delete` to
   free memory allocated using ``cork_xnew``.


Deallocation
------------

Since this is C, you must free any memory region once you're done with it.
You must use one of the functions from this section to free any memory that you
created using any of the allocation functions described previously.

.. function:: void cork_free(void \*ptr, size_t size)
              void cork_cfree(void \*ptr, size_t count, size_t size)
              void cork_delete(TYPE type, void \*ptr)

   Frees a region of memory allocated by one of libcork's allocation functions.

   Note that unlike the standard ``free`` function, you must provide the size of
   the allocated region when it's freed, as well as when it's created.  Most of
   the time this isn't an issue, since you're either freeing a region whose size
   is known at compile time, or you're already keeping track of the size of a
   dynamically sized memory region for some other reason.

   You should use ``cork_free`` to free memory allocated using
   :c:func:`cork_malloc`, :c:func:`cork_realloc`, :c:func:`cork_xmalloc`,
   :c:func:`cork_xrealloc`, or :c:func:`cork_xreallocf`.  You should use
   ``cork_cfree`` to free memory allocated using :c:func:`cork_calloc` or
   :c:func:`cork_xcalloc`.  You should use ``cork_delete`` to free memory
   allocated using :c:func:`cork_new` or :c:func:`cork_xnew`.


Duplicating strings
-------------------

.. function:: const char \*cork_strdup(const char \*str)
              const char \*cork_strndup(const char \*str, size_t size)
              const char \*cork_xstrdup(const char \*str)
              const char \*cork_xstrndup(const char \*str, size_t size)

   These functions mimic the standard ``strdup`` function.  They create a copy
   of an existing C string, allocating exactly as much memory is needed to hold
   the copy.

   The ``strdup`` variants calculate the size of *str* using ``strlen``.  For
   the ``strndup`` variants, *str* does not need to be ``NUL``-terminated, and
   you must pass in its *size*.  (Note that is different than the standard
   ``strndup``, where *str* must be ``NUL``-terminated, and which copies **at
   most** *size* bytes.  Our version always copies **exactly** *size* bytes.)
   The result is guaranteed to be ``NUL``-terminated, even if the source *str*
   is not.

   You shouldn't modify the contents of the copied string.  You must use
   :c:func:`cork_strfree()` to free the string when you're done with it.  The
   ``x`` variant returns a ``NULL`` pointer if the allocation fails; the non-\
   ``x`` variant is guaranteed to return a valid pointer to a copied string.

.. function:: void cork_strfree(const char \*str)

   Frees *str*, which must have been created using
   :c:func:`cork_strdup()` or :c:func:`cork_xstrdup()`.


.. _libcork-allocators:

Customizing how libcork allocates
=================================

The ``cork_alloc`` type encapsulates a particular memory allocation scheme.  To
customize how libcork allocates memory, you create a new instance of this type,
and then use :c:func:`cork_set_allocator` to register it with libcork.

.. function:: void cork_set_allocator(const struct cork_alloc \*alloc)

   Override which :ref:`allocator instance <allocators>` libcork will use to
   create and free memory.  We will take control of *alloc*; you must not free
   it yourself after passing it to this function.

   You can only call this function at most once.  This function is **not**
   thread-safe; it's only safe to call before you've called **any** other
   libcork function (or any function from any other library that uses libcork.
   (The only exceptions are libcork functions that take in a
   :c:type:`cork_alloc` parameter or return a :c:type:`cork_alloc` result; these
   functions are safe to call before calling ``cork_set_allocator``.)

.. var:: const struct cork_alloc \*cork_allocator

   The current :ref:`allocator instance <allocators>` that libcork will use to
   create and free memory.


.. _allocators:

Writing a custom allocator
--------------------------

.. type:: struct cork_alloc

   The ``cork_alloc`` type contains several methods for performing different
   allocation and deallocation operations.

   You are only required to provide implementations of ``xmalloc`` and ``free``;
   we can provide default implementations of all of the other methods in terms
   of those two.  You can provide optimized versions of the other methods, if
   appropriate.


.. function:: struct cork_alloc \*cork_alloc_new_alloc(const struct cork_alloc \*parent)

   ``cork_alloc_new`` creates a new allocator instance.  The new instance will
   itself be allocated using *parent*.  You must provide implementations of at
   least the ``xmalloc`` and ``free`` methods.  You can also override our
   default implementations of any of the other methods.

   This function is **not** thread-safe; it's only safe to call before you've
   called **any** other libcork function (or any function from any other library
   that uses libcork.  (The only exceptions are libcork functions that take in a
   :c:type:`cork_alloc` parameter or return a :c:type:`cork_alloc` result; these
   functions are safe to call before calling ``cork_set_allocator``.)

   The new allocator instance will automatically be freed when the process
   exits.  If you registered a *user_data* pointer for your allocation methods
   (via :c:func:`cork_alloc_set_user_data`), it will be freed using the
   *free_user_data* method you provided.  If you create more than one
   ``cork_alloc`` instance in the process, they will be freed in the reverse
   order that they were created.

   .. note::

      In your allocator implementation, you cannot assume that the rest of the
      libcork allocation framework has been set up yet.  So if your allocator
      needs to allocate, you must not use the usual :c:func:`cork_malloc` family
      of functions; instead you should use the ``cork_alloc_malloc`` variants to
      explicitly allocate memory using your new allocator's *parent*.


.. function:: void cork_alloc_set_user_data(struct cork_alloc \*alloc, void \*user_data, cork_free_f free_user_data)

   Provide a *user_data* pointer, which will be passed unmodified to each
   allocation method that you register.  You can also provide an optional
   *free_user_data* method, which we will use to free the *user_data* instance
   when the allocator itself is freed.


.. function:: void cork_alloc_set_calloc(struct cork_alloc \*alloc, cork_alloc_calloc_f calloc)
              void cork_alloc_set_xcalloc(struct cork_alloc \*alloc, cork_alloc_calloc_f calloc)

   .. type:: void \*(\*cork_alloc_calloc_f)(const struct cork_alloc \*alloc, size_t count, size_t size)

      These methods are used to implement the :c:func:`cork_calloc` and
      :c:func:`cork_xcalloc` functions.  Your must allocate and return ``count *
      size`` bytes of memory.  You must ensure that every byte in this region is
      initialized to ``0``.  The ``calloc`` variant must always return a valid
      pointer; if memory allocation fails, it must not return.  The ``xcalloc``
      variant should return ``NULL`` if allocation fails.


.. function:: void cork_alloc_set_malloc(struct cork_alloc \*alloc, cork_alloc_malloc_f malloc)
              void cork_alloc_set_xmalloc(struct cork_alloc \*alloc, cork_alloc_malloc_f malloc)

   .. type:: void \*(\*cork_alloc_malloc_f)(const struct cork_alloc \*alloc, size_t size)

      These methods are used to implement the :c:func:`cork_malloc` and
      :c:func:`cork_xmalloc` functions.  You must allocate and return *size*
      bytes of memory.  The ``malloc`` variant must always return a valid
      pointer; if memory allocation fails, it must not return.  The ``xmalloc``
      variant should return ``NULL`` if allocation fails.


.. function:: void cork_alloc_set_realloc(struct cork_alloc \*alloc, cork_alloc_realloc_f realloc)
              void cork_alloc_set_xrealloc(struct cork_alloc \*alloc, cork_alloc_realloc_f realloc)

   .. type:: void \*(\*cork_alloc_realloc_f)(const struct cork_alloc \*alloc, void \*ptr, size_t old_size, size_t new_size)

      These methods are used to implement the :c:func:`cork_realloc`,
      :c:func:`cork_xrealloc`, and :c:func:`cork_xreallocf` functions.  You
      must reallocate *ptr* to contain *new_size* bytes of memory and return the
      reallocated pointer.  *old_size* will be the previously allocated size of
      *ptr*.  The ``realloc`` variant must always return a valid pointer; if
      memory reallocation fails, it must not return.  The ``xrealloc`` variant
      should return ``NULL`` if reallocation fails.


.. function:: void cork_alloc_set_free(struct cork_alloc \*alloc, cork_alloc_free_f free)

   .. type:: void \*(\*cork_alloc_free_f)(const struct cork_alloc \*alloc, void \*ptr, size_t size)

      These methods are used to implement the :c:func:`cork_free`,
      :c:func:`cork_cfree`, and :c:func:`cork_delete` functions.  You must
      deallocate *ptr*.  *size* will be the allocated size of *ptr*.


================================================
FILE: docs/old/array.rst
================================================
.. _array:

****************
Resizable arrays
****************

.. highlight:: c

::

  #include <libcork/ds.h>

This section defines a resizable array class, similar to C++'s
``std::vector`` or Java's ``ArrayList`` classes.  Our arrays can store
any fixed-size element.  The arrays automatically resize themselves as
necessary to store the elements that you add.


.. type:: cork_array(element_type)

   A resizable array that contains elements of type *element_type*.

.. function:: void cork_array_init(cork_array(T) \*array)

   Initializes a new array.  You should allocate *array* yourself,
   presumably on the stack or directly within some other data type.  The
   array will start empty.

.. function:: void cork_array_done(cork_array(T) \*array)

   Finalizes an array, freeing any storage that was allocated to hold
   the arrays elements.

.. function:: size_t cork_array_size(cork_array(T) \*array)

   Returns the number of elements in *array*.

.. function:: bool cork_array_is_empty(cork_array(T) \*array)

   Returns whether *array* has any elements.

.. function:: void cork_array_void(cork_array(T) \*array)

   Removes all elements from *array*.

.. function:: T* cork_array_elements(cork_array(T) \*array)

   Returns a pointer to the underlying array of elements in *array*.  The
   elements are guaranteed to be contiguous, just like in a normal C array, but
   the particular pointer that is returned in **not** guaranteed to be
   consistent across function calls that modify the contents of the array.

.. function:: T cork_array_at(cork_array(T) \*array, size_t index)

   Returns the element in *array* at the given *index*.  Like accessing
   a normal C array, we don't do any bounds checking.  The result is a
   valid lvalue, so it can be directly assigned to::

     cork_array(int64_t)  array;
     cork_array_append(array, 5, err);
     cork_array_at(array, 0) = 12;

.. function:: void cork_array_append(cork_array(T) \*array, T element)

   Appends *element* to the end of *array*, reallocating the array's
   storage if necessary.  If you have an ``init`` or ``reset`` callback for
   *array*, it will be used to initialize the space that was allocated for the
   new element, and then *element* will be directly copied into that space
   (using ``memcpy`` or an equivalent).  If that is not the right copy behavior
   for the elements of *array*, then you should use
   :c:func:`cork_array_append_get` instead, and fill in the allocated element
   directly.

.. function:: T \*cork_array_append_get(cork_array(T) \*array)

   Appends a new element to the end of *array*, reallocating the array's storage
   if necessary, returning a pointer to the new element.

.. function:: int cork_array_ensure_size(cork_array(T) \*array, size_t desired_count)

   Ensures that *array* has enough allocated space to store *desired_count*
   elements, reallocating the array's storage if needed.  The actual size and
   existing contents of the array aren't changed.

.. function:: int cork_array_copy(cork_array(T) \*dest, cork_array(T) \*src, cork_copy_f \*copy, void \*user_data)

   Copy elements from *src* to *dest*.  If you provide a *copy* function, it
   will be called on each element to perform the copy.  If not, we'll use
   ``memcpy`` to bulk-copy the elements.

   If you've provided :ref:`callbacks <array-callbacks>` for *dest*, then those
   callbacks will be called appropriately.  We'll call the ``remove`` callback
   for any existing entries (will be overwritten by the copy).  We'll call
   ``init`` or ``reuse`` on each element entry before it's copied.

   .. type:: typedef int (\*cork_copy_f)(void \*user_data, void \*dest, const void \*src)

.. function:: size_t cork_array_element_size(cork_array(T) \*array)

   Returns the size of the elements that are stored in *array*.  You
   won't normally need to call this, since you can just use
   ``sizeof(T)``.


.. _array-callbacks:

Initializing and finalizing elements
------------------------------------

You can provide callback functions that will be used to automatically initialize
and finalize the elements of a resizable array.


.. function:: void cork_array_set_init(cork_array(T) \*array, cork_init_f init)
              void cork_array_set_done(cork_array(T) \*array, cork_done_f done)
              void cork_array_set_reuse(cork_array(T) \*array, cork_init_f reuse)
              void cork_array_set_remove(cork_array(T) \*array, cork_done_f remove)
              void cork_array_set_callback_data(cork_array(T) \*array, void \*user_data, cork_free_f free_user_data)

   Set one of the callback functions for *array*.  There are two pairs of
   callbacks: ``init`` and ``done``, and ``reuse`` and ``remove``.  Within each
   pair, one callback is used to initialize an element of the array, while the
   other is used to finalize it.

   The ``init`` callback is used to initialize an element when its array entry
   is used for the first time.  If you then shrink the array (via
   :c:func:`cork_array_clear`, for instance), and then append elements again,
   you will reuse array entries; in this case, the ``reset`` callback is used
   instead.  (Having separate ``init`` and ``reuse`` callbacks can be useful
   when the elements are complex objects with deep memory requirements.  If you
   use the ``init`` callback to allocate that memory, and use the ``reset``
   callback to "clear" it, then you can reduce some of the memory allocation
   overhead.)

   Similarly, the ``remove`` callback is used when an element is removed from
   the array, but the space that the element used isn't being reclaimed yet.
   The ``done`` callback, on the other hand, is used when the array entry is
   reclaimed and freed.

   All of the callbacks take in an additional *user_data* parameter, in addition
   to the array entries themselves.  You provide that parameter by calling the
   :c:func:`cork_array_set_callback_data` function.  If you pass in a
   *free_user_data* function, then we will use that function to free the
   *user_data* when the array itself is finalized.

   .. type:: typedef void (\*cork_init_f)(void \*user_data, void \*value)
             typedef void (\*cork_done_f)(void \*user_data, void \*value)
             typedef void (\*cork_free_f)(void \*value)


================================================
FILE: docs/old/attributes.rst
================================================
.. _attributes:

*******************
Compiler attributes
*******************

.. highlight:: c

::

  #include <libcork/core.h>

The macros in this section define compiler-agnostic versions of several
common compiler attributes.


.. function:: CORK_LIKELY(expression)
              CORK_UNLIKELY(expression)

   Indicate that the given Boolean *expression* is likely to be ``true``
   or ``false``, respectively.  The compiler can sometimes use this
   information to generate more efficient code.


.. macro:: CORK_ATTR_CONST

   Declare a “constant” function.  The return value of a constant
   function can only depend on its parameters.  This is slightly more
   strict than a “pure” function (declared by
   :c:macro:`CORK_ATTR_PURE`); a constant function is not allowed to
   read from global variables, whereas a pure function is.

   .. note:: Note that the compiler won't verify that your function
      meets the requirements of a constant function.  Instead, this
      attribute notifies the compiler of your intentions, which allows
      the compiler to assume more about your function when optimizing
      code that calls it.

   ::

     int square(int x) CORK_ATTR_CONST;


.. macro:: CORK_ATTR_MALLOC

   Declare a function that returns a newly allocated pointer.  The
   compiler can use this information to generate more accurate aliasing
   information, since it can infer that the result of the function
   cannot alias any other existing pointer.

   ::

     void *custom_malloc(size_t size) CORK_ATTR_MALLOC;


.. macro:: CORK_ATTR_NOINLINE

   Declare that a function shouldn't be eligible for inlining.


.. macro:: CORK_ATTR_PRINTF(format_index, args_index)

   Declare a function that takes in ``printf``\ -like parameters.
   *format_index* is the index (starting from 1) of the parameter that
   contains the ``printf`` format string.  *args_index* is the index of
   the first parameter that contains the data to format.


.. macro:: CORK_ATTR_PURE

   Declare a “pure” function.  The return value of a pure function can
   only depend on its parameters, and on global variables.

   ::

     static int  _next_id;
     int get_next_id(void) CORK_ATTR_PURE;


.. macro:: CORK_ATTR_SENTINEL

   Declare a var-arg function whose last parameter must be a ``NULL``
   sentinel value.  When the compiler supports this attribute, it will
   check the actual parameters whenever this function is called, and
   ensure that the last parameter is a ``NULL``.


.. macro:: CORK_ATTR_UNUSED

   Declare a entity that might not be used.  This lets you keep
   ``-Wall`` activated in several cases where you're obligated to define
   something that you don't intend to use.

   ::

     CORK_ATTR_UNUSED static void
     unused_function(void)
     {
         CORK_ATTR_UNUSED int  unused_value;
     }


.. macro:: CORK_INITIALIZER(func_name)
           CORK_FINALIZER(func_name)

   Declare a ``static`` function that will be automatically called at program
   startup (for ``CORK_INITIALIZER``) or shutdown (for ``CORK_FINALIZER``).  If
   there are multiple initializer functions linked into a program, there is no
   guarantee about the order in which the functions will be called.

   ::

     #include <libcork/core.h>
     #include <libcork/ds.h>

     static cork_array(int)  array;

     CORK_INITIALIZER(init_array)
     {
        cork_array_init(&array);
     }

     CORK_FINALIZER(done_array)
     {
        cork_array_done(&array);
     }


================================================
FILE: docs/old/basic-types.rst
================================================
.. _basic-types:

***********
Basic types
***********

.. highlight:: c

::

  #include <libcork/core.h>

The types in this section ensure that the C99 integer types are
available, regardless of platform.  We also define some preprocessor
macros that give the size of the non-fixed-size standard types.  In
addition, libcork defines some useful low-level types:

.. toctree::
   :maxdepth: 1

   int128
   net-addresses
   timestamps
   hash-values
   unique-ids

Integral types
==============

.. type:: bool

   A boolean.  Where possible, we simply include ``<stdbool.h>`` to get
   this type.  It might be ``typedef``\ ed to ``int``\ .  We also make
   sure that the following constants are defined:

   .. var:: bool false
            bool true

.. type:: int8_t
          uint8_t
          int16_t
          uint16_t
          int32_t
          uint32_t
          int64_t
          uint64_t

   Signed and unsigned, fixed-size integral types.

.. type:: intptr_t
          uintptr_t

   Signed and unsigned integers that are guaranteed to be big enough to
   hold a type-cast ``void *``\ .

.. type:: size_t

   An unsigned integer big enough to hold the size of a memory object,
   or a maximal array index.

.. type:: ptrdiff_t

   A signed integer big enough to hold the difference between two
   pointers.

Size macros
===========

.. macro:: CORK_SIZEOF_SHORT
           CORK_SIZEOF_INT
           CORK_SIZEOF_LONG
           CORK_SIZEOF_POINTER

   The size (in bytes) of the ``short``, ``int``, ``long``, and ``void
   *`` types, respectively.


.. _embedded-struct:

Embedded ``struct``\ s
======================

Quite often a callback function or API will take in a pointer to a
particular ``struct``, with the expectation that you can embed that
``struct`` into some other type for extension purposes.  Kind of a
bastardized subclassing mechanism for C code.  The doubly-linked list
module is a perfect example; you're meant to embed
:c:type:`cork_dllist_item` within the linked list element type.  You can
use the following macro to obtain the pointer to the containing
(“subclass”) ``struct``, when given a pointer to the contained
(“superclass”) ``struct``:

.. function:: struct_type \*cork_container_of(field_type \*field, TYPE struct_type, FIELD field_name)

   The *struct_type* parameter must be the name of a ``struct`` type,
   *field_name* must be the name of some field within that
   ``struct``, and *field* must be a pointer to an instance of that
   field.  The macro returns a pointer to the containing ``struct``.
   So, given the following definitions::

     struct superclass {
         int  a;
     };

     struct subclass {
         int  b;
         struct superclass  parent;
     };

     struct subclass  instance;

   then the following identity holds::

     cork_container_of(&instance.parent, struct subclass, parent) == &instance

   .. note:: When the superclass ``struct`` appears as the first element
      of the subclass ``struct``, you can obtain the same effect using a
      simple type-cast.  However, the ``cork_container_of`` macro is
      more robust, since it also works when the superclass ``struct``
      appears later on in the subclass ``struct``.


================================================
FILE: docs/old/bitset.rst
================================================
.. _bits:

********
Bit sets
********

.. highlight:: c

::

  #include <libcork/ds.h>

This sections defines a type for storing an array of bits.  This data structure
is most often used to implement a set of integers.  It is particularly good when
you expect your sets to be *dense*.  You should not use a bitset if the number
of possibly elements is outrageously large, however, since that would cause your
bitset to exhaust the available memory.

.. type:: struct cork_bitset

   An array of bits.  You should not allocate any instances of this type
   yourself; use :c:func:`cork_bitset_new` instead.

   .. member:: size_t bit_count

      The number of bits that are included in this array.  (Each bit can be on
      or off; this does not give you the number of bits that are *on*, it gives
      you the number of bits in total, on or off.)


.. function:: void cork_bitset_init(struct cork_bitset \*set)

   Initialize a new bitset instance that you've allocated yourself
   (usually on the stack).  All bits will be initialized to ``0``.

.. function:: struct cork_bitset \*cork_bitset_new(size_t bit_count)

   Create a new bitset with enough space to store the given number of bits.
   All bits will be initialized to ``0``.

.. function:: void cork_bitset_done(struct cork_bitset \*set)

   Finalize a bitset, freeing any set content that it contains.  This
   function should only be used for bitsets that you allocated yourself,
   and initialized using :c:func:`cork_bitset_init()`.  You must **not** use
   this function to free a bitset allocated using :c:func:`cork_bitset_new()`.

.. function:: void cork_bitset_free(struct cork_bitset \*set)

   Finalize and deallocate a bitset, freeing any set content that it
   contains.  This function should only be used for bitsets allocated
   using :c:func:`cork_bitset_new()`.  You must **not** use this
   function to free a bitset initialized using :c:func:`cork_bitset_init()`.

.. function:: bool cork_bitset_get(struct cork_bitset \*set, size_t index)

   Return whether the given bit is on or off in *set*.  It is your
   responsibility to ensure that *index* is within the valid range for *set*.

.. function:: void cork_bitset_set(struct cork_bitset \*set, size_t index, bool value)

   Turn the given bit on or off in *set*.  It is your responsibility to ensure
   that *index* is within the valid range for *set*.

.. function:: void cork_bitset_clear(struct cork_bitset \*set)

   Turn off of the bits in *set*.


================================================
FILE: docs/old/buffer.rst
================================================
.. _buffer:

************************
Resizable binary buffers
************************

.. highlight:: c

::

  #include <libcork/ds.h>

This section defines a resizable binary buffer type.  This class can
also be used to construct C strings, when you don't know the size of
the string in advance.

This class is not reference counted; we assume that there's a single
owner of the buffer.  The contents of a :c:type:`cork_buffer` are fully
mutable.  If you want to turn the buffer into something that's safe to
pass between threads, you can use the :c:func:`cork_buffer_to_slice()`
or :c:func:`cork_buffer_to_managed_buffer()` functions to create an
immutable managed wrapper around the buffer.

You can read the contents of the buffer by accessing the :c:member:`buf
<cork_buffer.buf>` and :c:member:`size <cork_buffer.size>` fields
directly.  However, to modify the contents of a buffer, you should use
the mutator functions described below, since they take care of
automatically resizing the underlying buffer when necessary.

.. note::

   This class always creates its own copy of any data added to the
   buffer; there aren't any methods for wrapping existing buffers
   without copying.  If you want to do that, you should use
   :ref:`managed-buffer` or :ref:`slice`.


.. type:: struct cork_buffer

   A resizable binary buffer.

   .. member:: void \*buf

      The current contents of the buffer.

   .. member:: size_t  size

      The current size of the buffer.


.. function:: void cork_buffer_init(struct cork_buffer \*buffer)
              struct cork_buffer CORK_BUFFER_INIT()

   Initialize a new buffer instance that you've allocated yourself
   (usually on the stack).  The ``CORK_BUFFER_INIT`` version can only be
   used as a static initializer.

   The preallocated ``cork_buffer`` instance that you provide doesn't
   include space for the content of the buffer; this will be allocated
   automatically as content is added.

.. function:: struct cork_buffer \*cork_buffer_new(void)

   Allocate and initialize a new buffer instance.

.. function:: void cork_buffer_done(struct cork_buffer \*buffer)

   Finalize a buffer, freeing any content that it contains.  This
   function should only be used for buffers that you allocated yourself,
   and initialized using :c:func:`cork_buffer_init()` or
   :c:func:`CORK_BUFFER_INIT()`.  You must **not** use this function to
   free a buffer allocated using :c:func:`cork_buffer_new()`.

.. function:: void cork_buffer_free(struct cork_buffer \*buffer)

   Finalize and deallocate a buffer, freeing any content that it
   contains.  This function should only be used for buffers allocated
   using :c:func:`cork_buffer_new()`.  You must **not** use this
   function to free a buffer initialized using
   :c:func:`cork_buffer_init()` or :c:func:`CORK_BUFFER_INIT()`.

.. function:: bool cork_buffer_equal(const struct cork_buffer \*buffer1, const struct cork_buffer \*buffer2)

   Compare two buffers for equality.

.. function:: void cork_buffer_ensure_size(struct cork_buffer \*buffer, size_t desired_size)

   Ensure that a buffer has allocated enough space to store at least
   *desired_size* bytes.  We won't shrink the size of the buffer's
   internal storage; if the buffer has already allocated at least
   *desired_size* bytes, the function acts as a no-op.

.. function:: uint8_t cork_buffer_byte(struct cork_buffer \*buffer, size_t index)
              char cork_buffer_char(struct cork_buffer \*buffer, size_t index)

   Return the byte or character at the given index in *buffer*.


Mutator functions
-----------------

Most of the mutator functions defined in this section come in two
variants: a ``_set`` function, which clears the buffer before adding new
content, and an ``_append`` function, which retains the old content,
adding the new content to the end of the buffer.

Each mutator function will automatically append an extra ``NUL`` byte to
the end of whatever content is placed into the buffer.  However, this
``NUL`` byte will **not** be included in the :c:member:`size
<cork_buffer.size>` of the buffer.  This ensures that the contents of
any ``cork_buffer`` can be used as a ``NUL``\ -terminated C string
(assuming that there aren't any internal ``NUL``\ s), even if the buffer
is constructed from a data source that doesn't include ``NUL``
terminators.

.. function:: void cork_buffer_clear(struct cork_buffer \*buffer)

   Clear a buffer.  This does not free any storage that the buffer has
   allocated; this storage will be reused if you add contents back to the
   buffer.

.. function:: void cork_buffer_truncate(struct cork_buffer \*buffer, size_t length)

   Truncate a buffer so that contains no more than *length* bytes.  If the
   buffer is already shorter than this, it is not modified.

.. function:: void cork_buffer_copy(struct cork_buffer \*dest, const struct cork_buffer \*src)
              void cork_buffer_append_copy(struct cork_buffer \*dest, const struct cork_buffer \*src)

   Copy the contents of the *src* buffer into *dest*.  The ``_set`` variant
   clears the buffer first, while the ``_append`` variant adds *src* to whatever
   content is already there.

.. function:: void cork_buffer_set(struct cork_buffer \*buffer, const void \*src, size_t length)
              void cork_buffer_append(struct cork_buffer \*buffer, const void \*src, size_t length)

   Copy the contents of *src* into a buffer.  The ``_set`` variant
   clears the buffer first, while the ``_append`` variant adds *src* to
   whatever content is already there.

.. function:: void cork_buffer_set_string(struct cork_buffer \*buffer, const char \*str)
              void cork_buffer_append_string(struct cork_buffer \*buffer, const char \*str)
              void cork_buffer_set_literal(struct cork_buffer \*buffer, const char \*str)
              void cork_buffer_append_literal(struct cork_buffer \*buffer, const char \*str)

   Copy the contents of *str* (which must be a ``NUL``\ -terminated C
   string) into a buffer.  The ``_set`` variants clears the buffer first,
   while the ``_append`` variants adds *str* to whatever content is
   already there.  The ``_literal`` variants only work when *str* is a C string
   literal; we use the ``sizeof`` operator to determine the length of the string
   at compile time.  The ``_string`` variants work with any C string; we use the
   builtin ``strlen`` function to determine the length of the string.

.. function:: void cork_buffer_printf(struct cork_buffer \*buffer, const char \*format, ...)
              void cork_buffer_vprintf(struct cork_buffer \*buffer, const char \*format, va_list args)
              void cork_buffer_append_printf(struct cork_buffer \*buffer, const char \*format, ...)
              void cork_buffer_append_vprintf(struct cork_buffer \*buffer, const char \*format, va_list args)

   Format data according to a ``printf`` format string, placing the
   result into a buffer.  The ``_append`` variants add the formatted
   string to whatever content is already in the buffer; the non-\
   ``_append`` variants clear the buffer first.  The ``_printf``
   variants are vararg functions, and take in the format string's data
   as direct parameters.  The ``_vprintf`` variants can be used within
   another vararg function, and let you pass in the format string's data
   as a C99-standard ``va_list`` instance.


Pretty-printing
---------------

We also provide several helper functions for adding pretty-printed content to a
``cork_buffer``.

.. function:: void cork_buffer_append_indent(struct cork_buffer \*buffer, size_t indent)

   Append *indent* spaces to *buffer*.

.. function:: void cork_buffer_append_c_string(struct cork_buffer \*buffer, const char \*str, size_t length)

   Append the C string literal representation of *str* to *buffer*.  This will
   include opening and closing double quotes, and any non-printable characters
   will be escaped.  (We will use the standard letter-based escapes where
   possible, and fall back on ``"\xXX"`` hexadecimal escapes for other
   non-printable characters.)  The result is guaranteed to stay on a single
   line, since any embedded newlines will be converted to a ``\n`` escape
   sequence.

.. function:: void cork_buffer_append_hex_dump(struct cork_buffer \*buffer, size_t indent, const char \*str, size_t length)
              void cork_buffer_append_multiline(struct cork_buffer \*buffer, size_t indent, const char \*str, size_t length)
              void cork_buffer_append_binary(struct cork_buffer \*buffer, size_t indent, const char \*str, size_t length)

   Append a pretty-printed representation of *str* to *buffer*.  All of these
   functions can produce multiple lines of output.  All lines except for the
   first will be prefaced with *indent* space characters.  The final line will
   **not** have a trailing newline.

   The ``hex_dump`` variant will output a hex-dump representation of *str*.
   This will include the hexadecimal representation of each byte, and the actual
   character of any printable byte.

   The ``multiline`` variant appends the raw content of *str* to the buffer,
   without making any attempt to sanitize non-printable characters.  (That means
   you should only call this variant if you know that *str* contains only
   printable characters.)  If *str* itself spans multiple lines, then we'll
   insert indentation to make sure that we satisfy the indentation rules
   described above.

   The ``binary`` variant autodetects how to best render *str*.  If it contains
   any non-printable characters, then we'll use the ``hex_dump`` representation.
   If it spans multiple lines, we'll use the ``multiline`` representation.
   Otherwise, we'll append the content directly without any modification.


Other binary data structures
----------------------------

The ``cork_buffer`` class is the only binary data class that is mutable;
this comes at the cost of only being usable by a single owner thread or
function at a time.  Once you have constructed a binary string or
payload using a ``cork_buffer``, you can use the functions in this
section to produce a corresponding instance of one of libcork's
sharable, immutable binary data types.

.. function:: struct cork_managed_buffer \*cork_buffer_to_managed_buffer(struct cork_buffer \*buffer)

   Create a new :ref:`managed buffer <managed-buffer>` to manage the
   contents of a ``cork_buffer`` instance.  *buffer* must have been
   allocated on the heap (i.e., using :c:func:`cork_buffer_new()`, and
   not :c:func:`cork_buffer_init()`).  We take ownership of *buffer*,
   regardless of whether we're able to successfully create a new
   :c:type:`cork_managed_buffer` instance.  You must **not** try to free
   *buffer* yourself.

.. function:: int cork_buffer_to_slice(struct cork_buffer \*buffer, struct cork_slice \*slice)

   Initialize a new :ref:`slice <slice>` to manage the contents of
   *buffer*.  *buffer* must have been allocated on the heap (i.e., using
   :c:func:`cork_buffer_new()`, and not :c:func:`cork_buffer_init()`).
   We take ownership of *buffer*, regardless of whether we're able to
   successfully create a new :c:type:`cork_managed_buffer` instance.
   You must **not** try to free *buffer* yourself.

   The slice will point into the contents of a new :ref:`managed buffer
   <managed-buffer>` instance.  The managed buffer isn't returned
   directly, though you can create additional slices into it using the
   usual :c:type:`cork_slice` methods.

   Regardless of whether we can initialize the slice successfully, you
   **must** call :c:func:`cork_slice_finish()` on *slice* when you're
   done with the slice.

.. function:: struct cork_stream_consumer \*cork_buffer_to_stream_consumer(struct cork_buffer \*buffer)

   Create a new stream consumer that appends any received data into
   *buffer*.

   We do **not** take control of *buffer*.  You retain responsibility
   for freeing the buffer, and you must ensure that it remains allocated
   and valid for the entire lifetime of the stream consumer that we
   return.


================================================
FILE: docs/old/byte-order.rst
================================================
.. _byte-order:

**********
Byte order
**********

.. highlight:: c

::

  #include <libcork/core.h>

This section contains definitions for determining the endianness of the
host system, and for byte-swapping integer values of various sizes.


Endianness detection
====================

.. macro:: CORK_LITTLE_ENDIAN
           CORK_BIG_ENDIAN
           CORK_HOST_ENDIANNESS
           CORK_OTHER_ENDIANNESS

   The ``CORK_HOST_ENDIANNESS`` macro can be used to determine the
   endianness of the host system.  It will be equal to either
   ``CORK_LITTLE_ENDIAN`` or ``CORK_BIG_ENDIAN``.  (The actual values
   don't matter; you should always compare against the predefined
   constants.)  The ``CORK_OTHER_endianness`` macro is defined to be the
   opposite endianness as ``CORK_HOST_ENDIANNESS``.  A common use case
   would be something like::

     #if CORK_HOST_endianness == CORK_LITTLE_ENDIAN
     /* do something to little-endian values */
     #else
     /* do something to big-endian values */
     #endif

.. macro:: CORK_HOST_ENDIANNESS_NAME
           CORK_OTHER_ENDIANNESS_NAME

   These macros give you a human-readable name of the host's endianness.
   You can use this in debugging messages.

   .. note:: You should *not* use these macros to detect the
      endianness of the system, since we might change their definitions
      at some point to support localization.  For that,
      use :macro:`CORK_LITTLE_ENDIAN` and :macro:`CORK_BIG_ENDIAN`.


Byte swapping
=============

Swapping arbitrary expressions
------------------------------

All of the macros in this section take in an rvalue (i.e., any arbitrary
expression) as a parameter.  The result of the swap is returned as the
value of the macro.

.. function:: uint16_t CORK_SWAP_UINT16(uint16_t value)
              uint32_t CORK_SWAP_UINT32(uint32_t value)
              uint64_t CORK_SWAP_UINT64(uint64_t value)
              cork_u128 CORK_SWAP_UINT128(cork_128 value)

   These functions always perform a byte-swap, regardless of the
   endianness of the host system.

.. function:: uint16_t CORK_UINT16_BIG_TO_HOST(uint16_t value)
              uint32_t CORK_UINT32_BIG_TO_HOST(uint32_t value)
              uint64_t CORK_UINT64_BIG_TO_HOST(uint64_t value)
              cork_u128 CORK_UINT128_BIG_TO_HOST(cork_u128 value)

   These functions convert a big-endian (or network-endian) value into
   host endianness.  (I.e., they only perform a swap if the current host
   is little-endian.)

.. function:: uint16_t CORK_UINT16_HOST_TO_BIG(uint16_t value)
              uint32_t CORK_UINT32_HOST_TO_BIG(uint32_t value)
              uint64_t CORK_UINT64_HOST_TO_BIG(uint64_t value)
              cork_u128 CORK_UINT128_HOST_TO_BIG(cork_u128 value)

   These functions convert a host-endian value into big (or network)
   endianness.  (I.e., they only perform a swap if the current host is
   little-endian.)

.. function:: uint16_t CORK_UINT16_LITTLE_TO_HOST(uint16_t value)
              uint32_t CORK_UINT32_LITTLE_TO_HOST(uint32_t value)
              uint64_t CORK_UINT64_LITTLE_TO_HOST(uint64_t value)
              cork_u128 CORK_UINT128_LITTLE_TO_HOST(cork_u128 value)

   These functions convert a little-endian value into host endianness.
   (I.e., they only perform a swap if the current host is big-endian.)

.. function:: uint16_t CORK_UINT16_HOST_TO_LITTLE(uint16_t value)
              uint32_t CORK_UINT32_HOST_TO_LITTLE(uint32_t value)
              uint64_t CORK_UINT64_HOST_TO_LITTLE(uint64_t value)
              cork_u128 CORK_UINT128_HOST_TO_LITTLE(cork_u128 value)

   These functions convert a host-endian value into little endianness.
   (I.e., they only perform a swap if the current host is big-endian.)

Swapping values in place
------------------------

The macros in this section swap an integer *in place*, which means that
the original value is overwritten with the result of the swap.  To
support this, you must pass in an *lvalue* as the parameter to the
macro.  (Note that you don't pass in a *pointer* to the original value;
these operations are implemented as macros, and you just need to provide
a reference to the variable to be swapped.)

.. function:: void CORK_SWAP_UINT16_IN_PLACE(uint16_t &value)
              void CORK_SWAP_UINT32_IN_PLACE(uint32_t &value)
              void CORK_SWAP_UINT64_IN_PLACE(uint64_t &value)
              void CORK_SWAP_UINT128_IN_PLACE(cork_u128 &value)

   These functions always perform a byte-swap, regardless of the
   endianness of the host system.

.. function:: void CORK_UINT16_BIG_TO_HOST_IN_PLACE(uint16_t &value)
              void CORK_UINT32_BIG_TO_HOST_IN_PLACE(uint32_t &value)
              void CORK_UINT64_BIG_TO_HOST_IN_PLACE(uint64_t &value)
              void CORK_UINT128_BIG_TO_HOST_IN_PLACE(cork_u128 &value)

   These functions convert a big-endian (or network-endian) value into
   host endianness, and vice versa.  (I.e., they only perform a swap if
   the current host is little-endian.)

.. function:: void CORK_UINT16_HOST_TO_BIG_IN_PLACE(uint16_t &value)
              void CORK_UINT32_HOST_TO_BIG_IN_PLACE(uint32_t &value)
              void CORK_UINT64_HOST_TO_BIG_IN_PLACE(uint64_t &value)
              void CORK_UINT128_HOST_TO_BIG_IN_PLACE(cork_u128 &value)

   These functions convert a host-endian value into big (or network)
   endianness.  (I.e., they only perform a swap if the current host is
   little-endian.)

.. function:: void CORK_UINT16_LITTLE_TO_HOST_IN_PLACE(uint16_t &value)
              void CORK_UINT32_LITTLE_TO_HOST_IN_PLACE(uint32_t &value)
              void CORK_UINT64_LITTLE_TO_HOST_IN_PLACE(uint64_t &value)
              void CORK_UINT128_LITTLE_TO_HOST_IN_PLACE(cork_u128 &value)

   These functions convert a little-endian value into host endianness, and
   vice versa.  (I.e., they only perform a swap if the current host is
   big-endian.)

.. function:: void CORK_UINT16_HOST_TO_LITTLE_IN_PLACE(uint16_t &value)
              void CORK_UINT32_HOST_TO_LITTLE_IN_PLACE(uint32_t &value)
              void CORK_UINT64_HOST_TO_LITTLE_IN_PLACE(uint64_t &value)
              void CORK_UINT128_HOST_TO_LITTLE_IN_PLACE(cork_u128 &value)

   These functions convert a host-endian value into little endianness.
   (I.e., they only perform a swap if the current host is big-endian.)


================================================
FILE: docs/old/cli.rst
================================================
.. _cli:

*********************
Command-line programs
*********************

.. highlight:: c

::

  #include <libcork/cli.h>

The functions in this section let you easily create complex command-line
applications that include subcommands, in the style of the ``git`` or ``svn``
programs.


Overview
========

If you're designing an application where you want to provide command-line access
to many different operations or use cases, the simplest solution is to create a
separate executable for each one.  This can clutter up the user's
``$PREFIX/bin`` directory, however, and can add complexity to your code base.
Many projects instead create a single “super-command” executable, which includes
within it all of the operations that you want to support.  You choose specific
operations by selecting a *subcommand* on the command line.

.. type:: struct cork_command

   An opaque type describing one of the subcommands in an executable.

So, for instance, if you were writing a library for manipulating sets of
objects, you could define several subcommands of a single ``set`` executable:

.. code-block:: none

    $ set add <filename> <element>
    $ set query <filename> <element>
    $ set remove <filename> <element>
    $ set union -o <output file> <file1> <file2>
    $ set print avro <filename>
    $ set print json <filename>

Each of these operations acts in exactly the same as if they were defined as
separate executables:

.. code-block:: none

    $ set-add <filename> <element>
    $ set-query <filename> <element>
    $ set-remove <filename> <element>
    $ set-union -o <output file> <file1> <file2>
    $ set-print-avro <filename>
    $ set-print-json <filename>

Note that you're not limited to one level of subcommands.  The ``set print``
subcommand, for instance, itself contains two subcommands: ``avro`` and
``json``.


Leaf commands
=============

A *leaf command* is a subcommand that represents one operation in your
executable.  In the example above, there are six leaf commands: ``set add``,
``set query``, ``set remove``, ``set union``, ``set print avro``, and ``set
print json``.

To define a leaf command, you use the following macro:

.. macro:: cork_leaf_command(const char \*name, const char \*short_description, const char \*usage, const char \*full_help, cork_option_parser parse_options, run)

   Returns :c:type:`cork_command` instance that defines a leaf command.  *name*
   is the name of the leaf command; this is the word that the user must type on
   the command-line to select this command.  (For ``set add``, this would be
   ``add``; for ``set print avro``, this would be ``avro``.)

   *short_description*, *usage*, and *full_help* should be static strings, and
   will be used to produce various forms of :ref:`help text <cli-help>` for the
   subcommand.  *short_description* should fit into one line; this will be used
   as the short description of this leaf command when we print out a list of all
   of the subcommands that are in the command set that this leaf belongs to.
   *usage* will be printed whenever we need to print out a usage synopsis.  This
   should describe the options and arguments to the leaf command; it will be
   printed after the full name of the subcommand.  (For instance, using the
   example above, the ``set add`` command's usage text would be ``<filename>
   <element>``.)  *full_help* should be a longer, multi-line string that
   describes the subcommand *in full detail*.  We will automatically preface the
   help text with the usage summary for the command.

   *parse_options* is a function that will be used to parse any command-line
   options that appear *after* the subcommand's name on the command line.  (See
   :ref:`below <cli-options>` for more details.)  This can be ``NULL`` if the
   subcommand does not have any options.

   *run* is the function that will be called to actually execute the command.
   Any options will have already been processed by the *parse_options* function;
   you should stash the option values into global or file-scope variables, and
   then use the contents of those variables in this function.  Your *run*
   function must be an instance of the :c:type:`cork_leaf_command_run` function
   type:

   .. type:: void (\*cork_leaf_command_run)(int argc, char \*\*argv)

      The *argc* and *argv* parameters will describe any values that appear on
      the command line after the name of the leaf command.  This will *not*
      include any options that were processed by the command's *parse_options*
      function.

As an example, we could define the ``set add`` command as follows::

    static void
    set_add_run(int argc, char **argv);

    #define SET_ADD_SHORT  "Adds an element to a set"
    #define SET_ADD_USAGE  "<filename> <element>"
    #define SET_ADD_FULL \
        "Loads in a set from <filename>, and adds <element> to the set.  The\n" \
        "new set will be written back out to <filename>.\n"

    static struct cork_command  set_add =
        cork_leaf_command("add", SET_ADD_SHORT, SET_ADD_USAGE, SET_ADD_FULL,
                          NULL, set_add_run);

    static void
    set_add_run(int argc, char **argv)
    {
        /* Verify that the user gave both required options... */
        if (argc < 1) {
            cork_command_show_help(&set_add, "Missing set filename.");
            exit(EXIT_FAILURE);
        }
        if (argc < 2) {
            cork_command_show_help(&set_add, "Missing element to add.");
            exit(EXIT_FAILURE);
        }

        /* ...and no others. */
        if (argc > 2) {
            cork_command_show_help(&set_add, "Too many values on command line.");
            exit(EXIT_FAILURE);
        }

        /* At this point, <filename> will be in argv[0], <element> will be in
         * argv[1]. */

        /* Do what needs to be done */
        exit(EXIT_SUCCESS);
    }

There are a few interesting points to make.  First, note that we use
preprocessor macros to define all of the help text for the command.  Also, note
that *each* line (including the last) of the full help text needs to have a
trailing newline included in the string literal.

Lastly, note that we still have to perform some final validation of the command
line arguments given by the user.  If the user hasn't satisfied the subcommand's
requirements, we use the :c:func:`cork_command_show_help` function to print out
a nice error message (including a usage summary of the subcommand), and then we
halt the executable using the standard ``exit`` function.


Command sets
============

A *command set* is a collection of subcommands.  Every executable will have at
least one command set, for the root executable itself.  It's also possible to
have nested command sets.  In our example above, ``set`` and ``set print`` are
both command sets.

To define a command set, you use the following macro:

.. macro:: cork_command_set(const char \*name, const char \*short_description, cork_option_parser parse_options, struct cork_command \*\*subcommands)

   Returns :c:type:`cork_command` instance that defines a command set.  *name*
   is the name of the command set; this is the word that the user must type on
   the command-line to select this set of commands.  If the user only specifies
   the name of the command set, then we'll print out a list of this set's
   subcommands, along with their short descriptions.  (For instance, running
   ``set`` on its own would describe the ``set add``, ``set query``, ``set
   remove``, ``set union``, and ``set print`` subcommands.  Running ``set
   print`` on its own would describe the ``set print avro`` and ``set print
   json`` commands.)

   *short_description*, should be a static strings, and will be used to produce
   various forms of :ref:`help text <cli-help>` for the command set.
   *short_description* should fit into one line; this will be used as the short
   description of this command when we print out a list of all of the
   subcommands that are in the command set that this command belongs to.

   *parse_options* is a function that will be used to parse any command-line
   options that appear *after* the command set's name on the command line, but
   *before* the name of one of the set's subcommands.  (See :ref:`below
   <cli-options>` for more details.)  This can be ``NULL`` if the command set
   does not have any options.

   *subcommands* should be an array of :c:type:`cork_command` pointers.  The
   array **must** have a ``NULL`` pointer as its last element.  The order of the
   subcommands in the array will effect the order that the commands are listed
   in the command set's help text.

As an example, we could define the ``set print`` command set as follows::

    /* Assuming set_print_avro and set_print_json were already defined
     * previously, using cork_leaf_command: */
    struct cork_command  set_print_avro = cork_leaf_command(...);
    struct cork_command  set_print_json = cork_leaf_command(...);

    /* "set print" command set */
    static struct cork_command  *set_print_subcommands[] = {
        &set_print_avro,
        &set_print_json,
        NULL
    };

    #define SET_PRINT_SHORT \
        "Print out the contents of a set in a variety of formats"

    static struct cork_command  set_print =
        cork_command_set("print", SET_PRINT_SHORT, NULL, &set_print_subcommands);

You must define your executable's top level of subcommands as a command set as
well.  For instance, we could define the ``set`` command set as follows::

    static struct cork_command  *root_subcommands[] = {
        &set_add,
        &set_query,
        &set_remove,
        &set_union,
        &set_print,
        NULL
    };

    static struct cork_command  root =
        cork_command_set("set", NULL, NULL, &root_subcommands);

Note that we don't need to provide a short description for the root command,
since it doesn't belong to any command sets.


Running the commands
====================

Once you've defined all of your subcommands, your executable's ``main`` function
is trivial::

    int
    main(int argc, char **argv)
    {
        return cork_command_main(&root, argc, argv);
    }

.. function:: int cork_command_main(struct cork_command \*root, int argc, char \*\*argv)

   Runs a subcommand, as defined by the command-line arguments given by *argc*
   and *argv*.  *root* should define the root command set for the executable.


.. _cli-help:

Help text
=========

The command-line programs created with this framework automatically support
generating several flavors of help text for its subcommands.  You don't need to
do anything special, except for ensuring that the actual help text that you
provide to the :c:macro:`cork_leaf_command` and :c:macro:`cork_command_set`
macros defined is intelligble and useful.

Your executable will automatically include a ``help`` command in every command
set, as well as ``--help`` and ``-h`` options in every command set and leaf
command.  So all of the following would print out the help text for the ``set
add`` command:

.. code-block:: none

    $ set help add
    $ set add --help
    $ set add -h

And all of the following would print out the list of ``set print`` subcommands:

.. code-block:: none

    $ set help print
    $ set print --help
    $ set print -h

You can also print out the help text for a command explicitly by calling the
following function:

.. function:: void cork_command_show_help(struct cork_command \*command, const char \*message)

    Prints out help text for *command*.  (If it's a leaf command, this is the
    full help text.  If it's a command set, it's a list of the set's
    subcommands.)  We will preface the help text with *message* if it's
    non-``NULL``.  (The message should not include a trailing newline.)


.. _cli-options:

Option parsing
==============

Leaf commands and command sets both let you provide a function that parse
command-line options for the given command.  We don't prescribe any particular
option parsing library, you just need to conform to the interface described in
this section.  (Note that the standard ``getopt`` and ``getopt_long`` functions
can easily be used in an option parsing function.)

.. type:: int (\*cork_option_parser)(int argc, char \*\*argv)

   Should parse any command-line options that can appear at this point in the
   executable's command line.  (The options must appear immediately after the
   name of the command that this function belongs to.  See below for several
   examples.)

   Your function must look for and process any options that appear at the
   beginning of *argv*.  If there are any errors processing the options, you
   should print out an error message (most likely via
   :c:func:`cork_command_show_help`) and exit the program, using the standard
   ``exit`` function, with an exit code of ``EXIT_FAILURE``.

   If there aren't any errors processing the options, you should return the
   number of *argv* elements that were consumed while processing the options.
   We will use this return value to update *argc* and *argv* beforing continuing
   with subcommand selection and argument processing.  (Note that ``getopt``'s
   ``optind`` variable is exactly what you need for the return value.)

As mentioned above, different option parsing functions are used to parse options
from a particular point in the command line.  Given the following command:

.. code-block:: none

    $ set --opt1 print --opt2 avro --opt3 --opt4=foo <filename>

The ``--opt1`` option would be parsed by the ``set`` command's parser.  The
``--opt2`` option would be parsed by the ``set print`` command's parser.  The
``--opt3`` and ``-opt4=foo`` options would be parsed by the ``set print avro``
command's parser.  And the ``<filename>`` argument would be parsed by the ``set
print avro`` command's *run* function.


================================================
FILE: docs/old/conf.py
================================================
# -*- coding: utf-8 -*-

import sys, os

extensions = ['sphinx.ext.mathjax']
source_suffix = '.rst'
master_doc = 'index'
project_name = u'libcork'
project_slug = u'libcork'
company = u'libcork authors'
copyright_years = u'2011-2017'

default_role = 'c:func'
primary_domain = 'c'

rst_epilog = """
.. |project_name| replace:: """ + project_name + """
"""

# Intersphinx stuff

# If your documentation uses intersphinx to link to other Sphinx
# documentation sets, uncomment and fill in the following.
#
#intersphinx_mapping = {
#    'libcork': ('http://libcork.readthedocs.org/en/latest/', None),
#}

# Our CMake build scripts will insert overrides below if the prereq
# libraries have installed their Sphinx documentation locally.  DO NOT
# uncomment out the last line of this block; we need it commented so
# that this conf.py file still works if CMake doesn't do its
# substitution thing.
# @INTERSPHINX_OVERRIDES@

#----------------------------------------------------------------------
# Everything below here shouldn't need to be changed.

release = None
version = None

# Give CMake a chance to insert a version number
# @VERSION_FOR_CONF_PY@

# Otherwise grab version from git
if version is None:
    import re
    import subprocess
    release = str(subprocess.check_output(["git", "describe"]).rstrip())
    version = re.sub(r"-dev.*$", "-dev", release)

# Project details

project = project_name
copyright = copyright_years+u', '+company
templates_path = ['_templates']
exclude_patterns = ['_build']
pygments_style = 'sphinx'

html_theme = 'default'
html_style = 'docco-sphinx.css'
html_static_path = ['_static']
htmlhelp_basename = project_slug+'-doc'


latex_documents = [
  ('index', project_slug+'.tex', project_name+u' Documentation',
   company, 'manual'),
]

man_pages = [
    ('index', 'libcork', u'libcork documentation',
     [u'libcork authors'], 1)
]

texinfo_documents = [
  ('index', 'libcork', u'libcork documentation',
   u'libcork authors', 'libcork', 'One line description of project.',
   'Miscellaneous'),
]


================================================
FILE: docs/old/config.rst
================================================
.. _config:

*******************
Configuring libcork
*******************

.. highlight:: c

::

  #include <libcork/config.h>

Several libcork features have different implementations on different
platforms.  Since we want libcork to be easily embeddable into projects
with a wide range of build systems, we try to autodetect which
implementations to use, using only the C preprocessor and the predefined
macros that are available on the current system.

This module provides a layer of indirection, with all of the
preprocessor-based autodetection in one place.  This module's task is to
define a collection of libcork-specific configuration macros, which all
other libcork modules will use to select which implementation to use.

This design also lets you skip the autodetection, and provide values for
the configuration macros directly.  This is especially useful if you're
embedding libcork into another project, and already have a ``configure``
step in your build system that performs platform detection.  See
:c:macro:`CORK_CONFIG_SKIP_AUTODETECT` for details.

.. note::

   The autodetection logic is almost certainly incomplete.  If you need
   to port libcork to another platform, this is where an important chunk
   of edits will take place.  Patches are welcome!


.. _configuration-macros:

Configuration macros
====================

This section lists all of the macros that are defined by libcork's
autodetection logic.  Other libcork modules will use the values of these
macros to choose among the possible implementations.


.. macro:: CORK_CONFIG_VERSION_MAJOR
           CORK_CONFIG_VERSION_MINOR
           CORK_CONFIG_VERSION_PATCH

   The libcork library version, with each part of the version number separated
   out into separate macros.


.. macro:: CORK_CONFIG_VERSION_STRING

   The libcork library version, encoded as a single string.


.. macro:: CORK_CONFIG_REVISION

   The git SHA-1 commit identifier of the libcork version that you're using.


.. macro:: CORK_CONFIG_ARCH_X86
           CORK_CONFIG_ARCH_X64
           CORK_CONFIG_ARCH_PPC

   Exactly one of these macros should be defined to ``1`` to indicate
   the architecture of the current platform.  All of the other macros
   should be defined to ``0`` or left undefined.  The macros correspond
   to the following architectures:

   ============ ================================================
   Macro suffix Architecture
   ============ ================================================
   ``X86``      32-bit Intel (386 or greater)
   ``X64``      64-bit Intel/AMD (AMD64/EM64T, *not* IA-64)
   ``PPC``      32-bit PowerPC
   ============ ================================================


.. macro:: CORK_CONFIG_HAVE_GCC_ASM

   Whether the GCC `inline assembler`_ syntax is available.  (This
   doesn't imply that the compiler is specifically GCC.)  Should be
   defined to ``0`` or ``1``.

   .. _inline assembler: http://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html


.. macro:: CORK_CONFIG_HAVE_GCC_ATTRIBUTES

   Whether the GCC-style syntax for `compiler attributes`_ is available.
   (This doesn't imply that the compiler is specifically GCC.)  Should
   be defined to ``0`` or ``1``.

   .. _compiler attributes: http://gcc.gnu.org/onlinedocs/gcc/Attribute-Syntax.html


.. macro:: CORK_CONFIG_HAVE_GCC_ATOMICS

   Whether GCC-style `atomic intrinsics`_ are available.  (This doesn't
   imply that the compiler is specifically GCC.)  Should be defined to
   ``0`` or ``1``.

   .. _atomic intrinsics: http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html



.. macro:: CORK_CONFIG_HAVE_GCC_INT128

   Whether the GCC-style `128-bit integer`_ types (``__int128`` and ``unsigned
   __int128``) are available.  (This doesn't imply that the compiler is
   specifically GCC.)  Should be defined to ``0`` or ``1``.

   .. _128-bit integer: http://gcc.gnu.org/onlinedocs/gcc/_005f_005fint128.html


.. macro:: CORK_CONFIG_HAVE_GCC_MODE_ATTRIBUTE

   Whether GCC-style `machine modes`_ are available.  (This doesn't imply that
   the compiler is specifically GCC.)  Should be defined to ``0`` or ``1``.

   .. _machine modes: http://gcc.gnu.org/onlinedocs/gcc-4.8.1/gccint/Machine-Modes.html#Machine-Modes


.. macro:: CORK_CONFIG_HAVE_GCC_STATEMENT_EXPRS

   Whether GCC-style `statement expressions`_ are available.
   (This doesn't imply that the compiler is specifically GCC.)  Should
   be defined to ``0`` or ``1``.

   .. _statement expressions: http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html


.. macro:: CORK_CONFIG_HAVE_REALLOCF

   Whether this platform defines a ``reallocf`` function in
   ``stdlib.h``.  ``reallocf`` is a BSD extension to the standard
   ``realloc`` function that frees the existing pointer if a
   reallocation fails.  If this function exists, we can use it to
   implement :func:`cork_realloc`.


.. macro:: CORK_CONFIG_IS_BIG_ENDIAN
           CORK_CONFIG_IS_LITTLE_ENDIAN

   Whether the current system is big-endian or little-endian.  Exactly
   one of these macros should be defined to ``1``; the other should be
   defined to ``0``.


.. _skipping-autodetection:

Skipping autodetection
======================


.. macro:: CORK_CONFIG_SKIP_AUTODETECT

   If you want to skip libcork's autodetection logic, then you are
   responsible for providing the appropriate values for all of the
   macros defined in :ref:`configuration-macros`.  To do this, have your
   build system define this macro, with a value of ``1``.  This will
   override the default value of ``0`` provided in the
   ``libcork/config/config.h`` header file.

   Then, create (or have your build system create) a
   ``libcork/config/custom.h`` header file.  You can place this file
   anywhere in your header search path.  We will load that file instead
   of libcork's autodetection logic.  Place the appropriate definitions
   for each of the configuration macros into this file.  If needed, you
   can generate this file as part of the ``configure`` step of your
   build system; the only requirement is that it's available once you
   start compiling the libcork source files.


================================================
FILE: docs/old/dllist.rst
================================================
.. _dllist:

*******************
Doubly-linked lists
*******************

.. highlight:: c

::

  #include <libcork/ds.h>

This section defines a doubly-linked list data structure.  The structure
is “invasive”, since you must place an instance of the
:c:type:`cork_dllist_item` type into the type whose instances will be
stored in the list.  The list itself is represented by the
:c:type:`cork_dllist` type.

As an example, we could define the following types for storing groups,
as well as the users within each group::

  struct group {
      const char  *group_name;
      struct cork_dllist  members;
  };

  struct user {
      const char  *username;
      const char  *real_name;
      struct cork_dllist_item  list;
  };

Note that both ``cork_dllist`` and ``cork_dllist_item`` are embedded
directly into our domain-specific types.  This means that every list
operation defined in this section is guaranteed to succeed, since no
memory operations will be involved.  (The list and any items will have
already been allocated before you try to call the list function.)

Like with any embedded ``struct``, you can use the
:c:func:`cork_container_of` macro to obtain a pointer to a ``struct
user`` if you're given a pointer to a :c:type:`cork_dllist_item`.


.. type:: struct cork_dllist

   A doubly-linked list.  The list itself is represented by a sentinel
   element, representing the empty list.


.. type:: struct cork_dllist_item

   An element of a doubly-linked list.  This type will usually be
   embedded within the type whose instances will be stored in the list.

   .. member:: struct cork_dllist_item \*next
               struct cork_dllist_item \*prev

      A pointer to the next (or previous) element in the list.  If this
      element marks the end (or beginning) of the list, then *next* (or
      *prev*) will point to the list's sentinel value.


.. function:: void cork_dllist_init(struct cork_dllist \*list)
              struct cork_dllist CORK_DLLIST_INIT(SYMBOL name)

   Initializes a doubly-linked list.  The list will initially be empty.

   The second variant is a static initializer, that lets you initialize a list
   at compile time, rather than runtime.  You must pass in the name of the list
   for this to work, since we need to be able to extract pointers into the list
   object.


Querying a list
---------------

.. function:: size_t cork_dllist_size(const struct cork_dllist \*list)

   Returns the number of elements in *list*.
   
   This operation runs in :math:`O(n)` time.


.. function:: bool cork_dllist_is_empty(struct cork_dllist \*list)

   Returns whether *list* is empty.

   This operation runs in :math:`O(1)` time.


Editing a list
--------------

.. function:: void cork_dllist_add_to_head(struct cork_dllist \*list, struct cork_dllist_item \*element)
              void cork_dllist_add_to_tail(struct cork_dllist \*list, struct cork_dllist_item \*element)

   Adds *element* to *list*.  The ``_head`` variant adds the new element to the
   beginning of the list; the ``_tail`` variant adds it to the end.
   
   You are responsible for allocating the list element yourself, most likely by
   allocating the ``struct`` that you've embedded :c:type:`cork_dllist_item`
   into.

   .. note::

      This function assumes that *element* isn't already a member of a different
      list.  You're responsible for calling :c:func:`cork_dllist_remove()` if
      this isn't the case.  (If you don't, the other list will become
      malformed.)

   This operation runs in :math:`O(1)` time.


.. function:: void cork_dllist_add_after(struct cork_dllist_item \*pred, struct cork_dllist_item \*element)
              void cork_dllist_add_before(struct cork_dllist_item \*succ, struct cork_dllist_item \*element)

   Adds *element* to the same list that *pred* or *succ* belong to.  The
   ``_after`` variant ensures that *element* appears in the list immediately
   after *pred*.  The ``_before`` variant ensures that *element* appears in the
   list immediately before *succ*.

   .. note::

      This function assumes that *element* isn't already a member of a different
      list.  You're responsible for calling :c:func:`cork_dllist_remove()` if
      this isn't the case.  (If you don't, the other list will become
      malformed.)

   This operation runs in :math:`O(1)` time.


.. function:: void cork_dllist_add_list_to_head(struct cork_dllist \*dest, struct cork_dllist \*src)
              void cork_dllist_add_list_to_tail(struct cork_dllist \*dest, struct cork_dllist \*src)

   Moves all of the elements in *src* to *dest*.  The ``_head`` variant moves
   the elements to the beginning of *dest*; the ``_tail`` variant moves them to
   the end.  After these functions return, *src* will be empty.

   This operation runs in :math:`O(1)` time.


.. function:: void cork_dllist_remove(struct cork_dllist_item \*element)

   Removes *element* from the list that it currently belongs to.  (Note
   that you don't have to pass in a pointer to that list.)

   .. note::

      You must not call this function on a list's sentinel element.

   This operation runs in :math:`O(1)` time.


Iterating through a list
------------------------

There are two strategies you can use to access all of the elements in a
doubly-linked list: *visiting* and *iterating*.  With visiting, you write
a visitor function, which will be applied to each element in the list.
(In this case, libcork controls the loop that steps through each
element.)

.. function:: int cork_dllist_visit(struct cork_dllist \*list, void \*user_data, cork_dllist_visit_f \*func)

   Apply a function to each element in *list*.  The function is allowed
   to remove the current element from the list; this will not affect our
   ability to iterate through the remainder of the list.  The function
   will be given a pointer to the :c:type:`cork_dllist_item` for each
   element; you can use :c:func:`cork_container_of()` to get a pointer to the
   actual element type.

   If your visitor function ever returns a non-zero value, we will abort the
   iteration and return that value from ``cork_dllist_visit``.  If your function
   always returns ``0``, then you will visit all of the elements in *list*, and
   we'll return ``0`` from ``cork_dllist_visit``.

   .. type:: int cork_dllist_visit_f(void \*user_data, struct cork_dllist_item \*element)

      A function that can be applied to each element in a doubly-linked list.

For instance, you can manually calculate the number of elements in a
list as follows (assuming you didn't want to use the built-in
:c:func:`cork_dllist_size()` function, of course)::

  static int
  count_elements(void *user_data, struct cork_dllist_item *element)
  {
      size_t  *count = ud;
      (*count)++;
      return 0;
  }

  struct cork_dllist  *list = /* from somewhere */;
  size_t  count = 0;
  cork_dllist_visit(list, &count, count_elements);  /* returns 0 */
  /* the number of elements is now in count */


The second strategy is to iterate through the elements yourself.

.. macro:: cork_dllist_foreach(struct cork_dllist \*list, struct cork_dllist_item &\*curr, struct cork_dllist_item &\*next, TYPE element_type, TYPE &\*element, FIELD item_field)
           cork_dllist_foreach_void(struct cork_dllist \*list, struct cork_dllist_item &\*curr, struct cork_dllist_item &\*next)

   Iterate through each element in *list*, executing a statement for each one.
   You must declare two variables of type ``struct cork_dllist_item *``, and
   pass in their names as *curr* and *next*.  (You'll usually call the variables
   ``curr`` and ``next``, too.)

   For the ``_void`` variant, your statement can only use these
   :c:type:`cork_dllist_item` variables to access the current list element.  You
   can use :c:func:`cork_container_of` to get a pointer to the actual element
   type.

   For the non-``_void`` variant, we'll automatically call
   :c:func:`cork_container_of` for you.  *element_type* should be the actual
   element type, which must contain an embedded :c:func:`cork_dllist_item`
   field.  *item_field* should be the name of this embedded field.  You must
   allocate a pointer to the element type, and pass in its name as *element*.

For instance, you can use these macros calculate the number of elements as
follows::

  struct cork_dllist  *list = /* from somewhere */;
  struct cork_dllist  *curr;
  struct cork_dllist  *next;
  size_t  count = 0;
  cork_dllist_foreach_void(list, curr, next) {
      count++;
  }
  /* the number of elements is now in count */

We're able to use :c:macro:`cork_dllist_foreach_void` since we don't need to
access the contents of each element to calculate how many of theo there are.  If
we wanted to calculuate a sum, however, we'd have to use
:c:macro:`cork_dllist_foreach`::

  struct element {
      unsigned int  value;
      struct cork_dllist_item  item;
  };

  struct cork_dllist  *list = /* from somewhere */;
  struct cork_dllist  *curr;
  struct cork_dllist  *next;
  struct element  *element;
  unsigned int  sum = 0;
  cork_dllist_foreach(list, curr, next, struct element, element, item) {
      sum += element->value;
  }
  /* the sum of the elements is now in sum */


If the ``foreach`` macros don't provide what you need, you can also iterate
through the list manually.

.. function:: struct cork_dllist_item \*cork_dllist_head(struct cork_dllist \*list)
              struct cork_dllist_item \*cork_dllist_start(struct cork_dllist \*list)

   Returns the element at the beginning of *list*.  If *list* is empty,
   then the ``_head`` variant will return ``NULL``, while the ``_start``
   variant will return the list's sentinel element.


.. function:: struct cork_dllist_item \*cork_dllist_tail(struct cork_dllist \*list)
              struct cork_dllist_item \*cork_dllist_end(struct cork_dllist \*list)

   Returns the element at the end of *list*.  If *list* is empty, then
   the ``_tail`` variant will return ``NULL``, while the ``_end``
   variant will return the list's sentinel element.

.. function:: bool cork_dllist_is_start(struct cork_dllist \*list, struct cork_dllist_item \*element)
              bool cork_dllist_is_end(struct cork_dllist \*list, struct cork_dllist_item \*element)

   Returns whether *element* marks the start (or end) of *list*.

With these functions, manually counting the list elements looks like::

  struct cork_dllist  *list = /* from somewhere */;
  struct cork_dllist_item  *curr;
  size_t  count = 0;
  for (curr = cork_dllist_start(list); !cork_dllist_is_end(list, curr);
       curr = curr->next) {
      count++;
  }
  /* the number of elements is now in count */

You can also count the elements in reverse order::

  struct cork_dllist  *list = /* from somewhere */;
  struct cork_dllist_item  *curr;
  size_t  count = 0;
  for (curr = cork_dllist_end(list); !cork_dllist_is_start(list, curr);
       curr = curr->prev) {
      count++;
  }
  /* the number of elements is now in count */


================================================
FILE: docs/old/ds.rst
================================================
.. _ds:

***************
Data structures
***************

.. highlight:: c

::

  #include <libcork/ds.h>

libcork includes implementations of a number of useful data structures.

.. toctree::
   :maxdepth: 1

   array
   bitset
   slice
   managed-buffer
   buffer
   stream
   dllist
   hash-table
   ring-buffer


================================================
FILE: docs/old/errors.rst
================================================
.. _errors:

***************
Error reporting
***************

.. highlight:: c

::

  #include <libcork/core.h>

This section defines an API for reporting error conditions.  It's loosely
modeled on the POSIX ``errno`` mechanism.

The standard POSIX approach for reporting errors is to return an integer status
code, and to store error codes into the ``errno`` global variable.  This
approach has a couple of drawbacks.  The first is that you --- or really, your C
library --- has to ensure that ``errno`` is placed in thread-local storage, so
that separate threads have their own error condition variables.  The second, and
in our mind more important, is that the set of error codes is fixed and
platform-dependent.  It's difficult to add new error codes to represent
application-level error conditions.

The libcork error API is a way around this.  Like standard POSIX-conforming
functions, you return an integer status code from any function that might need
to report an error to its caller.  The status return code is simple: ``0``
indicates success, ``-1`` indicates failure.

When an error occurs, you can use the functions in this section to get more
information about the error: an *error code*, and human-readable string
description of the error.  The POSIX ``errno`` values, while hard to extend, are
perfectly well-defined for most platforms; therefore, any ``errno`` value
supported by your system's C library is a valid libcork error code.  To support
new application-specific error codes, an error code can also be the hash of some
string describing the error.  This “hash of a string” approach makes it easy to
define new error codes without needing any centralized mechanism for assigning
IDs to the various codes.  Moreover, it's very unlikely that a hashed error code
will conflict with some existing POSIX ``errno`` value, or with any other hashed
error codes.

.. note::

   We correctly maintain a separate error condition for each thread in
   the current process.  This is all hidden by the functions in this
   section; it's safe to call them from multiple threads simultaneously.


Calling a function that can return an error
-------------------------------------------

There are two basic forms for a function that can produce an error.  The
first is if the function returns a single pointer as its result::

  TYPE *
  my_function(/* parameters */);

The second is for any other function::

  int
  my_function(/* parameters */);

If an error occurs, the function will return either ``NULL`` or ``-1``,
depending on its return type.  Success will be indicated by a non-\
``NULL`` pointer or a ``0``.  (More complex return value schemes are
possible, if the function needs to signal more than a simple “success”
or “failure”; in that case, you'll need to check the function's
documentation for details.)

If you want to know specifics about the error, there are several
functions that you can use to interrogate the current error condition.

.. function:: bool cork_error_occurred(void)

   Returns whether an error has occurred.

.. function:: cork_error cork_error_code(void)

   Returns the error code of the current error condition.  If no error has
   occurred, the result will be :c:macro:`CORK_ERROR_NONE`.

.. function:: const char \*cork_error_message(void)

   Returns the human-readable string description the current error
   condition.  If no error occurred, the result of this function is
   undefined.

You can use the ``cork_error_prefix`` family of functions to add additional
context to the beginning of an error message.

.. function:: void cork_error_prefix_printf(const char \*format, ...)
              void cork_error_prefix_string(const char \*string)
              void cork_error_prefix_vprintf(const char \*format, va_list args)

   Prepends some additional text to the current error condition.

When you're done checking the current error condition, you clear it so
that later calls to :c:func:`cork_error_occurred` and friends don't
re-report this error.

.. function:: void cork_error_clear(void)

   Clears the current error condition.


Writing a function that can return an error
-------------------------------------------

When writing a function that might produce an error condition, your
function signature should follow one of the two standard patterns
described above::

  int
  my_function(/* parameters */);

  TYPE *
  my_function(/* parameters */);

You should return ``-1`` or ``NULL`` if an error occurs, and ``0`` or a
non-\ ``NULL`` pointer if it succeeds.  If ``NULL`` is a valid
“successful” result of the function, you should use the first form, and
define a ``TYPE **`` output parameter to return the actual pointer
value.  (If you're using the first form, you can use additional return
codes if there are other possible results besides a simple “success” and
“failure”.)

If your function results in an error, you need to fill in the current
error condition using the ``cork_error_set`` family of functions:

.. function:: void cork_error_set_printf(cork_error ecode, const char \*format, ...)
              void cork_error_set_string(cork_error ecode, const char \*string)
              void cork_error_set_vprintf(cork_error ecode, const char \*format, va_list args)

   Fills in the current error condition.  The error condition is defined
   by the error code *ecode*.  The human-readable description is constructed
   from *string*, or from *format* and any additional parameters, depending on
   which variant you use.

As an example, the :ref:`IP address <net-addresses>` parsing functions fill in
:c:macro:`CORK_PARSE_ERROR` error conditions when you try to parse a malformed
address::

  const char  *str = /* the string that's being parsed */;
  cork_error_set_printf
      (CORK_PARSE_ERROR, "Invalid IP address: %s", str);

If a particular kind of error can be raised in several places
throughout your code, it can be useful to define a helper function for
filling in the current error condition::

  static void
  cork_ip_address_parse_error(const char *version, const char *str)
  {
      cork_error_set_printf
          (CORK_PARSE_ERROR, "Invalid %s address: %s", version, str);
  }


Error-checking macros
---------------------

There can be a lot of repetitive code when calling functions that return
error conditions.  We provide a collection of helper macros that make it
easier to write this code.

.. note::

   Unlike most libcork modules, these macros are **not** automatically
   defined when you include the ``libcork/core.h`` header file, since
   they don't include a ``cork_`` prefix.  Because of this, we don't
   want to pollute your namespace unless you ask for the macros.  To do
   so, you must explicitly include their header file::

     #include <libcork/helpers/errors.h>

Additional debugging output
~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. macro:: CORK_PRINT_ERRORS

   If you define this macro to ``1`` before including
   :file:`libcork/helpers/errors.h`, then we'll output the current
   function name, file, and line number, along with the description of
   the error, to stderr whenever an error is detected by one of the
   macros described in this section.

Returning a default error code
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you follow one of the standard function signature patterns described
above, then your function will either return an ``int`` or some pointer
type, and errors will be signalled by a return value of ``-1`` or
``NULL``.  If so, you can use the macros in this section to
automatically return the appropriate error return value if a nested
function call returns an error.

With these macros, you won't have a chance to inspect the error
condition when an error occurs, so you should pass in your own *err*
parameter when calling the nested function.

(The mnemonic for remembering these macro names is that they all start
with ``rXY_``.  The ``r`` indicates that they automatically “return”.
The second character indicates whether *your* function returns an
``int`` or a pointer.  The third character indicates whether the
function you're *calling* returns an ``int`` or a pointer.)

.. function:: void rie_check(call)

   Call a function whose return value isn't enough to check for an error, when
   your function returns an ``int``.  We'll use :c:func:`cork_error_occurred` to
   check for an error.  If the nested function call returns an error, we
   propagate that error on.

.. function:: void rii_check(call)

   Call a function that returns an ``int`` error indicator, when your
   function also returns an ``int``.  If the nested function call
   returns an error, we propagate that error on.

.. function:: void rip_check(call)

   Call a function that returns a pointer, when your function returns an
   ``int``.  If the nested function call returns an error, we propagate
   that error on.

.. function:: void rpe_check(call)

   Call a function whose return value isn't enough to check for an error, when
   your function returns a pointer.  We'll use :c:func:`cork_error_occurred` to
   check for an error.  If the nested function call returns an error, we
   propagate that error on.

.. function:: void rpi_check(call)

   Call a function that returns an ``int`` error indicator, when your
   function returns a pointer.  If the nested function call returns an
   error, we propagate that error on.

.. function:: void rpp_check(call)

   Call a function that returns a pointer, when your function also
   returns a pointer.  If the nested function call returns an error, we
   propagate that error on.

Returning a non-standard return value
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If your function doesn't have a standard signature, or it uses
additional return values besides ``0``, ``1``, ``NULL``, and valid
pointers, then you can use the macros in this section to return a custom
return value in case of an error.

With these macros, you won't have a chance to inspect the error
condition when an error occurs, so you should pass in your own *err*
parameter when calling the nested function.

(The mnemonic for remembering these macro names is that they all start
with ``xY_``.  The ``x`` doesn't standard for anything in particular.
The second character indicates whether the function you're *calling*
returns an ``int`` or a pointer.  We don't need separate macros for
*your* function's return type, since you provide a return value
explicitly.)

.. function:: void xe_check(retval, call)

   Call a function whose return value isn't enough to check for an error.  If
   the nested function call raises an error, we propagate that error on, and
   return *retval* from the current function.

.. function:: void xi_check(retval, call)

   Call a function that returns an ``int`` error indicator.  If the
   nested function call raises an error, we propagate that error on, and
   return *retval* from the current function.

.. function:: void xp_check(retval, call)

   Call a function that returns a pointer.  If the nested function call
   raises an error, we propagate that error on, and return *retval* from
   the current function.

Post-processing when an error occurs
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

If you need to perform some post-processing when a nested function
returns an error, you can use the functions in this section.  They will
automatically jump to the current scope's ``error`` label whenever an
error occurs.

(The mnemonic for remembering these macro names is that they all start
with ``eY_``.  The ``e`` indicates that they'll jump to the ``error``
label.  The second character indicates whether the function you're
*calling* returns an ``int`` or a pointer.  We don't need separate
macros for *your* function's return type, since the macros won't
automatically return anything.)

.. function:: void ei_check(call)

   Call a function whose return value isn't enough to check for an error.  If
   the nested function call raises an error, we automatically jump to the
   current scope's ``error`` label.

.. function:: void ei_check(call)

   Call a function that returns an ``int`` error indicator.  If the
   nested function call raises an error, we automatically jump to the
   current scope's ``error`` label.

.. function:: void ep_check(call)

   Call a function that returns a pointer.  If the nested function call
   raises an error, we automatically jump to the current scope's
   ``error`` label.


Calling POSIX functions
~~~~~~~~~~~~~~~~~~~~~~~

The :c:func:`cork_system_error_set` function automatically translates a POSIX
error (specified in the standard ``errno`` variable) into a libcork error
condition (which will be reported by :c:func:`cork_error_occurred` and friends).
We also define several helper macros for calling a POSIX function and
automatically checking its result.

::

   #include <libcork/helpers/posix.h>

.. note::

   For all of these macros, the ``EINTR`` POSIX error is handled specially.
   This error indicates that a system call was interrupted by a signal, and that
   the call should be retried.  The macros do not translate ``EINTR`` errors
   into libcork errors; instead, they will retry the ``call`` until the
   statement succeeds or returns a non-``EINTR`` error.

.. function:: void rii_check_posix(call)

   Call a function that returns an ``int`` error indicator, when your function
   also returns an ``int``.  If the nested function call returns a POSIX error,
   we translate it into a libcork error and return a libcork error code.

.. function:: void rip_check_posix(call)

   Call a function that returns a pointer, when your function returns an
   ``int``.  If the nested function call returns a POSIX error, we translate it
   into a libcork error and return a libcork error code.

.. function:: void rpi_check_posix(call)

   Call a function that returns an ``int`` error indicator, when your function
   returns a pointer.  If the nested function call returns a POSIX error, we
   translate it into a libcork error and return a libcork error code.

.. function:: void rpp_check_posix(call)

   Call a function that returns a pointer, when your function also returns a
   pointer.  If the nested function call returns a POSIX error, we translate it
   into a libcork error and return a libcork error code.

.. function:: void ei_check_posix(call)

   Call a function that returns an ``int`` error indicator.  If the nested
   function call raises a POSIX error, we translate it into a libcork error and
   automatically jump to the current scope's ``error`` label.

.. function:: void ep_check_posix(call)

   Call a function that returns a pointer.  If the nested function call raises a
   POSIX error, we translate it into a libcork error and automatically jump to
   the current scope's ``error`` label.


Defining new error codes
------------------------

If none of the built-in error codes suffice for an error condition that you need
to report, you'll have to define our own.  As mentioned above, each libcork
error code is either a predefined POSIX ``errno`` value, or a hash some of
string identifying a custom error condition.

Typically, you will create a macro in one of your public header files, whose
value will be your new custom error code.  If this is the case, you can use the
macro name itself to create the hash value for the error code.  This is what we
do for the non-POSIX builtin errors; for instance, the value of the
:c:macro:`CORK_PARSE_ERROR` error code macro is the hash of the string
``CORK_PARSE_ERROR``.

Given this string, you can produce the error code's hash value using the
:ref:`cork-hash <cork-hash>` command that's installed with libcork::

  $ cork-hash CORK_PARSE_ERROR
  0x95dfd3c8

It's incredibly unlikely that the hash value for your new error code will
conflict with any other custom hash-based error codes, or with any predefined
POSIX ``errno`` values.

With your macro name and hash value ready, defining the new error code is
simple::

  #define CORK_PARSE_ERROR  0x95dfd3c8

You should also provide a helper macro that makes it easier to report new
instances of this error condition::

  #define cork_parse_error(...) \
      cork_error_set_printf(CORK_PARSE_ERROR, __VA_ARGS__)

.. type:: uint32_t  cork_error

   An identifier for a particular error condition.  This will either be a
   predefined POSIX ``errno`` value, or the hash of a unique string describing
   the error condition.

With your error class and code defined, you can fill in error instances
using :c:func:`cork_error_set_printf` and friends.


Builtin errors
--------------

In addition to all of the predefined POSIX ``errno`` values, we also provide
error codes for a handful of common error conditions.  You should feel free to
use these in your libraries and applications, instead of creating custom error
codes, if they apply.

.. macro:: CORK_ERROR_NONE

   A special error code that signals that no error occurred.

.. macro:: CORK_PARSE_ERROR

   The provided input violates the rules of the language grammar or file format
   (or anything else, really) that you're trying to parse.

   .. function:: void cork_parse_error(const char *format*, ...)

.. macro:: CORK_REDEFINED
           CORK_UNDEFINED

   Useful when you have a container type that must ensure that there is only one
   entry for any given key.

   .. function:: void cork_redefined(const char *format*, ...)
                 void cork_undefined(const char *format*, ...)

.. macro:: CORK_UNKNOWN_ERROR

   Some error occurred, but we don't have any other information about the error.

   .. function:: void cork_unknown_error(void)

      The error description will include the name of the current function.


We also provide some helper functions for setting these built-in errors:

.. function:: void cork_system_error_set(void)
              void cork_system_error_set_explicit(int err)

   Fills in the current libcork error condition with information from a POSIX
   ``errno`` value.  The human-readable description of the error will be
   obtained from the standard ``strerror`` function.  With the ``_explicit``
   variant, you provide the ``errno`` value directly; for the other variant, we
   get the error code from the C library's ``errno`` variable.


.. function:: void cork_abort(const char \*fmt, ...)

   Aborts the current program with an error message given by *fmt* and any
   additional parameters.

.. function:: void cork_unreachable(void)

   Aborts the current program with a message indicating that the code path
   should be unreachable.  This can be useful in the ``default`` clause of a
   ``switch`` statement if you can ensure that one of the non-``default``
   branches will always be selected.


================================================
FILE: docs/old/files.rst
================================================
.. _files:

*********************
Files and directories
*********************

.. highlight:: c

::

  #include <libcork/os.h>

The functions in this section let you interact with files and directories in the
local filesystem.


Paths
=====

We provide several functions for constructing and handling paths into the local
filesystem.

.. type:: struct cork_path

   Represents a path in the local filesystem.  The path can be relative or
   absolute.  The paths don't have to refer to existing files or directories.

.. function:: struct cork_path \*cork_path_new(const char \*path)
              struct cork_path \*cork_path_clone(const struct cork_path \*other)

   Construct a new path object from the given path string, or as a copy of
   another path object.

.. function:: void cork_path_free(struct cork_path \*path)

   Free a path object.

.. function:: const char \*cork_path_get(const struct cork_path \*path)

   Return the string content of a path.  This is not normalized in any way.  The
   result is guaranteed to be non-``NULL``, but may refer to an empty string.
   The return value belongs to the path object; you must not modify the contents
   of the string, nor should you try to free the underlying memory.

.. function:: struct cork_path \*cork_path_absolute(const struct cork_path \*other)
              int cork_path_make_absolute(struct cork_path \path)

   Convert a relative path into an absolute path.  The first variant constructs
   a new path object to hold the result; the second variant overwritesthe
   contents of *path*.

   If there is a problem obtaining the current working directory, these
   functions will return an error condition.

.. function:: struct cork_path \*cork_path_join(const struct cork_path \*path, const char \*more)
              struct cork_path \*cork_path_join_path(const struct cork_path \*path, const struct cork_path \*more)
              void \*cork_path_append(struct cork_path \path, const char \*more)
              void \*cork_path_append_path(struct cork_path \*path, const struct cork_path \*more)

   Concatenate two paths together.  The ``join`` variants create a new path
   object containing the concatenated results.  The ``append`` variants
   overwrite the contents of *path* with the concatenated results.


.. function:: struct cork_path \*cork_path_basename(const struct cork_path \*path)
              void \*cork_path_set_basename(struct cork_path \*path)

   Extract the base name of *path*.  This is the portion after the final
   trailing slash.  The first variant constructs a new path object to hold the
   result; the second variant overwritesthe contents of *path*.

   .. note::

      These functions return a different result than the standard
      ``basename(3)`` function.  We consider a trailing slash to be significant,
      whereas ``basename(3)`` does not::

          basename("a/b/c/") == "c"
          cork_path_basename("a/b/c/") == ""

.. function:: struct cork_path \*cork_path_dirname(const struct cork_path \*path)
              void \*cork_path_set_dirname(struct cork_path \*path)

   Extract the directory name of *path*.  This is the portion before the final
   trailing slash.  The first variant constructs a new path object to hold the
   result; the second variant overwritesthe contents of *path*.

   .. note::

      These functions return a different result than the standard ``dirname(3)``
      function.  We consider a trailing slash to be significant, whereas
      ``dirname(3)`` does not::

          dirname("a/b/c/") == "a/b"
          cork_path_dirname("a/b/c/") == "a/b/c"


Lists of paths
==============

.. type:: struct cork_path_list

   A list of paths in the local filesystem.

.. function:: struct cork_path_list \*cork_path_list_new_empty(void)
              struct cork_path_list \*cork_path_list_new(const char \*list)

   Create a new list of paths.  The first variant creates a list that is
   initially empty.  The second variant takes in a colon-separated list of paths
   as a single string, and adds each of those paths to the new list.

.. function:: void cork_path_list_free(struct cork_path_list \*list)

   Free a path list.

.. function:: void cork_path_list_add(struct cork_path_list \*list, struct cork_path \*path)

   Add *path* to *list*.  The list takes control of the path instance; you must
   not try to free *path* yourself.

.. function:: size_t cork_path_list_size(const struct cork_path_list \*list)

   Return the number of paths in *list*.

.. function:: const struct cork_path \*cork_path_list_get(const struct cork_path_list \*list, size_t index)

   Return the path in *list* at the given *index*.  The list still owns the path
   instance that's returned; you must not try to free it or modify its contents.

.. function:: const char \*cork_path_list_to_string(const struct cork_path_list \*list)

   Return a string containing all of the paths in *list* separated by colons.


.. function:: struct cork_file \*cork_path_list_find_file(const struct cork_path_list \*list, const char \*rel_path)
              struct cork_file_list \*cork_path_list_find_files(const struct cork_path_list \*list, const char \*rel_file)

   Search for a file in a list of paths.  *rel_path* gives the path of the
   sought-after file, relative to each of the directories in *list*.

   The first variant returns a :c:type:`cork_file` instance for the first match.
   In no file can be found, it returns ``NULL`` and sets an error condition.

   The second variant returns a :c:type:`cork_file_list` instance containing all
   of the matches.  In no file can be found, we return an empty list.  (Unlike
   the first variant, this is not considered an error.)


Standard paths
==============

.. function:: struct cork_path \*cork_path_home(void)

   Return a :c:type:`cork_path` that refers to the current user's home
   directory.  If we can't determine the current user's home directory, we set
   an error condition and return ``NULL``.

   On POSIX systems, this directory is determined by the ``HOME`` environment
   variable.

.. function:: struct cork_path_list \*cork_path_config_paths(void)

   Return a :c:type:`cork_path_list` that includes all of the standard
   directories that can be used to store configuration files.  This includes a
   user-specific directory that allows the user to override any global
   configuration files.

   On POSIX systems, these directories are defined XDG Base Directory
   Specification.

.. function:: struct cork_path_list \*cork_path_data_paths(void)

   Return a :c:type:`cork_path_list` that includes all of the standard
   directories that can be used to store application data files.  This includes
   a user-specific directory that allows the user to override any global data
   files.

   On POSIX systems, these directories are defined XDG Base Directory
   Specification.

.. function:: struct cork_path \*cork_path_user_cache_path(void)

   Return a :c:type:`cork_path` that refers to a directory that can be used to
   store cache files created on behalf of the current user.  This directory
   should only be used to store data that you can reproduce if needed.

   On POSIX systems, these directories are defined XDG Base Directory
   Specification.

.. function:: struct cork_path \*cork_path_user_runtime_path(void)

   Return a :c:type:`cork_path` that refers to a directory that can be used to
   store small runtime management files on behalf of the current user.

   On POSIX systems, these directories are defined XDG Base Directory
   Specification.


Files
=====

.. type:: struct cork_file

   Represents a file on the local filesystem.  The file in question does not
   necessarily have to exist; you can use :c:type:`cork_file` instances to refer
   to files that you have not yet created, for instance.

.. type:: typedef unsigned int  cork_file_mode

   Represents a Unix-style file permission set.


.. function:: struct cork_file \*cork_file_new(const char \*path)
              struct cork_file \*cork_file_new_from_path(struct cork_path \*path)

   Create a new :c:type:`cork_file` instance to represent the file with the
   given *path*.  The ``_from_path`` variant uses an existing
   :c:type:`cork_path` instance to specify the path.  The new file instance will
   take control of the :c:type`cork_path` instance, so you should not try to
   free it yourself.

.. function:: void cork_file_free(struct cork_file \*file)

   Free a file instance.

.. function:: const struct cork_path \*cork_file_path(struct cork_file \*file)

   Return the path of a file.  The :c:type:`cork_path` instance belongs to the
   file; you must not try to modify or free the path instance.

.. function:: int cork_file_exists(struct cork_file \*file, bool \*exists)

   Check whether a file exists in the filesystem, storing the result in
   *exists*.  The function returns an error condition if we are unable to
   determine whether the file exists --- for instance, because you do not have
   permission to look into one of the containing directories.

.. function:: int cork_file_type(struct cork_file \*file, enum cork_file_type \*type)

   Return what kind of file the given :c:type:`cork_file` instance refers to.
   The function returns an error condition if there is an error accessing the
   file --- for instance, because you do not have permission to look into one of
   the containing directories.

   If the function succeeds, it will fill in *type* with one of the following
   values:

   .. type:: enum cork_file_type

      .. member:: CORK_FILE_MISSING

         *file* does not exist.

      .. member:: CORK_FILE_REGULAR

         *file* is a regular file.

      .. member:: CORK_FILE_DIRECTORY

         *file* is a directory.

      .. member:: CORK_FILE_SYMLINK

         *file* is a symbolic link.

      .. member:: CORK_FILE_UNKNOWN

         We can access *file*, but we do not know what type of file it is.


.. function:: int cork_file_remove(struct cork_file \*file, unsigned int flags)

   Remove *file* from the filesystem.  *flags* must be the bitwise OR (``|``) of
   the following flags.  (Use ``0`` if you do not want any of the flags.)

   .. macro:: CORK_FILE_PERMISSIVE

      If this flag is given, then it is not considered an error if *file* does
      not exist.  If the flag is not given, then the function function returns
      an error if *file* doesn't exist.  (This mimics the standard ``rm -f``
      command.)

   .. macro:: CORK_FILE_RECURSIVE

      If this flag is given, and *file* refers to a directory, then the function
      will automatically remove the directory and all of its contents.  If the
      flag is not given, and *file* refers to a directory, then the directory
      must be empty for this function to succeed.  If *file* does not refer to a
      directory, this flag has no effect.  (This mimics the standard ``rmdir
      -r`` command.)


Directories
===========

Certain functions can only be applied to a :c:type:`cork_file` instance that
refers to a directory.


.. function:: int cork_file_mkdir(struct cork_file \*directory, cork_file_mode mode, unsigned int flags)

   Create a new directory in the filesystem, with permissions given by *mode*.
   *flags* must be the bitwise OR (``|``) of the following flags.  (Use ``0`` if
   you do not want any of the flags.)

   .. macro:: CORK_FILE_PERMISSIVE

      If this flag is given, then it is not considered an error if *directory*
      already exists.  If the flag is not given, then the function function
      returns an error if *directory* exists.  (This mimics part of the standard
      ``mkdir -p`` command.)

   .. macro:: CORK_FILE_RECURSIVE

      If this flag is given, then the function will ensure that all of the
      parent directories of *directory* exist, creating them if necessary.  Each
      directory created will have permissions given by *mode*.  (This mimics
      part of the standard ``mkdir -p`` command.)


.. function:: int cork_file_iterate_directory(struct cork_file \*directory, cork_file_directory_iterator iterator, void \*user_data)

   Call *iterator* for each file or subdirectory contained in *directory* (not
   including the directory's ``.`` and ``..`` entries).  This function does not
   recurse into any subdirectories; it only iterates through the immediate
   children of *directory*.

   If your iteration function returns a non-zero result, we will abort the
   iteration and return that value.  Otherwise, if each call to the iteration
   function returns ``0``, then we will return ``0`` as well.

   *iterator* must be an instance of the following function type:

   .. type:: typedef int (\*cork_file_directory_iterator)(struct cork_file \*child, const char \*rel_name, void \*user_data)

      Called for each child entry in *directory*.  *child* will be a file
      instance referring to the child entry.  *rel_name* gives the relative name
      of the child entry within its parent *directory*.


Lists of files
==============

.. type:: struct cork_file_list

   A list of files in the local filesystem.

.. function:: struct cork_file_list \*cork_file_list_new_empty(void)
              struct cork_file_list \*cork_file_list_new(struct cork_path_list \*path_list)

   Create a new list of files.  The first variant creates a list that is
   initially empty.  The second variant adds a new file instance for each of the
   paths in *path_list*.

.. function:: void cork_file_list_free(struct cork_file_list \*list)

   Free a file list.

.. function:: void cork_file_list_add(struct cork_file_list \*list, struct cork_file \*file)

   Add *file* to *list*.  The list takes control of the file instance; you must
   not try to free *file* yourself.

.. function:: size_t cork_file_list_size(const struct cork_file_list \*list)

   Return the number of files in *list*.

.. function:: struct cork_file \*cork_file_list_get(const struct cork_file_list \*list, size_t index)

   Return the file in *list* at the given *index*.  The list still owns the file
   instance that's returned; you must not try to free it.



Directory walking
=================

.. function:: int cork_walk_directory(const char \*path, struct cork_dir_walker \*walker)

   Walk through the contents of a directory.  *path* can be an absolute or
   relative path.  If it's relative, it will be interpreted relative to the
   current directory.  If *path* doesn't exist, or there are any problems
   reading the contents of the directory, we'll set an error condition and
   return ``-1``.

   To process the contents of the directory, you must provide a *walker* object,
   which contains several callback methods that we will call when files and
   subdirectories of *path* are encountered.  Each method should return ``0`` on
   success.  Unless otherwise noted, if we receive any other return result, we
   will abort the directory walk, and return that same result from the
   :c:func:`cork_walk_directory` call itself.

   In all of the following methods, *base_name* will be the base name of the
   entry within its immediate subdirectory.  *rel_path* will be the relative
   path of the entry within the *path* that you originally asked to walk
   through.  *full_path* will the full path to the entry, including *path*
   itself.

   .. type:: struct cork_dir_walker

      .. member:: int (\*file)(struct cork_dir_walker \*walker, const char \*full_path, const char \*rel_path, const char \*base_name)

         Called when a regular file is encountered.

      .. member:: int (\*enter_directory)(struct cork_dir_walker \*walker, const char \*full_path, const char \*rel_path, const char \*base_name)

         Called when a subdirectory of *path* of encountered.  If you don't want
         to recurse into this directory, return :c:data:`CORK_SKIP_DIRECTORY`.

         .. macro:: CORK_SKIP_DIRECTORY

      .. member:: int (\*leave_directory)(struct cork_dir_walker \*walker, const char \*full_path, const char \*rel_path, const char \*base_name)

         Called when a subdirectory has been fully processed.


================================================
FILE: docs/old/gc.rst
================================================
.. _gc:

************************************
Reference-counted garbage collection
************************************

.. highlight:: c

::

  #include <libcork/core.h>

The functions in this section implement a reference counting garbage
collector.  The garbage collector handles reference cycles correctly.
It is **not** a conservative garbage collector — i.e., we don't assume
that every word inside an object might be a pointer.  Instead, each
garbage-collected object must provide a *recursion function* that knows
how to delve down into any child objects that it references.

The garbage collector is **not** thread-safe.  If your application is
multi-threaded, each thread will (automatically) have its own garbage
collection context.  There are two strategies that you can use when
using the garbage collector in a multi-threaded application:

* Have a single “master” thread be responsible for the lifecycle of
  every object.  This thread is the only one allowed to interact with
  the garbage collector.  **No** other threads are allowed to call any
  of the functions in this section, including the
  :c:func:`cork_gc_incref()` and :c:func:`cork_gc_decref()` functions.
  Other threads are allowed to access the objects that are managed by
  the garbage collector, but the master thread must ensure that all
  objects are live whenever another thread attempts to use them.  This
  will require some kind of thread-safe communication or synchronization
  between the master thread and the worker threads.

* Have a separate garbage collector per thread.  Each object is “owned”
  by a single thread, and the object is managed by that thread's garbage
  collector.  As with the first strategy, other threads can use any
  object, as long as the object's owner thread is able to guarantee that
  the object will be live for as long as it's needed.  (Eventually we'll
  also support migrating an object from one garbage collector to
  another, but that feature isn't currently implemented.)

The garbage collection implementation is based on the algorithm
described in §3 of [1]_.

.. [1] Bacon, DF and Rajan VT.  *Concurrent cycle collection in
   reference counted systems*.  Proc. ECOOP 2001.  LNCS 2072.


Creating a garbage collector
============================

.. function:: void cork_gc_init(void)

   Initalizes a garbage collection context for the current thread.
   Usually, you can allocate this on the stack of your ``main``
   function::

     int
     main(int argc, char ** argv)
     {
         cork_gc_init();

         // use the GC context

         // and free it when you're done
         cork_gc_done();
     }

   It's not required that you call this function at all; if you don't,
   we'll automatically initialize a garbage collection context for the
   current thread the first time you try to allocate a garbage-collected
   object.  You can call this function, though, if you want to have more
   control over when the initialization occurs.

.. function:: void cork_gc_done(void)

   Finalize the garbage collection context for the current thread.  All
   objects created in this thread will be freed when this function
   returns.

   You must call this function in each thread that allocates
   garbage-collected objects, just before that thread finishes.  (If
   your application is single-threaded, then you must call this function
   before the ``main`` function finishes.)  If you don't, you'll almost
   certainly get memory leaks.


Managing garbage-collected objects
==================================

A garbage collection context can't be used to manage arbitrary objects,
since each garbage-collected class must define some callback functions
for interacting with the garbage collector.  (The :ref:`next section
<new-gc-class>` contains more details.)

Each garbage-collected class will provide its own constructor function
for instantiating a new instance of that class.  There aren't any
explicit destructors for garbage-collected objects; instead you manage
“references” to the objects.  Each pointer to a garbage-collected object
is a reference, and each object maintains a count of the references to
itself.  A newly constructed object starts with a reference count of
``1``.  Whenever you save a pointer to a garbage-collected object, you
should increase the object's reference count.  When you're done with the
pointer, you decrease its reference count.  When the reference count
drops to ``0``, the garbage collector frees the object.

.. function:: void \*cork_gc_incref(void \*obj)

   Increments the reference count of an object *obj* that is managed by
   the current thread's garbage collector.  We always return *obj* as a
   result, which allows you to use the following idiom::

     struct my_obj * my_copy_of_obj = cork_gc_incref(obj);

.. function:: void cork_gc_decref(void \*obj)

   Decrements the reference count of an object *obj* that is managed by
   the current thread's garbage collector  If the reference count drops
   to ``0``, then the garbage collector will free the object.

   .. note::

      It's safe to call this function with a ``NULL`` *obj* pointer; in
      this case, the function acts as a no-op.

.. _borrow-ref:

Borrowing a reference
---------------------

While the strategy mentioned above implies that you should call
:c:func:`cork_gc_incref()` and :c:func:`cork_gc_decref()` for *every*
pointer to a garbage-collected object, you can sometimes get away
without bumping the reference count.  In particular, you can often
*borrow* an existing reference to an object, if you can guarantee that
the borrowed reference will exist for as long as you need access to the
object.  The most common example of this when you pass in a
garbage-collected object as the parameter to a function::

  int
  use_new_reference(struct my_obj *obj)
  {
      /* Here we're being pedantically correct, and incrementing obj's
       * reference count since we've got our own pointer to the object. */
      cork_gc_incref(obj);

      /* Do something useful with obj */

      /* And now that we're done with it, decrement the reference count. */
      cork_gc_decref(obj);
  }

  int
  borrowed_reference(struct my_obj *obj)
  {
      /* We can assume that the caller has a valid reference to obj, so
       * we're just going to borrow that reference. */

      /* Do something useful with obj */
  }

In this example, ``borrowed_reference`` doesn't need to update *obj*\ 's
reference count.  We assume that the caller has a valid reference to
*obj* when it makes the call to ``borrowed_reference``.  Moreover, we
know that the caller can't possibly release this reference (via
:c:func:`cork_gc_decref()`) until ``borrowed_reference`` returns.  Since
we can guarantee that the caller's reference to *obj* will exist for the
entire duration of ``borrowed_reference``, we don't need to protect it
with an ``incref``/``decref`` pair.

.. _steal-ref:

Stealing a reference
--------------------

Another common pattern is for a “parent” object to maintain a reference
to a “child” object.  (For example, a container class might maintain
references to all of the elements in the container, assuming that the
container and elements are all garbage-collected objects.)  When you
have a network of objects like this, the parent object's constructor
will usually take in a pointer to the child object as a parameter.  If
we strictly follow the basic referencing counting rules described above,
you'll end up with something like::

  struct child  *child = child_new();
  struct parent  *parent = parent_new(child);
  cork_gc_decref(child);

The ``child_new`` constructor gives us a reference to *child*.  The
``parent_new`` constructor then creates a new reference to *child*,
which will be stored somewhere in *parent*.  We no longer need our own
reference to *child*, so we immediately decrement its reference count.

This is a common enough occurrence that many constructor functions will
instead *steal* the reference passed in as a parameter.  This means that
the constructor takes control of the caller's reference.  This allows us
to rewrite the example as::

  struct parent  *parent = parent_new_stealing(child_new());

For functions that steal a reference, the caller **cannot** assume that
the object pointed to by the stolen reference exists when the function
returns.  (If there's an error in ``parent_new_stealing``, for instance,
it must release the stolen reference to *child* to prevent a memory
leak.)  If a function is going to steal a reference, but you also need
to use the object after the function call returns, then you need to
explicitly increment the reference count *before* calling the function::

  struct child  *child = child_new();
  struct parent  *parent = parent_new_stealing(cork_gc_incref(child));
  /* Do something with child. */
  /* And then release our reference when we're done. */
  cork_gc_decref(child);

.. note::

   It's important to point out that not every constructor will steal the
   references passed in as parameters.  Moreover, there are some
   constructors that steal references for some parameters but not for
   others.  It entirely depends on what the “normal” use case is for the
   constructor.  If you're almost always going to pass in a child object
   that was just created, and that will always be accessed via the
   parent, then the constructor will usually steal the reference.  If
   the child can be referenced by many parents, then the constructor
   will usually *not* steal the reference.  The documentation for each
   constructor function will explicitly state which references are
   stolen and which objects it creates new references for.


.. _new-gc-class:

Writing a new garbage-collected class
=====================================

When you are creating a new class that you want to be managed by a
garbage collector, there are two basic steps you need to follow:

* Implement a set of callback functions that allow the garbage collector
  to interact with objects of the new class.

* Use the garbage collector's allocation functions to allocate storage
  for instance of your class.

You won't need to write a public destructor function, since objects of
the new class will be destroyed automatically when the garbage collector
determines that they're no longer needed.

Garbage collector callback interface
------------------------------------

Each garbage-collected class must provide an implementation of the
“callback interface”:

.. type:: struct cork_gc_obj_iface

   .. member:: void (\*free)(void \*obj)

      This callback is called when a garbage-collected object is about
      to be freed.  You can perform any special cleanup steps in this
      callback.  You do **not** need to deallocate the object's storage,
      and you do **not** need to release any references that you old to
      other objects.  Both of these steps will be taken care of for you
      by the garbage collector.

      If your class doesn't need any additional finalization steps, this
      entry in the callback interface can be ``NULL``.

   .. member:: void (\*recurse)(struct cork_gc \*gc, void \*obj, cork_gc_recurser recurse, void \*ud)

      This callback is how you inform the garbage collector of your
      references to other garbage-collected objects.

      The garbage collector will call this function whenever it needs to
      traverse through a graph of object references.  Your
      implementation of this callback should just call *recurse* with
      each garbage-collected object that you hold a reference to.  You
      must pass in *gc* as the first parameter to each call to
      *recurse*, and *ud* as the third parameter.

      Note that it's fine to call *recurse* with a ``NULL`` object
      pointer, which makes it slightly easier to write implementations
      of this callback.

      If instances of your class can never contain references to other
      garbage-collected objects, this entry in the callback interface
      can be ``NULL``.

.. type:: void (\*cork_gc_recurser)(struct cork_gc \*gc, void \*obj, void \*ud)

   An opaque callback provided by the garbage collector when it calls an
   object's :c:member:`~cork_gc_obj_iface.recurse` method.

.. type:: struct cork_gc

   An opaque type representing the current thread's garbage-collection
   context.  You'll only need to use this type when implementing a
   :c:member:`~cork_gc_obj_iface.recurse` function.


.. _gc-macros:

Helper macros
~~~~~~~~~~~~~

There are several macros declared in :file:`libcork/helpers/gc.h` that
make it easier to define the garbage-collection interface for a new
class.

.. note::

   Unlike most libcork modules, these macros are **not** automatically
   defined when you include the ``libcork/core.h`` header file, since
   they don't include a ``cork_`` prefix.  Because of this, we don't
   want to pollute your namespace unless you ask for the macros.  To do
   so, you must explicitly include their header file::

     #include <libcork/helpers/gc.h>

.. macro:: _free_(SYMBOL name)
           _recurse_(SYMBOL name)

   These macros declare the *free* and *recurse* methods for a new
   class.  The functions will be declared with exactly the signatures
   and parameter names shown in the entries for the
   :c:member:`~cork_gc_obj_iface.free` and
   :c:member:`~cork_gc_obj_iface.recurse` methods.

   You will almost certainly not need to refer to the method
   implementations directly, since you can use the :c:macro:`_gc_*_
   <_gc_>` macros below to declare the interface struct.  But if you do,
   they'll be called :samp:`{[name]}__free` and
   :samp:`{[name]}__recurse`.  (Note the double underscore.)

.. macro:: _gc_(SYMBOL name)
           _gc_no_free_(SYMBOL name)
           _gc_no_recurse_(SYMBOL name)
           _gc_leaf_(SYMBOL name)

   Define the garbage-collection interface struct for a new class.  If
   you defined both ``free`` and ``recurse`` methods, you should use the
   ``_gc_`` variant.  If you only defined one of the methods, you should
   use ``_gc_no_free_`` or ``_gc_no_recurse_``.  If you didn't define
   either method, you should use ``_gc_free_``.

   Like the method definitions, you probably won't need to refer to the
   interface struct directly, since you can use the
   :c:func:`cork_gc_new` macro to allocate new instances of the new
   class.  But if you do, it will be called :samp:`{[name]}__gc`.  (Note
   the double underscore.)


As an example, we can use these macros to define a new tree class::

    #include <libcork/helpers/gc.h>

    struct tree {
        const char  *name;
        struct tree  *left;
        struct tree  *right;
    };

    _free_(tree) {
        struct tree  *self = obj;
        cork_strfree(self->name);
    }

    _recurse_(tree) {
        struct tree  *self = obj;
        recurse(self->left, ud);
        recurse(self->right, ud);
    }

    _gc_(tree);


Allocating new garbage-collected objects
----------------------------------------

In your garbage-collected class's constructor, you must use one of the
following functions to allocate the object's storage.  (The garbage
collector hides some additional state in the object's memory region, so
you can't allocate the storage using ``malloc`` or :c:func:`cork_new()`
directly.)

.. function:: void \*cork_gc_alloc(size_t instance_size, struct cork_gc_obj_iface \*iface)

   Allocates a new garbage-collected object that is *instance_size*
   bytes large.  *iface* should be a pointer to a callback interface for
   the object.  If there are any problems allocating the new instance,
   the program will abort.

.. function:: type \*cork_gc_new_iface(TYPE type, struct cork_gc_obj_iface \*iface)

   Allocates a new garbage-collected instance of *type*.  The size of
   the memory region to allocate is calculated using the ``sizeof``
   operator, and the result will be automatically cast to ``type *``.
   *iface* should be a pointer to a callback interface for the object.
   If there are any problems allocating the new instance, the program
   will abort.

.. function:: struct name \*cork_gc_new(SYMBOL name)

   Allocates a new garbage-collected instance of :samp:`struct
   {[name]}`.  (Note that you don't pass in the ``struct`` part of the
   type name.) We assume that the garbage collection interface was
   created using one of the :c:macro:`_gc_*_ <_gc_>` macros, using the
   same *name* parameter.

Using these functions, could instantiate our example tree class as
follows::

    struct tree *
    tree_new(const char *name)
    {
        struct tree  *self = cork_gc_new(tree);
        self->name = cork_strdup(name);
        self->left = NULL;
        self->right = NULL;
        return self;
    }


================================================
FILE: docs/old/hash-table.rst
================================================
.. _hash-table:

***********
Hash tables
***********

.. highlight:: c

::

  #include <libcork/ds.h>

This section defines a hash table class.  Our hash table implementation
is based on the public domain hash table package written in the late
1980's by Peter Moore at UC Berkeley.

The keys and values of a libcork hash table are both represented by ``void *``
pointers.  You can also store integer keys or values, as long as you use the
:c:type:`intptr_t` or :c:type:`uintptr_t` integral types.  (These are the only
integer types guaranteed by the C99 standard to fit within the space used by a
``void *``.)  The keys of the hash table can be any arbitrary type; you must
provide two functions that control how key pointers are used to identify entries
in the table: the *hasher* (:c:type:`cork_hash_f`) and the *comparator*
(:c:type:`cork_equals_f`).  It's your responsibility to ensure that these two
functions are consistent with each other — i.e., if two keys are equ
Download .txt
gitextract_iakl50pb/

├── .buzzy/
│   ├── links.yaml
│   └── package.yaml
├── .clang-format
├── .github/
│   └── workflows/
│       └── ci.yml
├── .gitignore
├── AUTHORS
├── CMakeLists.txt
├── COPYING
├── INSTALL
├── Makefile.am
├── README.markdown
├── autogen.sh
├── build-aux/
│   └── calculate
├── cmake/
│   ├── FindCTargets.cmake
│   ├── FindParseArguments.cmake
│   └── FindPrereqs.cmake
├── configure.ac
├── docs/
│   ├── .gitattributes
│   ├── CMakeLists.txt
│   └── old/
│       ├── CMakeLists.txt
│       ├── _static/
│       │   ├── .keep
│       │   ├── docco-sphinx.css
│       │   └── pygments.css
│       ├── _templates/
│       │   └── .keep
│       ├── allocation.rst
│       ├── array.rst
│       ├── attributes.rst
│       ├── basic-types.rst
│       ├── bitset.rst
│       ├── buffer.rst
│       ├── byte-order.rst
│       ├── cli.rst
│       ├── conf.py
│       ├── config.rst
│       ├── dllist.rst
│       ├── ds.rst
│       ├── errors.rst
│       ├── files.rst
│       ├── gc.rst
│       ├── hash-table.rst
│       ├── hash-values.rst
│       ├── index.rst
│       ├── int128.rst
│       ├── managed-buffer.rst
│       ├── mempool.rst
│       ├── net-addresses.rst
│       ├── process.rst
│       ├── ring-buffer.rst
│       ├── slice.rst
│       ├── stream.rst
│       ├── subprocess.rst
│       ├── threads.rst
│       ├── timestamps.rst
│       ├── unique-ids.rst
│       ├── versions.rst
│       └── visibility.rst
├── extras/
│   └── hashstring.py
├── include/
│   ├── CMakeLists.txt
│   └── libcork/
│       ├── cli/
│       │   └── commands.h
│       ├── cli.h
│       ├── config/
│       │   ├── arch.h
│       │   ├── bsd.h
│       │   ├── config.h
│       │   ├── gcc.h
│       │   ├── linux.h
│       │   ├── macosx.h
│       │   └── version.h.in
│       ├── config.h
│       ├── core/
│       │   ├── allocator.h
│       │   ├── api.h
│       │   ├── attributes.h
│       │   ├── byte-order.h
│       │   ├── callbacks.h
│       │   ├── error.h
│       │   ├── gc.h
│       │   ├── hash.h
│       │   ├── id.h
│       │   ├── mempool.h
│       │   ├── net-addresses.h
│       │   ├── timestamp.h
│       │   ├── types.h
│       │   └── u128.h
│       ├── core.h
│       ├── ds/
│       │   ├── array.h
│       │   ├── bitset.h
│       │   ├── buffer.h
│       │   ├── dllist.h
│       │   ├── hash-table.h
│       │   ├── managed-buffer.h
│       │   ├── ring-buffer.h
│       │   ├── slice.h
│       │   └── stream.h
│       ├── ds.h
│       ├── helpers/
│       │   ├── errors.h
│       │   ├── gc.h
│       │   └── posix.h
│       ├── os/
│       │   ├── files.h
│       │   ├── process.h
│       │   └── subprocess.h
│       ├── os.h
│       ├── threads/
│       │   ├── atomics.h
│       │   └── basics.h
│       └── threads.h
├── m4/
│   ├── ax_pthread.m4
│   └── ax_valgrind_check.m4
├── make-dist.sh
├── run.sh
├── scripts/
│   ├── install
│   └── test
├── share/
│   ├── CMakeLists.txt
│   └── valgrind/
│       └── libcork.supp
├── src/
│   ├── APPNAME.pc.in
│   ├── CMakeLists.txt
│   ├── cork-hash/
│   │   └── cork-hash.c
│   ├── cork-initializer/
│   │   ├── init1.c
│   │   ├── init2.c
│   │   └── main.c
│   ├── cork-test/
│   │   └── cork-test.c
│   ├── libcork/
│   │   ├── cli/
│   │   │   └── commands.c
│   │   ├── core/
│   │   │   ├── allocator.c
│   │   │   ├── error.c
│   │   │   ├── gc.c
│   │   │   ├── hash.c
│   │   │   ├── id.c
│   │   │   ├── ip-address.c
│   │   │   ├── mempool.c
│   │   │   ├── timestamp.c
│   │   │   ├── u128.c
│   │   │   └── version.c
│   │   ├── ds/
│   │   │   ├── array.c
│   │   │   ├── bitset.c
│   │   │   ├── buffer.c
│   │   │   ├── dllist.c
│   │   │   ├── file-stream.c
│   │   │   ├── hash-table.c
│   │   │   ├── managed-buffer.c
│   │   │   ├── ring-buffer.c
│   │   │   ├── slice.c
│   │   │   └── stream.c
│   │   ├── posix/
│   │   │   ├── directory-walker.c
│   │   │   ├── env.c
│   │   │   ├── exec.c
│   │   │   ├── files.c
│   │   │   ├── process.c
│   │   │   └── subprocess.c
│   │   └── pthreads/
│   │       └── thread.c
│   └── libcork.pc.in
└── tests/
    ├── .gitattributes
    ├── .gitignore
    ├── CMakeLists.txt
    ├── COPYING.cram.txt
    ├── ccram
    ├── cork-hash.t
    ├── cork-initializer.t
    ├── cork-test/
    │   ├── cleanup.t
    │   ├── directory-watcher.t
    │   ├── help1-c1-s1.t
    │   ├── help1-c1-s2.t
    │   ├── help1-c1.t
    │   ├── help1-c2.t
    │   ├── help1-root.t
    │   ├── help2-c1-s1.t
    │   ├── help2-c1-s2.t
    │   ├── help2-c1.t
    │   ├── help2-c2.t
    │   ├── help2-root.t
    │   ├── help3-c1-s1.t
    │   ├── help3-c1-s2.t
    │   ├── help3-c1.t
    │   ├── help3-c2.t
    │   ├── help3-root.t
    │   ├── no-command-c1.t
    │   ├── no-command-root.t
    │   ├── run-c1-s1-f-t.t
    │   ├── run-c1-s1-f.t
    │   ├── run-c1-s1-t.t
    │   ├── run-c1-s1-test.t
    │   ├── run-c1-s1.t
    │   ├── run-c1-s2-f.t
    │   ├── run-c1-s2-file.t
    │   ├── run-c1-s2.t
    │   ├── run-c2.t
    │   ├── run-find-01.t
    │   ├── run-find-all-01.t
    │   ├── run-mkdir-01.t
    │   ├── run-paths-01.t
    │   ├── run-pwd-01.t
    │   ├── run-rm-01.t
    │   ├── run-sub-01.t
    │   ├── run-sub-02.t
    │   ├── run-sub-03.t
    │   ├── run-sub-04.t
    │   ├── run-sub-05.t
    │   └── run-sub-06.t
    ├── cram.py
    ├── create-u128-test-cases.py
    ├── helpers.h
    ├── test-array.c
    ├── test-bitset.c
    ├── test-buffer.c
    ├── test-core.c
    ├── test-dllist.c
    ├── test-files.c
    ├── test-gc.c
    ├── test-hash-table.c
    ├── test-managed-buffer.c
    ├── test-mempool.c
    ├── test-ring-buffer.c
    ├── test-slice.c
    ├── test-subprocess.c
    ├── test-threads.c
    └── test-u128.c
Download .txt
SYMBOL INDEX (1287 symbols across 71 files)

FILE: extras/hashstring.py
  function rotl32 (line 12) | def rotl32(a, b):
  function fmix (line 16) | def fmix(h):
  function hash (line 24) | def hash(value, seed):
  function myhex (line 67) | def myhex(v):

FILE: include/libcork/cli/commands.h
  type cork_command_type (line 22) | enum cork_command_type {
  type cork_command (line 27) | struct cork_command {
  type cork_command (line 54) | struct cork_command
  type cork_command (line 57) | struct cork_command

FILE: include/libcork/core/allocator.h
  type cork_alloc (line 27) | struct cork_alloc
  type cork_alloc (line 30) | struct cork_alloc
  type cork_alloc (line 34) | struct cork_alloc
  type cork_alloc (line 38) | struct cork_alloc
  type cork_alloc (line 42) | struct cork_alloc
  type cork_alloc (line 44) | struct cork_alloc {
  type cork_alloc (line 60) | struct cork_alloc
  type cork_alloc (line 64) | struct cork_alloc
  type cork_alloc (line 76) | struct cork_alloc
  type cork_alloc (line 79) | struct cork_alloc
  type cork_alloc (line 82) | struct cork_alloc
  type cork_alloc (line 87) | struct cork_alloc
  type cork_alloc (line 90) | struct cork_alloc
  type cork_alloc (line 93) | struct cork_alloc
  type cork_alloc (line 98) | struct cork_alloc
  type cork_alloc (line 106) | struct cork_alloc
  type cork_alloc (line 114) | struct cork_alloc
  type cork_alloc (line 122) | struct cork_alloc
  type cork_alloc (line 131) | struct cork_alloc
  type cork_alloc (line 139) | struct cork_alloc
  type cork_alloc (line 147) | struct cork_alloc
  type cork_alloc (line 156) | struct cork_alloc
  function CORK_INLINE (line 168) | CORK_INLINE
  function CORK_INLINE (line 175) | CORK_INLINE
  type cork_alloc (line 195) | struct cork_alloc
  type cork_alloc (line 199) | struct cork_alloc
  type cork_alloc (line 204) | struct cork_alloc
  type cork_alloc (line 208) | struct cork_alloc
  type cork_alloc (line 212) | struct cork_alloc
  type cork_alloc (line 243) | struct cork_alloc
  type cork_alloc (line 250) | struct cork_alloc
  type cork_alloc (line 267) | struct cork_alloc
  type cork_alloc (line 276) | struct cork_alloc
  type cork_alloc (line 285) | struct cork_alloc
  type cork_alloc (line 294) | struct cork_alloc
  type cork_alloc (line 303) | struct cork_alloc
  type cork_alloc (line 312) | struct cork_alloc
  type cork_alloc (line 321) | struct cork_alloc
  function CORK_INLINE (line 325) | CORK_INLINE
  function CORK_INLINE (line 333) | CORK_INLINE
  type cork_alloc (line 353) | struct cork_alloc
  type cork_alloc (line 362) | struct cork_alloc
  type cork_alloc (line 371) | struct cork_alloc
  type cork_alloc (line 380) | struct cork_alloc
  function CORK_INLINE (line 384) | CORK_INLINE
  function CORK_INLINE (line 392) | CORK_INLINE
  type cork_alloc (line 413) | struct cork_alloc
  type cork_alloc (line 414) | struct cork_alloc

FILE: include/libcork/core/callbacks.h
  type cork_hash (line 26) | typedef cork_hash

FILE: include/libcork/core/error.h
  type cork_error (line 24) | typedef uint32_t  cork_error;
  function CORK_INLINE (line 120) | CORK_INLINE

FILE: include/libcork/core/gc.h
  type cork_gc (line 18) | struct cork_gc
  type cork_gc (line 23) | struct cork_gc
  type cork_gc (line 29) | struct cork_gc
  type cork_gc_obj_iface (line 33) | struct cork_gc_obj_iface {
  type cork_gc_obj_iface (line 49) | struct cork_gc_obj_iface

FILE: include/libcork/core/hash.h
  type cork_hash (line 24) | typedef uint32_t  cork_hash;
  type cork_big_hash (line 26) | typedef struct {
  function CORK_INLINE (line 30) | CORK_INLINE
  function CORK_INLINE (line 48) | CORK_INLINE
  function CORK_INLINE (line 56) | CORK_INLINE
  function CORK_INLINE (line 64) | CORK_INLINE
  function CORK_INLINE (line 75) | CORK_INLINE
  function CORK_INLINE (line 86) | CORK_INLINE
  function cork_hash (line 334) | cork_hash
  function CORK_INLINE (line 350) | CORK_INLINE

FILE: include/libcork/core/id.h
  type cork_uid (line 17) | struct cork_uid {
  type cork_uid (line 21) | struct cork_uid
  function CORK_INLINE (line 31) | CORK_INLINE
  function CORK_INLINE (line 38) | CORK_INLINE
  function CORK_INLINE (line 45) | CORK_INLINE

FILE: include/libcork/core/mempool.h
  type cork_mempool (line 24) | struct cork_mempool
  function cork_mempool (line 31) | cork_mempool*
  type cork_mempool (line 45) | struct cork_mempool
  type cork_mempool (line 49) | struct cork_mempool
  type cork_mempool (line 53) | struct cork_mempool
  type cork_mempool (line 56) | struct cork_mempool
  type cork_mempool (line 61) | struct cork_mempool
  type cork_mempool (line 68) | struct cork_mempool
  type cork_mempool (line 72) | struct cork_mempool

FILE: include/libcork/core/net-addresses.h
  type cork_ipv4 (line 26) | struct cork_ipv4 {
  type cork_ipv6 (line 34) | struct cork_ipv6 {
  type cork_ip (line 43) | struct cork_ip {
  function CORK_INLINE (line 62) | CORK_INLINE
  function CORK_INLINE (line 69) | CORK_INLINE
  type cork_ipv4 (line 77) | struct cork_ipv4
  type cork_ipv4 (line 80) | struct cork_ipv4
  type cork_ipv4 (line 80) | struct cork_ipv4
  type cork_ipv4 (line 83) | struct cork_ipv4
  type cork_ipv4 (line 86) | struct cork_ipv4
  function CORK_INLINE (line 93) | CORK_INLINE
  function CORK_INLINE (line 100) | CORK_INLINE
  type cork_ipv6 (line 109) | struct cork_ipv6
  type cork_ipv6 (line 112) | struct cork_ipv6
  type cork_ipv6 (line 112) | struct cork_ipv6
  type cork_ipv6 (line 115) | struct cork_ipv6
  type cork_ipv6 (line 118) | struct cork_ipv6
  function CORK_INLINE (line 124) | CORK_INLINE
  function CORK_INLINE (line 138) | CORK_INLINE
  function CORK_INLINE (line 147) | CORK_INLINE
  type cork_ip (line 156) | struct cork_ip
  type cork_ip (line 159) | struct cork_ip
  type cork_ip (line 162) | struct cork_ip

FILE: include/libcork/core/timestamp.h
  type cork_timestamp (line 20) | typedef uint64_t  cork_timestamp;
  function CORK_INLINE (line 23) | CORK_INLINE
  function CORK_INLINE (line 30) | CORK_INLINE
  function CORK_INLINE (line 37) | CORK_INLINE
  function CORK_INLINE (line 44) | CORK_INLINE
  function CORK_INLINE (line 51) | CORK_INLINE
  function CORK_INLINE (line 63) | CORK_INLINE
  function CORK_INLINE (line 70) | CORK_INLINE
  function CORK_INLINE (line 77) | CORK_INLINE
  function CORK_INLINE (line 89) | CORK_INLINE
  function CORK_INLINE (line 96) | CORK_INLINE
  function CORK_INLINE (line 103) | CORK_INLINE
  type cork_buffer (line 113) | struct cork_buffer
  type cork_buffer (line 117) | struct cork_buffer

FILE: include/libcork/core/u128.h
  type cork_u128 (line 20) | typedef struct {
  function CORK_INLINE (line 45) | CORK_INLINE
  function CORK_INLINE (line 65) | CORK_INLINE
  function CORK_INLINE (line 80) | CORK_INLINE
  function CORK_INLINE (line 130) | CORK_INLINE
  function CORK_INLINE (line 141) | CORK_INLINE
  function CORK_INLINE (line 152) | CORK_INLINE
  function CORK_INLINE (line 167) | CORK_INLINE
  function CORK_INLINE (line 182) | CORK_INLINE
  function CORK_INLINE (line 197) | CORK_INLINE
  function CORK_INLINE (line 213) | CORK_INLINE
  function CORK_INLINE (line 241) | CORK_INLINE
  function CORK_INLINE (line 270) | CORK_INLINE
  function CORK_INLINE (line 285) | CORK_INLINE

FILE: include/libcork/ds/array.h
  type cork_array_priv (line 23) | struct cork_array_priv
  type cork_raw_array (line 25) | struct cork_raw_array {
  type cork_raw_array (line 32) | struct cork_raw_array
  type cork_raw_array (line 35) | struct cork_raw_array
  type cork_raw_array (line 38) | struct cork_raw_array
  type cork_raw_array (line 42) | struct cork_raw_array
  type cork_raw_array (line 45) | struct cork_raw_array
  type cork_raw_array (line 48) | struct cork_raw_array
  type cork_raw_array (line 51) | struct cork_raw_array
  type cork_raw_array (line 54) | struct cork_raw_array
  type cork_raw_array (line 57) | struct cork_raw_array
  type cork_raw_array (line 60) | struct cork_raw_array
  type cork_raw_array (line 63) | struct cork_raw_array
  type cork_raw_array (line 66) | struct cork_raw_array
  type cork_raw_array (line 69) | struct cork_raw_array
  type cork_raw_array (line 72) | struct cork_raw_array
  type cork_raw_array (line 75) | struct cork_raw_array
  type cork_raw_array (line 78) | struct cork_raw_array
  function CORK_INLINE (line 81) | CORK_INLINE
  type cork_raw_array (line 89) | struct cork_raw_array
  type cork_raw_array (line 90) | struct cork_raw_array
  type cork_raw_array (line 155) | struct cork_raw_array
  type cork_string_array (line 160) | struct cork_string_array {
  type cork_string_array (line 167) | struct cork_string_array
  type cork_string_array (line 170) | struct cork_string_array
  type cork_string_array (line 173) | struct cork_string_array
  type cork_string_array (line 174) | struct cork_string_array

FILE: include/libcork/ds/bitset.h
  type cork_bitset (line 22) | struct cork_bitset {
  type cork_bitset (line 32) | struct cork_bitset
  type cork_bitset (line 35) | struct cork_bitset
  type cork_bitset (line 38) | struct cork_bitset
  type cork_bitset (line 41) | struct cork_bitset

FILE: include/libcork/ds/buffer.h
  type cork_buffer (line 22) | struct cork_buffer {
  function CORK_INLINE (line 32) | CORK_INLINE
  type cork_buffer (line 47) | struct cork_buffer
  type cork_buffer (line 50) | struct cork_buffer
  type cork_buffer (line 54) | struct cork_buffer
  type cork_buffer (line 55) | struct cork_buffer
  type cork_buffer (line 60) | struct cork_buffer
  function CORK_INLINE (line 62) | CORK_INLINE
  function CORK_INLINE (line 72) | CORK_INLINE
  function CORK_INLINE (line 82) | CORK_INLINE
  function CORK_INLINE (line 102) | CORK_INLINE
  function CORK_INLINE (line 112) | CORK_INLINE
  function CORK_INLINE (line 119) | CORK_INLINE
  function CORK_INLINE (line 129) | CORK_INLINE
  function CORK_INLINE (line 137) | CORK_INLINE
  function CORK_INLINE (line 144) | CORK_INLINE
  type cork_buffer (line 159) | struct cork_buffer
  type cork_buffer (line 163) | struct cork_buffer
  type cork_buffer (line 167) | struct cork_buffer
  type cork_buffer (line 172) | struct cork_buffer
  type cork_buffer (line 182) | struct cork_buffer
  type cork_buffer (line 185) | struct cork_buffer
  type cork_buffer (line 189) | struct cork_buffer
  type cork_buffer (line 193) | struct cork_buffer
  type cork_buffer (line 197) | struct cork_buffer
  type cork_buffer (line 209) | struct cork_buffer
  type cork_buffer (line 212) | struct cork_buffer
  type cork_slice (line 212) | struct cork_slice
  type cork_buffer (line 222) | struct cork_buffer

FILE: include/libcork/ds/dllist.h
  type cork_dllist_item (line 17) | struct cork_dllist_item {
  type cork_dllist (line 25) | struct cork_dllist {
  type cork_dllist_item (line 42) | struct cork_dllist_item
  type cork_dllist (line 45) | struct cork_dllist
  type cork_dllist_item (line 50) | struct cork_dllist_item
  type cork_dllist (line 53) | struct cork_dllist
  type cork_dllist (line 71) | struct cork_dllist

FILE: include/libcork/ds/hash-table.h
  type cork_hash_table_entry (line 25) | struct cork_hash_table_entry {
  type cork_hash_table (line 32) | struct cork_hash_table
  type cork_hash_table (line 38) | struct cork_hash_table
  type cork_hash_table (line 42) | struct cork_hash_table
  type cork_hash_table (line 46) | struct cork_hash_table
  type cork_hash_table (line 49) | struct cork_hash_table
  type cork_hash_table (line 52) | struct cork_hash_table
  type cork_hash_table (line 55) | struct cork_hash_table
  type cork_hash_table (line 59) | struct cork_hash_table
  type cork_hash_table (line 63) | struct cork_hash_table
  type cork_hash_table (line 67) | struct cork_hash_table
  type cork_hash_table (line 71) | struct cork_hash_table
  type cork_hash_table (line 74) | struct cork_hash_table
  type cork_hash_table (line 78) | struct cork_hash_table
  type cork_hash_table (line 82) | struct cork_hash_table
  type cork_hash_table (line 86) | struct cork_hash_table
  type cork_hash_table (line 90) | struct cork_hash_table
  type cork_hash_table (line 94) | struct cork_hash_table
  type cork_hash_table (line 99) | struct cork_hash_table
  type cork_hash_table (line 104) | struct cork_hash_table
  type cork_hash_table_entry (line 105) | struct cork_hash_table_entry
  type cork_hash_table (line 108) | struct cork_hash_table
  type cork_hash_table (line 112) | struct cork_hash_table
  type cork_hash_table_map_result (line 117) | enum cork_hash_table_map_result {
  type cork_hash_table_map_result (line 127) | enum cork_hash_table_map_result
  type cork_hash_table_entry (line 128) | struct cork_hash_table_entry
  type cork_hash_table (line 131) | struct cork_hash_table
  type cork_hash_table_iterator (line 135) | struct cork_hash_table_iterator {
  type cork_hash_table (line 141) | struct cork_hash_table
  type cork_hash_table_iterator (line 142) | struct cork_hash_table_iterator
  type cork_hash_table_iterator (line 145) | struct cork_hash_table_iterator

FILE: include/libcork/ds/managed-buffer.h
  type cork_managed_buffer (line 22) | struct cork_managed_buffer
  type cork_managed_buffer_iface (line 24) | struct cork_managed_buffer_iface {
  type cork_managed_buffer (line 32) | struct cork_managed_buffer {
  type cork_managed_buffer (line 58) | struct cork_managed_buffer
  type cork_managed_buffer (line 61) | struct cork_managed_buffer
  type cork_slice (line 65) | struct cork_slice
  type cork_managed_buffer (line 66) | struct cork_managed_buffer
  type cork_slice (line 70) | struct cork_slice
  type cork_managed_buffer (line 71) | struct cork_managed_buffer

FILE: include/libcork/ds/ring-buffer.h
  type cork_ring_buffer (line 17) | struct cork_ring_buffer {
  type cork_ring_buffer (line 33) | struct cork_ring_buffer
  type cork_ring_buffer (line 39) | struct cork_ring_buffer
  type cork_ring_buffer (line 42) | struct cork_ring_buffer
  type cork_ring_buffer (line 50) | struct cork_ring_buffer
  type cork_ring_buffer (line 53) | struct cork_ring_buffer
  type cork_ring_buffer (line 56) | struct cork_ring_buffer

FILE: include/libcork/ds/slice.h
  type cork_slice_error (line 25) | enum cork_slice_error {
  type cork_slice (line 35) | struct cork_slice
  type cork_slice_iface (line 37) | struct cork_slice_iface {
  type cork_slice (line 67) | struct cork_slice {
  type cork_slice (line 81) | struct cork_slice
  function CORK_INLINE (line 83) | CORK_INLINE
  type cork_slice (line 92) | struct cork_slice
  type cork_slice (line 92) | struct cork_slice
  function CORK_INLINE (line 95) | CORK_INLINE
  type cork_slice (line 104) | struct cork_slice
  type cork_slice (line 104) | struct cork_slice
  function CORK_INLINE (line 107) | CORK_INLINE
  type cork_slice (line 117) | struct cork_slice
  type cork_slice (line 117) | struct cork_slice
  function CORK_INLINE (line 120) | CORK_INLINE
  type cork_slice (line 130) | struct cork_slice
  type cork_slice (line 131) | struct cork_slice
  function CORK_INLINE (line 133) | CORK_INLINE
  type cork_slice (line 144) | struct cork_slice
  function CORK_INLINE (line 146) | CORK_INLINE
  type cork_slice (line 160) | struct cork_slice
  function CORK_INLINE (line 162) | CORK_INLINE
  type cork_slice (line 176) | struct cork_slice
  function CORK_INLINE (line 178) | CORK_INLINE
  type cork_slice (line 199) | struct cork_slice
  type cork_slice (line 202) | struct cork_slice
  type cork_slice (line 203) | struct cork_slice
  type cork_slice (line 206) | struct cork_slice
  type cork_slice (line 209) | struct cork_slice

FILE: include/libcork/ds/stream.h
  type cork_stream_consumer (line 20) | struct cork_stream_consumer {
  function CORK_INLINE (line 33) | CORK_INLINE
  function CORK_INLINE (line 41) | CORK_INLINE
  function CORK_INLINE (line 48) | CORK_INLINE
  type cork_stream_consumer (line 57) | struct cork_stream_consumer
  type cork_stream_consumer (line 60) | struct cork_stream_consumer
  type cork_stream_consumer (line 63) | struct cork_stream_consumer

FILE: include/libcork/os/files.h
  type cork_path (line 21) | struct cork_path
  type cork_path (line 28) | struct cork_path
  type cork_path (line 31) | struct cork_path
  type cork_path (line 35) | struct cork_path
  type cork_path (line 38) | struct cork_path
  type cork_path (line 42) | struct cork_path
  type cork_path (line 49) | struct cork_path
  type cork_path (line 52) | struct cork_path
  type cork_path (line 56) | struct cork_path
  type cork_path (line 59) | struct cork_path
  type cork_path (line 59) | struct cork_path
  type cork_path (line 62) | struct cork_path
  type cork_path (line 65) | struct cork_path
  type cork_path (line 66) | struct cork_path
  type cork_path (line 70) | struct cork_path
  type cork_path (line 73) | struct cork_path
  type cork_path (line 77) | struct cork_path
  type cork_path (line 80) | struct cork_path
  type cork_path_list (line 87) | struct cork_path_list
  type cork_path_list (line 97) | struct cork_path_list
  type cork_path_list (line 100) | struct cork_path_list
  type cork_path_list (line 104) | struct cork_path_list
  type cork_path (line 104) | struct cork_path
  type cork_path_list (line 107) | struct cork_path_list
  type cork_path_list (line 111) | struct cork_path_list
  type cork_file_mode (line 121) | typedef unsigned int  cork_file_mode;
  type cork_file_type (line 123) | enum cork_file_type {
  type cork_file (line 131) | struct cork_file
  type cork_path (line 138) | struct cork_path
  type cork_file (line 141) | struct cork_file
  type cork_file (line 145) | struct cork_file
  type cork_file (line 148) | struct cork_file
  type cork_file (line 151) | struct cork_file
  type cork_file_type (line 151) | enum cork_file_type
  type cork_file (line 155) | struct cork_file
  type cork_file (line 159) | struct cork_file
  type cork_file (line 167) | struct cork_file
  type cork_file (line 174) | struct cork_file
  type cork_path_list (line 178) | struct cork_path_list
  type cork_file_list (line 186) | struct cork_file_list
  type cork_path_list (line 192) | struct cork_path_list
  type cork_file_list (line 195) | struct cork_file_list
  type cork_file_list (line 199) | struct cork_file_list
  type cork_file (line 199) | struct cork_file
  type cork_file_list (line 202) | struct cork_file_list
  type cork_file_list (line 207) | struct cork_file_list
  type cork_path_list (line 211) | struct cork_path_list
  type cork_dir_walker (line 221) | struct cork_dir_walker {
  type cork_dir_walker (line 246) | struct cork_dir_walker

FILE: include/libcork/os/subprocess.h
  type cork_env (line 26) | struct cork_env
  type cork_env (line 35) | struct cork_env
  type cork_env (line 39) | struct cork_env
  type cork_env (line 47) | struct cork_env
  type cork_env (line 50) | struct cork_env
  type cork_env (line 53) | struct cork_env
  type cork_env (line 58) | struct cork_env
  type cork_env (line 63) | struct cork_env
  type cork_exec (line 70) | struct cork_exec
  type cork_exec (line 76) | struct cork_exec
  type cork_exec (line 83) | struct cork_exec
  type cork_exec (line 86) | struct cork_exec
  type cork_exec (line 89) | struct cork_exec
  type cork_exec (line 92) | struct cork_exec
  type cork_exec (line 95) | struct cork_exec
  type cork_exec (line 98) | struct cork_exec
  type cork_exec (line 102) | struct cork_exec
  type cork_exec (line 106) | struct cork_exec
  type cork_env (line 106) | struct cork_env
  type cork_exec (line 110) | struct cork_exec
  type cork_exec (line 113) | struct cork_exec
  type cork_exec (line 116) | struct cork_exec
  type cork_subprocess (line 123) | struct cork_subprocess
  type cork_stream_consumer (line 131) | struct cork_stream_consumer
  type cork_stream_consumer (line 132) | struct cork_stream_consumer
  type cork_exec (line 137) | struct cork_exec
  type cork_stream_consumer (line 138) | struct cork_stream_consumer
  type cork_stream_consumer (line 139) | struct cork_stream_consumer
  type cork_subprocess (line 143) | struct cork_subprocess
  type cork_subprocess (line 146) | struct cork_subprocess
  type cork_subprocess (line 149) | struct cork_subprocess
  type cork_subprocess (line 152) | struct cork_subprocess
  type cork_subprocess (line 155) | struct cork_subprocess
  type cork_subprocess (line 158) | struct cork_subprocess
  type cork_subprocess (line 161) | struct cork_subprocess
  type cork_subprocess_group (line 168) | struct cork_subprocess_group
  type cork_subprocess_group (line 174) | struct cork_subprocess_group
  type cork_subprocess_group (line 178) | struct cork_subprocess_group
  type cork_subprocess (line 179) | struct cork_subprocess
  type cork_subprocess_group (line 182) | struct cork_subprocess_group
  type cork_subprocess_group (line 185) | struct cork_subprocess_group
  type cork_subprocess_group (line 188) | struct cork_subprocess_group
  type cork_subprocess_group (line 191) | struct cork_subprocess_group
  type cork_subprocess_group (line 194) | struct cork_subprocess_group

FILE: include/libcork/threads/basics.h
  type cork_thread_id (line 25) | typedef unsigned int  cork_thread_id;
  type cork_thread (line 39) | struct cork_thread
  type cork_thread (line 53) | struct cork_thread
  type cork_thread (line 56) | struct cork_thread
  type cork_thread (line 59) | struct cork_thread
  type cork_thread (line 64) | struct cork_thread
  type cork_thread (line 68) | struct cork_thread

FILE: src/cork-hash/cork-hash.c
  type cork_hash_type (line 17) | enum cork_hash_type {
  type cork_hash_type (line 23) | enum cork_hash_type
  type option (line 28) | struct option
  function usage (line 36) | static void
  function print_version (line 48) | static void
  function parse_options (line 60) | static void
  function main (line 92) | int

FILE: src/cork-initializer/init1.c
  function CORK_INITIALIZER (line 14) | CORK_INITIALIZER(init)
  function CORK_FINALIZER (line 19) | CORK_FINALIZER(done)

FILE: src/cork-initializer/init2.c
  function CORK_INITIALIZER (line 14) | CORK_INITIALIZER(init)

FILE: src/cork-initializer/main.c
  function main (line 10) | int

FILE: src/cork-test/cork-test.c
  type cork_command (line 59) | struct cork_command
  function c1_s1_options (line 64) | static int
  function c1_s1_run (line 75) | static void
  function c1_s2_run (line 91) | static void
  type cork_command (line 109) | struct cork_command
  type cork_command (line 120) | struct cork_command
  type cork_command (line 124) | struct cork_command
  function c1_options (line 128) | static int
  function c2_run (line 151) | static void
  type cork_command (line 158) | struct cork_command
  type cork_command (line 177) | struct cork_command
  function sub_options (line 182) | static int
  function sub_run (line 210) | static void
  type cork_command (line 267) | struct cork_command
  function pwd_run (line 273) | static void
  type cork_command (line 298) | struct cork_command
  function mkdir_options (line 304) | static int
  function mkdir_run (line 324) | static void
  type cork_command (line 358) | struct cork_command
  function rm_options (line 364) | static int
  function rm_run (line 384) | static void
  type cork_command (line 418) | struct cork_command
  function find_options (line 424) | static int
  function find_run (line 434) | static void
  type cork_command (line 484) | struct cork_command
  function print_path (line 490) | static void
  function print_path_list (line 498) | static void
  function paths_run (line 506) | static void
  function dir_options (line 526) | static int
  function print_indent (line 552) | static void
  function enter_directory (line 561) | static int
  function print_file (line 578) | static int
  function leave_directory (line 591) | static int
  type cork_dir_walker (line 603) | struct cork_dir_walker
  function dir_run (line 609) | static void
  type cork_command (line 616) | struct cork_command
  function cleanup_run (line 641) | static void
  type cork_command (line 652) | struct cork_command
  type cork_command (line 664) | struct cork_command
  type cork_command (line 677) | struct cork_command
  function main (line 685) | int

FILE: src/libcork/cli/commands.c
  type cork_buffer (line 21) | struct cork_buffer
  function cork_command_add_breadcrumb (line 23) | static void
  type cork_command (line 32) | struct cork_command
  type cork_command (line 34) | struct cork_command
  type cork_command (line 35) | struct cork_command
  type cork_command (line 38) | struct cork_command
  function cork_command_set_show_help (line 47) | static void
  function cork_command_leaf_show_help (line 76) | static void
  function cork_command_show_help (line 90) | void
  function cork_command_set_run_help (line 104) | static void
  function cork_command_set_run (line 134) | static void
  function cork_command_leaf_run (line 166) | static void
  function cork_command_cleanup (line 172) | static void
  function cork_command_run (line 178) | static void
  function cork_command_main (line 215) | int

FILE: src/libcork/core/allocator.c
  type cork_alloc_priv (line 26) | struct cork_alloc_priv {
  type cork_alloc (line 32) | struct cork_alloc
  type cork_alloc (line 43) | struct cork_alloc
  type cork_alloc (line 53) | struct cork_alloc
  type cork_alloc (line 64) | struct cork_alloc
  type cork_alloc (line 77) | struct cork_alloc
  type cork_alloc (line 83) | struct cork_alloc
  function cork_alloc__default_free (line 95) | static void
  type cork_alloc_priv (line 102) | struct cork_alloc_priv
  function cork_alloc_free_alloc (line 104) | static void
  function cork_alloc_free_all (line 111) | static void
  function cork_alloc_register_cleanup (line 122) | static void
  type cork_alloc (line 136) | struct cork_alloc
  type cork_alloc (line 137) | struct cork_alloc
  type cork_alloc_priv (line 139) | struct cork_alloc_priv
  function cork_alloc_set_user_data (line 160) | void
  function cork_alloc_set_calloc (line 169) | void
  function cork_alloc_set_malloc (line 175) | void
  function cork_alloc_set_realloc (line 181) | void
  function cork_alloc_set_xcalloc (line 187) | void
  function cork_alloc_set_xmalloc (line 193) | void
  function cork_alloc_set_xrealloc (line 199) | void
  function cork_alloc_set_free (line 206) | void
  type cork_alloc (line 218) | struct cork_alloc
  type cork_alloc (line 232) | struct cork_alloc
  type cork_alloc (line 238) | struct cork_alloc
  type cork_alloc (line 245) | struct cork_alloc
  type cork_alloc (line 263) | struct cork_alloc
  type cork_alloc (line 269) | struct cork_alloc
  function cork_alloc_strfree (line 275) | void
  type cork_alloc (line 290) | struct cork_alloc
  type cork_alloc (line 301) | struct cork_alloc
  type cork_alloc (line 311) | struct cork_alloc
  type cork_alloc (line 335) | struct cork_alloc
  type cork_alloc (line 342) | struct cork_alloc
  type cork_alloc (line 348) | struct cork_alloc
  function cork_stdlib_alloc__free (line 354) | static void
  type cork_alloc (line 361) | struct cork_alloc
  type cork_alloc (line 379) | struct cork_alloc
  function cork_set_allocator (line 381) | void
  type cork_alloc (line 393) | struct cork_alloc
  function cork_debug_alloc__free (line 401) | static void
  type cork_alloc (line 416) | struct cork_alloc
  type cork_alloc (line 417) | struct cork_alloc
  type cork_alloc (line 419) | struct cork_alloc
  type cork_alloc (line 430) | struct cork_alloc
  type cork_alloc (line 433) | struct cork_alloc
  type cork_alloc (line 436) | struct cork_alloc
  type cork_alloc (line 440) | struct cork_alloc
  type cork_alloc (line 443) | struct cork_alloc
  type cork_alloc (line 446) | struct cork_alloc
  type cork_alloc (line 450) | struct cork_alloc
  type cork_alloc (line 454) | struct cork_alloc
  type cork_alloc (line 457) | struct cork_alloc

FILE: src/libcork/core/error.c
  type cork_error (line 27) | struct cork_error {
  type cork_error (line 36) | struct cork_error
  type cork_error (line 39) | struct cork_error
  function cork_error_free (line 48) | static void
  type cork_error (line 57) | struct cork_error
  function cork_error_list_done (line 61) | static void
  function cork_error_list_init (line 72) | static void
  type cork_error (line 79) | struct cork_error
  type cork_error (line 81) | struct cork_error
  type cork_error (line 84) | struct cork_error
  type cork_error (line 86) | struct cork_error
  type cork_error (line 87) | struct cork_error
  function cork_error_occurred (line 105) | bool
  function cork_error (line 112) | cork_error
  type cork_error (line 122) | struct cork_error
  function cork_error_clear (line 126) | void
  function cork_error_set_printf (line 134) | void
  function cork_error_set_string (line 145) | void
  function cork_error_set_vprintf (line 153) | void
  function cork_error_prefix_printf (line 161) | void
  function cork_error_prefix_string (line 176) | void
  function cork_error_prefix_vprintf (line 188) | void
  function cork_error_set (line 205) | void
  function cork_error_prefix (line 216) | void
  function cork_system_error_set_explicit (line 230) | void
  function cork_system_error_set (line 236) | void
  function cork_unknown_error_set_ (line 242) | void

FILE: src/libcork/core/gc.c
  type cork_gc_header (line 39) | struct cork_gc_header
  type cork_gc (line 42) | struct cork_gc {
  type cork_gc (line 49) | struct cork_gc
  type cork_gc (line 52) | struct cork_gc
  type cork_gc_header (line 59) | struct cork_gc_header {
  type cork_gc_color (line 133) | enum cork_gc_color {
  function cork_gc_init (line 151) | void
  function cork_gc_done (line 157) | void
  type cork_gc_obj_iface (line 164) | struct cork_gc_obj_iface
  type cork_gc_header (line 166) | struct cork_gc_header
  type cork_gc_header (line 168) | struct cork_gc_header
  type cork_gc_header (line 180) | struct cork_gc_header
  type cork_gc (line 190) | struct cork_gc
  function cork_gc_release (line 192) | static void
  function cork_gc_possible_root (line 202) | static void
  function cork_gc_decref_step (line 220) | static void
  function cork_gc_decref (line 237) | void
  type cork_gc (line 257) | struct cork_gc
  function cork_gc_mark_gray (line 259) | static void
  function cork_gc_mark_gray_step (line 269) | static void
  function cork_gc_mark_roots (line 281) | static void
  type cork_gc (line 308) | struct cork_gc
  function cork_gc_scan_black (line 310) | static void
  function cork_gc_scan_black_step (line 319) | static void
  function cork_gc_scan (line 333) | static void
  function cork_gc_scan_roots (line 354) | static void
  function cork_gc_collect_white (line 366) | static void
  function cork_gc_collect_roots (line 382) | static void
  function cork_gc_collect_cycles (line 399) | static void

FILE: src/libcork/core/ip-address.c
  type cork_ipv4 (line 40) | struct cork_ipv4
  function cork_ipv4_init (line 105) | int
  function cork_ipv4_equal_ (line 111) | bool
  function cork_ipv4_to_raw_string (line 117) | void
  function cork_ipv4_is_valid_network (line 124) | bool
  function cork_ipv6_init (line 144) | int
  function cork_ipv6_equal_ (line 342) | bool
  function cork_ipv6_to_raw_string (line 351) | void
  function cork_ipv6_is_valid_network (line 432) | bool
  function cork_ip_from_ipv4_ (line 462) | void
  function cork_ip_from_ipv6_ (line 468) | void
  function cork_ip_init (line 474) | int
  function cork_ip_equal_ (line 501) | bool
  function cork_ip_to_raw_string (line 507) | void
  function cork_ip_is_valid_network (line 525) | bool
  type cork_ipv4 (line 543) | struct cork_ipv4
  type cork_ipv4 (line 546) | struct cork_ipv4
  type cork_ipv4 (line 546) | struct cork_ipv4
  type cork_ipv6 (line 549) | struct cork_ipv6
  type cork_ipv6 (line 552) | struct cork_ipv6
  type cork_ipv6 (line 552) | struct cork_ipv6
  type cork_ip (line 555) | struct cork_ip
  type cork_ip (line 555) | struct cork_ip
  type cork_ip (line 558) | struct cork_ip
  type cork_ip (line 561) | struct cork_ip

FILE: src/libcork/core/mempool.c
  type cork_mempool (line 32) | struct cork_mempool {
  type cork_mempool_object (line 47) | struct cork_mempool_object {
  type cork_mempool_block (line 53) | struct cork_mempool_block {
  type cork_mempool (line 67) | struct cork_mempool
  type cork_mempool (line 70) | struct cork_mempool
  function cork_mempool_free (line 83) | void
  function cork_mempool_set_user_data (line 110) | void
  function cork_mempool_set_init_object (line 119) | void
  function cork_mempool_set_done_object (line 125) | void
  function cork_mempool_set_callbacks (line 131) | void
  function cork_mempool_new_block (line 145) | static void
  type cork_mempool (line 174) | struct cork_mempool
  type cork_mempool_object (line 176) | struct cork_mempool_object
  function cork_mempool_free_object (line 190) | void
  type cork_mempool (line 204) | struct cork_mempool

FILE: src/libcork/core/timestamp.c
  function cork_timestamp_init_now (line 18) | void
  function power_of_10 (line 29) | static uint64_t
  function append_fractional (line 45) | static int
  function cork_timestamp_format_parts (line 62) | static int
  function cork_timestamp_format_utc (line 142) | int
  function cork_timestamp_format_local (line 153) | int

FILE: src/libcork/ds/array.c
  type cork_array_priv (line 38) | struct cork_array_priv {
  function cork_raw_array_init (line 51) | void
  function cork_raw_array_done (line 69) | void
  function cork_raw_array_set_callback_data (line 87) | void
  function cork_raw_array_set_init (line 95) | void
  function cork_raw_array_set_done (line 101) | void
  function cork_raw_array_set_reuse (line 107) | void
  function cork_raw_array_set_remove (line 113) | void
  function cork_raw_array_element_size (line 119) | size_t
  function cork_raw_array_clear (line 125) | void
  type cork_raw_array (line 140) | struct cork_raw_array
  type cork_raw_array (line 146) | struct cork_raw_array
  function cork_raw_array_size (line 151) | size_t
  function cork_raw_array_is_empty (line 157) | bool
  function cork_raw_array_ensure_size (line 163) | void
  type cork_raw_array (line 191) | struct cork_raw_array
  type cork_raw_array (line 224) | struct cork_raw_array
  function cork_raw_array_remove_range (line 226) | void
  function cork_raw_array_copy (line 264) | int
  type cork_pointer_array (line 331) | struct cork_pointer_array {
  function pointer__init (line 335) | static void
  function pointer__done (line 342) | static void
  function pointer__remove (line 352) | static void
  function pointer__free (line 363) | static void
  function cork_raw_pointer_array_init (line 370) | void
  function cork_string_array_init (line 387) | void
  function cork_string_array_append (line 394) | void
  function string__copy (line 401) | static int
  function cork_string_array_copy (line 410) | void

FILE: src/libcork/ds/bitset.c
  function bytes_needed (line 18) | static size_t
  function cork_bitset_init (line 28) | void
  type cork_bitset (line 37) | struct cork_bitset
  type cork_bitset (line 40) | struct cork_bitset
  function cork_bitset_done (line 45) | void
  function cork_bitset_free (line 51) | void
  function cork_bitset_clear (line 58) | void

FILE: src/libcork/ds/buffer.c
  type cork_buffer (line 23) | struct cork_buffer
  type cork_buffer (line 26) | struct cork_buffer
  type cork_buffer (line 29) | struct cork_buffer
  function cork_buffer_done (line 35) | void
  function cork_buffer_free (line 47) | void
  function cork_buffer_equal (line 55) | bool
  function cork_buffer_ensure_size_ (line 71) | void
  type cork_buffer (line 87) | struct cork_buffer
  type cork_buffer (line 91) | struct cork_buffer
  type cork_buffer (line 94) | struct cork_buffer
  type cork_buffer (line 97) | struct cork_buffer
  type cork_buffer (line 100) | struct cork_buffer
  type cork_buffer (line 103) | struct cork_buffer
  type cork_buffer (line 106) | struct cork_buffer
  function cork_buffer_append_vprintf (line 109) | void
  function cork_buffer_vprintf (line 137) | void
  function cork_buffer_append_printf (line 146) | void
  function cork_buffer_printf (line 156) | void
  function cork_buffer_append_indent (line 166) | void
  function cork_buffer_append_c_string (line 192) | void
  function cork_buffer_append_hex_dump (line 235) | void
  function cork_buffer_append_multiline (line 278) | void
  function cork_buffer_append_binary (line 294) | void
  type cork_buffer__managed_buffer (line 326) | struct cork_buffer__managed_buffer {
  function cork_buffer__managed_free (line 331) | static void
  type cork_managed_buffer_iface (line 340) | struct cork_managed_buffer_iface
  type cork_managed_buffer (line 344) | struct cork_managed_buffer
  type cork_buffer (line 345) | struct cork_buffer
  type cork_buffer__managed_buffer (line 347) | struct cork_buffer__managed_buffer
  function cork_buffer_to_slice (line 358) | int
  type cork_buffer__stream_consumer (line 377) | struct cork_buffer__stream_consumer {
  function cork_buffer_stream_consumer_data (line 382) | static int
  function cork_buffer_stream_consumer_eof (line 393) | static int
  function cork_buffer_stream_consumer_free (line 399) | static void
  type cork_stream_consumer (line 408) | struct cork_stream_consumer
  type cork_buffer (line 409) | struct cork_buffer
  type cork_buffer__stream_consumer (line 411) | struct cork_buffer__stream_consumer

FILE: src/libcork/ds/dllist.c
  function CORK_API (line 18) | CORK_API void
  function cork_dllist_map (line 26) | void
  function cork_dllist_visit (line 37) | int
  function cork_dllist_size (line 53) | size_t

FILE: src/libcork/ds/file-stream.c
  function cork_consume_fd (line 27) | int
  function cork_consume_file (line 50) | int
  function cork_consume_file_from_path (line 73) | int
  type cork_file_consumer (line 93) | struct cork_file_consumer {
  function cork_file_consumer__data (line 98) | static int
  function cork_file_consumer__eof (line 115) | static int
  function cork_file_consumer__free (line 123) | static void
  type cork_stream_consumer (line 131) | struct cork_stream_consumer
  type cork_file_consumer (line 134) | struct cork_file_consumer
  type cork_fd_consumer (line 143) | struct cork_fd_consumer {
  function cork_fd_consumer__data (line 148) | static int
  function cork_fd_consumer__eof_close (line 170) | static int
  function cork_fd_consumer__free (line 180) | static void
  type cork_stream_consumer (line 188) | struct cork_stream_consumer
  type cork_fd_consumer (line 191) | struct cork_fd_consumer
  type cork_stream_consumer (line 200) | struct cork_stream_consumer
  type cork_fd_consumer (line 205) | struct cork_fd_consumer

FILE: src/libcork/ds/hash-table.c
  type cork_hash_table_entry_priv (line 40) | struct cork_hash_table_entry_priv {
  type cork_hash_table (line 46) | struct cork_hash_table {
  function cork_hash (line 60) | static cork_hash
  function cork_hash_table__default_equals (line 66) | static bool
  function cork_hash_table_new_size (line 83) | static inline size_t
  function cork_hash_table_allocate_bins (line 101) | static void
  type cork_hash_table_entry_priv (line 117) | struct cork_hash_table_entry_priv
  type cork_hash_table (line 118) | struct cork_hash_table
  type cork_hash_table_entry_priv (line 121) | struct cork_hash_table_entry_priv
  function cork_hash_table_free_entry (line 130) | static void
  type cork_hash_table (line 145) | struct cork_hash_table
  type cork_hash_table (line 148) | struct cork_hash_table
  function cork_hash_table_clear (line 164) | void
  function cork_hash_table_free (line 192) | void
  function cork_hash_table_size (line 200) | size_t
  function cork_hash_table_set_user_data (line 206) | void
  function cork_hash_table_set_hash (line 214) | void
  function cork_hash_table_set_equals (line 220) | void
  function cork_hash_table_set_free_key (line 226) | void
  function cork_hash_table_set_free_value (line 232) | void
  function cork_hash_table_ensure_size (line 239) | void
  function cork_hash_table_rehash (line 274) | static void
  type cork_hash_table_entry (line 282) | struct cork_hash_table_entry
  type cork_hash_table (line 283) | struct cork_hash_table
  type cork_dllist (line 287) | struct cork_dllist
  type cork_dllist_item (line 288) | struct cork_dllist_item
  type cork_hash_table_entry_priv (line 304) | struct cork_hash_table_entry_priv
  type cork_hash_table_entry (line 321) | struct cork_hash_table_entry
  type cork_hash_table (line 322) | struct cork_hash_table
  type cork_hash_table (line 329) | struct cork_hash_table
  type cork_hash_table_entry (line 332) | struct cork_hash_table_entry
  type cork_hash_table (line 343) | struct cork_hash_table
  type cork_hash_table_entry (line 345) | struct cork_hash_table_entry
  type cork_hash_table_entry (line 356) | struct cork_hash_table_entry
  type cork_hash_table (line 357) | struct cork_hash_table
  type cork_hash_table_entry_priv (line 360) | struct cork_hash_table_entry_priv
  type cork_dllist (line 364) | struct cork_dllist
  type cork_dllist_item (line 365) | struct cork_dllist_item
  type cork_hash_table_entry_priv (line 375) | struct cork_hash_table_entry_priv
  type cork_hash_table_entry (line 418) | struct cork_hash_table_entry
  type cork_hash_table (line 419) | struct cork_hash_table
  function cork_hash_table_put_hash (line 427) | void
  function cork_hash_table_put (line 508) | void
  function cork_hash_table_delete_entry (line 519) | void
  function cork_hash_table_delete_hash (line 531) | bool
  function cork_hash_table_delete (line 584) | bool
  function cork_hash_table_map (line 594) | void
  function cork_hash_table_iterator_init (line 627) | void
  type cork_hash_table_entry (line 637) | struct cork_hash_table_entry
  type cork_hash_table_iterator (line 638) | struct cork_hash_table_iterator
  type cork_hash_table (line 640) | struct cork_hash_table
  type cork_dllist_item (line 641) | struct cork_dllist_item
  type cork_hash_table_entry_priv (line 642) | struct cork_hash_table_entry_priv
  function cork_hash (line 660) | static cork_hash
  function string_equals (line 668) | static bool
  type cork_hash_table (line 676) | struct cork_hash_table
  type cork_hash_table (line 679) | struct cork_hash_table
  type cork_hash_table (line 685) | struct cork_hash_table

FILE: src/libcork/ds/managed-buffer.c
  function cork_slice_invalid_slice_set (line 24) | static void
  type cork_managed_buffer_wrapped (line 39) | struct cork_managed_buffer_wrapped {
  function cork_managed_buffer_wrapped__free (line 46) | static void
  type cork_managed_buffer_iface (line 55) | struct cork_managed_buffer_iface
  type cork_managed_buffer (line 59) | struct cork_managed_buffer
  type cork_managed_buffer_wrapped (line 68) | struct cork_managed_buffer_wrapped
  type cork_managed_buffer_copied (line 81) | struct cork_managed_buffer_copied {
  function cork_managed_buffer_copied__free (line 91) | static void
  type cork_managed_buffer_iface (line 101) | struct cork_managed_buffer_iface
  type cork_managed_buffer (line 105) | struct cork_managed_buffer
  type cork_managed_buffer_copied (line 109) | struct cork_managed_buffer_copied
  function cork_managed_buffer_free (line 123) | static void
  type cork_managed_buffer (line 134) | struct cork_managed_buffer
  type cork_managed_buffer (line 135) | struct cork_managed_buffer
  function cork_managed_buffer_unref (line 148) | void
  type cork_slice_iface (line 163) | struct cork_slice_iface
  function cork_managed_buffer__slice_free (line 165) | static void
  function cork_managed_buffer__slice_copy (line 172) | static int
  type cork_slice_iface (line 185) | struct cork_slice_iface
  function cork_managed_buffer_slice (line 193) | int
  function cork_managed_buffer_slice_offset (line 227) | int

FILE: src/libcork/ds/ring-buffer.c
  function cork_ring_buffer_init (line 17) | int
  type cork_ring_buffer (line 28) | struct cork_ring_buffer
  type cork_ring_buffer (line 31) | struct cork_ring_buffer
  function cork_ring_buffer_done (line 36) | void
  function cork_ring_buffer_free (line 42) | void
  function cork_ring_buffer_add (line 49) | int
  type cork_ring_buffer (line 65) | struct cork_ring_buffer
  type cork_ring_buffer (line 80) | struct cork_ring_buffer

FILE: src/libcork/ds/slice.c
  function cork_slice_invalid_slice_set (line 23) | static void
  function cork_slice_clear (line 38) | void
  function cork_slice_copy (line 48) | int
  function cork_slice_copy_offset (line 78) | int
  function cork_slice_light_copy (line 93) | int
  function cork_slice_light_copy_offset (line 123) | int
  function cork_slice_slice (line 138) | int
  function cork_slice_slice_offset (line 172) | int
  type cork_slice (line 186) | struct cork_slice
  function cork_slice_finish (line 199) | void
  function cork_slice_equal (line 214) | bool
  type cork_slice_iface (line 234) | struct cork_slice_iface
  function cork_static_slice_copy (line 236) | static int
  type cork_slice_iface (line 247) | struct cork_slice_iface
  function cork_slice_init_static (line 254) | void
  type cork_slice_iface (line 268) | struct cork_slice_iface
  function cork_copy_once_slice__copy (line 270) | static int
  function cork_copy_once_slice__light_copy (line 284) | static int
  type cork_slice_iface (line 296) | struct cork_slice_iface
  function cork_slice_init_copy_once (line 303) | void
  type cork_slice (line 317) | struct cork_slice
  type cork_slice (line 320) | struct cork_slice
  type cork_slice (line 320) | struct cork_slice
  type cork_slice (line 324) | struct cork_slice
  type cork_slice (line 325) | struct cork_slice
  type cork_slice (line 328) | struct cork_slice
  type cork_slice (line 329) | struct cork_slice
  type cork_slice (line 333) | struct cork_slice
  type cork_slice (line 334) | struct cork_slice
  type cork_slice (line 338) | struct cork_slice
  type cork_slice (line 341) | struct cork_slice
  type cork_slice (line 344) | struct cork_slice

FILE: src/libcork/ds/stream.c
  type cork_stream_consumer (line 17) | struct cork_stream_consumer
  type cork_stream_consumer (line 21) | struct cork_stream_consumer
  type cork_stream_consumer (line 24) | struct cork_stream_consumer

FILE: src/libcork/posix/directory-walker.c
  function cork_walk_one_directory (line 27) | static int
  function cork_walk_directory (line 103) | int

FILE: src/libcork/posix/env.c
  type cork_env_var (line 40) | struct cork_env_var {
  type cork_env_var (line 45) | struct cork_env_var
  type cork_env_var (line 48) | struct cork_env_var
  function cork_env_var_free (line 54) | static void
  type cork_env (line 64) | struct cork_env {
  type cork_env (line 69) | struct cork_env
  type cork_env (line 72) | struct cork_env
  function cork_env_add_internal (line 79) | static void
  type cork_env (line 97) | struct cork_env
  type cork_env (line 101) | struct cork_env
  function cork_env_free (line 123) | void
  type cork_env (line 132) | struct cork_env
  type cork_env_var (line 137) | struct cork_env_var
  function cork_env_add (line 143) | void
  function cork_env_add_vprintf (line 149) | void
  function cork_env_add_printf (line 157) | void
  function cork_env_remove (line 167) | void
  function cork_env_set_vars (line 182) | static enum cork_hash_table_map_result
  function clearenv (line 196) | static void
  function cork_env_replace_current (line 206) | void

FILE: src/libcork/posix/exec.c
  type cork_exec (line 36) | struct cork_exec {
  type cork_exec (line 44) | struct cork_exec
  type cork_exec (line 47) | struct cork_exec
  type cork_exec (line 57) | struct cork_exec
  type cork_exec (line 60) | struct cork_exec
  type cork_exec (line 73) | struct cork_exec
  type cork_exec (line 77) | struct cork_exec
  function cork_exec_free (line 84) | void
  type cork_exec (line 100) | struct cork_exec
  type cork_exec (line 106) | struct cork_exec
  function cork_exec_param_count (line 111) | size_t
  type cork_exec (line 118) | struct cork_exec
  function cork_exec_add_param (line 123) | void
  type cork_env (line 135) | struct cork_env
  type cork_exec (line 136) | struct cork_exec
  function cork_exec_set_env (line 141) | void
  type cork_exec (line 151) | struct cork_exec
  function cork_exec_set_cwd (line 156) | void
  function cork_exec_run (line 165) | int

FILE: src/libcork/posix/files.c
  type cork_path (line 49) | struct cork_path {
  type cork_path (line 53) | struct cork_path
  type cork_path (line 56) | struct cork_path
  type cork_path (line 67) | struct cork_path
  type cork_path (line 73) | struct cork_path
  type cork_path (line 74) | struct cork_path
  function cork_path_free (line 79) | void
  function cork_path_set (line 87) | void
  type cork_path (line 98) | struct cork_path
  function cork_path_set_cwd (line 109) | int
  type cork_path (line 125) | struct cork_path
  type cork_path (line 128) | struct cork_path
  function cork_path_set_absolute (line 138) | int
  type cork_path (line 173) | struct cork_path
  type cork_path (line 174) | struct cork_path
  type cork_path (line 176) | struct cork_path
  function cork_path_append (line 186) | void
  type cork_path (line 211) | struct cork_path
  type cork_path (line 212) | struct cork_path
  type cork_path (line 214) | struct cork_path
  function cork_path_append_path (line 219) | void
  type cork_path (line 225) | struct cork_path
  type cork_path (line 226) | struct cork_path
  type cork_path (line 226) | struct cork_path
  type cork_path (line 228) | struct cork_path
  function cork_path_set_basename (line 234) | void
  type cork_path (line 248) | struct cork_path
  type cork_path (line 249) | struct cork_path
  type cork_path (line 251) | struct cork_path
  function cork_path_set_dirname (line 257) | void
  type cork_path (line 275) | struct cork_path
  type cork_path (line 276) | struct cork_path
  type cork_path (line 278) | struct cork_path
  type cork_path_list (line 288) | struct cork_path_list {
  type cork_path_list (line 293) | struct cork_path_list
  type cork_path_list (line 296) | struct cork_path_list
  function cork_path_list_free (line 302) | void
  type cork_path_list (line 316) | struct cork_path_list
  function cork_path_list_add (line 321) | void
  function cork_path_list_size (line 331) | size_t
  type cork_path (line 337) | struct cork_path
  type cork_path_list (line 338) | struct cork_path_list
  function cork_path_list_append_string (line 343) | static void
  type cork_path_list (line 361) | struct cork_path_list
  type cork_path_list (line 364) | struct cork_path_list
  type cork_file (line 374) | struct cork_file {
  function cork_file_init (line 381) | static void
  type cork_file (line 388) | struct cork_file
  type cork_file (line 394) | struct cork_file
  type cork_path (line 395) | struct cork_path
  type cork_file (line 397) | struct cork_file
  function cork_file_reset (line 402) | static void
  function cork_file_done (line 408) | static void
  function cork_file_free (line 414) | void
  type cork_path (line 421) | struct cork_path
  type cork_file (line 422) | struct cork_file
  function cork_file_stat (line 427) | static int
  function cork_file_exists (line 462) | int
  function cork_file_type (line 470) | int
  type cork_file (line 479) | struct cork_file
  type cork_path_list (line 480) | struct cork_path_list
  type cork_file (line 485) | struct cork_file
  type cork_path (line 488) | struct cork_path
  type cork_path (line 489) | struct cork_path
  function cork_file_iterate_directory (line 515) | int
  function cork_file_mkdir_one (line 576) | static int
  function cork_file_mkdir (line 625) | int
  function cork_file_remove_iterator (line 632) | static int
  function cork_file_remove (line 640) | int
  type cork_file_list (line 674) | struct cork_file_list {
  type cork_file_list (line 678) | struct cork_file_list
  type cork_file_list (line 681) | struct cork_file_list
  function cork_file_list_free (line 686) | void
  function cork_file_list_add (line 698) | void
  function cork_file_list_size (line 704) | size_t
  type cork_file (line 710) | struct cork_file
  type cork_file_list (line 711) | struct cork_file_list
  type cork_file_list (line 716) | struct cork_file_list
  type cork_path_list (line 717) | struct cork_path_list
  type cork_file_list (line 719) | struct cork_file_list
  type cork_path (line 724) | struct cork_path
  type cork_file (line 725) | struct cork_file
  type cork_file_list (line 733) | struct cork_file_list
  type cork_path_list (line 734) | struct cork_path_list
  type cork_file_list (line 739) | struct cork_file_list
  type cork_file (line 740) | struct cork_file
  type cork_path (line 743) | struct cork_path
  type cork_path (line 744) | struct cork_path
  type cork_path (line 770) | struct cork_path
  type cork_path_list (line 783) | struct cork_path_list
  type cork_path_list (line 786) | struct cork_path_list
  type cork_path (line 788) | struct cork_path
  type cork_path_list (line 820) | struct cork_path_list
  type cork_path_list (line 823) | struct cork_path_list
  type cork_path (line 825) | struct cork_path
  type cork_path (line 859) | struct cork_path
  type cork_path (line 863) | struct cork_path
  type cork_path (line 877) | struct cork_path

FILE: src/libcork/posix/process.c
  type cork_cleanup_entry (line 30) | struct cork_cleanup_entry {
  type cork_cleanup_entry (line 37) | struct cork_cleanup_entry
  type cork_cleanup_entry (line 41) | struct cork_cleanup_entry
  function cork_cleanup_entry_free (line 48) | static void
  type cork_dllist (line 55) | struct cork_dllist
  function cork_cleanup_call_one (line 58) | static void
  function cork_cleanup_call_all (line 73) | static void
  function cork_cleanup_entry_add (line 79) | static void
  function CORK_API (line 108) | CORK_API void

FILE: src/libcork/posix/subprocess.c
  type cork_subprocess_group (line 44) | struct cork_subprocess_group {
  type cork_subprocess_group (line 48) | struct cork_subprocess_group
  type cork_subprocess_group (line 51) | struct cork_subprocess_group
  function cork_subprocess_group_free (line 58) | void
  function cork_subprocess_group_add (line 65) | void
  type cork_read_pipe (line 77) | struct cork_read_pipe {
  function cork_read_pipe_init (line 83) | static void
  function cork_read_pipe_close_read (line 91) | static int
  function cork_read_pipe_close_write (line 102) | static int
  function cork_read_pipe_close (line 113) | static void
  function cork_read_pipe_done (line 120) | static void
  function cork_read_pipe_open (line 126) | static int
  function cork_read_pipe_dup (line 150) | static int
  function cork_read_pipe_read (line 159) | static int
  function cork_read_pipe_is_finished (line 202) | static bool
  type cork_write_pipe (line 213) | struct cork_write_pipe {
  function cork_write_pipe_close_read (line 218) | static int
  function cork_write_pipe_close_write (line 229) | static int
  function cork_write_pipe__data (line 240) | static int
  function cork_write_pipe__eof (line 250) | static int
  function cork_write_pipe__free (line 258) | static void
  function cork_write_pipe_init (line 263) | static void
  function cork_write_pipe_close (line 273) | static void
  function cork_write_pipe_done (line 280) | static void
  function cork_write_pipe_open (line 286) | static int
  function cork_write_pipe_dup (line 295) | static int
  type cork_subprocess (line 309) | struct cork_subprocess {
  type cork_subprocess (line 321) | struct cork_subprocess
  type cork_stream_consumer (line 324) | struct cork_stream_consumer
  type cork_stream_consumer (line 325) | struct cork_stream_consumer
  type cork_subprocess (line 328) | struct cork_subprocess
  function cork_subprocess_free (line 340) | void
  type cork_stream_consumer (line 350) | struct cork_stream_consumer
  type cork_subprocess (line 351) | struct cork_subprocess
  function cork_exec__run (line 361) | static int
  function cork_exec__free (line 368) | static void
  type cork_subprocess (line 375) | struct cork_subprocess
  type cork_exec (line 376) | struct cork_exec
  type cork_stream_consumer (line 377) | struct cork_stream_consumer
  type cork_stream_consumer (line 378) | struct cork_stream_consumer
  function cork_subprocess_start (line 392) | int
  function cork_subprocess_reap (line 460) | static int
  function cork_subprocess_abort (line 476) | int
  function cork_subprocess_is_finished (line 489) | bool
  function cork_subprocess_yield (line 507) | static void
  function cork_subprocess_drain_ (line 537) | static int
  function cork_subprocess_drain (line 549) | bool
  function cork_subprocess_wait (line 557) | int
  function cork_subprocess_group_terminate (line 577) | static int
  function cork_subprocess_group_start (line 588) | int
  function cork_subprocess_group_abort (line 606) | int
  function cork_subprocess_group_is_finished (line 614) | bool
  function cork_subprocess_group_drain_ (line 628) | static int
  function cork_subprocess_group_drain (line 640) | bool
  function cork_subprocess_group_wait (line 648) | int

FILE: src/libcork/pthreads/thread.c
  type cork_thread (line 35) | struct cork_thread {
  type cork_thread_descriptor (line 48) | struct cork_thread_descriptor {
  type cork_thread_descriptor (line 53) | struct cork_thread_descriptor
  type cork_thread (line 55) | struct cork_thread
  type cork_thread_descriptor (line 58) | struct cork_thread_descriptor
  function cork_thread_id (line 62) | cork_thread_id
  type cork_thread (line 81) | struct cork_thread
  type cork_thread (line 86) | struct cork_thread
  function cork_thread_free_private (line 99) | static void
  function cork_thread_free (line 108) | void
  type cork_thread (line 116) | struct cork_thread
  function cork_thread_id (line 121) | cork_thread_id
  type cork_thread (line 133) | struct cork_thread
  type cork_thread_descriptor (line 134) | struct cork_thread_descriptor
  function cork_thread_start (line 167) | int
  function cork_thread_join (line 199) | int

FILE: tests/cram.py
  function findtests (line 23) | def findtests(paths):
  function regex (line 36) | def regex(pattern, s):
  function glob (line 47) | def glob(el, l):
  function match (line 74) | def match(el, l):
  class SequenceMatcher (line 82) | class SequenceMatcher(difflib.SequenceMatcher, object):
    method find_longest_match (line 85) | def find_longest_match(self, alo, ahi, blo, bhi):
  function unified_diff (line 106) | def unified_diff(a, b, fromfile='', tofile='', fromfiledate='',
  function escape (line 140) | def escape(s):
  function makeresetsigpipe (line 144) | def makeresetsigpipe():
  function test (line 155) | def test(path, shell, indent=2):
  function prompt (line 238) | def prompt(question, answers, auto=None):
  function log (line 265) | def log(msg=None, verbosemsg=None, verbose=False):
  function patch (line 276) | def patch(cmd, diff, path):
  function run (line 286) | def run(paths, tmpdir, shell, quiet=False, verbose=False, patchcmd=None,
  function which (line 362) | def which(cmd):
  function expandpath (line 370) | def expandpath(path):
  class OptionParser (line 374) | class OptionParser(optparse.OptionParser):
    method __init__ (line 378) | def __init__(self, *args, **kwargs):
    method add_option (line 382) | def add_option(self, *args, **kwargs):
    method parse_args (line 389) | def parse_args(self, args=None, values=None):
  function main (line 421) | def main(args):

FILE: tests/create-u128-test-cases.py
  function random_shift_count (line 20) | def random_shift_count():
  function random_128 (line 24) | def random_128():
  function dec_128 (line 31) | def dec_128(value):
  function hex_128 (line 34) | def hex_128(value):
  function output_one_cmp_test_case (line 39) | def output_one_cmp_test_case(op, op_str, lhs, rhs):
  function create_one_cmp_test_case (line 53) | def create_one_cmp_test_case(op, op_str):
  function create_one_shl_test_case (line 61) | def create_one_shl_test_case():
  function create_one_shr_test_case (line 77) | def create_one_shr_test_case():
  function create_one_add_test_case (line 93) | def create_one_add_test_case():
  function create_one_sub_test_case (line 109) | def create_one_sub_test_case():

FILE: tests/helpers.h
  function setup_allocator (line 26) | static void
  function setup_allocator (line 35) | static void

FILE: tests/test-array.c
  function START_TEST (line 128) | START_TEST(test_array_string)
  function END_TEST (line 170) | END_TEST
  function test_array__init (line 184) | static void
  function test_array__done (line 191) | static void
  function test_array__reuse (line 198) | static void
  function test_array__remove (line 205) | static void
  type test_array (line 212) | typedef cork_array(unsigned int)  test_array;
  function test_array_init (line 214) | static void
  function START_TEST (line 238) | START_TEST(test_array_callbacks)
  function END_TEST (line 300) | END_TEST
  function main (line 325) | int

FILE: tests/test-bitset.c
  function test_bitset_of_size (line 26) | static void
  function START_TEST (line 57) | START_TEST(test_bitset)
  function END_TEST (line 81) | END_TEST
  function main (line 102) | int

FILE: tests/test-buffer.c
  function check_buffers (line 28) | static void
  function check_buffer (line 36) | static void
  function START_TEST (line 45) | START_TEST(test_buffer)
  function END_TEST (line 85) | END_TEST
  function END_TEST (line 138) | END_TEST
  function END_TEST (line 184) | END_TEST
  function END_TEST (line 224) | END_TEST
  function START_TEST (line 240) | START_TEST(test_buffer_c_string)
  function END_TEST (line 248) | END_TEST
  function START_TEST (line 264) | START_TEST(test_buffer_pretty_print)
  function END_TEST (line 309) | END_TEST
  function main (line 334) | int
  type cork_buffer (line 354) | struct cork_buffer
  type cork_buffer (line 354) | struct cork_buffer
  type cork_buffer (line 357) | struct cork_buffer
  type cork_buffer (line 358) | struct cork_buffer

FILE: tests/test-core.c
  function START_TEST (line 36) | START_TEST(test_bool)
  function END_TEST (line 46) | END_TEST
  function END_TEST (line 76) | END_TEST
  function START_TEST (line 138) | START_TEST(test_string)
  function START_TEST (line 157) | START_TEST(test_endianness)
  function END_TEST (line 219) | END_TEST
  function END_TEST (line 241) | END_TEST
  function START_TEST (line 334) | START_TEST(test_hash)
  function START_TEST (line 475) | START_TEST(test_ipv4_address)
  function END_TEST (line 528) | END_TEST
  function END_TEST (line 584) | END_TEST
  function END_TEST (line 644) | END_TEST
  function test_timestamp_utc_format (line 659) | static void
  function test_timestamp_local_format (line 672) | static void
  function START_TEST (line 685) | START_TEST(test_timestamp)
  function END_TEST (line 771) | END_TEST
  function END_TEST (line 795) | END_TEST
  function END_TEST (line 809) | END_TEST
  function END_TEST (line 839) | END_TEST
  function main (line 897) | int

FILE: tests/test-dllist.c
  type int64_item (line 27) | struct int64_item {
  function int64_sum (line 32) | static int
  function check_int64_list (line 42) | static void
  function START_TEST (line 63) | START_TEST(test_dllist)
  function END_TEST (line 122) | END_TEST
  function END_TEST (line 162) | END_TEST
  function main (line 183) | int

FILE: tests/test-files.c
  function verify_path_content (line 31) | void
  function test_path (line 38) | void
  function START_TEST (line 63) | START_TEST(test_path_01)
  function END_TEST (line 70) | END_TEST
  function START_TEST (line 116) | START_TEST(test_path_join_01)
  function END_TEST (line 126) | END_TEST
  function END_TEST (line 136) | END_TEST
  function START_TEST (line 163) | START_TEST(test_path_basename_01)
  function END_TEST (line 179) | END_TEST
  function START_TEST (line 206) | START_TEST(test_path_dirname_01)
  function END_TEST (line 223) | END_TEST
  function START_TEST (line 243) | START_TEST(test_path_relative_child_01)
  function END_TEST (line 251) | END_TEST
  function START_TEST (line 285) | START_TEST(test_path_set_absolute_01)
  function END_TEST (line 297) | END_TEST
  function test_path_list (line 321) | void
  function START_TEST (line 334) | START_TEST(test_path_list_01)
  function END_TEST (line 342) | END_TEST
  function START_TEST (line 365) | START_TEST(test_file_exists_01)
  function END_TEST (line 371) | END_TEST
  function main (line 405) | int

FILE: tests/test-gc.c
  type tree (line 28) | struct tree {
  function _free_ (line 34) | _free_(tree) {
  function _recurse_ (line 38) | _recurse_(tree) {
  type tree (line 58) | struct tree
  type tree (line 59) | struct tree
  type tree (line 59) | struct tree
  type tree (line 61) | struct tree
  function START_TEST (line 68) | START_TEST(test_gc_acyclic_01)
  function END_TEST (line 83) | END_TEST
  function END_TEST (line 102) | END_TEST
  function END_TEST (line 123) | END_TEST
  function main (line 145) | int

FILE: tests/test-hash-table.c
  function uint64__free (line 28) | static void
  function uint64__equals (line 35) | static bool
  function cork_hash (line 47) | static cork_hash
  function uint64_sum (line 57) | static enum cork_hash_table_map_result
  function test_map_sum (line 66) | static void
  function test_iterator_sum (line 77) | static void
  function uint64_to_string (line 94) | static enum cork_hash_table_map_result
  function test_map_to_string (line 107) | static void
  function test_iterator_to_string (line 118) | static void
  function START_TEST (line 139) | START_TEST(test_uint64_hash_table)
  function END_TEST (line 266) | END_TEST
  function END_TEST (line 299) | END_TEST
  function END_TEST (line 331) | END_TEST
  function main (line 353) | int

FILE: tests/test-managed-buffer.c
  type flag_buffer (line 28) | struct flag_buffer {
  function set_flag_on_free (line 33) | static void
  type cork_managed_buffer_iface (line 42) | struct cork_managed_buffer_iface
  type cork_managed_buffer (line 46) | struct cork_managed_buffer
  type flag_buffer (line 49) | struct flag_buffer
  function START_TEST (line 64) | START_TEST(test_managed_buffer_refcount)
  function END_TEST (line 87) | END_TEST
  function END_TEST (line 117) | END_TEST
  function END_TEST (line 143) | END_TEST
  function END_TEST (line 182) | END_TEST
  function END_TEST (line 220) | END_TEST
  function END_TEST (line 254) | END_TEST
  function END_TEST (line 291) | END_TEST
  function main (line 326) | int

FILE: tests/test-mempool.c
  function START_TEST (line 28) | START_TEST(test_mempool_01)
  function END_TEST (line 58) | END_TEST
  function END_TEST (line 73) | END_TEST
  function int64_done (line 83) | static void
  function START_TEST (line 96) | START_TEST(test_mempool_reuse_01)
  function END_TEST (line 131) | END_TEST
  function main (line 158) | int

FILE: tests/test-ring-buffer.c
  function START_TEST (line 26) | START_TEST(test_ring_buffer_1)
  function END_TEST (line 69) | END_TEST
  function END_TEST (line 114) | END_TEST
  function main (line 135) | int

FILE: tests/test-slice.c
  function START_TEST (line 25) | START_TEST(test_static_slice)
  function END_TEST (line 51) | END_TEST
  function END_TEST (line 110) | END_TEST
  function main (line 131) | int

FILE: tests/test-subprocess.c
  type verify_consumer (line 30) | struct verify_consumer {
  function verify_consumer__data (line 37) | static int
  function verify_consumer__eof (line 50) | static int
  function verify_consumer__free (line 65) | static void
  type cork_stream_consumer (line 76) | struct cork_stream_consumer
  type verify_consumer (line 79) | struct verify_consumer
  type env (line 94) | struct env {
  type spec (line 99) | struct spec {
  type cork_env (line 111) | struct cork_env
  type env (line 112) | struct env
  type cork_env (line 114) | struct cork_env
  type env (line 115) | struct env
  function test_subprocesses_ (line 129) | static void
  type spec (line 176) | struct spec
  type spec (line 181) | struct spec
  type env (line 186) | struct env
  type spec (line 190) | struct spec
  type spec (line 195) | struct spec
  function START_TEST (line 200) | START_TEST(test_subprocess_01)
  function END_TEST (line 206) | END_TEST
  function END_TEST (line 215) | END_TEST
  function END_TEST (line 224) | END_TEST
  function END_TEST (line 233) | END_TEST
  function END_TEST (line 242) | END_TEST
  function main (line 266) | int

FILE: tests/test-threads.c
  function START_TEST (line 69) | START_TEST(test_atomic_ptr)
  function END_TEST (line 85) | END_TEST
  function END_TEST (line 117) | END_TEST
  function END_TEST (line 144) | END_TEST
  function END_TEST (line 157) | END_TEST
  function cork_test_thread__run (line 169) | static int
  function cork_test_thread__free (line 177) | static void
  type cork_thread (line 184) | struct cork_thread
  type cork_test_thread (line 187) | struct cork_test_thread
  function cork_error_thread__run (line 195) | static int
  function START_TEST (line 205) | START_TEST(test_threads_01)
  function END_TEST (line 216) | END_TEST
  function END_TEST (line 230) | END_TEST
  function END_TEST (line 250) | END_TEST
  function END_TEST (line 270) | END_TEST
  function END_TEST (line 282) | END_TEST
  function main (line 319) | int

FILE: tests/test-u128.c
  function test_one_u128_decimal (line 23) | static void
  function test_one_u128_hex (line 31) | static void
  function test_one_u128_padded_hex (line 39) | static void
  function test_one_u128_print_from_32 (line 47) | static void
  function test_one_u128_print_from_64 (line 59) | static void
  function START_TEST (line 71) | START_TEST(test_u128_print)
  function END_TEST (line 147) | END_TEST
  function check_shift_test (line 158) | static void
  function check_shift_tests_ (line 180) | static void
  type shift_test (line 195) | struct shift_test
  function START_TEST (line 202) | START_TEST(test_u128_shl)
  function START_TEST (line 217) | START_TEST(test_u128_shr)
  function END_TEST (line 222) | END_TEST
  function check_arithmetic_test (line 234) | static void
  function check_arithmetic_tests_ (line 259) | static void
  type arithmetic_test (line 274) | struct arithmetic_test
  function START_TEST (line 282) | START_TEST(test_u128_add)
  function START_TEST (line 299) | START_TEST(test_u128_sub)
  function END_TEST (line 304) | END_TEST
  function check_comparison_test (line 315) | static void
  function check_comparison_tests_ (line 335) | static void
  type comparison_test (line 349) | struct comparison_test
  function START_TEST (line 358) | START_TEST(test_u128_eq)
  function START_TEST (line 374) | START_TEST(test_u128_ne)
  function START_TEST (line 389) | START_TEST(test_u128_lt)
  function START_TEST (line 404) | START_TEST(test_u128_le)
  function START_TEST (line 419) | START_TEST(test_u128_gt)
  function START_TEST (line 434) | START_TEST(test_u128_ge)
  function END_TEST (line 439) | END_TEST
  function main (line 469) | int
Condensed preview — 212 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (950K chars).
[
  {
    "path": ".buzzy/links.yaml",
    "chars": 43,
    "preview": "- git://github.com/dcreager/buzzy-core.git\n"
  },
  {
    "path": ".buzzy/package.yaml",
    "chars": 81,
    "preview": "name: libcork\nbuild_dependencies:\n  - pkg-config\n  - check >= 0.9.4\nlicense: BSD\n"
  },
  {
    "path": ".clang-format",
    "chars": 1836,
    "preview": "Language: Cpp\nAlignAfterOpenBracket: Align\nAlignConsecutiveAssignments: false\nAlignConsecutiveDeclarations: false\nAlignE"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 869,
    "preview": "name: Continuous integration\non:\n  push:\n    branches:\n      - master\n  pull_request:\n  schedule:\n    - cron: \"0 0 1,15 "
  },
  {
    "path": ".gitignore",
    "chars": 589,
    "preview": "# autotools stuff\n/aclocal.m4\n/autom4te.cache/\n/build-aux/compile\n/build-aux/config.guess\n/build-aux/config.sub\n/build-a"
  },
  {
    "path": "AUTHORS",
    "chars": 475,
    "preview": "# This is the list of libcork authors for copyright purposes.\n#\n# This does not necessarily list everyone who has contri"
  },
  {
    "path": "CMakeLists.txt",
    "chars": 3867,
    "preview": "# -*- coding: utf-8 -*-\n# ----------------------------------------------------------------------\n# Copyright © 2011, lib"
  },
  {
    "path": "COPYING",
    "chars": 1517,
    "preview": "Copyright © 2011-2017, libcork authors\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or "
  },
  {
    "path": "INSTALL",
    "chars": 1746,
    "preview": "Installation instructions\n=========================\n\nThe libcork library is written in ANSI C.  It uses cmake as its bui"
  },
  {
    "path": "Makefile.am",
    "chars": 12333,
    "preview": "# -*- coding: utf-8 -*-\n# ------------------------------------------------------------------------------\n# Copyright © 2"
  },
  {
    "path": "README.markdown",
    "chars": 3578,
    "preview": "# libcork\n\n[![Build Status](https://travis-ci.org/dcreager/libcork.svg?branch=master)](https://travis-ci.org/dcreager/li"
  },
  {
    "path": "autogen.sh",
    "chars": 527,
    "preview": "#!/bin/sh\n# ------------------------------------------------------------------------------\n# Copyright © 2020, libcork a"
  },
  {
    "path": "build-aux/calculate",
    "chars": 1489,
    "preview": "#!/bin/sh\n# ----------------------------------------------------------------------\n# Copyright © 2011, libcork authors\n#"
  },
  {
    "path": "cmake/FindCTargets.cmake",
    "chars": 8227,
    "preview": "# -*- coding: utf-8 -*-\n# ----------------------------------------------------------------------\n# Copyright © 2015, lib"
  },
  {
    "path": "cmake/FindParseArguments.cmake",
    "chars": 1706,
    "preview": "# -*- coding: utf-8 -*-\n# ----------------------------------------------------------------------\n# Copyright © 2015, lib"
  },
  {
    "path": "cmake/FindPrereqs.cmake",
    "chars": 2990,
    "preview": "# -*- coding: utf-8 -*-\n# ----------------------------------------------------------------------\n# Copyright © 2015, lib"
  },
  {
    "path": "configure.ac",
    "chars": 2359,
    "preview": "# -*- coding: utf-8 -*-\n# ------------------------------------------------------------------------------\n# Copyright © 2"
  },
  {
    "path": "docs/.gitattributes",
    "chars": 66,
    "preview": "*.graffle      -diff -whitespace\n/*.[1-9]       -diff -whitespace\n"
  },
  {
    "path": "docs/CMakeLists.txt",
    "chars": 2868,
    "preview": "# -*- coding: utf-8 -*-\n# ----------------------------------------------------------------------\n# Copyright © 2011, lib"
  },
  {
    "path": "docs/old/CMakeLists.txt",
    "chars": 2396,
    "preview": "# -*- coding: utf-8 -*-\n# ----------------------------------------------------------------------\n# Copyright © 2011, lib"
  },
  {
    "path": "docs/old/_static/.keep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/old/_static/docco-sphinx.css",
    "chars": 4947,
    "preview": "@import url(\"basic.css\");\n\n/* -- page layout ----------------------------------------------------------- */\n\nbody {\n    "
  },
  {
    "path": "docs/old/_static/pygments.css",
    "chars": 4652,
    "preview": ".highlight .hll { background-color: #ffffcc }\n.highlight .c { color: #408080; font-style: italic }  /* Comment */\n.highl"
  },
  {
    "path": "docs/old/_templates/.keep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "docs/old/allocation.rst",
    "chars": 16220,
    "preview": ".. _allocation:\n\n*****************\nMemory allocation\n*****************\n\n.. highlight:: c\n\n::\n\n  #include <libcork/core.h"
  },
  {
    "path": "docs/old/array.rst",
    "chars": 6293,
    "preview": ".. _array:\n\n****************\nResizable arrays\n****************\n\n.. highlight:: c\n\n::\n\n  #include <libcork/ds.h>\n\nThis se"
  },
  {
    "path": "docs/old/attributes.rst",
    "chars": 3474,
    "preview": ".. _attributes:\n\n*******************\nCompiler attributes\n*******************\n\n.. highlight:: c\n\n::\n\n  #include <libcork/"
  },
  {
    "path": "docs/old/basic-types.rst",
    "chars": 3215,
    "preview": ".. _basic-types:\n\n***********\nBasic types\n***********\n\n.. highlight:: c\n\n::\n\n  #include <libcork/core.h>\n\nThe types in t"
  },
  {
    "path": "docs/old/bitset.rst",
    "chars": 2487,
    "preview": ".. _bits:\n\n********\nBit sets\n********\n\n.. highlight:: c\n\n::\n\n  #include <libcork/ds.h>\n\nThis sections defines a type for"
  },
  {
    "path": "docs/old/buffer.rst",
    "chars": 12075,
    "preview": ".. _buffer:\n\n************************\nResizable binary buffers\n************************\n\n.. highlight:: c\n\n::\n\n  #includ"
  },
  {
    "path": "docs/old/byte-order.rst",
    "chars": 6301,
    "preview": ".. _byte-order:\n\n**********\nByte order\n**********\n\n.. highlight:: c\n\n::\n\n  #include <libcork/core.h>\n\nThis section conta"
  },
  {
    "path": "docs/old/cli.rst",
    "chars": 13823,
    "preview": ".. _cli:\n\n*********************\nCommand-line programs\n*********************\n\n.. highlight:: c\n\n::\n\n  #include <libcork/c"
  },
  {
    "path": "docs/old/conf.py",
    "chars": 2038,
    "preview": "# -*- coding: utf-8 -*-\n\nimport sys, os\n\nextensions = ['sphinx.ext.mathjax']\nsource_suffix = '.rst'\nmaster_doc = 'index'"
  },
  {
    "path": "docs/old/config.rst",
    "chars": 6101,
    "preview": ".. _config:\n\n*******************\nConfiguring libcork\n*******************\n\n.. highlight:: c\n\n::\n\n  #include <libcork/conf"
  },
  {
    "path": "docs/old/dllist.rst",
    "chars": 10978,
    "preview": ".. _dllist:\n\n*******************\nDoubly-linked lists\n*******************\n\n.. highlight:: c\n\n::\n\n  #include <libcork/ds.h"
  },
  {
    "path": "docs/old/ds.rst",
    "chars": 315,
    "preview": ".. _ds:\n\n***************\nData structures\n***************\n\n.. highlight:: c\n\n::\n\n  #include <libcork/ds.h>\n\nlibcork inclu"
  },
  {
    "path": "docs/old/errors.rst",
    "chars": 18672,
    "preview": ".. _errors:\n\n***************\nError reporting\n***************\n\n.. highlight:: c\n\n::\n\n  #include <libcork/core.h>\n\nThis se"
  },
  {
    "path": "docs/old/files.rst",
    "chars": 16103,
    "preview": ".. _files:\n\n*********************\nFiles and directories\n*********************\n\n.. highlight:: c\n\n::\n\n  #include <libcork"
  },
  {
    "path": "docs/old/gc.rst",
    "chars": 16752,
    "preview": ".. _gc:\n\n************************************\nReference-counted garbage collection\n************************************\n"
  },
  {
    "path": "docs/old/hash-table.rst",
    "chars": 17474,
    "preview": ".. _hash-table:\n\n***********\nHash tables\n***********\n\n.. highlight:: c\n\n::\n\n  #include <libcork/ds.h>\n\nThis section defi"
  },
  {
    "path": "docs/old/hash-values.rst",
    "chars": 3245,
    "preview": ".. _hash-values:\n\n***********\nHash values\n***********\n\n.. highlight:: c\n\n::\n\n  #include <libcork/core.h>\n\n\nThe functions"
  },
  {
    "path": "docs/old/index.rst",
    "chars": 1318,
    "preview": ".. _index:\n\n|project_name| documentation\n============================\n\nThis is the documentation for |project_name| |rel"
  },
  {
    "path": "docs/old/int128.rst",
    "chars": 5149,
    "preview": ".. _int128:\n\n****************\n128-bit integers\n****************\n\n.. highlight:: c\n\n::\n\n  #include <libcork/core.h>\n\nWe p"
  },
  {
    "path": "docs/old/managed-buffer.rst",
    "chars": 4628,
    "preview": ".. _managed-buffer:\n\n**********************\nManaged binary buffers\n**********************\n\n.. highlight:: c\n\n::\n\n  #incl"
  },
  {
    "path": "docs/old/mempool.rst",
    "chars": 7031,
    "preview": ".. _mempool:\n\n************\nMemory pools\n************\n\n.. highlight:: c\n\n::\n\n  #include <libcork/core.h>\n\nThe functions i"
  },
  {
    "path": "docs/old/net-addresses.rst",
    "chars": 5527,
    "preview": ".. _net-addresses:\n\n*****************\nNetwork addresses\n*****************\n\n.. highlight:: c\n\n::\n\n  #include <libcork/cor"
  },
  {
    "path": "docs/old/process.rst",
    "chars": 7922,
    "preview": ".. _processes:\n\n*********\nProcesses\n*********\n\n.. highlight:: c\n\n::\n\n  #include <libcork/os.h>\n\nThe functions in this se"
  },
  {
    "path": "docs/old/ring-buffer.rst",
    "chars": 2946,
    "preview": ".. _ring-buffer:\n\n************\nRing buffers\n************\n\n.. highlight:: c\n\n::\n\n  #include <libcork/ds.h>\n\n\n.. type:: st"
  },
  {
    "path": "docs/old/slice.rst",
    "chars": 11132,
    "preview": ".. _slice:\n\n*************\nBinary slices\n*************\n\n.. highlight:: c\n\n::\n\n  #include <libcork/ds.h>\n\nThis section def"
  },
  {
    "path": "docs/old/stream.rst",
    "chars": 8161,
    "preview": ".. _stream:\n\n*****************\nStream processing\n*****************\n\n.. highlight:: c\n\n::\n\n  #include <libcork/ds.h>\n\n\nSt"
  },
  {
    "path": "docs/old/subprocess.rst",
    "chars": 9450,
    "preview": ".. _subprocesses:\n\n************\nSubprocesses\n************\n\n.. highlight:: c\n\n::\n\n  #include <libcork/os.h>\n\nThe function"
  },
  {
    "path": "docs/old/threads.rst",
    "chars": 12861,
    "preview": ".. _multithreading:\n\n**********************\nMultithreading support\n**********************\n\n.. highlight:: c\n\n::\n\n  #incl"
  },
  {
    "path": "docs/old/timestamps.rst",
    "chars": 4212,
    "preview": ".. _timestamps:\n\n*************************\nHigh-precision timestamps\n*************************\n\n.. highlight:: c\n\n::\n\n  "
  },
  {
    "path": "docs/old/unique-ids.rst",
    "chars": 2632,
    "preview": ".. _unique-ids:\n\n******************\nUnique identifiers\n******************\n\n.. highlight:: c\n\n::\n\n  #include <libcork/cor"
  },
  {
    "path": "docs/old/versions.rst",
    "chars": 2399,
    "preview": ".. _versions:\n\n***************\nLibrary version\n***************\n\n.. highlight:: c\n\n::\n\n  #include <libcork/core.h>\n\nThe m"
  },
  {
    "path": "docs/old/visibility.rst",
    "chars": 4376,
    "preview": ".. _visibility:\n\n*****************\nSymbol visibility\n*****************\n\n.. highlight:: c\n\n::\n\n  #include <libcork/core.h"
  },
  {
    "path": "extras/hashstring.py",
    "chars": 2065,
    "preview": "# -*- coding: utf-8 -*-\n# ----------------------------------------------------------------------\n# Copyright © 2011, lib"
  },
  {
    "path": "include/CMakeLists.txt",
    "chars": 703,
    "preview": "# -*- coding: utf-8 -*-\n# ----------------------------------------------------------------------\n# Copyright © 2011, lib"
  },
  {
    "path": "include/libcork/cli/commands.h",
    "chars": 1381,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2012, "
  },
  {
    "path": "include/libcork/cli.h",
    "chars": 458,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2012, "
  },
  {
    "path": "include/libcork/config/arch.h",
    "chars": 1057,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2012, "
  },
  {
    "path": "include/libcork/config/bsd.h",
    "chars": 873,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2013, "
  },
  {
    "path": "include/libcork/config/config.h",
    "chars": 1764,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/config/gcc.h",
    "chars": 3061,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/config/linux.h",
    "chars": 883,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/config/macosx.h",
    "chars": 886,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/config/version.h.in",
    "chars": 799,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2015, "
  },
  {
    "path": "include/libcork/config.h",
    "chars": 468,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/core/allocator.h",
    "chars": 11271,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/core/api.h",
    "chars": 1584,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2012, "
  },
  {
    "path": "include/libcork/core/attributes.h",
    "chars": 4796,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/core/byte-order.h",
    "chars": 7357,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/core/callbacks.h",
    "chars": 1088,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2013, "
  },
  {
    "path": "include/libcork/core/error.h",
    "chars": 3431,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/core/gc.h",
    "chars": 1587,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/core/hash.h",
    "chars": 11209,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/core/id.h",
    "chars": 1112,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2013, "
  },
  {
    "path": "include/libcork/core/mempool.h",
    "chars": 2042,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2012, "
  },
  {
    "path": "include/libcork/core/net-addresses.h",
    "chars": 3794,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/core/timestamp.h",
    "chars": 2463,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/core/types.h",
    "chars": 2118,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/core/u128.h",
    "chars": 7822,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2013, "
  },
  {
    "path": "include/libcork/core.h",
    "chars": 867,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/ds/array.h",
    "chars": 5374,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/ds/bitset.h",
    "chars": 2009,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2013, "
  },
  {
    "path": "include/libcork/ds/buffer.h",
    "chars": 5573,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/ds/dllist.h",
    "chars": 4551,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/ds/hash-table.h",
    "chars": 4884,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/ds/managed-buffer.h",
    "chars": 2094,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/ds/ring-buffer.h",
    "chars": 1599,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/ds/slice.h",
    "chars": 5994,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/ds/stream.h",
    "chars": 1820,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/ds.h",
    "chars": 715,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/helpers/errors.h",
    "chars": 3707,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/helpers/gc.h",
    "chars": 1127,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "include/libcork/helpers/posix.h",
    "chars": 2517,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2013, "
  },
  {
    "path": "include/libcork/os/files.h",
    "chars": 7009,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2012, "
  },
  {
    "path": "include/libcork/os/process.h",
    "chars": 741,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2013, "
  },
  {
    "path": "include/libcork/os/subprocess.h",
    "chars": 5083,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2012, "
  },
  {
    "path": "include/libcork/os.h",
    "chars": 518,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2012, "
  },
  {
    "path": "include/libcork/threads/atomics.h",
    "chars": 1775,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2012, "
  },
  {
    "path": "include/libcork/threads/basics.h",
    "chars": 6116,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2012, "
  },
  {
    "path": "include/libcork/threads.h",
    "chars": 509,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2012, "
  },
  {
    "path": "m4/ax_pthread.m4",
    "chars": 20818,
    "preview": "# ===========================================================================\n#        https://www.gnu.org/software/auto"
  },
  {
    "path": "m4/ax_valgrind_check.m4",
    "chars": 8857,
    "preview": "# ===========================================================================\n#     http://www.gnu.org/software/autoconf"
  },
  {
    "path": "make-dist.sh",
    "chars": 238,
    "preview": "#!/bin/sh\n\nPROJECT=libcork\n\nCOMMIT=\"$1\"\nif [ -z \"$COMMIT\" ]; then\n    COMMIT=\"HEAD\"\nfi\n\nVERSION=$(git describe ${COMMIT}"
  },
  {
    "path": "run.sh",
    "chars": 976,
    "preview": "#!/bin/sh\n# Usage: run.sh [debug|release] program arguments\n#\n# Runs a program from one of the build directories, with\n#"
  },
  {
    "path": "scripts/install",
    "chars": 260,
    "preview": "#!/bin/sh\n\nset -e\n\nif [ \"$OS_NAME\" = \"ubuntu-latest\" ]; then\n    sudo dpkg --add-architecture i386\n    sudo apt-get upda"
  },
  {
    "path": "scripts/test",
    "chars": 2775,
    "preview": "#!/bin/bash\n\nset -e\n\n# Defaults\nENABLE_SHARED_TESTS=NO\nSRCDIR=\"$PWD\"\n: ${TMPDIR:=/tmp}\n\nif [ \"$COMPILER\" = clang ]; then"
  },
  {
    "path": "share/CMakeLists.txt",
    "chars": 418,
    "preview": "# -*- coding: utf-8 -*-\n# ----------------------------------------------------------------------\n# Copyright © 2012, lib"
  },
  {
    "path": "share/valgrind/libcork.supp",
    "chars": 114,
    "preview": "# Valgrind suppressions for libcork\n\n{\n   libcork/cork_gc_get\n   Memcheck:Leak\n   fun:calloc\n   fun:cork_gc_get\n}\n"
  },
  {
    "path": "src/APPNAME.pc.in",
    "chars": 248,
    "preview": "prefix=@prefix@\nexec_prefix=${prefix}\nlibdir=${exec_prefix}/lib\nincludedir=${prefix}/include\nsharedir=${prefix}/share\n\nN"
  },
  {
    "path": "src/CMakeLists.txt",
    "chars": 3782,
    "preview": "# -*- coding: utf-8 -*-\n# ----------------------------------------------------------------------\n# Copyright © 2011, lib"
  },
  {
    "path": "src/cork-hash/cork-hash.c",
    "chars": 2976,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2012, "
  },
  {
    "path": "src/cork-initializer/init1.c",
    "chars": 475,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2012, "
  },
  {
    "path": "src/cork-initializer/init2.c",
    "chars": 420,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2012, "
  },
  {
    "path": "src/cork-initializer/main.c",
    "chars": 365,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2012, "
  },
  {
    "path": "src/cork-test/cork-test.c",
    "chars": 17391,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2012, "
  },
  {
    "path": "src/libcork/cli/commands.c",
    "chars": 5960,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2012, "
  },
  {
    "path": "src/libcork/core/allocator.c",
    "chars": 12680,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "src/libcork/core/error.c",
    "chars": 5971,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "src/libcork/core/gc.c",
    "chars": 11392,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "src/libcork/core/hash.c",
    "chars": 694,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "src/libcork/core/id.c",
    "chars": 600,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2020, "
  },
  {
    "path": "src/libcork/core/ip-address.c",
    "chars": 17027,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "src/libcork/core/mempool.c",
    "chars": 5713,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2012, "
  },
  {
    "path": "src/libcork/core/timestamp.c",
    "chars": 5326,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "src/libcork/core/u128.c",
    "chars": 3082,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2013, "
  },
  {
    "path": "src/libcork/core/version.c",
    "chars": 633,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2015, "
  },
  {
    "path": "src/libcork/ds/array.c",
    "chars": 11905,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "src/libcork/ds/bitset.c",
    "chars": 1472,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2013, "
  },
  {
    "path": "src/libcork/ds/buffer.c",
    "chars": 11839,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "src/libcork/ds/dllist.c",
    "chars": 1513,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "src/libcork/ds/file-stream.c",
    "chars": 5597,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2012, "
  },
  {
    "path": "src/libcork/ds/hash-table.c",
    "chars": 20282,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "src/libcork/ds/managed-buffer.c",
    "chars": 6614,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "src/libcork/ds/ring-buffer.c",
    "chars": 2022,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "src/libcork/ds/slice.c",
    "chars": 8773,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "src/libcork/ds/stream.c",
    "chars": 738,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2020, "
  },
  {
    "path": "src/libcork/posix/directory-walker.c",
    "chars": 3845,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2012, "
  },
  {
    "path": "src/libcork/posix/env.c",
    "chars": 5259,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2013, "
  },
  {
    "path": "src/libcork/posix/exec.c",
    "chars": 4428,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2013, "
  },
  {
    "path": "src/libcork/posix/files.c",
    "chars": 22998,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2013, "
  },
  {
    "path": "src/libcork/posix/process.c",
    "chars": 3575,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2013, "
  },
  {
    "path": "src/libcork/posix/subprocess.c",
    "chars": 16871,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2012, "
  },
  {
    "path": "src/libcork/pthreads/thread.c",
    "chars": 5989,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2013, "
  },
  {
    "path": "src/libcork.pc.in",
    "chars": 403,
    "preview": "PACKAGE_TARNAME=@PACKAGE_TARNAME@\nprefix=@prefix@\nexec_prefix=@exec_prefix@\ndatarootdir=@datarootdir@\ndocdir=@docdir@\nin"
  },
  {
    "path": "tests/.gitattributes",
    "chars": 38,
    "preview": "*.t       -whitespace\ncram.py   -diff\n"
  },
  {
    "path": "tests/.gitignore",
    "chars": 8,
    "preview": "*.t.err\n"
  },
  {
    "path": "tests/CMakeLists.txt",
    "chars": 3375,
    "preview": "# -*- coding: utf-8 -*-\n# ----------------------------------------------------------------------\n# Copyright © 2011, lib"
  },
  {
    "path": "tests/COPYING.cram.txt",
    "chars": 17992,
    "preview": "\t\t    GNU GENERAL PUBLIC LICENSE\n\t\t       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc."
  },
  {
    "path": "tests/ccram",
    "chars": 565,
    "preview": "#!/bin/sh\n\nset -e\n\nif [ \"$1\" = \"--python\" ]; then\n    shift\n    PYTHON=\"$1\"\n    shift\nelse\n    PYTHON=python\nfi\n\nif [ \"$"
  },
  {
    "path": "tests/cork-hash.t",
    "chars": 192,
    "preview": "Make sure that our stable hash is really stable.\n\n  $ cork-hash foo\n  0xf6a5c420\n  $ cork-hash bar\n  0x450e998d\n  $ cork"
  },
  {
    "path": "tests/cork-initializer.t",
    "chars": 187,
    "preview": "We need to sort the output, since there's no guarantee about which order our\ninitializer functions will run in.\n\n  $ cor"
  },
  {
    "path": "tests/cork-test/cleanup.t",
    "chars": 148,
    "preview": "  $ cork-test cleanup\n  Cleanup function 0\n  Cleanup function 1\n  Cleanup function 2\n  Cleanup function 3\n  Cleanup func"
  },
  {
    "path": "tests/cork-test/directory-watcher.t",
    "chars": 1377,
    "preview": "This first test makes sure to only create one file or subdirectory in each\ndirectory.  That means that we don't have to "
  },
  {
    "path": "tests/cork-test/help1-c1-s1.t",
    "chars": 111,
    "preview": "  $ cork-test c1 s1 --help\n  Usage: cork-test c1 s1 [<options>] <filename>\n  \n  This is a pretty cool command.\n"
  },
  {
    "path": "tests/cork-test/help1-c1-s2.t",
    "chars": 110,
    "preview": "  $ cork-test c1 s2 --help\n  Usage: cork-test c1 s2 [<options>] <filename>\n  \n  This is an excellent command.\n"
  },
  {
    "path": "tests/cork-test/help1-c1.t",
    "chars": 135,
    "preview": "  $ cork-test c1 --help\n  Usage: cork-test c1 <command> [<options>]\n  \n  Available commands:\n    s1  Subcommand 1\n    s2"
  },
  {
    "path": "tests/cork-test/help1-c2.t",
    "chars": 105,
    "preview": "  $ cork-test c2 --help\n  Usage: cork-test c2 [<options>] <filename>\n  \n  This command is pretty decent.\n"
  },
  {
    "path": "tests/cork-test/help1-root.t",
    "chars": 501,
    "preview": "  $ cork-test --help\n  Usage: cork-test <command> [<options>]\n  \n  Available commands:\n    c1       Command 1 (now with "
  },
  {
    "path": "tests/cork-test/help2-c1-s1.t",
    "chars": 107,
    "preview": "  $ cork-test c1 s1 -h\n  Usage: cork-test c1 s1 [<options>] <filename>\n  \n  This is a pretty cool command.\n"
  },
  {
    "path": "tests/cork-test/help2-c1-s2.t",
    "chars": 106,
    "preview": "  $ cork-test c1 s2 -h\n  Usage: cork-test c1 s2 [<options>] <filename>\n  \n  This is an excellent command.\n"
  },
  {
    "path": "tests/cork-test/help2-c1.t",
    "chars": 131,
    "preview": "  $ cork-test c1 -h\n  Usage: cork-test c1 <command> [<options>]\n  \n  Available commands:\n    s1  Subcommand 1\n    s2  Su"
  },
  {
    "path": "tests/cork-test/help2-c2.t",
    "chars": 101,
    "preview": "  $ cork-test c2 -h\n  Usage: cork-test c2 [<options>] <filename>\n  \n  This command is pretty decent.\n"
  },
  {
    "path": "tests/cork-test/help2-root.t",
    "chars": 497,
    "preview": "  $ cork-test -h\n  Usage: cork-test <command> [<options>]\n  \n  Available commands:\n    c1       Command 1 (now with subc"
  },
  {
    "path": "tests/cork-test/help3-c1-s1.t",
    "chars": 109,
    "preview": "  $ cork-test help c1 s1\n  Usage: cork-test c1 s1 [<options>] <filename>\n  \n  This is a pretty cool command.\n"
  },
  {
    "path": "tests/cork-test/help3-c1-s2.t",
    "chars": 108,
    "preview": "  $ cork-test help c1 s2\n  Usage: cork-test c1 s2 [<options>] <filename>\n  \n  This is an excellent command.\n"
  },
  {
    "path": "tests/cork-test/help3-c1.t",
    "chars": 133,
    "preview": "  $ cork-test help c1\n  Usage: cork-test c1 <command> [<options>]\n  \n  Available commands:\n    s1  Subcommand 1\n    s2  "
  },
  {
    "path": "tests/cork-test/help3-c2.t",
    "chars": 103,
    "preview": "  $ cork-test help c2\n  Usage: cork-test c2 [<options>] <filename>\n  \n  This command is pretty decent.\n"
  },
  {
    "path": "tests/cork-test/help3-root.t",
    "chars": 499,
    "preview": "  $ cork-test help\n  Usage: cork-test <command> [<options>]\n  \n  Available commands:\n    c1       Command 1 (now with su"
  },
  {
    "path": "tests/cork-test/no-command-c1.t",
    "chars": 154,
    "preview": "  $ cork-test c1\n  No command given.\n  Usage: cork-test c1 <command> [<options>]\n  \n  Available commands:\n    s1  Subcom"
  },
  {
    "path": "tests/cork-test/no-command-root.t",
    "chars": 520,
    "preview": "  $ cork-test\n  No command given.\n  Usage: cork-test <command> [<options>]\n  \n  Available commands:\n    c1       Command"
  },
  {
    "path": "tests/cork-test/run-c1-s1-f-t.t",
    "chars": 171,
    "preview": "  $ cork-test c1 -f foo s1 -t\n  You chose command \"c1 s1\".  Good for you!\n  And you gave the --test option!  Look at tha"
  },
  {
    "path": "tests/cork-test/run-c1-s1-f.t",
    "chars": 119,
    "preview": "  $ cork-test c1 -f foo s1\n  You chose command \"c1 s1\".  Good for you!\n  And you want the file to be foo.  Sure thing.\n"
  },
  {
    "path": "tests/cork-test/run-c1-s1-t.t",
    "chars": 116,
    "preview": "  $ cork-test c1 s1 -t\n  You chose command \"c1 s1\".  Good for you!\n  And you gave the --test option!  Look at that.\n"
  },
  {
    "path": "tests/cork-test/run-c1-s1-test.t",
    "chars": 120,
    "preview": "  $ cork-test c1 s1 --test\n  You chose command \"c1 s1\".  Good for you!\n  And you gave the --test option!  Look at that.\n"
  },
  {
    "path": "tests/cork-test/run-c1-s1.t",
    "chars": 64,
    "preview": "  $ cork-test c1 s1\n  You chose command \"c1 s1\".  Good for you!\n"
  },
  {
    "path": "tests/cork-test/run-c1-s2-f.t",
    "chars": 189,
    "preview": "  $ cd $TESTDIR\n  $ cork-test c1 -f ../test-input.txt s2\n  You chose command \"c1 s2\".  Fantastico!\n  And you want the fi"
  },
  {
    "path": "tests/cork-test/run-c1-s2-file.t",
    "chars": 193,
    "preview": "  $ cd $TESTDIR\n  $ cork-test c1 --file ../test-input.txt s2\n  You chose command \"c1 s2\".  Fantastico!\n  And you want th"
  },
  {
    "path": "tests/cork-test/run-c1-s2.t",
    "chars": 62,
    "preview": "  $ cork-test c1 s2\n  You chose command \"c1 s2\".  Fantastico!\n"
  },
  {
    "path": "tests/cork-test/run-c2.t",
    "chars": 64,
    "preview": "  $ cork-test c2\n  You chose command \"c2\".  That's pretty good.\n"
  },
  {
    "path": "tests/cork-test/run-find-01.t",
    "chars": 392,
    "preview": "  $ cork-test mkdir --recursive a/b/c/b\n\n  $ cork-test find b a\n  a/b\n  $ cork-test find b a/b/c\n  a/b/c/b\n  $ cork-test"
  },
  {
    "path": "tests/cork-test/run-find-all-01.t",
    "chars": 365,
    "preview": "  $ cork-test mkdir --recursive a/b/c/b\n\n  $ cork-test find --all b a\n  a/b\n  $ cork-test find --all b a/b/c\n  a/b/c/b\n "
  },
  {
    "path": "tests/cork-test/run-mkdir-01.t",
    "chars": 508,
    "preview": "  $ cork-test mkdir a\n  $ find a | sort\n  a\n\n  $ cork-test mkdir a\n  $ find a | sort\n  a\n\n  $ cork-test mkdir --require "
  },
  {
    "path": "tests/cork-test/run-paths-01.t",
    "chars": 1257,
    "preview": "  $ HOME= \\\n  >     cork-test paths\n  Cannot determine home directory\n  [1]\n\n  $ HOME=/home/test \\\n  > XDG_CONFIG_HOME= "
  },
  {
    "path": "tests/cork-test/run-pwd-01.t",
    "chars": 56,
    "preview": "  $ a=$(cork-test pwd)\n  $ b=$(pwd)\n  $ [ \"$a\" = \"$b\" ]\n"
  },
  {
    "path": "tests/cork-test/run-rm-01.t",
    "chars": 498,
    "preview": "  $ cork-test mkdir --recursive --require a/b/c\n  $ cork-test mkdir --recursive --require a/b/d\n  $ find a 2>/dev/null |"
  },
  {
    "path": "tests/cork-test/run-sub-01.t",
    "chars": 68,
    "preview": "  $ cork-test sub echo Hello world\n  echo Hello world\n  Hello world\n"
  },
  {
    "path": "tests/cork-test/run-sub-02.t",
    "chars": 32,
    "preview": "  $ cork-test sub false\n  false\n"
  },
  {
    "path": "tests/cork-test/run-sub-03.t",
    "chars": 116,
    "preview": "  $ CORK_TEST_VAR=\"Hello world\" cork-test sub sh -c 'echo $CORK_TEST_VAR'\n  sh -c echo $CORK_TEST_VAR\n  Hello world\n"
  },
  {
    "path": "tests/cork-test/run-sub-04.t",
    "chars": 72,
    "preview": "  $ cork-test sub bad-command\n  bad-command\n  No such file or directory\n"
  },
  {
    "path": "tests/cork-test/run-sub-05.t",
    "chars": 37,
    "preview": "  $ cork-test sub -d / pwd\n  pwd\n  /\n"
  },
  {
    "path": "tests/cork-test/run-sub-06.t",
    "chars": 41,
    "preview": "  $ cork-test sub -i foo cat\n  cat\n  foo\n"
  },
  {
    "path": "tests/cram.py",
    "chars": 18346,
    "preview": "#!/usr/bin/env python\n\"\"\"Functional testing framework for command line applications\"\"\"\n\nimport difflib\nimport itertools\n"
  },
  {
    "path": "tests/create-u128-test-cases.py",
    "chars": 4519,
    "preview": "# -*- coding: utf-8 -*-\n# ----------------------------------------------------------------------\n# Copyright © 2017, lib"
  },
  {
    "path": "tests/helpers.h",
    "chars": 2316,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "tests/test-array.c",
    "chars": 12491,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2011, "
  },
  {
    "path": "tests/test-bitset.c",
    "chars": 2850,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2013, "
  },
  {
    "path": "tests/test-buffer.c",
    "chars": 10367,
    "preview": "/* -*- coding: utf-8 -*-\n * ----------------------------------------------------------------------\n * Copyright © 2009, "
  }
]

// ... and 12 more files (download for full content)

About this extraction

This page contains the full source code of the dcreager/libcork GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 212 files (881.4 KB), approximately 233.2k tokens, and a symbol index with 1287 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!