diff --git a/.HEADER b/.HEADER deleted file mode 100644 index fd8430bc864..00000000000 --- a/.HEADER +++ /dev/null @@ -1,24 +0,0 @@ -/* - * This file is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2, - * as published by the Free Software Foundation. - * - * In addition to the permissions in the GNU General Public License, - * the authors give you unlimited permission to link the compiled - * version of this file into combinations with other programs, - * and to distribute those combinations without any restriction - * coming from the use of this file. (The General Public License - * restrictions do apply in other respects; for example, they cover - * modification of the file, and distribution when not linked into - * a combined executable.) - * - * This file is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; see the file COPYING. If not, write to - * the Free Software Foundation, 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index f90540b55b1..00000000000 --- a/.gitattributes +++ /dev/null @@ -1,2 +0,0 @@ -*.c eol=lf -*.h eol=lf diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 7fa7d547c75..00000000000 --- a/.gitignore +++ /dev/null @@ -1,30 +0,0 @@ -/tests-clar/clar.h -/tests-clar/clar_main.c -/tests-clar/clar_main.c.rule -/apidocs -/trash-*.exe -/libgit2.pc -/config.mak -*.o -*.a -*.exe -*.gcda -*.gcno -*.gcov -.lock-wafbuild -.waf* -build/ -tests/tmp/ -msvc/Debug/ -msvc/Release/ -*.sln -*.suo -*.vc*proj* -*.sdf -*.opensdf -*.aps -CMake* -*.cmake -.DS_Store -*~ -tags diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 54da48a40f3..00000000000 --- a/.travis.yml +++ /dev/null @@ -1,53 +0,0 @@ -# Travis-CI Build for libgit2 -# see travis-ci.org for details - -# As CMake is not officially supported we use erlang VMs -language: c - -compiler: - - gcc - - clang - -# Settings to try -env: - - OPTIONS="-DTHREADSAFE=ON -DCMAKE_BUILD_TYPE=Release" - - OPTIONS="-DBUILD_CLAR=ON -DBUILD_EXAMPLES=ON" - -matrix: - include: - - compiler: i586-mingw32msvc-gcc - env: OPTIONS="-DBUILD_CLAR=OFF -DWIN32=ON -DMINGW=ON" - -# Make sure CMake is installed -install: - - sudo apt-get install cmake valgrind - -# Run the Build script -script: - - mkdir _build - - cd _build - - cmake .. -DCMAKE_INSTALL_PREFIX=../_install $OPTIONS - - cmake --build . --target install - -# Run Tests -after_script: - - ctest -V . - - if [ -f ./libgit2_clar ]; then valgrind --leak-check=full --show-reachable=yes --suppressions=../libgit2_clar.supp ./libgit2_clar; else echo "Skipping valgrind"; fi - -# Only watch the development branch -branches: - only: - - development - -# Notify development list when needed -notifications: - irc: - channels: - - irc.freenode.net#libgit2 - on_success: change - on_failure: always - recipients: - - vicent@github.com - email: - on_success: change - on_failure: always diff --git a/AUTHORS b/AUTHORS deleted file mode 100644 index 9f621b9905f..00000000000 --- a/AUTHORS +++ /dev/null @@ -1,65 +0,0 @@ -The following people contribute or have contributed -to the libgit2 project (sorted alphabetically): - -Alex Budovski -Alexei Sholik -Andreas Ericsson -Ankur Sethi -Ben Noordhuis -Ben Straub -Benjamin C Meyer -Brian Lopez -Carlos Martín Nieto -Colin Timmermans -Daniel Huckstep -Dave Borowitz -David Boyce -David Glesser -Dmitry Kovega -Emeric Fermas -Emmanuel Rodriguez -Ingmar Vanhassel -J. David Ibáñez -Jakob Pfender -Jason Penny -Jason R. McNeil -Jerome Lambourg -Johan 't Hart -John Wiegley -Jonathan "Duke" Leto -Julien Miotte -Julio Espinoza-Sokal -Justin Love -Kirill A. Shutemov -Lambert CLARA -Luc Bertrand -Marc Pegon -Marcel Groothuis -Marco Villegas -Olivier Ramonat -Peter Drahoš -Pierre Habouzit -Przemyslaw Pawelczyk -Ramsay Jones -Robert G. Jakabosky -Romain Geissler -Romain Muller -Russell Belfer -Sakari Jokinen -Sam -Sarath Lakshman -Sascha Peilicke -Scott Chacon -Sebastian Schuberth -Sergey Nikishin -Shawn O. Pearce -Shuhei Tanuma -Steve Frécinaux -Tim Branyen -Tim Clem -Tim Harder -Trent Mick -Vicent Marti -antong -kelly.leahy -schu diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index 7a7a943e582..00000000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,251 +0,0 @@ -# CMake build script for the libgit2 project -# -# Building (out of source build): -# > mkdir build && cd build -# > cmake .. [-DSETTINGS=VALUE] -# > cmake --build . -# -# Testing: -# > ctest -V -# -# Install: -# > cmake --build . --target install - -PROJECT(libgit2 C) -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) - -FILE(STRINGS "include/git2/version.h" GIT2_HEADER REGEX "^#define LIBGIT2_VERSION \"[^\"]*\"$") - -STRING(REGEX REPLACE "^.*LIBGIT2_VERSION \"([0-9]+).*$" "\\1" LIBGIT2_VERSION_MAJOR "${GIT2_HEADER}") -STRING(REGEX REPLACE "^.*LIBGIT2_VERSION \"[0-9]+\\.([0-9]+).*$" "\\1" LIBGIT2_VERSION_MINOR "${GIT2_HEADER}") -STRING(REGEX REPLACE "^.*LIBGIT2_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1" LIBGIT2_VERSION_REV "${GIT2_HEADER}") -SET(LIBGIT2_VERSION_STRING "${LIBGIT2_VERSION_MAJOR}.${LIBGIT2_VERSION_MINOR}.${LIBGIT2_VERSION_REV}") - -IF (AMIGA) - # Default AmigaOS to use the PowerPC SHA1 - SET(SHA1_TYPE "ppc") -ENDIF() - -# Find required dependencies -INCLUDE_DIRECTORIES(src include deps/http-parser) - -IF (WIN32 AND NOT MINGW) - ADD_DEFINITIONS(-DGIT_WINHTTP) -ELSE () - FIND_PACKAGE(OpenSSL) - FILE(GLOB SRC_HTTP deps/http-parser/*.c) -ENDIF() - -# Specify sha1 implementation -IF (SHA1_TYPE STREQUAL "ppc") - ADD_DEFINITIONS(-DPPC_SHA1) - FILE(GLOB SRC_SHA1 src/ppc/*.c src/ppc/*.S) -ELSE () - SET (SRC_SHA1) -ENDIF() - -IF (NOT WIN32) - FIND_PACKAGE(ZLIB) - IF (CMAKE_SYSTEM_NAME STREQUAL "AmigaOS") - INCLUDE_DIRECTORIES(deps/regex) - SET(SRC_REGEX deps/regex/regex.c) - ENDIF() -ELSE() - # Windows doesn't understand POSIX regex on its own - INCLUDE_DIRECTORIES(deps/regex) - SET(SRC_REGEX deps/regex/regex.c) -ENDIF() - -IF (ZLIB_FOUND) - INCLUDE_DIRECTORIES(${ZLIB_INCLUDE_DIRS}) - LINK_LIBRARIES(${ZLIB_LIBRARIES}) -ELSE (ZLIB_FOUND) - INCLUDE_DIRECTORIES(deps/zlib) - ADD_DEFINITIONS(-DNO_VIZ -DSTDC -DNO_GZIP) - FILE(GLOB SRC_ZLIB deps/zlib/*.c) -ENDIF() - -# Installation paths -SET(INSTALL_BIN bin CACHE PATH "Where to install binaries to.") -SET(LIB_INSTALL_DIR lib CACHE PATH "Where to install libraries to.") -SET(INSTALL_INC include CACHE PATH "Where to install headers to.") - -# Build options -OPTION (BUILD_SHARED_LIBS "Build Shared Library (OFF for Static)" ON) -OPTION (THREADSAFE "Build libgit2 as threadsafe" OFF) -OPTION (BUILD_CLAR "Build Tests using the Clar suite" ON) -OPTION (BUILD_EXAMPLES "Build library usage example apps" OFF) -OPTION (TAGS "Generate tags" OFF) -OPTION (PROFILE "Generate profiling information" OFF) - -# Platform specific compilation flags -IF (MSVC) - # Default to stdcall, as that's what the CLR expects and how the Windows API is built - OPTION (STDCALL "Buildl libgit2 with the __stdcall convention" ON) - - SET(CMAKE_C_FLAGS "/W4 /MP /nologo /Zi ${CMAKE_C_FLAGS}") - IF (STDCALL) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Gz") - ENDIF () - SET(CMAKE_C_FLAGS_DEBUG "/Od /DEBUG /MTd /RTC1 /RTCs /RTCu") - SET(CMAKE_C_FLAGS_RELEASE "/MT /O2") - SET(WIN_RC "src/win32/git2.rc") - - # Precompiled headers -ELSE () - SET(CMAKE_C_FLAGS "-O2 -g -D_GNU_SOURCE -Wall -Wextra -Wno-missing-field-initializers -Wstrict-aliasing=2 -Wstrict-prototypes -Wmissing-prototypes ${CMAKE_C_FLAGS}") - SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") - IF (MINGW) # MinGW always does PIC and complains if we tell it to - STRING(REGEX REPLACE "-fPIC" "" CMAKE_SHARED_LIBRARY_C_FLAGS "${CMAKE_SHARED_LIBRARY_C_FLAGS}") - ELSE () - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fvisibility=hidden -fPIC") - ENDIF () - IF (PROFILE) - SET(CMAKE_C_FLAGS "-pg ${CMAKE_C_FLAGS}") - SET(CMAKE_EXE_LINKER_FLAGS "-pg ${CMAKE_EXE_LINKER_FLAGS}") - ENDIF () -ENDIF() - -# Build Debug by default -IF (NOT CMAKE_BUILD_TYPE) - SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) -ENDIF () - -IF (OPENSSL_FOUND) - ADD_DEFINITIONS(-DGIT_SSL) - INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR}) - SET(SSL_LIBRARIES ${OPENSSL_LIBRARIES}) -ENDIF() - -IF (THREADSAFE) - IF (NOT WIN32) - find_package(Threads REQUIRED) - ENDIF() - - ADD_DEFINITIONS(-DGIT_THREADS) -ENDIF() - -ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64) - -# Collect sourcefiles -FILE(GLOB SRC_H include/git2/*.h) - -# On Windows use specific platform sources -IF (WIN32 AND NOT CYGWIN) - ADD_DEFINITIONS(-DWIN32 -D_DEBUG -D_WIN32_WINNT=0x0501) - FILE(GLOB SRC src/*.c src/transports/*.c src/xdiff/*.c src/win32/*.c src/compat/*.c) -ELSEIF (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") - FILE(GLOB SRC src/*.c src/transports/*.c src/xdiff/*.c src/unix/*.c src/compat/*.c) -ELSEIF (AMIGA) - ADD_DEFINITIONS(-DNO_ADDRINFO -DNO_READDIR_R) - FILE(GLOB SRC src/*.c src/transports/*.c src/xdiff/*.c src/amiga/*.c src/compat/*.c) -ELSE() - FILE(GLOB SRC src/*.c src/transports/*.c src/xdiff/*.c src/unix/*.c) -ENDIF () - -# Compile and link libgit2 -ADD_LIBRARY(git2 ${SRC} ${SRC_ZLIB} ${SRC_HTTP} ${SRC_REGEX} ${SRC_SHA1} ${WIN_RC}) - -IF (WIN32) - TARGET_LINK_LIBRARIES(git2 ws2_32) -ELSEIF (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") - TARGET_LINK_LIBRARIES(git2 socket nsl) -ENDIF () - -TARGET_LINK_LIBRARIES(git2 ${CMAKE_THREAD_LIBS_INIT} ${SSL_LIBRARIES}) -SET_TARGET_PROPERTIES(git2 PROPERTIES VERSION ${LIBGIT2_VERSION_STRING}) -SET_TARGET_PROPERTIES(git2 PROPERTIES SOVERSION ${LIBGIT2_VERSION_MAJOR}) -CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/libgit2.pc.in ${CMAKE_CURRENT_BINARY_DIR}/libgit2.pc @ONLY) - -IF (MSVC) - # Precompiled headers - SET_TARGET_PROPERTIES(git2 PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h") - SET_SOURCE_FILES_PROPERTIES(src/win32/precompiled.c COMPILE_FLAGS "/Ycprecompiled.h") -ENDIF () - -# Backward compatibility with INSTALL_LIB variable -if (INSTALL_LIB) - set(LIB_INSTALL_DIR "${INSTALL_LIB}") -ENDIF() - -# Install -INSTALL(TARGETS git2 - RUNTIME DESTINATION ${INSTALL_BIN} - LIBRARY DESTINATION ${LIB_INSTALL_DIR} - ARCHIVE DESTINATION ${LIB_INSTALL_DIR} -) -INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/libgit2.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig ) -INSTALL(DIRECTORY include/git2 DESTINATION ${INSTALL_INC} ) -INSTALL(FILES include/git2.h DESTINATION ${INSTALL_INC} ) - -# Tests -IF (BUILD_CLAR) - - FIND_PACKAGE(PythonInterp REQUIRED) - - SET(CLAR_FIXTURES "${CMAKE_CURRENT_SOURCE_DIR}/tests-clar/resources/") - SET(CLAR_PATH "${CMAKE_CURRENT_SOURCE_DIR}/tests-clar") - SET(CLAR_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/tests-clar/resources" CACHE PATH "Path to test resources.") - ADD_DEFINITIONS(-DCLAR_FIXTURE_PATH=\"${CLAR_FIXTURES}\") - ADD_DEFINITIONS(-DCLAR_RESOURCES=\"${TEST_RESOURCES}\") - - INCLUDE_DIRECTORIES(${CLAR_PATH}) - FILE(GLOB_RECURSE SRC_TEST ${CLAR_PATH}/*/*.c ${CLAR_PATH}/clar_helpers.c ${CLAR_PATH}/testlib.c) - - ADD_CUSTOM_COMMAND( - OUTPUT ${CLAR_PATH}/clar_main.c ${CLAR_PATH}/clar.h - COMMAND ${PYTHON_EXECUTABLE} clar -vtap . - DEPENDS ${CLAR_PATH}/clar ${SRC_TEST} - WORKING_DIRECTORY ${CLAR_PATH} - ) - ADD_EXECUTABLE(libgit2_clar ${SRC} ${CLAR_PATH}/clar_main.c ${SRC_TEST} ${SRC_ZLIB} ${SRC_HTTP} ${SRC_REGEX}) - TARGET_LINK_LIBRARIES(libgit2_clar ${CMAKE_THREAD_LIBS_INIT} ${SSL_LIBRARIES}) - - IF (MSVC) - # Precompiled headers - SET_TARGET_PROPERTIES(libgit2_clar PROPERTIES COMPILE_FLAGS "/Yuprecompiled.h /FIprecompiled.h") - ENDIF () - - IF (WIN32) - TARGET_LINK_LIBRARIES(libgit2_clar ws2_32) - ELSEIF (CMAKE_SYSTEM_NAME MATCHES "(Solaris|SunOS)") - TARGET_LINK_LIBRARIES(libgit2_clar socket nsl) - ENDIF () - - ENABLE_TESTING() - ADD_TEST(libgit2_clar libgit2_clar) -ENDIF () - -IF (TAGS) - FIND_PROGRAM(CTAGS ctags) - IF (NOT CTAGS) - message(FATAL_ERROR "Could not find ctags command") - ENDIF () - - FILE(GLOB_RECURSE SRC_ALL *.[ch]) - - ADD_CUSTOM_COMMAND( - OUTPUT tags - COMMAND ${CTAGS} -a ${SRC_ALL} - DEPENDS ${SRC_ALL} - ) - ADD_CUSTOM_TARGET( - do_tags ALL - DEPENDS tags - ) -ENDIF () - -IF (BUILD_EXAMPLES) - FILE(GLOB_RECURSE EXAMPLE_SRC examples/network/*.c) - ADD_EXECUTABLE(cgit2 ${EXAMPLE_SRC}) - TARGET_LINK_LIBRARIES(cgit2 git2 pthread) - - ADD_EXECUTABLE(git-diff examples/diff.c) - TARGET_LINK_LIBRARIES(git-diff git2) - - ADD_EXECUTABLE(git-general examples/general.c) - TARGET_LINK_LIBRARIES(git-general git2) - - ADD_EXECUTABLE(git-showindex examples/showindex.c) - TARGET_LINK_LIBRARIES(git-showindex git2) -ENDIF () diff --git a/CONVENTIONS b/CONVENTIONS deleted file mode 100644 index f082d8e6c9c..00000000000 --- a/CONVENTIONS +++ /dev/null @@ -1,107 +0,0 @@ -libgit2 conventions -=================== - -Namespace Prefixes ------------------- - -All types and functions start with 'git_'. - -All #define macros start with 'GIT_'. - - -Type Definitions ----------------- - -Most types should be opaque, e.g.: - ----- - typedef struct git_odb git_odb; ----- - -with allocation functions returning an "instance" created within -the library, and not within the application. This allows the type -to grow (or shrink) in size without rebuilding client code. - - -Public Exported Function Definitions ------------------------------------- - -All exported functions must be declared as: - ----- - GIT_EXTERN(result_type) git_modulename_functionname(arg_list); ----- - - -Semi-Private Exported Functions -------------------------------- - -Functions whose modulename is followed by two underscores, -for example 'git_odb__read_packed', are semi-private functions. -They are primarily intended for use within the library itself, -and may disappear or change their signature in a future release. - - -Calling Conventions -------------------- - -Functions should prefer to return a 'int' to indicate success or -failure and supply any output through the first argument (or first -few arguments if multiple outputs are supplied). - -int status codes are 0 for GIT_OK and < 0 for an error. -This permits common POSIX result testing: - ----- - if (git_odb_open(&odb, path)) - abort("odb open failed"); ----- - -Functions returning a pointer may return NULL instead of an int -if there is only one type of failure (GIT_ENOMEM). - -Functions returning a pointer may also return NULL if the common -case needed by the application is strictly success/failure and a -(possibly slower) function exists that the caller can use to get -more detailed information. Parsing common data structures from -on-disk formats is a good example of this pattern; in general a -"corrupt" entity can be treated as though it does not exist but -a more sophisticated "fsck" support function can report how the -entity is malformed. - - -Documentation Fomatting ------------------------ - -All comments should conform to Doxygen "javadoc" style conventions -for formatting the public API documentation. - - -Public Header Format --------------------- - -All public headers defining types, functions or macros must use -the following form, where ${filename} is the name of the file, -after replacing non-identifier characters with '_'. - ----- - #ifndef INCLUDE_git_${filename}_h__ - #define INCLUDE_git_${filename}_h__ - - #include "git/common.h" - - /** - * @file git/${filename}.h - * @brief Git some description - * @defgroup git_${filename} some description routines - * @ingroup Git - * @{ - */ - GIT_BEGIN_DECL - - ... definitions ... - - /** @} */ - GIT_END_DECL - #endif ----- diff --git a/COPYING b/COPYING deleted file mode 100644 index e3f9969d05a..00000000000 --- a/COPYING +++ /dev/null @@ -1,930 +0,0 @@ - libgit2 is Copyright (C) 2009-2012 the libgit2 contributors, - unless otherwise stated. See the AUTHORS file for details. - - Note that the only valid version of the GPL as far as this project - is concerned is _this_ particular version of the license (ie v2, not - v2.2 or v3.x or whatever), unless explicitly otherwise stated. - ----------------------------------------------------------------------- - - LINKING EXCEPTION - - In addition to the permissions in the GNU General Public License, - the authors give you unlimited permission to link the compiled - version of this library into combinations with other programs, - and to distribute those combinations without any restriction - coming from the use of this file. (The General Public License - restrictions do apply in other respects; for example, they cover - modification of the file, and distribution when not linked into - a combined executable.) - ----------------------------------------------------------------------- - - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. - ----------------------------------------------------------------------- - -The bundled ZLib code is licensed under the ZLib license: - -Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - ----------------------------------------------------------------------- - -The priority queue implementation is based on code licensed under the -Apache 2.0 license: - - Copyright 2010 Volkan Yazıcı - Copyright 2006-2010 The Apache Software Foundation - -The full text of the Apache 2.0 license is available at: - - http://www.apache.org/licenses/LICENSE-2.0 - ----------------------------------------------------------------------- - -The Clay framework is licensed under the MIT license: - -Copyright (C) 2011 by Vicent Marti - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - ----------------------------------------------------------------------- - -The regex library (deps/regex/) is licensed under the GNU LGPL - - GNU LESSER GENERAL PUBLIC LICENSE - Version 2.1, February 1999 - - Copyright (C) 1991, 1999 Free Software Foundation, Inc. - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the Lesser GPL. It also counts - as the successor of the GNU Library Public License, version 2, hence - the version number 2.1.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Lesser General Public License, applies to some -specially designated software packages--typically libraries--of the -Free Software Foundation and other authors who decide to use it. You -can use it too, but we suggest you first think carefully about whether -this license or the ordinary General Public License is the better -strategy to use in any particular case, based on the explanations below. - - When we speak of free software, we are referring to freedom of use, -not price. Our General Public Licenses are designed to make sure that -you have the freedom to distribute copies of free software (and charge -for this service if you wish); that you receive source code or can get -it if you want it; that you can change the software and use pieces of -it in new free programs; and that you are informed that you can do -these things. - - To protect your rights, we need to make restrictions that forbid -distributors to deny you these rights or to ask you to surrender these -rights. These restrictions translate to certain responsibilities for -you if you distribute copies of the library or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link other code with the library, you must provide -complete object files to the recipients, so that they can relink them -with the library after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - We protect your rights with a two-step method: (1) we copyright the -library, and (2) we offer you this license, which gives you legal -permission to copy, distribute and/or modify the library. - - To protect each distributor, we want to make it very clear that -there is no warranty for the free library. Also, if the library is -modified by someone else and passed on, the recipients should know -that what they have is not the original version, so that the original -author's reputation will not be affected by problems that might be -introduced by others. - - Finally, software patents pose a constant threat to the existence of -any free program. We wish to make sure that a company cannot -effectively restrict the users of a free program by obtaining a -restrictive license from a patent holder. Therefore, we insist that -any patent license obtained for a version of the library must be -consistent with the full freedom of use specified in this license. - - Most GNU software, including some libraries, is covered by the -ordinary GNU General Public License. This license, the GNU Lesser -General Public License, applies to certain designated libraries, and -is quite different from the ordinary General Public License. We use -this license for certain libraries in order to permit linking those -libraries into non-free programs. - - When a program is linked with a library, whether statically or using -a shared library, the combination of the two is legally speaking a -combined work, a derivative of the original library. The ordinary -General Public License therefore permits such linking only if the -entire combination fits its criteria of freedom. The Lesser General -Public License permits more lax criteria for linking other code with -the library. - - We call this license the "Lesser" General Public License because it -does Less to protect the user's freedom than the ordinary General -Public License. It also provides other free software developers Less -of an advantage over competing non-free programs. These disadvantages -are the reason we use the ordinary General Public License for many -libraries. However, the Lesser license provides advantages in certain -special circumstances. - - For example, on rare occasions, there may be a special need to -encourage the widest possible use of a certain library, so that it becomes -a de-facto standard. To achieve this, non-free programs must be -allowed to use the library. A more frequent case is that a free -library does the same job as widely used non-free libraries. In this -case, there is little to gain by limiting the free library to free -software only, so we use the Lesser General Public License. - - In other cases, permission to use a particular library in non-free -programs enables a greater number of people to use a large body of -free software. For example, permission to use the GNU C Library in -non-free programs enables many more people to use the whole GNU -operating system, as well as its variant, the GNU/Linux operating -system. - - Although the Lesser General Public License is Less protective of the -users' freedom, it does ensure that the user of a program that is -linked with the Library has the freedom and the wherewithal to run -that program using a modified version of the Library. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, whereas the latter must -be combined with the library in order to run. - - GNU LESSER GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library or other -program which contains a notice placed by the copyright holder or -other authorized party saying it may be distributed under the terms of -this Lesser General Public License (also called "this License"). -Each licensee is addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also combine or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Use a suitable shared library mechanism for linking with the - Library. A suitable mechanism is one that (1) uses at run time a - copy of the library already present on the user's computer system, - rather than copying library functions into the executable, and (2) - will operate properly with a modified version of the library, if - the user installs one, as long as the modified version is - interface-compatible with the version that the work was made with. - - c) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - d) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - e) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the materials to be distributed need not include anything that is -normally distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties with -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Lesser General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with this library; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/HEAD.json b/HEAD.json new file mode 100644 index 00000000000..8ff742606a2 --- /dev/null +++ b/HEAD.json @@ -0,0 +1 @@ +{"files":[{"file":"reflog.h","functions":["git_reflog_read","git_reflog_write","git_reflog_append","git_reflog_rename","git_reflog_delete","git_reflog_entrycount","git_reflog_entry_byindex","git_reflog_drop","git_reflog_entry_oidold","git_reflog_entry_oidnew","git_reflog_entry_committer","git_reflog_entry_msg","git_reflog_free"],"meta":{"brief":"Git reflog management routines","defgroup":"git_reflog Git reflog management routines","ingroup":"Git","comments":"\n"},"lines":158},{"file":"clone.h","functions":["git_clone","git_clone_bare"],"meta":{"brief":"Git cloning routines","defgroup":"git_clone Git cloning routines","ingroup":"Git","comments":"\n"},"lines":59},{"file":"branch.h","functions":["git_branch_create","git_branch_delete","git_branch_foreach","git_branch_move","git_branch_lookup","git_branch_tracking"],"meta":{"brief":"Git branch parsing routines","defgroup":"git_branch Git branch management","ingroup":"Git","comments":"\n"},"lines":153},{"file":"indexer.h","functions":["git_indexer_stream_new","git_indexer_stream_add","git_indexer_stream_finalize","git_indexer_stream_hash","git_indexer_stream_free","git_indexer_new","git_indexer_run","git_indexer_write","git_indexer_hash","git_indexer_free"],"meta":{},"lines":122},{"file":"common.h","functions":["git_libgit2_version","git_libgit2_capabilities"],"meta":{"brief":"Git common platform definitions","defgroup":"git_common Git common platform definitions","ingroup":"Git","comments":"\n"},"lines":131},{"file":"refspec.h","functions":["git_refspec_parse","git_refspec_src","git_refspec_dst","git_refspec_force","git_refspec_src_matches","git_refspec_transform"],"meta":{"brief":"Git refspec attributes","defgroup":"git_refspec Git refspec attributes","ingroup":"Git","comments":"\n"},"lines":76},{"file":"signature.h","functions":["git_signature_new","git_signature_now","git_signature_dup","git_signature_free"],"meta":{"brief":"Git signature creation","defgroup":"git_signature Git signature creation","ingroup":"Git","comments":"\n"},"lines":68},{"file":"version.h","functions":[],"meta":{},"lines":15},{"file":"status.h","functions":["git_status_foreach","git_status_foreach_ext","git_status_file","git_status_should_ignore"],"meta":{"brief":"Git file status routines","defgroup":"git_status Git file status routines","ingroup":"Git","comments":"\n"},"lines":167},{"file":"notes.h","functions":["git_note_read","git_note_message","git_note_oid","git_note_create","git_note_remove","git_note_free","git_note_default_ref","git_note_foreach"],"meta":{"brief":"Git notes management routines","defgroup":"git_note Git notes management routines","ingroup":"Git","comments":"\n"},"lines":143},{"file":"config.h","functions":["git_config_find_global","git_config_find_system","git_config_open_default","git_config_file__ondisk","git_config_new","git_config_add_file","git_config_add_file_ondisk","git_config_open_ondisk","git_config_free","git_config_get_int32","git_config_get_int64","git_config_get_bool","git_config_get_string","git_config_get_multivar","git_config_set_int32","git_config_set_int64","git_config_set_bool","git_config_set_string","git_config_set_multivar","git_config_delete","git_config_foreach","git_config_foreach_match","git_config_get_mapped"],"meta":{"brief":"Git config management routines","defgroup":"git_config Git config management routines","ingroup":"Git","comments":"\n"},"lines":375},{"file":"net.h","functions":[],"meta":{"brief":"Git networking declarations","ingroup":"Git","comments":"\n"},"lines":51},{"file":"reset.h","functions":["git_reset"],"meta":{"brief":"Git reset management routines","ingroup":"Git","comments":"\n"},"lines":47},{"file":"blob.h","functions":["git_blob_lookup","git_blob_lookup_prefix","git_blob_free","git_blob_rawcontent","git_blob_rawsize","git_blob_create_fromfile","git_blob_create_fromdisk","git_blob_create_fromchunks","git_blob_create_frombuffer"],"meta":{"brief":"Git blob load and write routines","defgroup":"git_blob Git blob load and write routines","ingroup":"Git","comments":"\n"},"lines":174},{"file":"index.h","functions":["git_index_open","git_index_clear","git_index_free","git_index_caps","git_index_set_caps","git_index_read","git_index_write","git_index_find","git_index_uniq","git_index_add","git_index_add2","git_index_append","git_index_append2","git_index_remove","git_index_get","git_index_entrycount","git_index_entrycount_unmerged","git_index_get_unmerged_bypath","git_index_get_unmerged_byindex","git_index_entry_stage","git_index_read_tree"],"meta":{"brief":"Git index parsing and manipulation routines","defgroup":"git_index Git index parsing and manipulation routines","ingroup":"Git","comments":"\n"},"lines":353},{"file":"repository.h","functions":["git_repository_open","git_repository_wrap_odb","git_repository_discover","git_repository_open_ext","git_repository_free","git_repository_init","git_repository_init_ext","git_repository_head","git_repository_head_detached","git_repository_head_orphan","git_repository_is_empty","git_repository_path","git_repository_workdir","git_repository_set_workdir","git_repository_is_bare","git_repository_config","git_repository_set_config","git_repository_odb","git_repository_set_odb","git_repository_index","git_repository_set_index","git_repository_message","git_repository_message_remove","git_repository_hashfile","git_repository_set_head","git_repository_set_head_detached","git_repository_detach_head"],"meta":{"brief":"Git repository management routines","defgroup":"git_repository Git repository management routines","ingroup":"Git","comments":"\n"},"lines":572},{"file":"tag.h","functions":["git_tag_lookup","git_tag_lookup_prefix","git_tag_free","git_tag_id","git_tag_target","git_tag_target_oid","git_tag_type","git_tag_name","git_tag_tagger","git_tag_message","git_tag_create","git_tag_create_frombuffer","git_tag_create_lightweight","git_tag_delete","git_tag_list","git_tag_list_match","git_tag_peel"],"meta":{"brief":"Git tag parsing routines","defgroup":"git_tag Git tag management","ingroup":"Git","comments":"\n"},"lines":297},{"file":"odb_backend.h","functions":[],"meta":{"brief":"Git custom backend functions","defgroup":"git_backend Git custom backend API","ingroup":"Git","comments":"\n"},"lines":113},{"file":"revparse.h","functions":["git_revparse_single"],"meta":{"brief":"Git revision parsing routines","defgroup":"git_revparse Git revision parsing routines","ingroup":"Git","comments":"\n"},"lines":36},{"file":"stdint.h","functions":[],"meta":{},"lines":247},{"file":"inttypes.h","functions":[],"meta":{},"lines":305},{"file":"commit.h","functions":["git_commit_lookup","git_commit_lookup_prefix","git_commit_free","git_commit_id","git_commit_message_encoding","git_commit_message","git_commit_time","git_commit_time_offset","git_commit_committer","git_commit_author","git_commit_tree","git_commit_tree_oid","git_commit_parentcount","git_commit_parent","git_commit_parent_oid","git_commit_nth_gen_ancestor","git_commit_create","git_commit_create_v"],"meta":{"brief":"Git commit parsing, formatting routines","defgroup":"git_commit Git commit parsing, formatting routines","ingroup":"Git","comments":"\n"},"lines":289},{"file":"types.h","functions":[],"meta":{"brief":"libgit2 base & compatibility types","ingroup":"Git","comments":"\n"},"lines":198},{"file":"remote.h","functions":["git_remote_new","git_remote_load","git_remote_save","git_remote_name","git_remote_url","git_remote_pushurl","git_remote_set_url","git_remote_set_pushurl","git_remote_set_fetchspec","git_remote_fetchspec","git_remote_set_pushspec","git_remote_pushspec","git_remote_connect","git_remote_ls","git_remote_download","git_remote_connected","git_remote_disconnect","git_remote_free","git_remote_update_tips","git_remote_valid_url","git_remote_supported_url","git_remote_list","git_remote_add","git_remote_check_cert","git_remote_set_callbacks"],"meta":{"brief":"Git remote management functions","defgroup":"git_remote remote management functions","ingroup":"Git","comments":"\n"},"lines":309},{"file":"merge.h","functions":["git_merge_base","git_merge_base_many"],"meta":{"brief":"Git merge-base routines","defgroup":"git_revwalk Git merge-base routines","ingroup":"Git","comments":"\n"},"lines":45},{"file":"diff.h","functions":["git_diff_list_free","git_diff_tree_to_tree","git_diff_index_to_tree","git_diff_workdir_to_index","git_diff_workdir_to_tree","git_diff_merge","git_diff_foreach","git_diff_iterator_new","git_diff_iterator_free","git_diff_iterator_progress","git_diff_iterator_num_hunks_in_file","git_diff_iterator_num_lines_in_hunk","git_diff_iterator_next_file","git_diff_iterator_next_hunk","git_diff_iterator_next_line","git_diff_print_compact","git_diff_print_patch","git_diff_entrycount","git_diff_blobs"],"meta":{"brief":"Git tree and file differencing routines.","ingroup":"Git","comments":"\n"},"lines":600},{"file":"checkout.h","functions":["git_checkout_head","git_checkout_index","git_checkout_tree"],"meta":{"brief":"Git checkout routines","defgroup":"git_checkout Git checkout routines","ingroup":"Git","comments":"\n"},"lines":94},{"file":"tree.h","functions":["git_tree_lookup","git_tree_lookup_prefix","git_tree_free","git_tree_entry_free","git_tree_entry_dup","git_tree_id","git_tree_entrycount","git_tree_entry_byname","git_tree_entry_byindex","git_tree_entry_byoid","git_tree_entry_filemode","git_tree_entry_name","git_tree_entry_id","git_tree_entry_type","git_tree_entry_to_object","git_tree_create_fromindex","git_treebuilder_create","git_treebuilder_clear","git_treebuilder_free","git_treebuilder_get","git_treebuilder_insert","git_treebuilder_remove","git_treebuilder_filter","git_treebuilder_write","git_tree_entry_bypath","git_tree_walk"],"meta":{"brief":"Git tree parsing, loading routines","defgroup":"git_tree Git tree parsing, loading routines","ingroup":"Git","comments":"\n"},"lines":374},{"file":"submodule.h","functions":["git_submodule_lookup","git_submodule_foreach","git_submodule_add_setup","git_submodule_add_finalize","git_submodule_add_to_index","git_submodule_save","git_submodule_owner","git_submodule_name","git_submodule_path","git_submodule_url","git_submodule_set_url","git_submodule_index_oid","git_submodule_head_oid","git_submodule_wd_oid","git_submodule_ignore","git_submodule_set_ignore","git_submodule_update","git_submodule_set_update","git_submodule_fetch_recurse_submodules","git_submodule_set_fetch_recurse_submodules","git_submodule_init","git_submodule_sync","git_submodule_open","git_submodule_reload","git_submodule_reload_all","git_submodule_status"],"meta":{"brief":"Git submodule management utilities","defgroup":"git_submodule Git submodule management routines","ingroup":"Git","comments":"\n"},"lines":502},{"file":"ignore.h","functions":["git_ignore_add_rule","git_ignore_clear_internal_rules","git_ignore_path_is_ignored"],"meta":{},"lines":74},{"file":"message.h","functions":["git_message_prettify"],"meta":{"brief":"Git message management routines","ingroup":"Git","comments":"\n"},"lines":43},{"file":"odb.h","functions":["git_odb_new","git_odb_open","git_odb_add_backend","git_odb_add_alternate","git_odb_free","git_odb_read","git_odb_read_prefix","git_odb_read_header","git_odb_exists","git_odb_foreach","git_odb_write","git_odb_open_wstream","git_odb_open_rstream","git_odb_hash","git_odb_hashfile","git_odb_object_free","git_odb_object_id","git_odb_object_data","git_odb_object_size","git_odb_object_type"],"meta":{"brief":"Git object database routines","defgroup":"git_odb Git object database routines","ingroup":"Git","comments":"\n"},"lines":346},{"file":"threads.h","functions":["git_threads_init","git_threads_shutdown"],"meta":{"brief":"Library level thread functions","defgroup":"git_thread Threading functions","ingroup":"Git","comments":"\n"},"lines":47},{"file":"oid.h","functions":["git_oid_fromstr","git_oid_fromstrn","git_oid_fromraw","git_oid_fmt","git_oid_pathfmt","git_oid_allocfmt","git_oid_tostr","git_oid_cpy","git_oid_cmp","git_oid_equal","git_oid_ncmp","git_oid_streq","git_oid_iszero","git_oid_shorten_new","git_oid_shorten_add","git_oid_shorten_free"],"meta":{"brief":"Git object id routines","defgroup":"git_oid Git object id routines","ingroup":"Git","comments":"\n"},"lines":249},{"file":"attr.h","functions":["git_attr_get","git_attr_get_many","git_attr_foreach","git_attr_cache_flush","git_attr_add_macro"],"meta":{"brief":"Git attribute management routines","defgroup":"git_attr Git attribute management routines","ingroup":"Git","comments":"\n"},"lines":238},{"file":"errors.h","functions":["giterr_last","giterr_clear"],"meta":{"brief":"Git error handling routines and variables","ingroup":"Git","comments":"\n"},"lines":76},{"file":"revwalk.h","functions":["git_revwalk_new","git_revwalk_reset","git_revwalk_push","git_revwalk_push_glob","git_revwalk_push_head","git_revwalk_hide","git_revwalk_hide_glob","git_revwalk_hide_head","git_revwalk_push_ref","git_revwalk_hide_ref","git_revwalk_next","git_revwalk_sorting","git_revwalk_free","git_revwalk_repository"],"meta":{"brief":"Git revision traversal routines","defgroup":"git_revwalk Git revision traversal routines","ingroup":"Git","comments":"\n"},"lines":237},{"file":"object.h","functions":["git_object_lookup","git_object_lookup_prefix","git_object_id","git_object_type","git_object_owner","git_object_free","git_object_type2string","git_object_string2type","git_object_typeisloose","git_object__size","git_object_peel"],"meta":{"brief":"Git revision object management routines","defgroup":"git_object Git revision object management routines","ingroup":"Git","comments":"\n"},"lines":193},{"file":"refs.h","functions":["git_reference_lookup","git_reference_name_to_oid","git_reference_create_symbolic","git_reference_create_oid","git_reference_oid","git_reference_target","git_reference_type","git_reference_name","git_reference_resolve","git_reference_owner","git_reference_set_target","git_reference_set_oid","git_reference_rename","git_reference_delete","git_reference_packall","git_reference_list","git_reference_foreach","git_reference_is_packed","git_reference_reload","git_reference_free","git_reference_cmp","git_reference_foreach_glob","git_reference_has_log","git_reference_is_branch","git_reference_is_remote","git_reference_normalize_name","git_reference_peel"],"meta":{"brief":"Git reference management routines","defgroup":"git_reference Git reference management routines","ingroup":"Git","comments":"\n"},"lines":459}],"functions":{"git_reflog_read":{"type":"function","file":"reflog.h","line":37,"lineto":37,"args":[{"name":"reflog","type":"git_reflog **","comment":"pointer to reflog"},{"name":"ref","type":"git_reference *","comment":"log pointer to reflog"}],"argline":"git_reflog **reflog, git_reference *ref","sig":"git_reflog **::git_reference *","return":{"type":"int","comment":"0 or an error code"},"description":"Read the reflog for the given reference","comments":"If there is no reflog file for the given\nreference yet, an empty reflog object will\nbe returned.\n\nThe reflog must be freed manually by using\ngit_reflog_free().\n","group":"reflog"},"git_reflog_write":{"type":"function","file":"reflog.h","line":46,"lineto":46,"args":[{"name":"reflog","type":"git_reflog *","comment":"an existing reflog object"}],"argline":"git_reflog *reflog","sig":"git_reflog *","return":{"type":"int","comment":"0 or an error code"},"description":"Write an existing in-memory reflog object back to disk\nusing an atomic file lock.","comments":"","group":"reflog"},"git_reflog_append":{"type":"function","file":"reflog.h","line":59,"lineto":59,"args":[{"name":"reflog","type":"git_reflog *","comment":"an existing reflog object"},{"name":"new_oid","type":"const git_oid *","comment":"the OID the reference is now pointing to"},{"name":"committer","type":"const git_signature *","comment":"the signature of the committer"},{"name":"msg","type":"const char *","comment":"the reflog message"}],"argline":"git_reflog *reflog, const git_oid *new_oid, const git_signature *committer, const char *msg","sig":"git_reflog *::const git_oid *::const git_signature *::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Add a new entry to the reflog.","comments":"`msg` is optional and can be NULL.\n","group":"reflog"},"git_reflog_rename":{"type":"function","file":"reflog.h","line":70,"lineto":70,"args":[{"name":"ref","type":"git_reference *","comment":"the reference"},{"name":"new_name","type":"const char *","comment":"the new name of the reference"}],"argline":"git_reference *ref, const char *new_name","sig":"git_reference *::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Rename the reflog for the given reference","comments":"The reflog to be renamed is expected to already exist\n","group":"reflog"},"git_reflog_delete":{"type":"function","file":"reflog.h","line":78,"lineto":78,"args":[{"name":"ref","type":"git_reference *","comment":"the reference"}],"argline":"git_reference *ref","sig":"git_reference *","return":{"type":"int","comment":"0 or an error code"},"description":"Delete the reflog for the given reference","comments":"","group":"reflog"},"git_reflog_entrycount":{"type":"function","file":"reflog.h","line":86,"lineto":86,"args":[{"name":"reflog","type":"git_reflog *","comment":"the previously loaded reflog"}],"argline":"git_reflog *reflog","sig":"git_reflog *","return":{"type":"unsigned int","comment":"the number of log entries"},"description":"Get the number of log entries in a reflog","comments":"","group":"reflog"},"git_reflog_entry_byindex":{"type":"function","file":"reflog.h","line":95,"lineto":95,"args":[{"name":"reflog","type":"git_reflog *","comment":"a previously loaded reflog"},{"name":"idx","type":"size_t","comment":"the position to lookup"}],"argline":"git_reflog *reflog, size_t idx","sig":"git_reflog *::size_t","return":{"type":"const git_reflog_entry *","comment":"the entry; NULL if not found"},"description":"Lookup an entry by its index","comments":"","group":"reflog"},"git_reflog_drop":{"type":"function","file":"reflog.h","line":112,"lineto":115,"args":[{"name":"reflog","type":"git_reflog *","comment":"a previously loaded reflog."},{"name":"idx","type":"unsigned int","comment":"the position of the entry to remove."},{"name":"rewrite_previous_entry","type":"int","comment":"1 to rewrite the history; 0 otherwise."}],"argline":"git_reflog *reflog,\n\tunsigned int idx,\n\tint rewrite_previous_entry","sig":"git_reflog *::unsigned int::int","return":{"type":"int","comment":"0 on success or an error code."},"description":"Remove an entry from the reflog by its index","comments":"To ensure there's no gap in the log history, set the `rewrite_previosu_entry` to 1.\nWhen deleting entry `n`, member old_oid of entry `n-1` (if any) will be updated with\nthe value of memeber new_oid of entry `n+1`.\n","group":"reflog"},"git_reflog_entry_oidold":{"type":"function","file":"reflog.h","line":123,"lineto":123,"args":[{"name":"entry","type":"const git_reflog_entry *","comment":"a reflog entry"}],"argline":"const git_reflog_entry *entry","sig":"const git_reflog_entry *","return":{"type":"const git_oid *","comment":"the old oid"},"description":"Get the old oid","comments":"","group":"reflog"},"git_reflog_entry_oidnew":{"type":"function","file":"reflog.h","line":131,"lineto":131,"args":[{"name":"entry","type":"const git_reflog_entry *","comment":"a reflog entry"}],"argline":"const git_reflog_entry *entry","sig":"const git_reflog_entry *","return":{"type":"const git_oid *","comment":"the new oid at this time"},"description":"Get the new oid","comments":"","group":"reflog"},"git_reflog_entry_committer":{"type":"function","file":"reflog.h","line":139,"lineto":139,"args":[{"name":"entry","type":"const git_reflog_entry *","comment":"a reflog entry"}],"argline":"const git_reflog_entry *entry","sig":"const git_reflog_entry *","return":{"type":"git_signature *","comment":"the committer"},"description":"Get the committer of this entry","comments":"","group":"reflog"},"git_reflog_entry_msg":{"type":"function","file":"reflog.h","line":147,"lineto":147,"args":[{"name":"entry","type":"const git_reflog_entry *","comment":"a reflog entry"}],"argline":"const git_reflog_entry *entry","sig":"const git_reflog_entry *","return":{"type":"char *","comment":"the log msg"},"description":"Get the log msg","comments":"","group":"reflog"},"git_reflog_free":{"type":"function","file":"reflog.h","line":154,"lineto":154,"args":[{"name":"reflog","type":"git_reflog *","comment":"reflog to free"}],"argline":"git_reflog *reflog","sig":"git_reflog *","return":{"type":"void"},"description":"Free the reflog","comments":"","group":"reflog"},"git_clone":{"type":"function","file":"clone.h","line":36,"lineto":41,"args":[{"name":"out","type":"git_repository **","comment":"pointer that will receive the resulting repository object"},{"name":"origin_url","type":"const char *","comment":"repository to clone from"},{"name":"workdir_path","type":"const char *","comment":"local directory to clone to"},{"name":"fetch_stats","type":"git_indexer_stats *","comment":"pointer to structure that receives fetch progress information (may be NULL)"},{"name":"checkout_stats","type":"git_indexer_stats *"},{"name":"checkout_opts","type":"git_checkout_opts *","comment":"options for the checkout step (may be NULL)"}],"argline":"git_repository **out,\n\t\t\t\t\t\t\t\t const char *origin_url,\n\t\t\t\t\t\t\t\t const char *workdir_path,\n\t\t\t\t\t\t\t\t git_indexer_stats *fetch_stats,\n\t\t\t\t\t\t\t\t git_indexer_stats *checkout_stats,\n\t\t\t\t\t\t\t\t git_checkout_opts *checkout_opts","sig":"git_repository **::const char *::const char *::git_indexer_stats *::git_indexer_stats *::git_checkout_opts *","return":{"type":"int","comment":"0 on success, GIT_ERROR otherwise (use giterr_last for information about the error)"},"description":"Clone a remote repository, and checkout the branch pointed to by the remote\nHEAD.","comments":"","group":"clone","examples":{"network/clone.c":["ex/HEAD/clone.html#git_clone-1"]}},"git_clone_bare":{"type":"function","file":"clone.h","line":52,"lineto":55,"args":[{"name":"out","type":"git_repository **","comment":"pointer that will receive the resulting repository object"},{"name":"origin_url","type":"const char *","comment":"repository to clone from"},{"name":"dest_path","type":"const char *","comment":"local directory to clone to"},{"name":"fetch_stats","type":"git_indexer_stats *","comment":"pointer to structure that receives fetch progress information (may be NULL)"}],"argline":"git_repository **out,\n\t\t\t\t\t\t\t\t\t\t const char *origin_url,\n\t\t\t\t\t\t\t\t\t\t const char *dest_path,\n\t\t\t\t\t\t\t\t\t\t git_indexer_stats *fetch_stats","sig":"git_repository **::const char *::const char *::git_indexer_stats *","return":{"type":"int","comment":"0 on success, GIT_ERROR otherwise (use giterr_last for information about the error)"},"description":"Create a bare clone of a remote repository.","comments":"","group":"clone"},"git_branch_create":{"type":"function","file":"branch.h","line":49,"lineto":54,"args":[{"name":"branch_out","type":"git_reference **","comment":"Pointer where to store the underlying reference."},{"name":"repo","type":"git_repository *"},{"name":"branch_name","type":"const char *","comment":"Name for the branch; this name is validated for consistency. It should also not conflict with an already existing branch name."},{"name":"target","type":"const git_object *","comment":"Object to which this branch should point. This object must belong to the given `repo` and can either be a git_commit or a git_tag. When a git_tag is being passed, it should be dereferencable to a git_commit which oid will be used as the target of the branch."},{"name":"force","type":"int","comment":"Overwrite existing branch."}],"argline":"git_reference **branch_out,\n\t\tgit_repository *repo,\n\t\tconst char *branch_name,\n\t\tconst git_object *target,\n\t\tint force","sig":"git_reference **::git_repository *::const char *::const git_object *::int","return":{"type":"int","comment":"0 or an error code. A proper reference is written in the refs/heads namespace pointing to the provided target commit."},"description":"Create a new branch pointing at a target commit","comments":"A new direct reference will be created pointing to\nthis target commit. If `force` is true and a reference\nalready exists with the given name, it'll be replaced.\n\nThe returned reference must be freed by the user.\n","group":"branch"},"git_branch_delete":{"type":"function","file":"branch.h","line":65,"lineto":65,"args":[{"name":"branch","type":"git_reference *","comment":"A valid reference representing a branch"}],"argline":"git_reference *branch","sig":"git_reference *","return":{"type":"int","comment":"0 on success, or an error code."},"description":"Delete an existing branch reference.","comments":"If the branch is successfully deleted, the passed reference\nobject will be freed and invalidated.\n","group":"branch"},"git_branch_foreach":{"type":"function","file":"branch.h","line":84,"lineto":92,"args":[{"name":"repo","type":"git_repository *","comment":"Repository where to find the branches."},{"name":"list_flags","type":"unsigned int","comment":"Filtering flags for the branch listing. Valid values are GIT_BRANCH_LOCAL, GIT_BRANCH_REMOTE or a combination of the two."},{"name":"branch_cb","type":"int (*)(\n\t\t\tconst char *branch_name,\n\t\t\tgit_branch_t branch_type,\n\t\t\tvoid *payload)","comment":"Callback to invoke per found branch."},{"name":"payload","type":"void *","comment":"Extra parameter to callback function."}],"argline":"git_repository *repo,\n\t\tunsigned int list_flags,\n\t\tint (*branch_cb)(\n\t\t\tconst char *branch_name,\n\t\t\tgit_branch_t branch_type,\n\t\t\tvoid *payload),\n\t\tvoid *payload","sig":"git_repository *::unsigned int::int (*)(\n\t\t\tconst char *branch_name,\n\t\t\tgit_branch_t branch_type,\n\t\t\tvoid *payload)::void *","return":{"type":"int","comment":"0 on success, GIT_EUSER on non-zero callback, or error code"},"description":"Loop over all the branches and issue a callback for each one.","comments":"If the callback returns a non-zero value, this will stop looping.\n","group":"branch"},"git_branch_move":{"type":"function","file":"branch.h","line":106,"lineto":109,"args":[{"name":"branch","type":"git_reference *","comment":"Current underlying reference of the branch."},{"name":"new_branch_name","type":"const char *","comment":"Target name of the branch once the move is performed; this name is validated for consistency."},{"name":"force","type":"int","comment":"Overwrite existing branch."}],"argline":"git_reference *branch,\n\t\tconst char *new_branch_name,\n\t\tint force","sig":"git_reference *::const char *::int","return":{"type":"int","comment":"0 on success, or an error code."},"description":"Move/rename an existing local branch reference.","comments":"","group":"branch"},"git_branch_lookup":{"type":"function","file":"branch.h","line":129,"lineto":133,"args":[{"name":"branch_out","type":"git_reference **","comment":"pointer to the looked-up branch reference"},{"name":"repo","type":"git_repository *","comment":"the repository to look up the branch"},{"name":"branch_name","type":"const char *","comment":"Name of the branch to be looked-up; this name is validated for consistency."},{"name":"branch_type","type":"git_branch_t","comment":"Type of the considered branch. This should be valued with either GIT_BRANCH_LOCAL or GIT_BRANCH_REMOTE."}],"argline":"git_reference **branch_out,\n\t\tgit_repository *repo,\n\t\tconst char *branch_name,\n\t\tgit_branch_t branch_type","sig":"git_reference **::git_repository *::const char *::git_branch_t","return":{"type":"int","comment":"0 on success; GIT_ENOTFOUND when no matching branch exists, otherwise an error code."},"description":"Lookup a branch by its name in a repository.","comments":"The generated reference must be freed by the user.\n","group":"branch"},"git_branch_tracking":{"type":"function","file":"branch.h","line":147,"lineto":149,"args":[{"name":"tracking_out","type":"git_reference **","comment":"Pointer where to store the retrieved reference."},{"name":"branch","type":"git_reference *","comment":"Current underlying reference of the branch."}],"argline":"git_reference **tracking_out,\n\t\tgit_reference *branch","sig":"git_reference **::git_reference *","return":{"type":"int","comment":"0 on success; GIT_ENOTFOUND when no remote tracking reference exists, otherwise an error code."},"description":"Return the reference supporting the remote tracking branch,\ngiven a local branch reference.","comments":"","group":"branch"},"git_indexer_stream_new":{"type":"function","file":"indexer.h","line":35,"lineto":35,"args":[{"name":"out","type":"git_indexer_stream **","comment":"where to store the indexer instance"},{"name":"path","type":"const char *","comment":"to the directory where the packfile should be stored"}],"argline":"git_indexer_stream **out, const char *path","sig":"git_indexer_stream **::const char *","return":{"type":"int"},"description":"Create a new streaming indexer instance","comments":"","group":"indexer","examples":{"network/index-pack.c":["ex/HEAD/index-pack.html#git_indexer_stream_new-1"]}},"git_indexer_stream_add":{"type":"function","file":"indexer.h","line":45,"lineto":45,"args":[{"name":"idx","type":"git_indexer_stream *","comment":"the indexer"},{"name":"data","type":"const void *","comment":"the data to add"},{"name":"size","type":"size_t","comment":"the size of the data"},{"name":"stats","type":"git_indexer_stats *","comment":"stat storage"}],"argline":"git_indexer_stream *idx, const void *data, size_t size, git_indexer_stats *stats","sig":"git_indexer_stream *::const void *::size_t::git_indexer_stats *","return":{"type":"int"},"description":"Add data to the indexer","comments":"","group":"indexer","examples":{"network/index-pack.c":["ex/HEAD/index-pack.html#git_indexer_stream_add-2"]}},"git_indexer_stream_finalize":{"type":"function","file":"indexer.h","line":54,"lineto":54,"args":[{"name":"idx","type":"git_indexer_stream *","comment":"the indexer"},{"name":"stats","type":"git_indexer_stats *"}],"argline":"git_indexer_stream *idx, git_indexer_stats *stats","sig":"git_indexer_stream *::git_indexer_stats *","return":{"type":"int"},"description":"Finalize the pack and index","comments":"Resolve any pending deltas and write out the index file\n","group":"indexer","examples":{"network/index-pack.c":["ex/HEAD/index-pack.html#git_indexer_stream_finalize-3"]}},"git_indexer_stream_hash":{"type":"function","file":"indexer.h","line":64,"lineto":64,"args":[{"name":"idx","type":"git_indexer_stream *","comment":"the indexer instance"}],"argline":"git_indexer_stream *idx","sig":"git_indexer_stream *","return":{"type":"const git_oid *"},"description":"Get the packfile's hash","comments":"A packfile's name is derived from the sorted hashing of all object\nnames. This is only correct after the index has been finalized.\n","group":"indexer","examples":{"network/index-pack.c":["ex/HEAD/index-pack.html#git_indexer_stream_hash-4"]}},"git_indexer_stream_free":{"type":"function","file":"indexer.h","line":71,"lineto":71,"args":[{"name":"idx","type":"git_indexer_stream *","comment":"the indexer to free"}],"argline":"git_indexer_stream *idx","sig":"git_indexer_stream *","return":{"type":"void"},"description":"Free the indexer and its resources","comments":"","group":"indexer","examples":{"network/index-pack.c":["ex/HEAD/index-pack.html#git_indexer_stream_free-5"]}},"git_indexer_new":{"type":"function","file":"indexer.h","line":79,"lineto":79,"args":[{"name":"out","type":"git_indexer **","comment":"where to store the indexer instance"},{"name":"packname","type":"const char *","comment":"the absolute filename of the packfile to index"}],"argline":"git_indexer **out, const char *packname","sig":"git_indexer **::const char *","return":{"type":"int"},"description":"Create a new indexer instance","comments":"","group":"indexer"},"git_indexer_run":{"type":"function","file":"indexer.h","line":91,"lineto":91,"args":[{"name":"idx","type":"git_indexer *","comment":"the indexer instance"},{"name":"stats","type":"git_indexer_stats *","comment":"storage for the running state"}],"argline":"git_indexer *idx, git_indexer_stats *stats","sig":"git_indexer *::git_indexer_stats *","return":{"type":"int"},"description":"Iterate over the objects in the packfile and extract the information","comments":"Indexing a packfile can be very expensive so this function is\nexpected to be run in a worker thread and the stats used to provide\nfeedback the user.\n","group":"indexer"},"git_indexer_write":{"type":"function","file":"indexer.h","line":101,"lineto":101,"args":[{"name":"idx","type":"git_indexer *","comment":"the indexer instance"}],"argline":"git_indexer *idx","sig":"git_indexer *","return":{"type":"int"},"description":"Write the index file to disk.","comments":"The file will be stored as pack-$hash.idx in the same directory as\nthe packfile.\n","group":"indexer"},"git_indexer_hash":{"type":"function","file":"indexer.h","line":111,"lineto":111,"args":[{"name":"idx","type":"git_indexer *","comment":"the indexer instance"}],"argline":"git_indexer *idx","sig":"git_indexer *","return":{"type":"const git_oid *"},"description":"Get the packfile's hash","comments":"A packfile's name is derived from the sorted hashing of all object\nnames. This is only correct after the index has been written to disk.\n","group":"indexer"},"git_indexer_free":{"type":"function","file":"indexer.h","line":118,"lineto":122,"args":[{"name":"idx","type":"git_indexer *","comment":"the indexer to free"}],"argline":"git_indexer *idx","sig":"git_indexer *","return":{"type":"void"},"description":"Free the indexer and its resources","comments":"","group":"indexer"},"git_libgit2_version":{"type":"function","file":"common.h","line":104,"lineto":104,"args":[{"name":"major","type":"int *","comment":"Store the major version number"},{"name":"minor","type":"int *","comment":"Store the minor version number"},{"name":"rev","type":"int *","comment":"Store the revision (patch) number"}],"argline":"int *major, int *minor, int *rev","sig":"int *::int *::int *","return":{"type":"void"},"description":"Return the version of the libgit2 library\nbeing currently used.","comments":"","group":"libgit2"},"git_libgit2_capabilities":{"type":"function","file":"common.h","line":127,"lineto":127,"args":[],"argline":"void","sig":"","return":{"type":"int","comment":"A combination of GIT_CAP_* values. - GIT_CAP_THREADS Libgit2 was compiled with thread support. Note that thread support is still to be seen as a 'work in progress'. - GIT_CAP_HTTPS Libgit2 supports the https:// protocol. This requires the open ssl library to be found when compiling libgit2."},"description":"Query compile time options for libgit2.","comments":"","group":"libgit2"},"git_refspec_parse":{"type":"function","file":"refspec.h","line":28,"lineto":28,"args":[{"name":"refspec","type":"git_refspec *","comment":"pointer to the refspec structure to be used"},{"name":"str","type":"const char *","comment":"the refspec as a string"}],"argline":"git_refspec *refspec, const char *str","sig":"git_refspec *::const char *","return":{"type":"int"},"description":"Parse a refspec string and create a refspec object","comments":"","group":"refspec"},"git_refspec_src":{"type":"function","file":"refspec.h","line":36,"lineto":36,"args":[{"name":"refspec","type":"const git_refspec *","comment":"the refspec"}],"argline":"const git_refspec *refspec","sig":"const git_refspec *","return":{"type":"const char *","comment":"the refspec's source specifier"},"description":"Get the source specifier","comments":"","group":"refspec"},"git_refspec_dst":{"type":"function","file":"refspec.h","line":44,"lineto":44,"args":[{"name":"refspec","type":"const git_refspec *","comment":"the refspec"}],"argline":"const git_refspec *refspec","sig":"const git_refspec *","return":{"type":"const char *","comment":"the refspec's destination specifier"},"description":"Get the destination specifier","comments":"","group":"refspec"},"git_refspec_force":{"type":"function","file":"refspec.h","line":52,"lineto":52,"args":[{"name":"refspec","type":"const git_refspec *","comment":"the refspec"}],"argline":"const git_refspec *refspec","sig":"const git_refspec *","return":{"type":"int","comment":"1 if force update has been set, 0 otherwise"},"description":"Get the force update setting","comments":"","group":"refspec"},"git_refspec_src_matches":{"type":"function","file":"refspec.h","line":61,"lineto":61,"args":[{"name":"refspec","type":"const git_refspec *","comment":"the refspec"},{"name":"refname","type":"const char *","comment":"the name of the reference to check"}],"argline":"const git_refspec *refspec, const char *refname","sig":"const git_refspec *::const char *","return":{"type":"int","comment":"1 if the refspec matches, 0 otherwise"},"description":"Check if a refspec's source descriptor matches a reference","comments":"","group":"refspec"},"git_refspec_transform":{"type":"function","file":"refspec.h","line":72,"lineto":76,"args":[{"name":"out","type":"char *","comment":"where to store the target name"},{"name":"outlen","type":"size_t","comment":"the size ouf the `out` buffer"},{"name":"spec","type":"const git_refspec *","comment":"the refspec"},{"name":"name","type":"const char *","comment":"the name of the reference to transform"}],"argline":"char *out, size_t outlen, const git_refspec *spec, const char *name","sig":"char *::size_t::const git_refspec *::const char *","return":{"type":"int","comment":"0, GIT_EBUFS or another error"},"description":"Transform a reference to its target following the refspec's rules","comments":"","group":"refspec"},"git_signature_new":{"type":"function","file":"signature.h","line":36,"lineto":36,"args":[{"name":"sig_out","type":"git_signature **","comment":"new signature, in case of error NULL"},{"name":"name","type":"const char *","comment":"name of the person"},{"name":"email","type":"const char *","comment":"email of the person"},{"name":"time","type":"git_time_t","comment":"time when the action happened"},{"name":"offset","type":"int","comment":"timezone offset in minutes for the time"}],"argline":"git_signature **sig_out, const char *name, const char *email, git_time_t time, int offset","sig":"git_signature **::const char *::const char *::git_time_t::int","return":{"type":"int","comment":"0 or an error code"},"description":"Create a new action signature. The signature must be freed\nmanually or using git_signature_free","comments":"Note: angle brackets ('<' and '>') characters are not allowed\nto be used in either the `name` or the `email` parameter.\n","group":"signature","examples":{"general.c":["ex/HEAD/general.html#git_signature_new-1","ex/HEAD/general.html#git_signature_new-2"]}},"git_signature_now":{"type":"function","file":"signature.h","line":47,"lineto":47,"args":[{"name":"sig_out","type":"git_signature **","comment":"new signature, in case of error NULL"},{"name":"name","type":"const char *","comment":"name of the person"},{"name":"email","type":"const char *","comment":"email of the person"}],"argline":"git_signature **sig_out, const char *name, const char *email","sig":"git_signature **::const char *::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Create a new action signature with a timestamp of 'now'. The\nsignature must be freed manually or using git_signature_free","comments":"","group":"signature"},"git_signature_dup":{"type":"function","file":"signature.h","line":57,"lineto":57,"args":[{"name":"sig","type":"const git_signature *","comment":"signature to duplicated"}],"argline":"const git_signature *sig","sig":"const git_signature *","return":{"type":"git_signature *","comment":"a copy of sig, NULL on out of memory"},"description":"Create a copy of an existing signature.","comments":"All internal strings are also duplicated.","group":"signature"},"git_signature_free":{"type":"function","file":"signature.h","line":64,"lineto":64,"args":[{"name":"sig","type":"git_signature *","comment":"signature to free"}],"argline":"git_signature *sig","sig":"git_signature *","return":{"type":"void"},"description":"Free an existing signature","comments":"","group":"signature"},"git_status_foreach":{"type":"function","file":"status.h","line":47,"lineto":50,"args":[{"name":"repo","type":"git_repository *","comment":"a repository object"},{"name":"callback","type":"int (*)(const char *, unsigned int, void *)","comment":"the function to call on each file"},{"name":"payload","type":"void *"}],"argline":"git_repository *repo,\n\tint (*callback)(const char *, unsigned int, void *),\n\tvoid *payload","sig":"git_repository *::int (*)(const char *, unsigned int, void *)::void *","return":{"type":"int","comment":"0 on success, GIT_EUSER on non-zero callback, or error code"},"description":"Gather file statuses and run a callback for each one.","comments":"The callback is passed the path of the file, the status and the data\npointer passed to this function. If the callback returns something other\nthan 0, this function will stop looping and return GIT_EUSER.\n","group":"status"},"git_status_foreach_ext":{"type":"function","file":"status.h","line":125,"lineto":129,"args":[{"name":"repo","type":"git_repository *"},{"name":"opts","type":"const git_status_options *"},{"name":"callback","type":"int (*)(const char *, unsigned int, void *)"},{"name":"payload","type":"void *"}],"argline":"git_repository *repo,\n\tconst git_status_options *opts,\n\tint (*callback)(const char *, unsigned int, void *),\n\tvoid *payload","sig":"git_repository *::const git_status_options *::int (*)(const char *, unsigned int, void *)::void *","return":{"type":"int"},"description":"Gather file status information and run callbacks as requested.","comments":"","group":"status"},"git_status_file":{"type":"function","file":"status.h","line":141,"lineto":144,"args":[{"name":"status_flags","type":"unsigned int *","comment":"the status value"},{"name":"repo","type":"git_repository *","comment":"a repository object"},{"name":"path","type":"const char *","comment":"the file to retrieve status for, rooted at the repo's workdir"}],"argline":"unsigned int *status_flags,\n\tgit_repository *repo,\n\tconst char *path","sig":"unsigned int *::git_repository *::const char *","return":{"type":"int","comment":"GIT_EINVALIDPATH when `path` points at a folder, GIT_ENOTFOUND when the file doesn't exist in any of HEAD, the index or the worktree, 0 otherwise"},"description":"Get file status for a single file","comments":"","group":"status"},"git_status_should_ignore":{"type":"function","file":"status.h","line":160,"lineto":163,"args":[{"name":"ignored","type":"int *","comment":"boolean returning 0 if the file is not ignored, 1 if it is"},{"name":"repo","type":"git_repository *","comment":"a repository object"},{"name":"path","type":"const char *","comment":"the file to check ignores for, rooted at the repo's workdir."}],"argline":"int *ignored,\n\tgit_repository *repo,\n\tconst char *path","sig":"int *::git_repository *::const char *","return":{"type":"int","comment":"0 if ignore rules could be processed for the file (regardless of whether it exists or not), or an error < 0 if they could not."},"description":"Test if the ignore rules apply to a given file.","comments":"This function simply checks the ignore rules to see if they would apply\nto the given file. Unlike git_status_file(), this indicates if the file\nwould be ignored regardless of whether the file is already in the index\nor in the repository.\n","group":"status"},"git_note_read":{"type":"function","file":"notes.h","line":34,"lineto":35,"args":[{"name":"note","type":"git_note **","comment":"pointer to the read note; NULL in case of error"},{"name":"repo","type":"git_repository *","comment":"repository where to look up the note"},{"name":"notes_ref","type":"const char *","comment":"canonical name of the reference to use (optional); defaults to \"refs/notes/commits\""},{"name":"oid","type":"const git_oid *","comment":"OID of the git object to read the note from"}],"argline":"git_note **note, git_repository *repo,\n\t\t\t const char *notes_ref, const git_oid *oid","sig":"git_note **::git_repository *::const char *::const git_oid *","return":{"type":"int","comment":"0 or an error code"},"description":"Read the note for an object","comments":"The note must be freed manually by the user.\n","group":"note"},"git_note_message":{"type":"function","file":"notes.h","line":43,"lineto":43,"args":[{"name":"note","type":"git_note *","comment":""}],"argline":"git_note *note","sig":"git_note *","return":{"type":"const char *","comment":"the note message"},"description":"Get the note message","comments":"","group":"note"},"git_note_oid":{"type":"function","file":"notes.h","line":52,"lineto":52,"args":[{"name":"note","type":"git_note *","comment":""}],"argline":"git_note *note","sig":"git_note *","return":{"type":"const git_oid *","comment":"the note object OID"},"description":"Get the note object OID","comments":"","group":"note"},"git_note_create":{"type":"function","file":"notes.h","line":68,"lineto":71,"args":[{"name":"out","type":"git_oid *","comment":"pointer to store the OID (optional); NULL in case of error"},{"name":"repo","type":"git_repository *","comment":"repository where to store the note"},{"name":"author","type":"git_signature *","comment":"signature of the notes commit author"},{"name":"committer","type":"git_signature *","comment":"signature of the notes commit committer"},{"name":"notes_ref","type":"const char *","comment":"canonical name of the reference to use (optional); defaults to \"refs/notes/commits\""},{"name":"oid","type":"const git_oid *","comment":"OID of the git object to decorate"},{"name":"note","type":"const char *","comment":"s_ref canonical name of the reference to use (optional); defaults to \"refs/notes/commits\""}],"argline":"git_oid *out, git_repository *repo,\n\t\t\t\tgit_signature *author, git_signature *committer,\n\t\t\t\tconst char *notes_ref, const git_oid *oid,\n\t\t\t\t const char *note","sig":"git_oid *::git_repository *::git_signature *::git_signature *::const char *::const git_oid *::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Add a note for an object","comments":"","group":"note"},"git_note_remove":{"type":"function","file":"notes.h","line":86,"lineto":88,"args":[{"name":"repo","type":"git_repository *","comment":"repository where the note lives"},{"name":"notes_ref","type":"const char *","comment":"canonical name of the reference to use (optional); defaults to \"refs/notes/commits\""},{"name":"author","type":"git_signature *","comment":"signature of the notes commit author"},{"name":"committer","type":"git_signature *","comment":"signature of the notes commit committer"},{"name":"oid","type":"const git_oid *","comment":"OID of the git object to remove the note from"}],"argline":"git_repository *repo, const char *notes_ref,\n\t\t\t\tgit_signature *author, git_signature *committer,\n\t\t\t\tconst git_oid *oid","sig":"git_repository *::const char *::git_signature *::git_signature *::const git_oid *","return":{"type":"int","comment":"0 or an error code"},"description":"Remove the note for an object","comments":"","group":"note"},"git_note_free":{"type":"function","file":"notes.h","line":95,"lineto":95,"args":[{"name":"note","type":"git_note *","comment":"git_note object"}],"argline":"git_note *note","sig":"git_note *","return":{"type":"void"},"description":"Free a git_note object","comments":"","group":"note"},"git_note_default_ref":{"type":"function","file":"notes.h","line":105,"lineto":105,"args":[{"name":"out","type":"const char **","comment":"Pointer to the default notes reference"},{"name":"repo","type":"git_repository *","comment":"The Git repository"}],"argline":"const char **out, git_repository *repo","sig":"const char **::git_repository *","return":{"type":"int","comment":"0 or an error code"},"description":"Get the default notes reference for a repository","comments":"","group":"note"},"git_note_foreach":{"type":"function","file":"notes.h","line":134,"lineto":139,"args":[{"name":"repo","type":"git_repository *","comment":"Repository where to find the notes."},{"name":"notes_ref","type":"const char *","comment":"Reference to read from (optional); defaults to \"refs/notes/commits\"."},{"name":"note_cb","type":"int (*)(git_note_data *note_data, void *payload)","comment":"Callback to invoke per found annotation. Return non-zero to stop looping."},{"name":"payload","type":"void *","comment":"Extra parameter to callback function."}],"argline":"git_repository *repo,\n\tconst char *notes_ref,\n\tint (*note_cb)(git_note_data *note_data, void *payload),\n\tvoid *payload","sig":"git_repository *::const char *::int (*)(git_note_data *note_data, void *payload)::void *","return":{"type":"int","comment":"0 on success, GIT_EUSER on non-zero callback, or error code"},"description":"Loop over all the notes within a specified namespace\nand issue a callback for each one.","comments":"","group":"note"},"git_config_find_global":{"type":"function","file":"config.h","line":68,"lineto":68,"args":[{"name":"global_config_path","type":"char *","comment":"Buffer of GIT_PATH_MAX length to store the path"},{"name":"length","type":"size_t"}],"argline":"char *global_config_path, size_t length","sig":"char *::size_t","return":{"type":"int","comment":"0 if a global configuration file has been found. Its path will be stored in `buffer`."},"description":"Locate the path to the global configuration file","comments":"The user or global configuration file is usually\nlocated in `$HOME/.gitconfig`.\n\nThis method will try to guess the full path to that\nfile, if the file exists. The returned path\nmay be used on any `git_config` call to load the\nglobal configuration file.\n","group":"config"},"git_config_find_system":{"type":"function","file":"config.h","line":80,"lineto":80,"args":[{"name":"system_config_path","type":"char *","comment":"Buffer of GIT_PATH_MAX length to store the path"},{"name":"length","type":"size_t"}],"argline":"char *system_config_path, size_t length","sig":"char *::size_t","return":{"type":"int","comment":"0 if a system configuration file has been found. Its path will be stored in `buffer`."},"description":"Locate the path to the system configuration file","comments":"If /etc/gitconfig doesn't exist, it will look for\n%PROGRAMFILES%\\Git\\etc\\gitconfig.\n","group":"config"},"git_config_open_default":{"type":"function","file":"config.h","line":92,"lineto":92,"args":[{"name":"out","type":"git_config **","comment":"Pointer to store the config instance"}],"argline":"git_config **out","sig":"git_config **","return":{"type":"int","comment":"0 or an error code"},"description":"Open the global and system configuration files","comments":"Utility wrapper that finds the global and system configuration files\nand opens them into a single prioritized config object that can be\nused when accessing default config data outside a repository.\n","group":"config"},"git_config_file__ondisk":{"type":"function","file":"config.h","line":105,"lineto":105,"args":[{"name":"out","type":"struct git_config_file **","comment":"the new backend"},{"name":"path","type":"const char *","comment":"where the config file is located"}],"argline":"struct git_config_file **out, const char *path","sig":"struct git_config_file **::const char *","return":{"type":"int"},"description":"Create a configuration file backend for ondisk files","comments":"These are the normal `.gitconfig` files that Core Git\nprocesses. Note that you first have to add this file to a\nconfiguration object before you can query it for configuration\nvariables.\n","group":"config"},"git_config_new":{"type":"function","file":"config.h","line":116,"lineto":116,"args":[{"name":"out","type":"git_config **","comment":"pointer to the new configuration"}],"argline":"git_config **out","sig":"git_config **","return":{"type":"int","comment":"0 or an error code"},"description":"Allocate a new configuration object","comments":"This object is empty, so you have to add a file to it before you\ncan do anything with it.\n","group":"config"},"git_config_add_file":{"type":"function","file":"config.h","line":133,"lineto":133,"args":[{"name":"cfg","type":"git_config *","comment":"the configuration to add the file to"},{"name":"file","type":"git_config_file *","comment":"the configuration file (backend) to add"},{"name":"priority","type":"int","comment":"the priority the backend should have"}],"argline":"git_config *cfg, git_config_file *file, int priority","sig":"git_config *::git_config_file *::int","return":{"type":"int","comment":"0 or an error code"},"description":"Add a generic config file instance to an existing config","comments":"Note that the configuration object will free the file\nautomatically.\n\nFurther queries on this config object will access each\nof the config file instances in order (instances with\na higher priority will be accessed first).\n","group":"config"},"git_config_add_file_ondisk":{"type":"function","file":"config.h","line":154,"lineto":154,"args":[{"name":"cfg","type":"git_config *","comment":"the configuration to add the file to"},{"name":"path","type":"const char *","comment":"path to the configuration file (backend) to add"},{"name":"priority","type":"int","comment":"the priority the backend should have"}],"argline":"git_config *cfg, const char *path, int priority","sig":"git_config *::const char *::int","return":{"type":"int","comment":"0 or an error code"},"description":"Add an on-disk config file instance to an existing config","comments":"The on-disk file pointed at by `path` will be opened and\nparsed; it's expected to be a native Git config file following\nthe default Git config syntax (see man git-config).\n\nNote that the configuration object will free the file\nautomatically.\n\nFurther queries on this config object will access each\nof the config file instances in order (instances with\na higher priority will be accessed first).\n","group":"config"},"git_config_open_ondisk":{"type":"function","file":"config.h","line":169,"lineto":169,"args":[{"name":"cfg","type":"git_config **","comment":"The configuration instance to create"},{"name":"path","type":"const char *","comment":"Path to the on-disk file to open"}],"argline":"git_config **cfg, const char *path","sig":"git_config **::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Create a new config instance containing a single on-disk file","comments":"This method is a simple utility wrapper for the following sequence\nof calls:\n- git_config_new\n- git_config_add_file_ondisk\n","group":"config","examples":{"general.c":["ex/HEAD/general.html#git_config_open_ondisk-3"]}},"git_config_free":{"type":"function","file":"config.h","line":176,"lineto":176,"args":[{"name":"cfg","type":"git_config *","comment":"the configuration to free"}],"argline":"git_config *cfg","sig":"git_config *","return":{"type":"void"},"description":"Free the configuration and its associated memory and files","comments":"","group":"config"},"git_config_get_int32":{"type":"function","file":"config.h","line":186,"lineto":186,"args":[{"name":"out","type":"int32_t *","comment":"pointer to the variable where the value should be stored"},{"name":"cfg","type":"git_config *","comment":"where to look for the variable"},{"name":"name","type":"const char *","comment":"the variable's name"}],"argline":"int32_t *out, git_config *cfg, const char *name","sig":"int32_t *::git_config *::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Get the value of an integer config variable.","comments":"","group":"config","examples":{"general.c":["ex/HEAD/general.html#git_config_get_int32-4"]}},"git_config_get_int64":{"type":"function","file":"config.h","line":196,"lineto":196,"args":[{"name":"out","type":"int64_t *","comment":"pointer to the variable where the value should be stored"},{"name":"cfg","type":"git_config *","comment":"where to look for the variable"},{"name":"name","type":"const char *","comment":"the variable's name"}],"argline":"int64_t *out, git_config *cfg, const char *name","sig":"int64_t *::git_config *::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Get the value of a long integer config variable.","comments":"","group":"config"},"git_config_get_bool":{"type":"function","file":"config.h","line":209,"lineto":209,"args":[{"name":"out","type":"int *","comment":"pointer to the variable where the value should be stored"},{"name":"cfg","type":"git_config *","comment":"where to look for the variable"},{"name":"name","type":"const char *","comment":"the variable's name"}],"argline":"int *out, git_config *cfg, const char *name","sig":"int *::git_config *::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Get the value of a boolean config variable.","comments":"This function uses the usual C convention of 0 being false and\nanything else true.\n","group":"config"},"git_config_get_string":{"type":"function","file":"config.h","line":222,"lineto":222,"args":[{"name":"out","type":"const char **","comment":"pointer to the variable's value"},{"name":"cfg","type":"git_config *","comment":"where to look for the variable"},{"name":"name","type":"const char *","comment":"the variable's name"}],"argline":"const char **out, git_config *cfg, const char *name","sig":"const char **::git_config *::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Get the value of a string config variable.","comments":"The string is owned by the variable and should not be freed by the\nuser.\n","group":"config","examples":{"general.c":["ex/HEAD/general.html#git_config_get_string-5"]}},"git_config_get_multivar":{"type":"function","file":"config.h","line":236,"lineto":236,"args":[{"name":"cfg","type":"git_config *","comment":"where to look for the variable"},{"name":"name","type":"const char *","comment":"the variable's name"},{"name":"regexp","type":"const char *","comment":"regular expression to filter which variables we're interested in. Use NULL to indicate all"},{"name":"fn","type":"int (*)(const char *, void *)","comment":"the function to be called on each value of the variable"},{"name":"data","type":"void *","comment":"opaque pointer to pass to the callback"}],"argline":"git_config *cfg, const char *name, const char *regexp, int (*fn)(const char *, void *), void *data","sig":"git_config *::const char *::const char *::int (*)(const char *, void *)::void *","return":{"type":"int"},"description":"Get each value of a multivar.","comments":"The callback will be called on each variable found\n","group":"config"},"git_config_set_int32":{"type":"function","file":"config.h","line":246,"lineto":246,"args":[{"name":"cfg","type":"git_config *","comment":"where to look for the variable"},{"name":"name","type":"const char *","comment":"the variable's name"},{"name":"value","type":"int32_t","comment":"Integer value for the variable"}],"argline":"git_config *cfg, const char *name, int32_t value","sig":"git_config *::const char *::int32_t","return":{"type":"int","comment":"0 or an error code"},"description":"Set the value of an integer config variable.","comments":"","group":"config"},"git_config_set_int64":{"type":"function","file":"config.h","line":256,"lineto":256,"args":[{"name":"cfg","type":"git_config *","comment":"where to look for the variable"},{"name":"name","type":"const char *","comment":"the variable's name"},{"name":"value","type":"int64_t","comment":"Long integer value for the variable"}],"argline":"git_config *cfg, const char *name, int64_t value","sig":"git_config *::const char *::int64_t","return":{"type":"int","comment":"0 or an error code"},"description":"Set the value of a long integer config variable.","comments":"","group":"config"},"git_config_set_bool":{"type":"function","file":"config.h","line":266,"lineto":266,"args":[{"name":"cfg","type":"git_config *","comment":"where to look for the variable"},{"name":"name","type":"const char *","comment":"the variable's name"},{"name":"value","type":"int","comment":"the value to store"}],"argline":"git_config *cfg, const char *name, int value","sig":"git_config *::const char *::int","return":{"type":"int","comment":"0 or an error code"},"description":"Set the value of a boolean config variable.","comments":"","group":"config"},"git_config_set_string":{"type":"function","file":"config.h","line":279,"lineto":279,"args":[{"name":"cfg","type":"git_config *","comment":"where to look for the variable"},{"name":"name","type":"const char *","comment":"the variable's name"},{"name":"value","type":"const char *","comment":"the string to store."}],"argline":"git_config *cfg, const char *name, const char *value","sig":"git_config *::const char *::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Set the value of a string config variable.","comments":"A copy of the string is made and the user is free to use it\nafterwards.\n","group":"config"},"git_config_set_multivar":{"type":"function","file":"config.h","line":290,"lineto":290,"args":[{"name":"cfg","type":"git_config *","comment":"where to look for the variable"},{"name":"name","type":"const char *","comment":"the variable's name"},{"name":"regexp","type":"const char *","comment":"a regular expression to indicate which values to replace"},{"name":"value","type":"const char *","comment":"the new value."}],"argline":"git_config *cfg, const char *name, const char *regexp, const char *value","sig":"git_config *::const char *::const char *::const char *","return":{"type":"int"},"description":"Set a multivar","comments":"","group":"config"},"git_config_delete":{"type":"function","file":"config.h","line":298,"lineto":298,"args":[{"name":"cfg","type":"git_config *","comment":"the configuration"},{"name":"name","type":"const char *","comment":"the variable to delete"}],"argline":"git_config *cfg, const char *name","sig":"git_config *::const char *","return":{"type":"int"},"description":"Delete a config variable","comments":"","group":"config"},"git_config_foreach":{"type":"function","file":"config.h","line":313,"lineto":316,"args":[{"name":"cfg","type":"git_config *","comment":"where to get the variables from"},{"name":"callback","type":"int (*)(const char *var_name, const char *value, void *payload)","comment":"the function to call on each variable"},{"name":"payload","type":"void *","comment":"the data to pass to the callback"}],"argline":"git_config *cfg,\n\tint (*callback)(const char *var_name, const char *value, void *payload),\n\tvoid *payload","sig":"git_config *::int (*)(const char *var_name, const char *value, void *payload)::void *","return":{"type":"int","comment":"0 on success, GIT_EUSER on non-zero callback, or error code"},"description":"Perform an operation on each config variable.","comments":"The callback receives the normalized name and value of each variable\nin the config backend, and the data pointer passed to this function.\nAs soon as one of the callback functions returns something other than 0,\nthis function stops iterating and returns `GIT_EUSER`.\n","group":"config"},"git_config_foreach_match":{"type":"function","file":"config.h","line":331,"lineto":335,"args":[{"name":"cfg","type":"git_config *","comment":"where to get the variables from"},{"name":"regexp","type":"const char *","comment":"regular expression to match against config names"},{"name":"callback","type":"int (*)(const char *var_name, const char *value, void *payload)","comment":"the function to call on each variable"},{"name":"payload","type":"void *","comment":"the data to pass to the callback"}],"argline":"git_config *cfg,\n\tconst char *regexp,\n\tint (*callback)(const char *var_name, const char *value, void *payload),\n\tvoid *payload","sig":"git_config *::const char *::int (*)(const char *var_name, const char *value, void *payload)::void *","return":{"type":"int","comment":"0 or the return value of the callback which didn't return 0"},"description":"Perform an operation on each config variable matching a regular expression.","comments":"This behaviors like `git_config_foreach` with an additional filter of a\nregular expression that filters which config keys are passed to the\ncallback.\n","group":"config"},"git_config_get_mapped":{"type":"function","file":"config.h","line":371,"lineto":371,"args":[{"name":"out","type":"int *","comment":"place to store the result of the mapping"},{"name":"cfg","type":"git_config *","comment":"config file to get the variables from"},{"name":"name","type":"const char *","comment":"name of the config variable to lookup"},{"name":"maps","type":"git_cvar_map *","comment":"array of `git_cvar_map` objects specifying the possible mappings"},{"name":"map_n","type":"size_t","comment":"number of mapping objects in `maps`"}],"argline":"int *out, git_config *cfg, const char *name, git_cvar_map *maps, size_t map_n","sig":"int *::git_config *::const char *::git_cvar_map *::size_t","return":{"type":"int","comment":"0 on success, error code otherwise"},"description":"Query the value of a config variable and return it mapped to\nan integer constant.","comments":"This is a helper method to easily map different possible values\nto a variable to integer constants that easily identify them.\n\nA mapping array looks as follows:\n\ngit_cvar_map autocrlf_mapping[] = {\n\t{GIT_CVAR_FALSE, NULL, GIT_AUTO_CRLF_FALSE},\n\t{GIT_CVAR_TRUE, NULL, GIT_AUTO_CRLF_TRUE},\n\t{GIT_CVAR_STRING, \"input\", GIT_AUTO_CRLF_INPUT},\n\t{GIT_CVAR_STRING, \"default\", GIT_AUTO_CRLF_DEFAULT}};\n\nOn any \"false\" value for the variable (e.g. \"false\", \"FALSE\", \"no\"), the\nmapping will store `GIT_AUTO_CRLF_FALSE` in the `out` parameter.\n\nThe same thing applies for any \"true\" value such as \"true\", \"yes\" or \"1\", storing\nthe `GIT_AUTO_CRLF_TRUE` variable.\n\nOtherwise, if the value matches the string \"input\" (with case insensitive comparison),\nthe given constant will be stored in `out`, and likewise for \"default\".\n\nIf not a single match can be made to store in `out`, an error code will be\nreturned.\n","group":"config"},"git_reset":{"type":"function","file":"reset.h","line":43,"lineto":43,"args":[{"name":"repo","type":"git_repository *","comment":"Repository where to perform the reset operation."},{"name":"target","type":"git_object *","comment":"Object to which the Head should be moved to. This object must belong to the given `repo` and can either be a git_commit or a git_tag. When a git_tag is being passed, it should be dereferencable to a git_commit which oid will be used as the target of the branch."},{"name":"reset_type","type":"git_reset_type","comment":"Kind of reset operation to perform."}],"argline":"git_repository *repo, git_object *target, git_reset_type reset_type","sig":"git_repository *::git_object *::git_reset_type","return":{"type":"int","comment":"GIT_SUCCESS or an error code"},"description":"Sets the current head to the specified commit oid and optionally\nresets the index and working tree to match.","comments":"When specifying a Soft kind of reset, the head will be moved to the commit.\n\nSpecifying a Mixed kind of reset will trigger a Soft reset and the index will\nbe replaced with the content of the commit tree.\n\nSpecifying a Hard kind of reset will trigger a Mixed reset and the working\ndirectory will be replaced with the content of the index.\n\nTODO: Implement remaining kinds of resets.\n","group":"reset"},"git_blob_lookup":{"type":"function","file":"blob.h","line":32,"lineto":35,"args":[{"name":"blob","type":"git_blob **","comment":"pointer to the looked up blob"},{"name":"repo","type":"git_repository *","comment":"the repo to use when locating the blob."},{"name":"id","type":"const git_oid *","comment":"identity of the blob to locate."}],"argline":"git_blob **blob, git_repository *repo, const git_oid *id","sig":"git_blob **::git_repository *::const git_oid *","return":{"type":"int","comment":"0 or an error code"},"description":"Lookup a blob object from a repository.","comments":"","group":"blob","examples":{"general.c":["ex/HEAD/general.html#git_blob_lookup-6"]}},"git_blob_lookup_prefix":{"type":"function","file":"blob.h","line":49,"lineto":52,"args":[{"name":"blob","type":"git_blob **","comment":"pointer to the looked up blob"},{"name":"repo","type":"git_repository *","comment":"the repo to use when locating the blob."},{"name":"id","type":"const git_oid *","comment":"identity of the blob to locate."},{"name":"len","type":"size_t","comment":"the length of the short identifier"}],"argline":"git_blob **blob, git_repository *repo, const git_oid *id, size_t len","sig":"git_blob **::git_repository *::const git_oid *::size_t","return":{"type":"int","comment":"0 or an error code"},"description":"Lookup a blob object from a repository,\ngiven a prefix of its identifier (short id).","comments":"@see git_object_lookup_prefix\n","group":"blob"},"git_blob_free":{"type":"function","file":"blob.h","line":65,"lineto":68,"args":[{"name":"blob","type":"git_blob *","comment":"the blob to close"}],"argline":"git_blob *blob","sig":"git_blob *","return":{"type":"void"},"description":"Close an open blob","comments":"This is a wrapper around git_object_free()\n\nIMPORTANT:\nIt *is* necessary to call this method when you stop\nusing a blob. Failure to do so will cause a memory leak.\n","group":"blob"},"git_blob_rawcontent":{"type":"function","file":"blob.h","line":83,"lineto":83,"args":[{"name":"blob","type":"git_blob *","comment":"pointer to the blob"}],"argline":"git_blob *blob","sig":"git_blob *","return":{"type":"const void *","comment":"the pointer; NULL if the blob has no contents"},"description":"Get a read-only buffer with the raw content of a blob.","comments":"A pointer to the raw content of a blob is returned;\nthis pointer is owned internally by the object and shall\nnot be free'd. The pointer may be invalidated at a later\ntime.\n","group":"blob","examples":{"general.c":["ex/HEAD/general.html#git_blob_rawcontent-7"]}},"git_blob_rawsize":{"type":"function","file":"blob.h","line":91,"lineto":91,"args":[{"name":"blob","type":"git_blob *","comment":"pointer to the blob"}],"argline":"git_blob *blob","sig":"git_blob *","return":{"type":"size_t","comment":"size on bytes"},"description":"Get the size in bytes of the contents of a blob","comments":"","group":"blob","examples":{"general.c":["ex/HEAD/general.html#git_blob_rawsize-8","ex/HEAD/general.html#git_blob_rawsize-9"]}},"git_blob_create_fromfile":{"type":"function","file":"blob.h","line":104,"lineto":104,"args":[{"name":"oid","type":"git_oid *","comment":"return the id of the written blob"},{"name":"repo","type":"git_repository *","comment":"repository where the blob will be written. this repository cannot be bare"},{"name":"path","type":"const char *","comment":"file from which the blob will be created, relative to the repository's working dir"}],"argline":"git_oid *oid, git_repository *repo, const char *path","sig":"git_oid *::git_repository *::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Read a file from the working folder of a repository\nand write it to the Object Database as a loose blob","comments":"","group":"blob"},"git_blob_create_fromdisk":{"type":"function","file":"blob.h","line":116,"lineto":116,"args":[{"name":"oid","type":"git_oid *","comment":"return the id of the written blob"},{"name":"repo","type":"git_repository *","comment":"repository where the blob will be written. this repository can be bare or not"},{"name":"path","type":"const char *","comment":"file from which the blob will be created"}],"argline":"git_oid *oid, git_repository *repo, const char *path","sig":"git_oid *::git_repository *::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Read a file from the filesystem and write its content\nto the Object Database as a loose blob","comments":"","group":"blob"},"git_blob_create_fromchunks":{"type":"function","file":"blob.h","line":154,"lineto":159,"args":[{"name":"oid","type":"git_oid *","comment":"Return the id of the written blob"},{"name":"repo","type":"git_repository *","comment":"repository where the blob will be written. This repository can be bare or not."},{"name":"hintpath","type":"const char *","comment":"if not NULL, will help selecting the filters to apply onto the content of the blob to be created."},{"name":"source_cb","type":"int (*)(char *content, size_t max_length, void *payload)"},{"name":"payload","type":"void *"}],"argline":"git_oid *oid,\n\tgit_repository *repo,\n\tconst char *hintpath,\n\tint (*source_cb)(char *content, size_t max_length, void *payload),\n\tvoid *payload","sig":"git_oid *::git_repository *::const char *::int (*)(char *content, size_t max_length, void *payload)::void *","return":{"type":"int","comment":"GIT_SUCCESS or an error code"},"description":"Write a loose blob to the Object Database from a\nprovider of chunks of data.","comments":"Provided the `hintpath` parameter is filled, its value\nwill help to determine what git filters should be applied\nto the object before it can be placed to the object database.\n\n\nThe implementation of the callback has to respect the\nfollowing rules:\n\n - `content` will have to be filled by the consumer. The maximum number\nof bytes that the buffer can accept per call is defined by the\n`max_length` parameter. Allocation and freeing of the buffer will be taken\ncare of by the function.\n\n - The callback is expected to return the number of bytes\nthat `content` have been filled with.\n\n - When there is no more data to stream, the callback should\nreturn 0. This will prevent it from being invoked anymore.\n\n - When an error occurs, the callback should return -1.\n\n","group":"blob"},"git_blob_create_frombuffer":{"type":"function","file":"blob.h","line":170,"lineto":170,"args":[{"name":"oid","type":"git_oid *","comment":"return the oid of the written blob"},{"name":"repo","type":"git_repository *","comment":"repository where to blob will be written"},{"name":"buffer","type":"const void *","comment":"data to be written into the blob"},{"name":"len","type":"size_t","comment":"length of the data"}],"argline":"git_oid *oid, git_repository *repo, const void *buffer, size_t len","sig":"git_oid *::git_repository *::const void *::size_t","return":{"type":"int","comment":"0 or an error code"},"description":"Write an in-memory buffer to the ODB as a blob","comments":"","group":"blob"},"git_index_open":{"type":"function","file":"index.h","line":120,"lineto":120,"args":[{"name":"index","type":"git_index **","comment":"the pointer for the new index"},{"name":"index_path","type":"const char *","comment":"the path to the index file in disk"}],"argline":"git_index **index, const char *index_path","sig":"git_index **::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Create a new bare Git index object as a memory representation\nof the Git index file in 'index_path', without a repository\nto back it.","comments":"Since there is no ODB or working directory behind this index,\nany Index methods which rely on these (e.g. index_add) will\nfail with the GIT_EBAREINDEX error code.\n\nIf you need to access the index of an actual repository,\nuse the `git_repository_index` wrapper.\n\nThe index must be freed once it's no longer in use.\n","group":"index"},"git_index_clear":{"type":"function","file":"index.h","line":129,"lineto":129,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"}],"argline":"git_index *index","sig":"git_index *","return":{"type":"void"},"description":"Clear the contents (all the entries) of an index object.\nThis clears the index object in memory; changes must be manually\nwritten to disk for them to take effect.","comments":"","group":"index"},"git_index_free":{"type":"function","file":"index.h","line":136,"lineto":136,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"}],"argline":"git_index *index","sig":"git_index *","return":{"type":"void"},"description":"Free an existing index object.","comments":"","group":"index","examples":{"showindex.c":["ex/HEAD/showindex.html#git_index_free-1"],"general.c":["ex/HEAD/general.html#git_index_free-10"]}},"git_index_caps":{"type":"function","file":"index.h","line":144,"lineto":144,"args":[{"name":"index","type":"const git_index *","comment":"An existing index object"}],"argline":"const git_index *index","sig":"const git_index *","return":{"type":"unsigned int","comment":"A combination of GIT_INDEXCAP values"},"description":"Read index capabilities flags.","comments":"","group":"index"},"git_index_set_caps":{"type":"function","file":"index.h","line":157,"lineto":157,"args":[{"name":"index","type":"git_index *","comment":"An existing index object"},{"name":"caps","type":"unsigned int","comment":"A combination of GIT_INDEXCAP values"}],"argline":"git_index *index, unsigned int caps","sig":"git_index *::unsigned int","return":{"type":"int","comment":"0 on success, -1 on failure"},"description":"Set index capabilities flags.","comments":"If you pass `GIT_INDEXCAP_FROM_OWNER` for the caps, then the\ncapabilities will be read from the config of the owner object,\nlooking at `core.ignorecase`, `core.filemode`, `core.symlinks`.\n","group":"index"},"git_index_read":{"type":"function","file":"index.h","line":166,"lineto":166,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"}],"argline":"git_index *index","sig":"git_index *","return":{"type":"int","comment":"0 or an error code"},"description":"Update the contents of an existing index object in memory\nby reading from the hard disk.","comments":"","group":"index","examples":{"showindex.c":["ex/HEAD/showindex.html#git_index_read-2"]}},"git_index_write":{"type":"function","file":"index.h","line":175,"lineto":175,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"}],"argline":"git_index *index","sig":"git_index *","return":{"type":"int","comment":"0 or an error code"},"description":"Write an existing index object from memory back to disk\nusing an atomic file lock.","comments":"","group":"index"},"git_index_find":{"type":"function","file":"index.h","line":185,"lineto":185,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"path","type":"const char *","comment":"path to search"}],"argline":"git_index *index, const char *path","sig":"git_index *::const char *","return":{"type":"int","comment":"an index >= 0 if found, -1 otherwise"},"description":"Find the first index of any entries which point to given\npath in the Git index.","comments":"","group":"index"},"git_index_uniq":{"type":"function","file":"index.h","line":192,"lineto":192,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"}],"argline":"git_index *index","sig":"git_index *","return":{"type":"void"},"description":"Remove all entries with equal path except last added","comments":"","group":"index"},"git_index_add":{"type":"function","file":"index.h","line":211,"lineto":211,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"path","type":"const char *","comment":"filename to add"},{"name":"stage","type":"int","comment":"stage for the entry"}],"argline":"git_index *index, const char *path, int stage","sig":"git_index *::const char *::int","return":{"type":"int","comment":"0 or an error code"},"description":"Add or update an index entry from a file in disk","comments":"The file `path` must be relative to the repository's\nworking folder and must be readable.\n\nThis method will fail in bare index instances.\n\nThis forces the file to be added to the index, not looking\nat gitignore rules. Those rules can be evaluated through\nthe git_status APIs (in status.h) before calling this.\n","group":"index"},"git_index_add2":{"type":"function","file":"index.h","line":223,"lineto":223,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"source_entry","type":"const git_index_entry *","comment":"new entry object"}],"argline":"git_index *index, const git_index_entry *source_entry","sig":"git_index *::const git_index_entry *","return":{"type":"int","comment":"0 or an error code"},"description":"Add or update an index entry from an in-memory struct","comments":"A full copy (including the 'path' string) of the given\n'source_entry' will be inserted on the index.\n","group":"index"},"git_index_append":{"type":"function","file":"index.h","line":242,"lineto":242,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"path","type":"const char *","comment":"filename to add"},{"name":"stage","type":"int","comment":"stage for the entry"}],"argline":"git_index *index, const char *path, int stage","sig":"git_index *::const char *::int","return":{"type":"int","comment":"0 or an error code"},"description":"Add (append) an index entry from a file in disk","comments":"A new entry will always be inserted into the index;\nif the index already contains an entry for such\npath, the old entry will **not** be replaced.\n\nThe file `path` must be relative to the repository's\nworking folder and must be readable.\n\nThis method will fail in bare index instances.\n","group":"index"},"git_index_append2":{"type":"function","file":"index.h","line":259,"lineto":259,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"source_entry","type":"const git_index_entry *","comment":"new entry object"}],"argline":"git_index *index, const git_index_entry *source_entry","sig":"git_index *::const git_index_entry *","return":{"type":"int","comment":"0 or an error code"},"description":"Add (append) an index entry from an in-memory struct","comments":"A new entry will always be inserted into the index;\nif the index already contains an entry for the path\nin the `entry` struct, the old entry will **not** be\nreplaced.\n\nA full copy (including the 'path' string) of the given\n'source_entry' will be inserted on the index.\n","group":"index"},"git_index_remove":{"type":"function","file":"index.h","line":268,"lineto":268,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"position","type":"int","comment":"position of the entry to remove"}],"argline":"git_index *index, int position","sig":"git_index *::int","return":{"type":"int","comment":"0 or an error code"},"description":"Remove an entry from the index","comments":"","group":"index"},"git_index_get":{"type":"function","file":"index.h","line":283,"lineto":283,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"n","type":"size_t","comment":"the position of the entry"}],"argline":"git_index *index, size_t n","sig":"git_index *::size_t","return":{"type":"git_index_entry *","comment":"a pointer to the entry; NULL if out of bounds"},"description":"Get a pointer to one of the entries in the index","comments":"This entry can be modified, and the changes will be written\nback to disk on the next write() call.\n\nThe entry should not be freed by the caller.\n","group":"index","examples":{"showindex.c":["ex/HEAD/showindex.html#git_index_get-3"],"general.c":["ex/HEAD/general.html#git_index_get-11"]}},"git_index_entrycount":{"type":"function","file":"index.h","line":291,"lineto":291,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"}],"argline":"git_index *index","sig":"git_index *","return":{"type":"unsigned int","comment":"integer of count of current entries"},"description":"Get the count of entries currently in the index","comments":"","group":"index","examples":{"showindex.c":["ex/HEAD/showindex.html#git_index_entrycount-4"],"general.c":["ex/HEAD/general.html#git_index_entrycount-12"]}},"git_index_entrycount_unmerged":{"type":"function","file":"index.h","line":299,"lineto":299,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"}],"argline":"git_index *index","sig":"git_index *","return":{"type":"unsigned int","comment":"integer of count of current unmerged entries"},"description":"Get the count of unmerged entries currently in the index","comments":"","group":"index"},"git_index_get_unmerged_bypath":{"type":"function","file":"index.h","line":311,"lineto":311,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"path","type":"const char *","comment":"path to search"}],"argline":"git_index *index, const char *path","sig":"git_index *::const char *","return":{"type":"const git_index_entry_unmerged *","comment":"the unmerged entry; NULL if not found"},"description":"Get an unmerged entry from the index.","comments":"The returned entry is read-only and should not be modified\nof freed by the caller.\n","group":"index"},"git_index_get_unmerged_byindex":{"type":"function","file":"index.h","line":323,"lineto":323,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"n","type":"size_t","comment":"the position of the entry"}],"argline":"git_index *index, size_t n","sig":"git_index *::size_t","return":{"type":"const git_index_entry_unmerged *","comment":"a pointer to the unmerged entry; NULL if out of bounds"},"description":"Get an unmerged entry from the index.","comments":"The returned entry is read-only and should not be modified\nof freed by the caller.\n","group":"index"},"git_index_entry_stage":{"type":"function","file":"index.h","line":336,"lineto":336,"args":[{"name":"entry","type":"const git_index_entry *","comment":"The entry"}],"argline":"const git_index_entry *entry","sig":"const git_index_entry *","return":{"type":"int"},"description":"Return the stage number from a git index entry","comments":"This entry is calculated from the entry's flag\nattribute like this:\n\n(entry->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT\n","group":"index"},"git_index_read_tree":{"type":"function","file":"index.h","line":349,"lineto":349,"args":[{"name":"index","type":"git_index *","comment":"an existing index object"},{"name":"tree","type":"git_tree *","comment":"tree to read"},{"name":"stats","type":"git_indexer_stats *","comment":"structure that receives the total node count (may be NULL)"}],"argline":"git_index *index, git_tree *tree, git_indexer_stats *stats","sig":"git_index *::git_tree *::git_indexer_stats *","return":{"type":"int","comment":"0 or an error code"},"description":"Read a tree into the index file with stats","comments":"The current index contents will be replaced by the specified tree. The total\nnode count is collected in stats.\n","group":"index"},"git_repository_open":{"type":"function","file":"repository.h","line":36,"lineto":36,"args":[{"name":"repository","type":"git_repository **","comment":"pointer to the repo which will be opened"},{"name":"path","type":"const char *","comment":"the path to the repository"}],"argline":"git_repository **repository, const char *path","sig":"git_repository **::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Open a git repository.","comments":"The 'path' argument must point to either a git repository\nfolder, or an existing work dir.\n\nThe method will automatically detect if 'path' is a normal\nor bare repository or fail is 'path' is neither.\n","group":"repository","examples":{"showindex.c":["ex/HEAD/showindex.html#git_repository_open-5"],"general.c":["ex/HEAD/general.html#git_repository_open-13","ex/HEAD/general.html#git_repository_open-14"],"network/git2.c":["ex/HEAD/git2.html#git_repository_open-1"]}},"git_repository_wrap_odb":{"type":"function","file":"repository.h","line":49,"lineto":49,"args":[{"name":"repository","type":"git_repository **","comment":"pointer to the repo"},{"name":"odb","type":"git_odb *","comment":"the object database to wrap"}],"argline":"git_repository **repository, git_odb *odb","sig":"git_repository **::git_odb *","return":{"type":"int","comment":"0 or an error code"},"description":"Create a \"fake\" repository to wrap an object database","comments":"Create a repository object to wrap an object database to be used\nwith the API when all you have is an object database. This doesn't\nhave any paths associated with it, so use with care.\n","group":"repository"},"git_repository_discover":{"type":"function","file":"repository.h","line":79,"lineto":84,"args":[{"name":"repository_path","type":"char *","comment":"The user allocated buffer which will contain the found path."},{"name":"size","type":"size_t","comment":"repository_path size"},{"name":"start_path","type":"const char *","comment":"The base path where the lookup starts."},{"name":"across_fs","type":"int","comment":"If true, then the lookup will not stop when a filesystem device change is detected while exploring parent directories."},{"name":"ceiling_dirs","type":"const char *","comment":"A GIT_PATH_LIST_SEPARATOR separated list of absolute symbolic link free paths. The lookup will stop when any of this paths is reached. Note that the lookup always performs on start_path no matter start_path appears in ceiling_dirs ceiling_dirs might be NULL (which is equivalent to an empty string)"}],"argline":"char *repository_path,\n\t\tsize_t size,\n\t\tconst char *start_path,\n\t\tint across_fs,\n\t\tconst char *ceiling_dirs","sig":"char *::size_t::const char *::int::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Look for a git repository and copy its path in the given buffer.\nThe lookup start from base_path and walk across parent directories\nif nothing has been found. The lookup ends when the first repository\nis found, or when reaching a directory referenced in ceiling_dirs\nor when the filesystem changes (in case across_fs is true).","comments":"The method will automatically detect if the repository is bare\n(if there is a repository).\n","group":"repository"},"git_repository_open_ext":{"type":"function","file":"repository.h","line":120,"lineto":124,"args":[{"name":"repo","type":"git_repository **","comment":"_out Pointer to the repo which will be opened. This can actually be NULL if you only want to use the error code to see if a repo at this path could be opened."},{"name":"start_path","type":"const char *","comment":"Path to open as git repository. If the flags permit \"searching\", then this can be a path to a subdirectory inside the working directory of the repository."},{"name":"flags","type":"uint32_t","comment":"A combination of the GIT_REPOSITORY_OPEN flags above."},{"name":"ceiling_dirs","type":"const char *","comment":"A GIT_PATH_LIST_SEPARATOR delimited list of path prefixes at which the search for a containing repository should terminate."}],"argline":"git_repository **repo,\n\tconst char *start_path,\n\tuint32_t flags,\n\tconst char *ceiling_dirs","sig":"git_repository **::const char *::uint32_t::const char *","return":{"type":"int","comment":"0 on success, GIT_ENOTFOUND if no repository could be found, or -1 if there was a repository but open failed for some reason (such as repo corruption or system errors)."},"description":"Find and open a repository with extended controls.","comments":"","group":"repository","examples":{"diff.c":["ex/HEAD/diff.html#git_repository_open_ext-1"]}},"git_repository_free":{"type":"function","file":"repository.h","line":137,"lineto":137,"args":[{"name":"repo","type":"git_repository *","comment":"repository handle to close. If NULL nothing occurs."}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"void"},"description":"Free a previously allocated repository","comments":"Note that after a repository is free'd, all the objects it has spawned\nwill still exist until they are manually closed by the user\nwith `git_object_free`, but accessing any of the attributes of\nan object without a backing repository will result in undefined\nbehavior\n","group":"repository","examples":{"showindex.c":["ex/HEAD/showindex.html#git_repository_free-6"],"general.c":["ex/HEAD/general.html#git_repository_free-15"],"network/git2.c":["ex/HEAD/git2.html#git_repository_free-2"],"network/clone.c":["ex/HEAD/clone.html#git_repository_free-2"],"diff.c":["ex/HEAD/diff.html#git_repository_free-2"]}},"git_repository_init":{"type":"function","file":"repository.h","line":154,"lineto":157,"args":[{"name":"repo_out","type":"git_repository **","comment":"pointer to the repo which will be created or reinitialized"},{"name":"path","type":"const char *","comment":"the path to the repository"},{"name":"is_bare","type":"unsigned","comment":"if true, a Git repository without a working directory is created at the pointed path. If false, provided path will be considered as the working directory into which the .git directory will be created."}],"argline":"git_repository **repo_out,\n\tconst char *path,\n\tunsigned is_bare","sig":"git_repository **::const char *::unsigned","return":{"type":"int","comment":"0 or an error code"},"description":"Creates a new Git repository in the given folder.","comments":"TODO:\n- Reinit the repository\n","group":"repository"},"git_repository_init_ext":{"type":"function","file":"repository.h","line":264,"lineto":267,"args":[{"name":"repo_out","type":"git_repository **","comment":"Pointer to the repo which will be created or reinitialized."},{"name":"repo_path","type":"const char *","comment":"The path to the repository."},{"name":"opts","type":"git_repository_init_options *","comment":"Pointer to git_repository_init_options struct."}],"argline":"git_repository **repo_out,\n\tconst char *repo_path,\n\tgit_repository_init_options *opts","sig":"git_repository **::const char *::git_repository_init_options *","return":{"type":"int","comment":"0 or an error code on failure."},"description":"Create a new Git repository in the given folder with extended controls.","comments":"This will initialize a new git repository (creating the repo_path\nif requested by flags) and working directory as needed. It will\nauto-detect the case sensitivity of the file system and if the\nfile system supports file mode bits correctly.\n","group":"repository"},"git_repository_head":{"type":"function","file":"repository.h","line":277,"lineto":277,"args":[{"name":"head_out","type":"git_reference **","comment":"pointer to the reference which will be retrieved"},{"name":"repo","type":"git_repository *","comment":"a repository object"}],"argline":"git_reference **head_out, git_repository *repo","sig":"git_reference **::git_repository *","return":{"type":"int","comment":"0 on success; error code otherwise"},"description":"Retrieve and resolve the reference pointed at by HEAD.","comments":"","group":"repository"},"git_repository_head_detached":{"type":"function","file":"repository.h","line":289,"lineto":289,"args":[{"name":"repo","type":"git_repository *","comment":"Repo to test"}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"int","comment":"1 if HEAD is detached, 0 if it's not; error code if there was an error."},"description":"Check if a repository's HEAD is detached","comments":"A repository's HEAD is detached when it points directly to a commit\ninstead of a branch.\n","group":"repository"},"git_repository_head_orphan":{"type":"function","file":"repository.h","line":301,"lineto":301,"args":[{"name":"repo","type":"git_repository *","comment":"Repo to test"}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"int","comment":"1 if the current branch is an orphan, 0 if it's not; error code if there was an error"},"description":"Check if the current branch is an orphan","comments":"An orphan branch is one named from HEAD but which doesn't exist in\nthe refs namespace, because it doesn't have any commit to point to.\n","group":"repository"},"git_repository_is_empty":{"type":"function","file":"repository.h","line":313,"lineto":313,"args":[{"name":"repo","type":"git_repository *","comment":"Repo to test"}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"int","comment":"1 if the repository is empty, 0 if it isn't, error code if the repository is corrupted"},"description":"Check if a repository is empty","comments":"An empty repository has just been initialized and contains\nno commits.\n","group":"repository"},"git_repository_path":{"type":"function","file":"repository.h","line":324,"lineto":324,"args":[{"name":"repo","type":"git_repository *","comment":"A repository object"}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"const char *","comment":"the path to the repository"},"description":"Get the path of this repository","comments":"This is the path of the `.git` folder for normal repositories,\nor of the repository itself for bare repositories.\n","group":"repository"},"git_repository_workdir":{"type":"function","file":"repository.h","line":335,"lineto":335,"args":[{"name":"repo","type":"git_repository *","comment":"A repository object"}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"const char *","comment":"the path to the working dir, if it exists"},"description":"Get the path of the working directory for this repository","comments":"If the repository is bare, this function will always return\nNULL.\n","group":"repository"},"git_repository_set_workdir":{"type":"function","file":"repository.h","line":354,"lineto":355,"args":[{"name":"repo","type":"git_repository *","comment":"A repository object"},{"name":"workdir","type":"const char *","comment":"The path to a working directory"},{"name":"update_gitlink","type":"int","comment":"Create/update gitlink in workdir and set config \"core.worktree\" (if workdir is not the parent of the .git directory)"}],"argline":"git_repository *repo, const char *workdir, int update_gitlink","sig":"git_repository *::const char *::int","return":{"type":"int","comment":"0, or an error code"},"description":"Set the path to the working directory for this repository","comments":"The working directory doesn't need to be the same one\nthat contains the `.git` folder for this repository.\n\nIf this repository is bare, setting its working directory\nwill turn it into a normal repository, capable of performing\nall the common workdir operations (checkout, status, index\nmanipulation, etc).\n","group":"repository"},"git_repository_is_bare":{"type":"function","file":"repository.h","line":363,"lineto":363,"args":[{"name":"repo","type":"git_repository *","comment":"Repo to test"}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"int","comment":"1 if the repository is bare, 0 otherwise."},"description":"Check if a repository is bare","comments":"","group":"repository"},"git_repository_config":{"type":"function","file":"repository.h","line":379,"lineto":379,"args":[{"name":"out","type":"git_config **","comment":"Pointer to store the loaded config file"},{"name":"repo","type":"git_repository *","comment":"A repository object"}],"argline":"git_config **out, git_repository *repo","sig":"git_config **::git_repository *","return":{"type":"int","comment":"0, or an error code"},"description":"Get the configuration file for this repository.","comments":"If a configuration file has not been set, the default\nconfig set for the repository will be returned, including\nglobal and system configurations (if they are available).\n\nThe configuration file must be freed once it's no longer\nbeing used by the user.\n","group":"repository"},"git_repository_set_config":{"type":"function","file":"repository.h","line":394,"lineto":394,"args":[{"name":"repo","type":"git_repository *","comment":"A repository object"},{"name":"config","type":"git_config *","comment":"A Config object"}],"argline":"git_repository *repo, git_config *config","sig":"git_repository *::git_config *","return":{"type":"void"},"description":"Set the configuration file for this repository","comments":"This configuration file will be used for all configuration\nqueries involving this repository.\n\nThe repository will keep a reference to the config file;\nthe user must still free the config after setting it\nto the repository, or it will leak.\n","group":"repository"},"git_repository_odb":{"type":"function","file":"repository.h","line":410,"lineto":410,"args":[{"name":"out","type":"git_odb **","comment":"Pointer to store the loaded ODB"},{"name":"repo","type":"git_repository *","comment":"A repository object"}],"argline":"git_odb **out, git_repository *repo","sig":"git_odb **::git_repository *","return":{"type":"int","comment":"0, or an error code"},"description":"Get the Object Database for this repository.","comments":"If a custom ODB has not been set, the default\ndatabase for the repository will be returned (the one\nlocated in `.git/objects`).\n\nThe ODB must be freed once it's no longer being used by\nthe user.\n","group":"repository","examples":{"general.c":["ex/HEAD/general.html#git_repository_odb-16"]}},"git_repository_set_odb":{"type":"function","file":"repository.h","line":425,"lineto":425,"args":[{"name":"repo","type":"git_repository *","comment":"A repository object"},{"name":"odb","type":"git_odb *","comment":"An ODB object"}],"argline":"git_repository *repo, git_odb *odb","sig":"git_repository *::git_odb *","return":{"type":"void"},"description":"Set the Object Database for this repository","comments":"The ODB will be used for all object-related operations\ninvolving this repository.\n\nThe repository will keep a reference to the ODB; the user\nmust still free the ODB object after setting it to the\nrepository, or it will leak.\n","group":"repository"},"git_repository_index":{"type":"function","file":"repository.h","line":441,"lineto":441,"args":[{"name":"out","type":"git_index **","comment":"Pointer to store the loaded index"},{"name":"repo","type":"git_repository *","comment":"A repository object"}],"argline":"git_index **out, git_repository *repo","sig":"git_index **::git_repository *","return":{"type":"int","comment":"0, or an error code"},"description":"Get the Index file for this repository.","comments":"If a custom index has not been set, the default\nindex for the repository will be returned (the one\nlocated in `.git/index`).\n\nThe index must be freed once it's no longer being used by\nthe user.\n","group":"repository","examples":{"showindex.c":["ex/HEAD/showindex.html#git_repository_index-7"],"general.c":["ex/HEAD/general.html#git_repository_index-17"]}},"git_repository_set_index":{"type":"function","file":"repository.h","line":456,"lineto":456,"args":[{"name":"repo","type":"git_repository *","comment":"A repository object"},{"name":"index","type":"git_index *","comment":"An index object"}],"argline":"git_repository *repo, git_index *index","sig":"git_repository *::git_index *","return":{"type":"void"},"description":"Set the index file for this repository","comments":"This index will be used for all index-related operations\ninvolving this repository.\n\nThe repository will keep a reference to the index file;\nthe user must still free the index after setting it\nto the repository, or it will leak.\n","group":"repository"},"git_repository_message":{"type":"function","file":"repository.h","line":475,"lineto":475,"args":[{"name":"buffer","type":"char *","comment":"Buffer to write data into or NULL to just read required size"},{"name":"len","type":"size_t","comment":"Length of buffer in bytes"},{"name":"repo","type":"git_repository *","comment":"Repository to read prepared message from"}],"argline":"char *buffer, size_t len, git_repository *repo","sig":"char *::size_t::git_repository *","return":{"type":"int","comment":"Bytes written to buffer, GIT_ENOTFOUND if no message, or -1 on error"},"description":"Retrieve git's prepared message","comments":"Operations such as git revert/cherry-pick/merge with the -n option\nstop just short of creating a commit with the changes and save\ntheir prepared message in .git/MERGE_MSG so the next git-commit\nexecution can present it to the user for them to amend if they\nwish.\n\nUse this function to get the contents of this file. Don't forget to\nremove the file after you create the commit.\n","group":"repository"},"git_repository_message_remove":{"type":"function","file":"repository.h","line":482,"lineto":482,"args":[{"name":"repo","type":"git_repository *"}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"int"},"description":"Remove git's prepared message.","comments":"Remove the message that `git_repository_message` retrieves.","group":"repository"},"git_repository_hashfile":{"type":"function","file":"repository.h","line":502,"lineto":507,"args":[{"name":"out","type":"git_oid *","comment":"Output value of calculated SHA"},{"name":"repo","type":"git_repository *","comment":"Repository pointer"},{"name":"path","type":"const char *","comment":"Path to file on disk whose contents should be hashed. If the repository is not NULL, this can be a relative path."},{"name":"type","type":"git_otype","comment":"The object type to hash as (e.g. GIT_OBJ_BLOB)"},{"name":"as_path","type":"const char *","comment":"The path to use to look up filtering rules. If this is NULL, then the `path` parameter will be used instead. If this is passed as the empty string, then no filters will be applied when calculating the hash."}],"argline":"git_oid *out,\n git_repository *repo,\n const char *path,\n git_otype type,\n const char *as_path","sig":"git_oid *::git_repository *::const char *::git_otype::const char *","return":{"type":"int"},"description":"Calculate hash of file using repository filtering rules.","comments":"If you simply want to calculate the hash of a file on disk with no filters,\nyou can just use the `git_odb_hashfile()` API. However, if you want to\nhash a file in the repository and you want to apply filtering rules (e.g.\ncrlf filters) before generating the SHA, then use this function.\n","group":"repository"},"git_repository_set_head":{"type":"function","file":"repository.h","line":527,"lineto":529,"args":[{"name":"repo","type":"git_repository*","comment":"Repository pointer"},{"name":"refname","type":"const char*","comment":"Canonical name of the reference the HEAD should point at"}],"argline":"git_repository* repo,\n\tconst char* refname","sig":"git_repository*::const char*","return":{"type":"int","comment":"0 on success, or an error code"},"description":"Make the repository HEAD point to the specified reference.","comments":"If the provided reference points to a Tree or a Blob, the HEAD is\nunaltered and -1 is returned.\n\nIf the provided reference points to a branch, the HEAD will point\nto that branch, staying attached, or become attached if it isn't yet.\nIf the branch doesn't exist yet, no error will be return. The HEAD\nwill then be attached to an unborn branch.\n\nOtherwise, the HEAD will be detached and will directly point to\nthe Commit.\n","group":"repository"},"git_repository_set_head_detached":{"type":"function","file":"repository.h","line":547,"lineto":549,"args":[{"name":"repo","type":"git_repository*","comment":"Repository pointer"},{"name":"commitish","type":"const git_oid*","comment":"Object id of the Commit the HEAD should point to"}],"argline":"git_repository* repo,\n\tconst git_oid* commitish","sig":"git_repository*::const git_oid*","return":{"type":"int","comment":"0 on success, or an error code"},"description":"Make the repository HEAD directly point to the Commit.","comments":"If the provided committish cannot be found in the repository, the HEAD\nis unaltered and GIT_ENOTFOUND is returned.\n\nIf the provided commitish cannot be peeled into a commit, the HEAD\nis unaltered and -1 is returned.\n\nOtherwise, the HEAD will eventually be detached and will directly point to\nthe peeled Commit.\n","group":"repository"},"git_repository_detach_head":{"type":"function","file":"repository.h","line":567,"lineto":568,"args":[{"name":"repo","type":"git_repository*","comment":"Repository pointer"}],"argline":"git_repository* repo","sig":"git_repository*","return":{"type":"int","comment":"0 on success, or an error code"},"description":"Detach the HEAD.","comments":"If the HEAD is already detached and points to a Commit, 0 is returned.\n\nIf the HEAD is already detached and points to a Tag, the HEAD is\nupdated into making it point to the peeled Commit, and 0 is returned.\n\nIf the HEAD is already detached and points to a non commitish, the HEAD is \nunaletered, and -1 is returned.\n\nOtherwise, the HEAD will be detached and point to the peeled Commit.\n","group":"repository"},"git_tag_lookup":{"type":"function","file":"tag.h","line":32,"lineto":35,"args":[{"name":"tag","type":"git_tag **","comment":"pointer to the looked up tag"},{"name":"repo","type":"git_repository *","comment":"the repo to use when locating the tag."},{"name":"id","type":"const git_oid *","comment":"identity of the tag to locate."}],"argline":"git_tag **tag, git_repository *repo, const git_oid *id","sig":"git_tag **::git_repository *::const git_oid *","return":{"type":"int","comment":"0 or an error code"},"description":"Lookup a tag object from the repository.","comments":"","group":"tag","examples":{"general.c":["ex/HEAD/general.html#git_tag_lookup-18"]}},"git_tag_lookup_prefix":{"type":"function","file":"tag.h","line":49,"lineto":52,"args":[{"name":"tag","type":"git_tag **","comment":"pointer to the looked up tag"},{"name":"repo","type":"git_repository *","comment":"the repo to use when locating the tag."},{"name":"id","type":"const git_oid *","comment":"identity of the tag to locate."},{"name":"len","type":"size_t","comment":"the length of the short identifier"}],"argline":"git_tag **tag, git_repository *repo, const git_oid *id, size_t len","sig":"git_tag **::git_repository *::const git_oid *::size_t","return":{"type":"int","comment":"0 or an error code"},"description":"Lookup a tag object from the repository,\ngiven a prefix of its identifier (short id).","comments":"@see git_object_lookup_prefix\n","group":"tag"},"git_tag_free":{"type":"function","file":"tag.h","line":65,"lineto":68,"args":[{"name":"tag","type":"git_tag *","comment":"the tag to close"}],"argline":"git_tag *tag","sig":"git_tag *","return":{"type":"void"},"description":"Close an open tag","comments":"This is a wrapper around git_object_free()\n\nIMPORTANT:\nIt *is* necessary to call this method when you stop\nusing a tag. Failure to do so will cause a memory leak.\n","group":"tag"},"git_tag_id":{"type":"function","file":"tag.h","line":78,"lineto":78,"args":[{"name":"tag","type":"git_tag *","comment":"a previously loaded tag."}],"argline":"git_tag *tag","sig":"git_tag *","return":{"type":"const git_oid *","comment":"object identity for the tag."},"description":"Get the id of a tag.","comments":"","group":"tag"},"git_tag_target":{"type":"function","file":"tag.h","line":90,"lineto":90,"args":[{"name":"target","type":"git_object **","comment":"pointer where to store the target"},{"name":"tag","type":"git_tag *","comment":"a previously loaded tag."}],"argline":"git_object **target, git_tag *tag","sig":"git_object **::git_tag *","return":{"type":"int","comment":"0 or an error code"},"description":"Get the tagged object of a tag","comments":"This method performs a repository lookup for the\ngiven object and returns it\n","group":"tag","examples":{"general.c":["ex/HEAD/general.html#git_tag_target-19"]}},"git_tag_target_oid":{"type":"function","file":"tag.h","line":98,"lineto":98,"args":[{"name":"tag","type":"git_tag *","comment":"a previously loaded tag."}],"argline":"git_tag *tag","sig":"git_tag *","return":{"type":"const git_oid *","comment":"pointer to the OID"},"description":"Get the OID of the tagged object of a tag","comments":"","group":"tag"},"git_tag_type":{"type":"function","file":"tag.h","line":106,"lineto":106,"args":[{"name":"tag","type":"git_tag *","comment":"a previously loaded tag."}],"argline":"git_tag *tag","sig":"git_tag *","return":{"type":"git_otype","comment":"type of the tagged object"},"description":"Get the type of a tag's tagged object","comments":"","group":"tag","examples":{"general.c":["ex/HEAD/general.html#git_tag_type-20"]}},"git_tag_name":{"type":"function","file":"tag.h","line":114,"lineto":114,"args":[{"name":"tag","type":"git_tag *","comment":"a previously loaded tag."}],"argline":"git_tag *tag","sig":"git_tag *","return":{"type":"const char *","comment":"name of the tag"},"description":"Get the name of a tag","comments":"","group":"tag","examples":{"general.c":["ex/HEAD/general.html#git_tag_name-21"]}},"git_tag_tagger":{"type":"function","file":"tag.h","line":122,"lineto":122,"args":[{"name":"tag","type":"git_tag *","comment":"a previously loaded tag."}],"argline":"git_tag *tag","sig":"git_tag *","return":{"type":"const git_signature *","comment":"reference to the tag's author"},"description":"Get the tagger (author) of a tag","comments":"","group":"tag"},"git_tag_message":{"type":"function","file":"tag.h","line":130,"lineto":130,"args":[{"name":"tag","type":"git_tag *","comment":"a previously loaded tag."}],"argline":"git_tag *tag","sig":"git_tag *","return":{"type":"const char *","comment":"message of the tag"},"description":"Get the message of a tag","comments":"","group":"tag","examples":{"general.c":["ex/HEAD/general.html#git_tag_message-22"]}},"git_tag_create":{"type":"function","file":"tag.h","line":168,"lineto":175,"args":[{"name":"oid","type":"git_oid *","comment":"Pointer where to store the OID of the newly created tag. If the tag already exists, this parameter will be the oid of the existing tag, and the function will return a GIT_EEXISTS error code."},{"name":"repo","type":"git_repository *","comment":"Repository where to store the tag"},{"name":"tag_name","type":"const char *","comment":"Name for the tag; this name is validated for consistency. It should also not conflict with an already existing tag name"},{"name":"target","type":"const git_object *","comment":"Object to which this tag points. This object must belong to the given `repo`."},{"name":"tagger","type":"const git_signature *","comment":"Signature of the tagger for this tag, and of the tagging time"},{"name":"message","type":"const char *","comment":"Full message for this tag"},{"name":"force","type":"int","comment":"Overwrite existing references"}],"argline":"git_oid *oid,\n\t\tgit_repository *repo,\n\t\tconst char *tag_name,\n\t\tconst git_object *target,\n\t\tconst git_signature *tagger,\n\t\tconst char *message,\n\t\tint force","sig":"git_oid *::git_repository *::const char *::const git_object *::const git_signature *::const char *::int","return":{"type":"int","comment":"0 or an error code A tag object is written to the ODB, and a proper reference is written in the /refs/tags folder, pointing to it"},"description":"Create a new tag in the repository from an object","comments":"A new reference will also be created pointing to\nthis tag object. If `force` is true and a reference\nalready exists with the given name, it'll be replaced.\n\nThe message will not be cleaned up. This can be achieved\nthrough `git_message_prettify()`.\n","group":"tag"},"git_tag_create_frombuffer":{"type":"function","file":"tag.h","line":186,"lineto":190,"args":[{"name":"oid","type":"git_oid *","comment":"Pointer where to store the OID of the newly created tag"},{"name":"repo","type":"git_repository *","comment":"Repository where to store the tag"},{"name":"buffer","type":"const char *","comment":"Raw tag data"},{"name":"force","type":"int","comment":"Overwrite existing tags"}],"argline":"git_oid *oid,\n\t\tgit_repository *repo,\n\t\tconst char *buffer,\n\t\tint force","sig":"git_oid *::git_repository *::const char *::int","return":{"type":"int","comment":"0 on success; error code otherwise"},"description":"Create a new tag in the repository from a buffer","comments":"","group":"tag"},"git_tag_create_lightweight":{"type":"function","file":"tag.h","line":219,"lineto":224,"args":[{"name":"oid","type":"git_oid *","comment":"Pointer where to store the OID of the provided target object. If the tag already exists, this parameter will be filled with the oid of the existing pointed object and the function will return a GIT_EEXISTS error code."},{"name":"repo","type":"git_repository *","comment":"Repository where to store the lightweight tag"},{"name":"tag_name","type":"const char *","comment":"Name for the tag; this name is validated for consistency. It should also not conflict with an already existing tag name"},{"name":"target","type":"const git_object *","comment":"Object to which this tag points. This object must belong to the given `repo`."},{"name":"force","type":"int","comment":"Overwrite existing references"}],"argline":"git_oid *oid,\n\t\tgit_repository *repo,\n\t\tconst char *tag_name,\n\t\tconst git_object *target,\n\t\tint force","sig":"git_oid *::git_repository *::const char *::const git_object *::int","return":{"type":"int","comment":"0 or an error code A proper reference is written in the /refs/tags folder, pointing to the provided target object"},"description":"Create a new lightweight tag pointing at a target object","comments":"A new direct reference will be created pointing to\nthis target object. If `force` is true and a reference\nalready exists with the given name, it'll be replaced.\n","group":"tag"},"git_tag_delete":{"type":"function","file":"tag.h","line":236,"lineto":238,"args":[{"name":"repo","type":"git_repository *","comment":"Repository where lives the tag"},{"name":"tag_name","type":"const char *","comment":"Name of the tag to be deleted; this name is validated for consistency."}],"argline":"git_repository *repo,\n\t\tconst char *tag_name","sig":"git_repository *::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Delete an existing tag reference.","comments":"","group":"tag"},"git_tag_list":{"type":"function","file":"tag.h","line":253,"lineto":255,"args":[{"name":"tag_names","type":"git_strarray *","comment":"Pointer to a git_strarray structure where the tag names will be stored"},{"name":"repo","type":"git_repository *","comment":"Repository where to find the tags"}],"argline":"git_strarray *tag_names,\n\t\tgit_repository *repo","sig":"git_strarray *::git_repository *","return":{"type":"int","comment":"0 or an error code"},"description":"Fill a list with all the tags in the Repository","comments":"The string array will be filled with the names of the\nmatching tags; these values are owned by the user and\nshould be free'd manually when no longer needed, using\n`git_strarray_free`.\n","group":"tag"},"git_tag_list_match":{"type":"function","file":"tag.h","line":275,"lineto":278,"args":[{"name":"tag_names","type":"git_strarray *","comment":"Pointer to a git_strarray structure where the tag names will be stored"},{"name":"pattern","type":"const char *","comment":"Standard fnmatch pattern"},{"name":"repo","type":"git_repository *","comment":"Repository where to find the tags"}],"argline":"git_strarray *tag_names,\n\t\tconst char *pattern,\n\t\tgit_repository *repo","sig":"git_strarray *::const char *::git_repository *","return":{"type":"int","comment":"0 or an error code"},"description":"Fill a list with all the tags in the Repository\nwhich name match a defined pattern","comments":"If an empty pattern is provided, all the tags\nwill be returned.\n\nThe string array will be filled with the names of the\nmatching tags; these values are owned by the user and\nshould be free'd manually when no longer needed, using\n`git_strarray_free`.\n","group":"tag"},"git_tag_peel":{"type":"function","file":"tag.h","line":291,"lineto":293,"args":[{"name":"tag_target","type":"git_object **","comment":"Pointer to the peeled git_object"},{"name":"tag","type":"git_tag *","comment":"_target Pointer to the peeled git_object"}],"argline":"git_object **tag_target,\n\t\tgit_tag *tag","sig":"git_object **::git_tag *","return":{"type":"int","comment":"0 or an error code"},"description":"Recursively peel a tag until a non tag git_object\nis met","comments":"The retrieved `tag_target` object is owned by the repository\nand should be closed with the `git_object_free` method.\n","group":"tag"},"git_revparse_single":{"type":"function","file":"revparse.h","line":32,"lineto":32,"args":[{"name":"out","type":"git_object **","comment":"pointer to output object"},{"name":"repo","type":"git_repository *","comment":"the repository to search in"},{"name":"spec","type":"const char *","comment":"the textual specification for an object"}],"argline":"git_object **out, git_repository *repo, const char *spec","sig":"git_object **::git_repository *::const char *","return":{"type":"int","comment":"on success, GIT_ERROR otherwise (use git_error_last for information about the error)"},"description":"Find an object, as specified by a revision string. See `man gitrevisions`, or the documentation\nfor `git rev-parse` for information on the syntax accepted.","comments":"","group":"revparse"},"git_commit_lookup":{"type":"function","file":"commit.h","line":33,"lineto":36,"args":[{"name":"commit","type":"git_commit **","comment":"pointer to the looked up commit"},{"name":"repo","type":"git_repository *","comment":"the repo to use when locating the commit."},{"name":"id","type":"const git_oid *","comment":"identity of the commit to locate. If the object is an annotated tag it will be peeled back to the commit."}],"argline":"git_commit **commit, git_repository *repo, const git_oid *id","sig":"git_commit **::git_repository *::const git_oid *","return":{"type":"int","comment":"0 or an error code"},"description":"Lookup a commit object from a repository.","comments":"","group":"commit","examples":{"general.c":["ex/HEAD/general.html#git_commit_lookup-23","ex/HEAD/general.html#git_commit_lookup-24","ex/HEAD/general.html#git_commit_lookup-25"]}},"git_commit_lookup_prefix":{"type":"function","file":"commit.h","line":51,"lineto":54,"args":[{"name":"commit","type":"git_commit **","comment":"pointer to the looked up commit"},{"name":"repo","type":"git_repository *","comment":"the repo to use when locating the commit."},{"name":"id","type":"const git_oid *","comment":"identity of the commit to locate. If the object is an annotated tag it will be peeled back to the commit."},{"name":"len","type":"size_t","comment":"the length of the short identifier"}],"argline":"git_commit **commit, git_repository *repo, const git_oid *id, size_t len","sig":"git_commit **::git_repository *::const git_oid *::size_t","return":{"type":"int","comment":"0 or an error code"},"description":"Lookup a commit object from a repository,\ngiven a prefix of its identifier (short id).","comments":"@see git_object_lookup_prefix\n","group":"commit"},"git_commit_free":{"type":"function","file":"commit.h","line":67,"lineto":70,"args":[{"name":"commit","type":"git_commit *","comment":"the commit to close"}],"argline":"git_commit *commit","sig":"git_commit *","return":{"type":"void"},"description":"Close an open commit","comments":"This is a wrapper around git_object_free()\n\nIMPORTANT:\nIt *is* necessary to call this method when you stop\nusing a commit. Failure to do so will cause a memory leak.\n","group":"commit","examples":{"general.c":["ex/HEAD/general.html#git_commit_free-26","ex/HEAD/general.html#git_commit_free-27","ex/HEAD/general.html#git_commit_free-28","ex/HEAD/general.html#git_commit_free-29"]}},"git_commit_id":{"type":"function","file":"commit.h","line":79,"lineto":79,"args":[{"name":"commit","type":"git_commit *","comment":"a previously loaded commit."}],"argline":"git_commit *commit","sig":"git_commit *","return":{"type":"const git_oid *","comment":"object identity for the commit."},"description":"Get the id of a commit.","comments":"","group":"commit","examples":{"general.c":["ex/HEAD/general.html#git_commit_id-30"]}},"git_commit_message_encoding":{"type":"function","file":"commit.h","line":91,"lineto":91,"args":[{"name":"commit","type":"git_commit *","comment":"a previously loaded commit."}],"argline":"git_commit *commit","sig":"git_commit *","return":{"type":"const char *","comment":"NULL, or the encoding"},"description":"Get the encoding for the message of a commit,\nas a string representing a standard encoding name.","comments":"The encoding may be NULL if the `encoding` header\nin the commit is missing; in that case UTF-8 is assumed.\n","group":"commit"},"git_commit_message":{"type":"function","file":"commit.h","line":99,"lineto":99,"args":[{"name":"commit","type":"git_commit *","comment":"a previously loaded commit."}],"argline":"git_commit *commit","sig":"git_commit *","return":{"type":"const char *","comment":"the message of a commit"},"description":"Get the full message of a commit.","comments":"","group":"commit","examples":{"general.c":["ex/HEAD/general.html#git_commit_message-31","ex/HEAD/general.html#git_commit_message-32"]}},"git_commit_time":{"type":"function","file":"commit.h","line":107,"lineto":107,"args":[{"name":"commit","type":"git_commit *","comment":"a previously loaded commit."}],"argline":"git_commit *commit","sig":"git_commit *","return":{"type":"git_time_t","comment":"the time of a commit"},"description":"Get the commit time (i.e. committer time) of a commit.","comments":"","group":"commit","examples":{"general.c":["ex/HEAD/general.html#git_commit_time-33","ex/HEAD/general.html#git_commit_time-34"]}},"git_commit_time_offset":{"type":"function","file":"commit.h","line":115,"lineto":115,"args":[{"name":"commit","type":"git_commit *","comment":"a previously loaded commit."}],"argline":"git_commit *commit","sig":"git_commit *","return":{"type":"int","comment":"positive or negative timezone offset, in minutes from UTC"},"description":"Get the commit timezone offset (i.e. committer's preferred timezone) of a commit.","comments":"","group":"commit"},"git_commit_committer":{"type":"function","file":"commit.h","line":123,"lineto":123,"args":[{"name":"commit","type":"git_commit *","comment":"a previously loaded commit."}],"argline":"git_commit *commit","sig":"git_commit *","return":{"type":"const git_signature *","comment":"the committer of a commit"},"description":"Get the committer of a commit.","comments":"","group":"commit","examples":{"general.c":["ex/HEAD/general.html#git_commit_committer-35"]}},"git_commit_author":{"type":"function","file":"commit.h","line":131,"lineto":131,"args":[{"name":"commit","type":"git_commit *","comment":"a previously loaded commit."}],"argline":"git_commit *commit","sig":"git_commit *","return":{"type":"const git_signature *","comment":"the author of a commit"},"description":"Get the author of a commit.","comments":"","group":"commit","examples":{"general.c":["ex/HEAD/general.html#git_commit_author-36","ex/HEAD/general.html#git_commit_author-37"]}},"git_commit_tree":{"type":"function","file":"commit.h","line":140,"lineto":140,"args":[{"name":"tree_out","type":"git_tree **","comment":"pointer where to store the tree object"},{"name":"commit","type":"git_commit *","comment":"a previously loaded commit."}],"argline":"git_tree **tree_out, git_commit *commit","sig":"git_tree **::git_commit *","return":{"type":"int","comment":"0 or an error code"},"description":"Get the tree pointed to by a commit.","comments":"","group":"commit","examples":{"diff.c":["ex/HEAD/diff.html#git_commit_tree-3"]}},"git_commit_tree_oid":{"type":"function","file":"commit.h","line":150,"lineto":150,"args":[{"name":"commit","type":"git_commit *","comment":"a previously loaded commit."}],"argline":"git_commit *commit","sig":"git_commit *","return":{"type":"const git_oid *","comment":"the id of tree pointed to by commit."},"description":"Get the id of the tree pointed to by a commit. This differs from\n`git_commit_tree` in that no attempts are made to fetch an object\nfrom the ODB.","comments":"","group":"commit"},"git_commit_parentcount":{"type":"function","file":"commit.h","line":158,"lineto":158,"args":[{"name":"commit","type":"git_commit *","comment":"a previously loaded commit."}],"argline":"git_commit *commit","sig":"git_commit *","return":{"type":"unsigned int","comment":"integer of count of parents"},"description":"Get the number of parents of this commit","comments":"","group":"commit","examples":{"general.c":["ex/HEAD/general.html#git_commit_parentcount-38"]}},"git_commit_parent":{"type":"function","file":"commit.h","line":168,"lineto":168,"args":[{"name":"parent","type":"git_commit **","comment":"Pointer where to store the parent commit"},{"name":"commit","type":"git_commit *","comment":"a previously loaded commit."},{"name":"n","type":"unsigned int","comment":"the position of the parent (from 0 to `parentcount`)"}],"argline":"git_commit **parent, git_commit *commit, unsigned int n","sig":"git_commit **::git_commit *::unsigned int","return":{"type":"int","comment":"0 or an error code"},"description":"Get the specified parent of the commit.","comments":"","group":"commit","examples":{"general.c":["ex/HEAD/general.html#git_commit_parent-39"]}},"git_commit_parent_oid":{"type":"function","file":"commit.h","line":179,"lineto":179,"args":[{"name":"commit","type":"git_commit *","comment":"a previously loaded commit."},{"name":"n","type":"unsigned int","comment":"the position of the parent (from 0 to `parentcount`)"}],"argline":"git_commit *commit, unsigned int n","sig":"git_commit *::unsigned int","return":{"type":"const git_oid *","comment":"the id of the parent, NULL on error."},"description":"Get the oid of a specified parent for a commit. This is different from\n`git_commit_parent`, which will attempt to load the parent commit from\nthe ODB.","comments":"","group":"commit"},"git_commit_nth_gen_ancestor":{"type":"function","file":"commit.h","line":195,"lineto":198,"args":[{"name":"ancestor","type":"git_commit **","comment":"Pointer where to store the ancestor commit"},{"name":"commit","type":"const git_commit *","comment":"a previously loaded commit."},{"name":"n","type":"unsigned int","comment":"the requested generation"}],"argline":"git_commit **ancestor,\n\tconst git_commit *commit,\n\tunsigned int n","sig":"git_commit **::const git_commit *::unsigned int","return":{"type":"int","comment":"0 on success; GIT_ENOTFOUND if no matching ancestor exists or an error code"},"description":"Get the commit object that is the th generation ancestor\nof the named commit object, following only the first parents.\nThe returned commit has to be freed by the caller.","comments":"Passing `0` as the generation number returns another instance of the\nbase commit itself.\n","group":"commit"},"git_commit_create":{"type":"function","file":"commit.h","line":247,"lineto":257,"args":[{"name":"oid","type":"git_oid *","comment":"Pointer where to store the OID of the newly created commit"},{"name":"repo","type":"git_repository *","comment":"Repository where to store the commit"},{"name":"update_ref","type":"const char *","comment":"If not NULL, name of the reference that will be updated to point to this commit. If the reference is not direct, it will be resolved to a direct reference. Use \"HEAD\" to update the HEAD of the current branch and make it point to this commit. If the reference doesn't exist yet, it will be created."},{"name":"author","type":"const git_signature *","comment":"Signature representing the author and the authory time of this commit"},{"name":"committer","type":"const git_signature *","comment":"Signature representing the committer and the commit time of this commit"},{"name":"message_encoding","type":"const char *","comment":"The encoding for the message in the commit, represented with a standard encoding name. E.g. \"UTF-8\". If NULL, no encoding header is written and UTF-8 is assumed."},{"name":"message","type":"const char *","comment":"_encoding The encoding for the message in the commit, represented with a standard encoding name. E.g. \"UTF-8\". If NULL, no encoding header is written and UTF-8 is assumed."},{"name":"tree","type":"const git_tree *","comment":"An instance of a `git_tree` object that will be used as the tree for the commit. This tree object must also be owned by the given `repo`."},{"name":"parent_count","type":"int","comment":"Number of parents for this commit"}],"argline":"git_oid *oid,\n\t\tgit_repository *repo,\n\t\tconst char *update_ref,\n\t\tconst git_signature *author,\n\t\tconst git_signature *committer,\n\t\tconst char *message_encoding,\n\t\tconst char *message,\n\t\tconst git_tree *tree,\n\t\tint parent_count,\n\t\tconst git_commit *parents[]","sig":"git_oid *::git_repository *::const char *::const git_signature *::const git_signature *::const char *::const char *::const git_tree *::int","return":{"type":"int","comment":"0 or an error code The created commit will be written to the Object Database and the given reference will be updated to point to it"},"description":"Create a new commit in the repository using `git_object`\ninstances as parameters.","comments":"The message will not be cleaned up. This can be achieved\nthrough `git_message_prettify()`.\n","group":"commit"},"git_commit_create_v":{"type":"function","file":"commit.h","line":275,"lineto":285,"args":[{"name":"oid","type":"git_oid *"},{"name":"repo","type":"git_repository *"},{"name":"update_ref","type":"const char *"},{"name":"author","type":"const git_signature *"},{"name":"committer","type":"const git_signature *"},{"name":"message_encoding","type":"const char *"},{"name":"message","type":"const char *"},{"name":"tree","type":"const git_tree *"},{"name":"parent_count","type":"int"}],"argline":"git_oid *oid,\n\t\tgit_repository *repo,\n\t\tconst char *update_ref,\n\t\tconst git_signature *author,\n\t\tconst git_signature *committer,\n\t\tconst char *message_encoding,\n\t\tconst char *message,\n\t\tconst git_tree *tree,\n\t\tint parent_count,\n\t\t...","sig":"git_oid *::git_repository *::const char *::const git_signature *::const git_signature *::const char *::const char *::const git_tree *::int","return":{"type":"int"},"description":"Create a new commit in the repository using a variable\nargument list.","comments":"The message will be cleaned up from excess whitespace\nit will be made sure that the last line ends with a '\\n'.\n\nThe parents for the commit are specified as a variable\nlist of pointers to `const git_commit *`. Note that this\nis a convenience method which may not be safe to export\nfor certain languages or compilers\n\nAll other parameters remain the same\n\n@see git_commit_create","group":"commit","examples":{"general.c":["ex/HEAD/general.html#git_commit_create_v-40"]}},"git_remote_new":{"type":"function","file":"remote.h","line":46,"lineto":46,"args":[{"name":"out","type":"git_remote **","comment":"pointer to the new remote object"},{"name":"repo","type":"git_repository *","comment":"the associated repository"},{"name":"name","type":"const char *","comment":"the remote's name"},{"name":"url","type":"const char *","comment":"the remote repository's URL"},{"name":"fetch","type":"const char *","comment":"the fetch refspec to use for this remote"}],"argline":"git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch","sig":"git_remote **::git_repository *::const char *::const char *::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Create a remote in memory","comments":"Create a remote with the default refspecs in memory. You can use\nthis when you have a URL instead of a remote's name.\n","group":"remote","examples":{"network/ls-remote.c":["ex/HEAD/ls-remote.html#git_remote_new-1"],"network/fetch.c":["ex/HEAD/fetch.html#git_remote_new-1"]}},"git_remote_load":{"type":"function","file":"remote.h","line":56,"lineto":56,"args":[{"name":"out","type":"git_remote **","comment":"pointer to the new remote object"},{"name":"repo","type":"git_repository *"},{"name":"name","type":"const char *","comment":"the remote's name"}],"argline":"git_remote **out, git_repository *repo, const char *name","sig":"git_remote **::git_repository *::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Get the information for a particular remote","comments":"","group":"remote","examples":{"network/ls-remote.c":["ex/HEAD/ls-remote.html#git_remote_load-2"],"network/fetch.c":["ex/HEAD/fetch.html#git_remote_load-2"]}},"git_remote_save":{"type":"function","file":"remote.h","line":64,"lineto":64,"args":[{"name":"remote","type":"const git_remote *","comment":"the remote to save to config"}],"argline":"const git_remote *remote","sig":"const git_remote *","return":{"type":"int","comment":"0 or an error code"},"description":"Save a remote to its repository's configuration","comments":"","group":"remote"},"git_remote_name":{"type":"function","file":"remote.h","line":72,"lineto":72,"args":[{"name":"remote","type":"git_remote *","comment":"the remote"}],"argline":"git_remote *remote","sig":"git_remote *","return":{"type":"const char *","comment":"a pointer to the name"},"description":"Get the remote's name","comments":"","group":"remote"},"git_remote_url":{"type":"function","file":"remote.h","line":80,"lineto":80,"args":[{"name":"remote","type":"git_remote *","comment":"the remote"}],"argline":"git_remote *remote","sig":"git_remote *","return":{"type":"const char *","comment":"a pointer to the url"},"description":"Get the remote's url","comments":"","group":"remote"},"git_remote_pushurl":{"type":"function","file":"remote.h","line":88,"lineto":88,"args":[{"name":"remote","type":"git_remote *","comment":"the remote"}],"argline":"git_remote *remote","sig":"git_remote *","return":{"type":"const char *","comment":"a pointer to the url or NULL if no special url for pushing is set"},"description":"Get the remote's url for pushing","comments":"","group":"remote"},"git_remote_set_url":{"type":"function","file":"remote.h","line":99,"lineto":99,"args":[{"name":"remote","type":"git_remote *","comment":"the remote"},{"name":"url","type":"const char*","comment":"the url to set"}],"argline":"git_remote *remote, const char* url","sig":"git_remote *::const char*","return":{"type":"int","comment":"0 or an error value"},"description":"Set the remote's url","comments":"Existing connections will not be updated.\n","group":"remote"},"git_remote_set_pushurl":{"type":"function","file":"remote.h","line":110,"lineto":110,"args":[{"name":"remote","type":"git_remote *","comment":"the remote"},{"name":"url","type":"const char*","comment":"the url to set or NULL to clear the pushurl"}],"argline":"git_remote *remote, const char* url","sig":"git_remote *::const char*","return":{"type":"int","comment":"0 or an error value"},"description":"Set the remote's url for pushing","comments":"Existing connections will not be updated.\n","group":"remote"},"git_remote_set_fetchspec":{"type":"function","file":"remote.h","line":119,"lineto":119,"args":[{"name":"remote","type":"git_remote *","comment":"the remote @apram spec the new fetch refspec"},{"name":"spec","type":"const char *"}],"argline":"git_remote *remote, const char *spec","sig":"git_remote *::const char *","return":{"type":"int","comment":"0 or an error value"},"description":"Set the remote's fetch refspec","comments":"","group":"remote"},"git_remote_fetchspec":{"type":"function","file":"remote.h","line":127,"lineto":127,"args":[{"name":"remote","type":"git_remote *","comment":"the remote"}],"argline":"git_remote *remote","sig":"git_remote *","return":{"type":"const git_refspec *","comment":"a pointer to the fetch refspec or NULL if it doesn't exist"},"description":"Get the fetch refspec","comments":"","group":"remote"},"git_remote_set_pushspec":{"type":"function","file":"remote.h","line":136,"lineto":136,"args":[{"name":"remote","type":"git_remote *","comment":"the remote"},{"name":"spec","type":"const char *","comment":"the new push refspec"}],"argline":"git_remote *remote, const char *spec","sig":"git_remote *::const char *","return":{"type":"int","comment":"0 or an error value"},"description":"Set the remote's push refspec","comments":"","group":"remote"},"git_remote_pushspec":{"type":"function","file":"remote.h","line":144,"lineto":144,"args":[{"name":"remote","type":"git_remote *","comment":"the remote"}],"argline":"git_remote *remote","sig":"git_remote *","return":{"type":"const git_refspec *","comment":"a pointer to the push refspec or NULL if it doesn't exist"},"description":"Get the push refspec","comments":"","group":"remote"},"git_remote_connect":{"type":"function","file":"remote.h","line":158,"lineto":158,"args":[{"name":"remote","type":"git_remote *","comment":"the remote to connect to"},{"name":"direction","type":"int","comment":"whether you want to receive or send data"}],"argline":"git_remote *remote, int direction","sig":"git_remote *::int","return":{"type":"int","comment":"0 or an error code"},"description":"Open a connection to a remote","comments":"The transport is selected based on the URL. The direction argument\nis due to a limitation of the git protocol (over TCP or SSH) which\nstarts up a specific binary which can only do the one or the other.\n","group":"remote","examples":{"network/ls-remote.c":["ex/HEAD/ls-remote.html#git_remote_connect-3","ex/HEAD/ls-remote.html#git_remote_connect-4"],"network/fetch.c":["ex/HEAD/fetch.html#git_remote_connect-3"]}},"git_remote_ls":{"type":"function","file":"remote.h","line":173,"lineto":173,"args":[{"name":"remote","type":"git_remote *","comment":"the remote"},{"name":"list_cb","type":"git_headlist_cb"},{"name":"payload","type":"void *"}],"argline":"git_remote *remote, git_headlist_cb list_cb, void *payload","sig":"git_remote *::git_headlist_cb::void *","return":{"type":"int","comment":"0 on success, GIT_EUSER on non-zero callback, or error code"},"description":"Get a list of refs at the remote","comments":"The remote (or more exactly its transport) must be connected. The\nmemory belongs to the remote.\n\nIf you a return a non-zero value from the callback, this will stop\nlooping over the refs.\n","group":"remote","examples":{"network/ls-remote.c":["ex/HEAD/ls-remote.html#git_remote_ls-5","ex/HEAD/ls-remote.html#git_remote_ls-6","ex/HEAD/ls-remote.html#git_remote_ls-7"]}},"git_remote_download":{"type":"function","file":"remote.h","line":188,"lineto":188,"args":[{"name":"remote","type":"git_remote *","comment":"the remote to download from"},{"name":"bytes","type":"git_off_t *"},{"name":"stats","type":"git_indexer_stats *"}],"argline":"git_remote *remote, git_off_t *bytes, git_indexer_stats *stats","sig":"git_remote *::git_off_t *::git_indexer_stats *","return":{"type":"int","comment":"0 or an error code"},"description":"Download the packfile","comments":"Negotiate what objects should be downloaded and download the\npackfile with those objects. The packfile is downloaded with a\ntemporary filename, as it's final name is not known yet. If there\nwas no packfile needed (all the objects were available locally),\nfilename will be NULL and the function will return success.\n","group":"remote","examples":{"network/fetch.c":["ex/HEAD/fetch.html#git_remote_download-4"]}},"git_remote_connected":{"type":"function","file":"remote.h","line":198,"lineto":198,"args":[{"name":"remote","type":"git_remote *"}],"argline":"git_remote *remote","sig":"git_remote *","return":{"type":"int","comment":"1 if it's connected, 0 otherwise."},"description":"Check whether the remote is connected","comments":"Check whether the remote's underlying transport is connected to the\nremote host.\n","group":"remote"},"git_remote_disconnect":{"type":"function","file":"remote.h","line":208,"lineto":208,"args":[{"name":"remote","type":"git_remote *","comment":"the remote to disconnect from"}],"argline":"git_remote *remote","sig":"git_remote *","return":{"type":"void"},"description":"Disconnect from the remote","comments":"Close the connection to the remote and free the underlying\ntransport.\n","group":"remote","examples":{"network/fetch.c":["ex/HEAD/fetch.html#git_remote_disconnect-5"]}},"git_remote_free":{"type":"function","file":"remote.h","line":218,"lineto":218,"args":[{"name":"remote","type":"git_remote *","comment":"the remote to free"}],"argline":"git_remote *remote","sig":"git_remote *","return":{"type":"void"},"description":"Free the memory associated with a remote","comments":"This also disconnects from the remote, if the connection\nhas not been closed yet (using git_remote_disconnect).\n","group":"remote","examples":{"network/ls-remote.c":["ex/HEAD/ls-remote.html#git_remote_free-8","ex/HEAD/ls-remote.html#git_remote_free-9"],"network/fetch.c":["ex/HEAD/fetch.html#git_remote_free-6","ex/HEAD/fetch.html#git_remote_free-7"]}},"git_remote_update_tips":{"type":"function","file":"remote.h","line":226,"lineto":226,"args":[{"name":"remote","type":"git_remote *","comment":"the remote to update"}],"argline":"git_remote *remote","sig":"git_remote *","return":{"type":"int"},"description":"Update the tips to the new state","comments":"","group":"remote","examples":{"network/fetch.c":["ex/HEAD/fetch.html#git_remote_update_tips-8"]}},"git_remote_valid_url":{"type":"function","file":"remote.h","line":234,"lineto":234,"args":[{"name":"url","type":"const char *","comment":"the url to check"}],"argline":"const char *url","sig":"const char *","return":{"type":"int"},"description":"Return whether a string is a valid remote URL","comments":"","group":"remote"},"git_remote_supported_url":{"type":"function","file":"remote.h","line":242,"lineto":242,"args":[{"name":"url","type":"const char*","comment":"the url to check"}],"argline":"const char* url","sig":"const char*","return":{"type":"int","comment":"1 if the url is supported, 0 otherwise"},"description":"Return whether the passed URL is supported by this version of the library.","comments":"","group":"remote"},"git_remote_list":{"type":"function","file":"remote.h","line":253,"lineto":253,"args":[{"name":"remotes_list","type":"git_strarray *","comment":"a string array with the names of the remotes"},{"name":"repo","type":"git_repository *","comment":"the repository to query"}],"argline":"git_strarray *remotes_list, git_repository *repo","sig":"git_strarray *::git_repository *","return":{"type":"int","comment":"0 or an error code"},"description":"Get a list of the configured remotes for a repo","comments":"The string array must be freed by the user.\n","group":"remote"},"git_remote_add":{"type":"function","file":"remote.h","line":263,"lineto":263,"args":[{"name":"out","type":"git_remote **","comment":"the resulting remote"},{"name":"repo","type":"git_repository *","comment":"the repository in which to create the remote"},{"name":"name","type":"const char *","comment":"the remote's name"},{"name":"url","type":"const char *","comment":"the remote's url"}],"argline":"git_remote **out, git_repository *repo, const char *name, const char *url","sig":"git_remote **::git_repository *::const char *::const char *","return":{"type":"int"},"description":"Add a remote with the default fetch refspec to the repository's configuration","comments":"","group":"remote"},"git_remote_check_cert":{"type":"function","file":"remote.h","line":271,"lineto":271,"args":[{"name":"remote","type":"git_remote *","comment":"the remote to configure"},{"name":"check","type":"int","comment":"whether to check the server's certificate (defaults to yes)"}],"argline":"git_remote *remote, int check","sig":"git_remote *::int","return":{"type":"void"},"description":"Choose whether to check the server's certificate (applies to HTTPS only)","comments":"","group":"remote"},"git_remote_set_callbacks":{"type":"function","file":"remote.h","line":305,"lineto":305,"args":[{"name":"remote","type":"git_remote *","comment":"the remote to configure"},{"name":"callbacks","type":"git_remote_callbacks *","comment":"a pointer to the user's callback settings"}],"argline":"git_remote *remote, git_remote_callbacks *callbacks","sig":"git_remote *::git_remote_callbacks *","return":{"type":"void"},"description":"Set the callbacks for a remote","comments":"Note that the remote keeps its own copy of the data and you need to\ncall this function again if you want to change the callbacks.\n","group":"remote","examples":{"network/fetch.c":["ex/HEAD/fetch.html#git_remote_set_callbacks-9"]}},"git_merge_base":{"type":"function","file":"merge.h","line":31,"lineto":31,"args":[{"name":"out","type":"git_oid *","comment":"the OID of a merge base between 'one' and 'two'"},{"name":"repo","type":"git_repository *","comment":"the repository where the commits exist"},{"name":"one","type":"const git_oid *","comment":"one of the commits"},{"name":"two","type":"const git_oid *","comment":"the other commit"}],"argline":"git_oid *out, git_repository *repo, const git_oid *one, const git_oid *two","sig":"git_oid *::git_repository *::const git_oid *::const git_oid *","return":{"type":"int"},"description":"Find a merge base between two commits","comments":"","group":"merge"},"git_merge_base_many":{"type":"function","file":"merge.h","line":41,"lineto":41,"args":[{"name":"out","type":"git_oid *","comment":"the OID of a merge base considering all the commits"},{"name":"repo","type":"git_repository *","comment":"the repository where the commits exist"},{"name":"length","type":"size_t","comment":"The number of commits in the provided `input_array`"}],"argline":"git_oid *out, git_repository *repo, const git_oid input_array[], size_t length","sig":"git_oid *::git_repository *::size_t","return":{"type":"int"},"description":"Find a merge base given a list of commits","comments":"","group":"merge"},"git_diff_list_free":{"type":"function","file":"diff.h","line":237,"lineto":237,"args":[{"name":"diff","type":"git_diff_list *"}],"argline":"git_diff_list *diff","sig":"git_diff_list *","return":{"type":"void"},"description":"Deallocate a diff list.","comments":"","group":"diff","examples":{"diff.c":["ex/HEAD/diff.html#git_diff_list_free-4","ex/HEAD/diff.html#git_diff_list_free-5"]}},"git_diff_tree_to_tree":{"type":"function","file":"diff.h","line":250,"lineto":255,"args":[{"name":"repo","type":"git_repository *","comment":"The repository containing the trees."},{"name":"opts","type":"const git_diff_options *","comment":"Structure with options to influence diff or NULL for defaults.\ncan be NULL for defaults"},{"name":"old_tree","type":"git_tree *","comment":"A git_tree object to diff from."},{"name":"new_tree","type":"git_tree *","comment":"A git_tree object to diff to."},{"name":"diff","type":"git_diff_list **","comment":"A pointer to a git_diff_list pointer that will be allocated."}],"argline":"git_repository *repo,\n\tconst git_diff_options *opts, \n\tgit_tree *old_tree,\n\tgit_tree *new_tree,\n\tgit_diff_list **diff","sig":"git_repository *::const git_diff_options *::git_tree *::git_tree *::git_diff_list **","return":{"type":"int"},"description":"Compute a difference between two tree objects.","comments":"This is equivalent to `git diff `\n","group":"diff","examples":{"diff.c":["ex/HEAD/diff.html#git_diff_tree_to_tree-6"]}},"git_diff_index_to_tree":{"type":"function","file":"diff.h","line":268,"lineto":272,"args":[{"name":"repo","type":"git_repository *","comment":"The repository containing the tree and index."},{"name":"opts","type":"const git_diff_options *","comment":"Structure with options to influence diff or NULL for defaults.\ncan be NULL for defaults"},{"name":"old_tree","type":"git_tree *","comment":"A git_tree object to diff from."},{"name":"diff","type":"git_diff_list **","comment":"A pointer to a git_diff_list pointer that will be allocated."}],"argline":"git_repository *repo,\n\tconst git_diff_options *opts, \n\tgit_tree *old_tree,\n\tgit_diff_list **diff","sig":"git_repository *::const git_diff_options *::git_tree *::git_diff_list **","return":{"type":"int"},"description":"Compute a difference between a tree and the index.","comments":"This is equivalent to `git diff --cached ` or if you pass\nthe HEAD tree, then like `git diff --cached`.\n","group":"diff","examples":{"diff.c":["ex/HEAD/diff.html#git_diff_index_to_tree-7","ex/HEAD/diff.html#git_diff_index_to_tree-8","ex/HEAD/diff.html#git_diff_index_to_tree-9"]}},"git_diff_workdir_to_index":{"type":"function","file":"diff.h","line":286,"lineto":289,"args":[{"name":"repo","type":"git_repository *","comment":"The repository."},{"name":"opts","type":"const git_diff_options *","comment":"Structure with options to influence diff or NULL for defaults.\ncan be NULL for defaults"},{"name":"diff","type":"git_diff_list **","comment":"A pointer to a git_diff_list pointer that will be allocated."}],"argline":"git_repository *repo,\n\tconst git_diff_options *opts, \n\tgit_diff_list **diff","sig":"git_repository *::const git_diff_options *::git_diff_list **","return":{"type":"int"},"description":"Compute a difference between the working directory and the index.","comments":"This matches the `git diff` command. See the note below on\n`git_diff_workdir_to_tree` for a discussion of the difference between\n`git diff` and `git diff HEAD` and how to emulate a `git diff `\nusing libgit2.\n","group":"diff","examples":{"diff.c":["ex/HEAD/diff.html#git_diff_workdir_to_index-10","ex/HEAD/diff.html#git_diff_workdir_to_index-11"]}},"git_diff_workdir_to_tree":{"type":"function","file":"diff.h","line":318,"lineto":322,"args":[{"name":"repo","type":"git_repository *","comment":"The repository containing the tree."},{"name":"opts","type":"const git_diff_options *","comment":"Structure with options to influence diff or NULL for defaults.\ncan be NULL for defaults"},{"name":"old_tree","type":"git_tree *","comment":"A git_tree object to diff from."},{"name":"diff","type":"git_diff_list **","comment":"A pointer to a git_diff_list pointer that will be allocated."}],"argline":"git_repository *repo,\n\tconst git_diff_options *opts, \n\tgit_tree *old_tree,\n\tgit_diff_list **diff","sig":"git_repository *::const git_diff_options *::git_tree *::git_diff_list **","return":{"type":"int"},"description":"Compute a difference between the working directory and a tree.","comments":"This is *NOT* the same as `git diff `. Running `git diff HEAD`\nor the like actually uses information from the index, along with the tree\nand workdir dir info.\n\nThis function returns strictly the differences between the tree and the\nfiles contained in the working directory, regardless of the state of\nfiles in the index. It may come as a surprise, but there is no direct\nequivalent in core git.\n\nTo emulate `git diff `, you should call both\n`git_diff_index_to_tree` and `git_diff_workdir_to_index`, then call\n`git_diff_merge` on the results. That will yield a `git_diff_list` that\nmatches the git output.\n\nIf this seems confusing, take the case of a file with a staged deletion\nwhere the file has then been put back into the working dir and modified.\nThe tree-to-workdir diff for that file is 'modified', but core git would\nshow status 'deleted' since there is a pending deletion in the index.\n","group":"diff"},"git_diff_merge":{"type":"function","file":"diff.h","line":337,"lineto":339,"args":[{"name":"onto","type":"git_diff_list *","comment":"Diff to merge into."},{"name":"from","type":"const git_diff_list *","comment":"Diff to merge."}],"argline":"git_diff_list *onto,\n\tconst git_diff_list *from","sig":"git_diff_list *::const git_diff_list *","return":{"type":"int"},"description":"Merge one diff list into another.","comments":"This merges items from the \"from\" list into the \"onto\" list. The\nresulting diff list will have all items that appear in either list.\nIf an item appears in both lists, then it will be \"merged\" to appear\nas if the old version was from the \"onto\" list and the new version\nis from the \"from\" list (with the exception that if the item has a\npending DELETE in the middle, then it will show as deleted).\n","group":"diff","examples":{"diff.c":["ex/HEAD/diff.html#git_diff_merge-12"]}},"git_diff_foreach":{"type":"function","file":"diff.h","line":376,"lineto":381,"args":[{"name":"diff","type":"git_diff_list *","comment":"A git_diff_list generated by one of the above functions."},{"name":"cb_data","type":"void *","comment":"Reference pointer that will be passed to your callbacks."},{"name":"file_cb","type":"git_diff_file_fn","comment":"Callback function to make per file in the diff."},{"name":"hunk_cb","type":"git_diff_hunk_fn","comment":"Optional callback to make per hunk of text diff. This callback is called to describe a range of lines in the diff. It will not be issued for binary files."},{"name":"line_cb","type":"git_diff_data_fn","comment":"Optional callback to make per line of diff text. This same callback will be made for context lines, added, and removed lines, and even for a deleted trailing newline."}],"argline":"git_diff_list *diff,\n\tvoid *cb_data,\n\tgit_diff_file_fn file_cb,\n\tgit_diff_hunk_fn hunk_cb,\n\tgit_diff_data_fn line_cb","sig":"git_diff_list *::void *::git_diff_file_fn::git_diff_hunk_fn::git_diff_data_fn","return":{"type":"int","comment":"0 on success, GIT_EUSER on non-zero callback, or error code"},"description":"Iterate over a diff list issuing callbacks.","comments":"This will iterate through all of the files described in a diff. You\nshould provide a file callback to learn about each file.\n\nThe \"hunk\" and \"line\" callbacks are optional, and the text diff of the\nfiles will only be calculated if they are not NULL. Of course, these\ncallbacks will not be invoked for binary files on the diff list or for\nfiles whose only changed is a file mode change.\n\nReturning a non-zero value from any of the callbacks will terminate\nthe iteration and cause this return `GIT_EUSER`.\n","group":"diff"},"git_diff_iterator_new":{"type":"function","file":"diff.h","line":395,"lineto":397,"args":[{"name":"iterator","type":"git_diff_iterator **","comment":"Output parameter of newly created iterator."},{"name":"diff","type":"git_diff_list *","comment":"Diff over which you wish to iterate."}],"argline":"git_diff_iterator **iterator,\n\tgit_diff_list *diff","sig":"git_diff_iterator **::git_diff_list *","return":{"type":"int","comment":"0 on success, < 0 on error"},"description":"Create a diff iterator object that can be used to traverse a diff.","comments":"This iterator can be used instead of `git_diff_foreach` in situations\nwhere callback functions are awkward to use. Because of the way that\ndiffs are calculated internally, using an iterator will use somewhat\nmore memory than `git_diff_foreach` would.\n","group":"diff"},"git_diff_iterator_free":{"type":"function","file":"diff.h","line":406,"lineto":406,"args":[{"name":"iterator","type":"git_diff_iterator *","comment":"The diff iterator to be freed."}],"argline":"git_diff_iterator *iterator","sig":"git_diff_iterator *","return":{"type":"void"},"description":"Release the iterator object.","comments":"Call this when you are done using the iterator.\n","group":"diff"},"git_diff_iterator_progress":{"type":"function","file":"diff.h","line":418,"lineto":418,"args":[{"name":"iterator","type":"git_diff_iterator *","comment":"The diff iterator"}],"argline":"git_diff_iterator *iterator","sig":"git_diff_iterator *","return":{"type":"float","comment":"Value between 0.0 and 1.0"},"description":"Return progress value for traversing the diff.","comments":"This returns a value between 0.0 and 1.0 that represents the progress\nthrough the diff iterator. The value is monotonically increasing and\nwill advance gradually as you progress through the iteration.\n","group":"diff"},"git_diff_iterator_num_hunks_in_file":{"type":"function","file":"diff.h","line":430,"lineto":430,"args":[{"name":"iterator","type":"git_diff_iterator *","comment":"The iterator object"}],"argline":"git_diff_iterator *iterator","sig":"git_diff_iterator *","return":{"type":"int","comment":"The number of hunks in the current file or <0 on loading failure"},"description":"Return the number of hunks in the current file","comments":"This will return the number of diff hunks in the current file. If the\ndiff has not been performed yet, this may result in loading the file and\nperforming the diff.\n","group":"diff"},"git_diff_iterator_num_lines_in_hunk":{"type":"function","file":"diff.h","line":443,"lineto":443,"args":[{"name":"iterator","type":"git_diff_iterator *","comment":"The iterator object"}],"argline":"git_diff_iterator *iterator","sig":"git_diff_iterator *","return":{"type":"int","comment":"The number of lines in the current hunk (context, added, and removed all added together) or <0 on loading failure"},"description":"Return the number of lines in the hunk currently being examined.","comments":"This will return the number of lines in the current hunk. If the diff\nhas not been performed yet, this may result in loading the file and\nperforming the diff.\n","group":"diff"},"git_diff_iterator_next_file":{"type":"function","file":"diff.h","line":456,"lineto":458,"args":[{"name":"delta","type":"git_diff_delta **","comment":"Output parameter for the next delta object"},{"name":"iterator","type":"git_diff_iterator *","comment":"The iterator object"}],"argline":"git_diff_delta **delta,\n\tgit_diff_iterator *iterator","sig":"git_diff_delta **::git_diff_iterator *","return":{"type":"int","comment":"0 on success, GIT_ITEROVER when done, other value < 0 on error"},"description":"Return the delta information for the next file in the diff.","comments":"This will return a pointer to the next git_diff_delta` to be processed or\nNULL if the iterator is at the end of the diff, then advance. This\nreturns the value `GIT_ITEROVER` after processing the last file.\n","group":"diff"},"git_diff_iterator_next_hunk":{"type":"function","file":"diff.h","line":483,"lineto":487,"args":[{"name":"range","type":"git_diff_range **","comment":"Output pointer to range of lines covered by the hunk; This range object is owned by the library and should not be freed."},{"name":"header","type":"const char **","comment":"Output pointer to the text of the hunk header This string is owned by the library and should not be freed."},{"name":"header_len","type":"size_t *","comment":"Output pointer to store the length of the header text"},{"name":"iterator","type":"git_diff_iterator *","comment":"The iterator object"}],"argline":"git_diff_range **range,\n\tconst char **header,\n\tsize_t *header_len,\n\tgit_diff_iterator *iterator","sig":"git_diff_range **::const char **::size_t *::git_diff_iterator *","return":{"type":"int","comment":"0 on success, GIT_ITEROVER when done with current file, other value < 0 on error"},"description":"Return the hunk information for the next hunk in the current file.","comments":"It is recommended that you not call this if the file is a binary\nfile, but it is allowed to do so.\n\nThe `header` text output will contain the standard hunk header that\nwould appear in diff output. The header string will be NUL terminated.\n\nWARNING! Call this function for the first time on a file is when the\nactual text diff will be computed (it cannot be computed incrementally)\nso the first call for a new file is expensive (at least in relative\nterms - in reality, it is still pretty darn fast).\n","group":"diff"},"git_diff_iterator_next_line":{"type":"function","file":"diff.h","line":508,"lineto":512,"args":[{"name":"line_origin","type":"char *","comment":"Output pointer to store a GIT_DIFF_LINE value for this next chunk of data. The value is a single character, not a buffer.\nGIT_DIFF_LINE_... value from above"},{"name":"content","type":"const char **","comment":"Output pointer to store the content of the diff; this string is owned by the library and should not be freed."},{"name":"content_len","type":"size_t *","comment":"Output pointer to store the length of the content."},{"name":"iterator","type":"git_diff_iterator *","comment":"The iterator object"}],"argline":"char *line_origin, \n\tconst char **content,\n\tsize_t *content_len,\n\tgit_diff_iterator *iterator","sig":"char *::const char **::size_t *::git_diff_iterator *","return":{"type":"int","comment":"0 on success, GIT_ITEROVER when done with current line, other value < 0 on error"},"description":"Return the next line of the current hunk of diffs.","comments":"The `line_origin` output will tell you what type of line this is\n(e.g. was it added or removed or is it just context for the diff).\n\nThe `content` will be a pointer to the file data that goes in the\nline. IT WILL NOT BE NUL TERMINATED. You have to use the `content_len`\nvalue and only process that many bytes of data from the content string.\n","group":"diff"},"git_diff_print_compact":{"type":"function","file":"diff.h","line":525,"lineto":528,"args":[{"name":"diff","type":"git_diff_list *","comment":"A git_diff_list generated by one of the above functions."},{"name":"cb_data","type":"void *","comment":"Reference pointer that will be passed to your callback."},{"name":"print_cb","type":"git_diff_data_fn","comment":"Callback to make per line of diff text."}],"argline":"git_diff_list *diff,\n\tvoid *cb_data,\n\tgit_diff_data_fn print_cb","sig":"git_diff_list *::void *::git_diff_data_fn","return":{"type":"int","comment":"0 on success, GIT_EUSER on non-zero callback, or error code"},"description":"Iterate over a diff generating text output like \"git diff --name-status\".","comments":"Returning a non-zero value from the callbacks will terminate the\niteration and cause this return `GIT_EUSER`.\n","group":"diff","examples":{"diff.c":["ex/HEAD/diff.html#git_diff_print_compact-13"]}},"git_diff_print_patch":{"type":"function","file":"diff.h","line":547,"lineto":550,"args":[{"name":"diff","type":"git_diff_list *","comment":"A git_diff_list generated by one of the above functions."},{"name":"cb_data","type":"void *","comment":"Reference pointer that will be passed to your callbacks."},{"name":"print_cb","type":"git_diff_data_fn","comment":"Callback function to output lines of the diff. This same function will be called for file headers, hunk headers, and diff lines. Fortunately, you can probably use various GIT_DIFF_LINE constants to determine what text you are given."}],"argline":"git_diff_list *diff,\n\tvoid *cb_data,\n\tgit_diff_data_fn print_cb","sig":"git_diff_list *::void *::git_diff_data_fn","return":{"type":"int","comment":"0 on success, GIT_EUSER on non-zero callback, or error code"},"description":"Iterate over a diff generating text output like \"git diff\".","comments":"This is a super easy way to generate a patch from a diff.\n\nReturning a non-zero value from the callbacks will terminate the\niteration and cause this return `GIT_EUSER`.\n","group":"diff","examples":{"diff.c":["ex/HEAD/diff.html#git_diff_print_patch-14"]}},"git_diff_entrycount":{"type":"function","file":"diff.h","line":563,"lineto":565,"args":[{"name":"diff","type":"git_diff_list *","comment":"A git_diff_list generated by one of the above functions"},{"name":"delta_t","type":"int","comment":"A git_delta_t value to filter the count, or -1 for all records"}],"argline":"git_diff_list *diff,\n\tint delta_t","sig":"git_diff_list *::int","return":{"type":"int","comment":"Count of number of deltas matching delta_t type"},"description":"Query how many diff records are there in a diff list.","comments":"You can optionally pass in a `git_delta_t` value if you want a count\nof just entries that match that delta type, or pass -1 for all delta\nrecords.\n","group":"diff"},"git_diff_blobs":{"type":"function","file":"diff.h","line":588,"lineto":597,"args":[{"name":"old_blob","type":"git_blob *"},{"name":"new_blob","type":"git_blob *"},{"name":"options","type":"git_diff_options *"},{"name":"cb_data","type":"void *"},{"name":"file_cb","type":"git_diff_file_fn"},{"name":"hunk_cb","type":"git_diff_hunk_fn"},{"name":"line_cb","type":"git_diff_data_fn"}],"argline":"git_blob *old_blob,\n\tgit_blob *new_blob,\n\tgit_diff_options *options,\n\tvoid *cb_data,\n\tgit_diff_file_fn file_cb,\n\tgit_diff_hunk_fn hunk_cb,\n\tgit_diff_data_fn line_cb","sig":"git_blob *::git_blob *::git_diff_options *::void *::git_diff_file_fn::git_diff_hunk_fn::git_diff_data_fn","return":{"type":"int","comment":"0 on success, GIT_EUSER on non-zero callback, or error code"},"description":"Directly run a text diff on two blobs.","comments":"Compared to a file, a blob lacks some contextual information. As such,\nthe `git_diff_file` parameters of the callbacks will be filled\naccordingly to the following: `mode` will be set to 0, `path` will be set\nto NULL. When dealing with a NULL blob, `oid` will be set to 0.\n\nWhen at least one of the blobs being dealt with is binary, the\n`git_diff_delta` binary attribute will be set to 1 and no call to the\nhunk_cb nor line_cb will be made.\n","group":"diff"},"git_checkout_head":{"type":"function","file":"checkout.h","line":55,"lineto":58,"args":[{"name":"repo","type":"git_repository *","comment":"repository to check out (must be non-bare)"},{"name":"opts","type":"git_checkout_opts *","comment":"specifies checkout options (may be NULL)"},{"name":"stats","type":"git_indexer_stats *","comment":"structure through which progress information is reported"}],"argline":"git_repository *repo,\n\tgit_checkout_opts *opts,\n\tgit_indexer_stats *stats","sig":"git_repository *::git_checkout_opts *::git_indexer_stats *","return":{"type":"int","comment":"0 on success, GIT_ERROR otherwise (use giterr_last for information about the error)"},"description":"Updates files in the index and the working tree to match the content of the\ncommit pointed at by HEAD.","comments":"","group":"checkout"},"git_checkout_index":{"type":"function","file":"checkout.h","line":69,"lineto":72,"args":[{"name":"repo","type":"git_repository *","comment":"repository to check out (must be non-bare)"},{"name":"opts","type":"git_checkout_opts *","comment":"specifies checkout options (may be NULL)"},{"name":"stats","type":"git_indexer_stats *","comment":"structure through which progress information is reported"}],"argline":"git_repository *repo,\n\tgit_checkout_opts *opts,\n\tgit_indexer_stats *stats","sig":"git_repository *::git_checkout_opts *::git_indexer_stats *","return":{"type":"int","comment":"0 on success, GIT_ERROR otherwise (use giterr_last for information about the error)"},"description":"Updates files in the working tree to match the content of the index.","comments":"","group":"checkout"},"git_checkout_tree":{"type":"function","file":"checkout.h","line":86,"lineto":90,"args":[{"name":"repo","type":"git_repository *","comment":"repository to check out (must be non-bare)"},{"name":"treeish","type":"git_object *","comment":"a commit, tag or tree which content will be used to update the working directory"},{"name":"opts","type":"git_checkout_opts *","comment":"specifies checkout options (may be NULL)"},{"name":"stats","type":"git_indexer_stats *","comment":"structure through which progress information is reported"}],"argline":"git_repository *repo,\n\tgit_object *treeish,\n\tgit_checkout_opts *opts,\n\tgit_indexer_stats *stats","sig":"git_repository *::git_object *::git_checkout_opts *::git_indexer_stats *","return":{"type":"int","comment":"0 on success, GIT_ERROR otherwise (use giterr_last for information about the error)"},"description":"Updates files in the index and working tree to match the content of the\ntree pointed at by the treeish.","comments":"","group":"checkout"},"git_tree_lookup":{"type":"function","file":"tree.h","line":32,"lineto":35,"args":[{"name":"tree","type":"git_tree **","comment":"pointer to the looked up tree"},{"name":"repo","type":"git_repository *","comment":"the repo to use when locating the tree."},{"name":"id","type":"const git_oid *","comment":"identity of the tree to locate."}],"argline":"git_tree **tree, git_repository *repo, const git_oid *id","sig":"git_tree **::git_repository *::const git_oid *","return":{"type":"int","comment":"0 or an error code"},"description":"Lookup a tree object from the repository.","comments":"","group":"tree","examples":{"general.c":["ex/HEAD/general.html#git_tree_lookup-41","ex/HEAD/general.html#git_tree_lookup-42"]}},"git_tree_lookup_prefix":{"type":"function","file":"tree.h","line":49,"lineto":56,"args":[{"name":"tree","type":"git_tree **","comment":"pointer to the looked up tree"},{"name":"repo","type":"git_repository *","comment":"the repo to use when locating the tree."},{"name":"id","type":"const git_oid *","comment":"identity of the tree to locate."},{"name":"len","type":"size_t","comment":"the length of the short identifier"}],"argline":"git_tree **tree,\n\tgit_repository *repo,\n\tconst git_oid *id,\n\tsize_t len","sig":"git_tree **::git_repository *::const git_oid *::size_t","return":{"type":"int","comment":"0 or an error code"},"description":"Lookup a tree object from the repository,\ngiven a prefix of its identifier (short id).","comments":"@see git_object_lookup_prefix\n","group":"tree"},"git_tree_free":{"type":"function","file":"tree.h","line":69,"lineto":72,"args":[{"name":"tree","type":"git_tree *","comment":"the tree to close"}],"argline":"git_tree *tree","sig":"git_tree *","return":{"type":"void"},"description":"Close an open tree","comments":"This is a wrapper around git_object_free()\n\nIMPORTANT:\nIt *is* necessary to call this method when you stop\nusing a tree. Failure to do so will cause a memory leak.\n","group":"tree","examples":{"diff.c":["ex/HEAD/diff.html#git_tree_free-15","ex/HEAD/diff.html#git_tree_free-16"]}},"git_tree_entry_free":{"type":"function","file":"tree.h","line":83,"lineto":83,"args":[{"name":"entry","type":"git_tree_entry *","comment":"The entry to free"}],"argline":"git_tree_entry *entry","sig":"git_tree_entry *","return":{"type":"void"},"description":"Free a tree entry","comments":"IMPORTANT: This function is only needed for tree\nentries owned by the user, such as the ones returned\nby `git_tree_entry_dup`.\n","group":"tree"},"git_tree_entry_dup":{"type":"function","file":"tree.h","line":95,"lineto":95,"args":[{"name":"entry","type":"const git_tree_entry *","comment":"A tree entry to duplicate"}],"argline":"const git_tree_entry *entry","sig":"const git_tree_entry *","return":{"type":"git_tree_entry *","comment":"a copy of the original entry"},"description":"Duplicate a tree entry","comments":"Create a copy of a tree entry. The returned copy is owned\nby the user, and must be freed manually with\n`git_tree_entry_free`.\n","group":"tree"},"git_tree_id":{"type":"function","file":"tree.h","line":103,"lineto":103,"args":[{"name":"tree","type":"git_tree *","comment":"a previously loaded tree."}],"argline":"git_tree *tree","sig":"git_tree *","return":{"type":"const git_oid *","comment":"object identity for the tree."},"description":"Get the id of a tree.","comments":"","group":"tree"},"git_tree_entrycount":{"type":"function","file":"tree.h","line":111,"lineto":111,"args":[{"name":"tree","type":"git_tree *","comment":"a previously loaded tree."}],"argline":"git_tree *tree","sig":"git_tree *","return":{"type":"unsigned int","comment":"the number of entries in the tree"},"description":"Get the number of entries listed in a tree","comments":"","group":"tree","examples":{"general.c":["ex/HEAD/general.html#git_tree_entrycount-43"]}},"git_tree_entry_byname":{"type":"function","file":"tree.h","line":120,"lineto":120,"args":[{"name":"tree","type":"git_tree *","comment":"a previously loaded tree."},{"name":"filename","type":"const char *","comment":"the filename of the desired entry"}],"argline":"git_tree *tree, const char *filename","sig":"git_tree *::const char *","return":{"type":"const git_tree_entry *","comment":"the tree entry; NULL if not found"},"description":"Lookup a tree entry by its filename","comments":"","group":"tree","examples":{"general.c":["ex/HEAD/general.html#git_tree_entry_byname-44"]}},"git_tree_entry_byindex":{"type":"function","file":"tree.h","line":129,"lineto":129,"args":[{"name":"tree","type":"git_tree *","comment":"a previously loaded tree."},{"name":"idx","type":"size_t","comment":"the position in the entry list"}],"argline":"git_tree *tree, size_t idx","sig":"git_tree *::size_t","return":{"type":"const git_tree_entry *","comment":"the tree entry; NULL if not found"},"description":"Lookup a tree entry by its position in the tree","comments":"","group":"tree","examples":{"general.c":["ex/HEAD/general.html#git_tree_entry_byindex-45"]}},"git_tree_entry_byoid":{"type":"function","file":"tree.h","line":140,"lineto":140,"args":[{"name":"tree","type":"git_tree *","comment":"a previously loaded tree."},{"name":"oid","type":"const git_oid *","comment":"the sha being looked for"}],"argline":"git_tree *tree, const git_oid *oid","sig":"git_tree *::const git_oid *","return":{"type":"const git_tree_entry *","comment":"the tree entry; NULL if not found"},"description":"Lookup a tree entry by SHA value.","comments":"Warning: this must examine every entry in the tree, so it is not fast.\n","group":"tree"},"git_tree_entry_filemode":{"type":"function","file":"tree.h","line":148,"lineto":148,"args":[{"name":"entry","type":"const git_tree_entry *","comment":"a tree entry"}],"argline":"const git_tree_entry *entry","sig":"const git_tree_entry *","return":{"type":"git_filemode_t","comment":"filemode as an integer"},"description":"Get the UNIX file attributes of a tree entry","comments":"","group":"tree"},"git_tree_entry_name":{"type":"function","file":"tree.h","line":156,"lineto":156,"args":[{"name":"entry","type":"const git_tree_entry *","comment":"a tree entry"}],"argline":"const git_tree_entry *entry","sig":"const git_tree_entry *","return":{"type":"const char *","comment":"the name of the file"},"description":"Get the filename of a tree entry","comments":"","group":"tree","examples":{"general.c":["ex/HEAD/general.html#git_tree_entry_name-46","ex/HEAD/general.html#git_tree_entry_name-47"]}},"git_tree_entry_id":{"type":"function","file":"tree.h","line":164,"lineto":164,"args":[{"name":"entry","type":"const git_tree_entry *","comment":"a tree entry"}],"argline":"const git_tree_entry *entry","sig":"const git_tree_entry *","return":{"type":"const git_oid *","comment":"the oid of the object"},"description":"Get the id of the object pointed by the entry","comments":"","group":"tree"},"git_tree_entry_type":{"type":"function","file":"tree.h","line":172,"lineto":172,"args":[{"name":"entry","type":"const git_tree_entry *","comment":"a tree entry"}],"argline":"const git_tree_entry *entry","sig":"const git_tree_entry *","return":{"type":"git_otype","comment":"the type of the pointed object"},"description":"Get the type of the object pointed by the entry","comments":"","group":"tree"},"git_tree_entry_to_object":{"type":"function","file":"tree.h","line":182,"lineto":185,"args":[{"name":"object_out","type":"git_object **"},{"name":"repo","type":"git_repository *","comment":"repository where to lookup the pointed object"},{"name":"entry","type":"const git_tree_entry *","comment":"a tree entry"}],"argline":"git_object **object_out,\n\tgit_repository *repo,\n\tconst git_tree_entry *entry","sig":"git_object **::git_repository *::const git_tree_entry *","return":{"type":"int","comment":"0 or an error code"},"description":"Convert a tree entry to the git_object it points too.","comments":"","group":"tree","examples":{"general.c":["ex/HEAD/general.html#git_tree_entry_to_object-48"]}},"git_tree_create_fromindex":{"type":"function","file":"tree.h","line":203,"lineto":203,"args":[{"name":"oid","type":"git_oid *","comment":"Pointer where to store the written tree"},{"name":"index","type":"git_index *","comment":"Index to write"}],"argline":"git_oid *oid, git_index *index","sig":"git_oid *::git_index *","return":{"type":"int","comment":"0 or an error code"},"description":"Write a tree to the ODB from the index file","comments":"This method will scan the index and write a representation\nof its current state back to disk; it recursively creates\ntree objects for each of the subtrees stored in the index,\nbut only returns the OID of the root tree. This is the OID\nthat can be used e.g. to create a commit.\n\nThe index instance cannot be bare, and needs to be associated\nto an existing repository.\n","group":"tree"},"git_treebuilder_create":{"type":"function","file":"tree.h","line":222,"lineto":222,"args":[{"name":"builder_p","type":"git_treebuilder **","comment":"Pointer where to store the tree builder"},{"name":"source","type":"const git_tree *","comment":"Source tree to initialize the builder (optional)"}],"argline":"git_treebuilder **builder_p, const git_tree *source","sig":"git_treebuilder **::const git_tree *","return":{"type":"int","comment":"0 on success; error code otherwise"},"description":"Create a new tree builder.","comments":"The tree builder can be used to create or modify\ntrees in memory and write them as tree objects to the\ndatabase.\n\nIf the `source` parameter is not NULL, the tree builder\nwill be initialized with the entries of the given tree.\n\nIf the `source` parameter is NULL, the tree builder will\nhave no entries and will have to be filled manually.\n","group":"treebuilder"},"git_treebuilder_clear":{"type":"function","file":"tree.h","line":229,"lineto":229,"args":[{"name":"bld","type":"git_treebuilder *","comment":"Builder to clear"}],"argline":"git_treebuilder *bld","sig":"git_treebuilder *","return":{"type":"void"},"description":"Clear all the entires in the builder","comments":"","group":"treebuilder"},"git_treebuilder_free":{"type":"function","file":"tree.h","line":240,"lineto":240,"args":[{"name":"bld","type":"git_treebuilder *","comment":"Builder to free"}],"argline":"git_treebuilder *bld","sig":"git_treebuilder *","return":{"type":"void"},"description":"Free a tree builder","comments":"This will clear all the entries and free to builder.\nFailing to free the builder after you're done using it\nwill result in a memory leak\n","group":"treebuilder"},"git_treebuilder_get":{"type":"function","file":"tree.h","line":252,"lineto":252,"args":[{"name":"bld","type":"git_treebuilder *","comment":"Tree builder"},{"name":"filename","type":"const char *","comment":"Name of the entry"}],"argline":"git_treebuilder *bld, const char *filename","sig":"git_treebuilder *::const char *","return":{"type":"const git_tree_entry *","comment":"pointer to the entry; NULL if not found"},"description":"Get an entry from the builder from its filename","comments":"The returned entry is owned by the builder and should\nnot be freed manually.\n","group":"treebuilder"},"git_treebuilder_insert":{"type":"function","file":"tree.h","line":279,"lineto":284,"args":[{"name":"entry_out","type":"const git_tree_entry **","comment":"Pointer to store the entry (optional)"},{"name":"bld","type":"git_treebuilder *","comment":"Tree builder"},{"name":"filename","type":"const char *","comment":"Filename of the entry"},{"name":"id","type":"const git_oid *","comment":"SHA1 oid of the entry"},{"name":"filemode","type":"git_filemode_t","comment":"Folder attributes of the entry. This parameter must be valued with one of the following entries: 0040000, 0100644, 0100755, 0120000 or 0160000."}],"argline":"const git_tree_entry **entry_out,\n\tgit_treebuilder *bld,\n\tconst char *filename,\n\tconst git_oid *id,\n\tgit_filemode_t filemode","sig":"const git_tree_entry **::git_treebuilder *::const char *::const git_oid *::git_filemode_t","return":{"type":"int","comment":"0 or an error code"},"description":"Add or update an entry to the builder","comments":"Insert a new entry for `filename` in the builder with the\ngiven attributes.\n\nif an entry named `filename` already exists, its attributes\nwill be updated with the given ones.\n\nThe optional pointer `entry_out` can be used to retrieve a\npointer to the newly created/updated entry.\n\nNo attempt is being made to ensure that the provided oid points\nto an existing git object in the object database, nor that the\nattributes make sense regarding the type of the pointed at object.\n","group":"treebuilder"},"git_treebuilder_remove":{"type":"function","file":"tree.h","line":292,"lineto":292,"args":[{"name":"bld","type":"git_treebuilder *","comment":"Tree builder"},{"name":"filename","type":"const char *","comment":"Filename of the entry to remove"}],"argline":"git_treebuilder *bld, const char *filename","sig":"git_treebuilder *::const char *","return":{"type":"int"},"description":"Remove an entry from the builder by its filename","comments":"","group":"treebuilder"},"git_treebuilder_filter":{"type":"function","file":"tree.h","line":305,"lineto":308,"args":[{"name":"bld","type":"git_treebuilder *","comment":"Tree builder"},{"name":"filter","type":"int (*)(const git_tree_entry *, void *)","comment":"Callback to filter entries"},{"name":"payload","type":"void *"}],"argline":"git_treebuilder *bld,\n\tint (*filter)(const git_tree_entry *, void *),\n\tvoid *payload","sig":"git_treebuilder *::int (*)(const git_tree_entry *, void *)::void *","return":{"type":"void"},"description":"Filter the entries in the tree","comments":"The `filter` callback will be called for each entry\nin the tree with a pointer to the entry and the\nprovided `payload`: if the callback returns 1, the\nentry will be filtered (removed from the builder).\n","group":"treebuilder"},"git_treebuilder_write":{"type":"function","file":"tree.h","line":322,"lineto":322,"args":[{"name":"oid","type":"git_oid *","comment":"Pointer where to store the written OID"},{"name":"repo","type":"git_repository *","comment":"Repository where to store the object"},{"name":"bld","type":"git_treebuilder *","comment":"Tree builder to write"}],"argline":"git_oid *oid, git_repository *repo, git_treebuilder *bld","sig":"git_oid *::git_repository *::git_treebuilder *","return":{"type":"int","comment":"0 or an error code"},"description":"Write the contents of the tree builder as a tree object","comments":"The tree builder will be written to the given `repo`, and\nit's identifying SHA1 hash will be stored in the `oid`\npointer.\n","group":"treebuilder"},"git_tree_entry_bypath":{"type":"function","file":"tree.h","line":336,"lineto":339,"args":[{"name":"entry","type":"git_tree_entry **","comment":"Pointer where to store the tree entry"},{"name":"root","type":"git_tree *","comment":"A previously loaded tree which will be the root of the relative path"},{"name":"path","type":"const char *"}],"argline":"git_tree_entry **entry,\n\tgit_tree *root,\n\tconst char *path","sig":"git_tree_entry **::git_tree *::const char *","return":{"type":"int","comment":"0 on success; GIT_ENOTFOUND if the path does not exist"},"description":"Retrieve a tree entry contained in a tree or in any\nof its subtrees, given its relative path.","comments":"The returned tree entry is owned by the user and must\nbe freed manually with `git_tree_entry_free`.\n","group":"tree"},"git_tree_walk":{"type":"function","file":"tree.h","line":370,"lineto":370,"args":[{"name":"tree","type":"git_tree *","comment":"The tree to walk"},{"name":"callback","type":"git_treewalk_cb","comment":"Function to call on each tree entry"},{"name":"mode","type":"int","comment":"Traversal mode (pre or post-order)"},{"name":"payload","type":"void *","comment":"Opaque pointer to be passed on each callback"}],"argline":"git_tree *tree, git_treewalk_cb callback, int mode, void *payload","sig":"git_tree *::git_treewalk_cb::int::void *","return":{"type":"int","comment":"0 or an error code"},"description":"Traverse the entries in a tree and its subtrees in\npost or pre order","comments":"The entries will be traversed in the specified order,\nchildren subtrees will be automatically loaded as required,\nand the `callback` will be called once per entry with\nthe current (relative) root for the entry and the entry\ndata itself.\n\nIf the callback returns a positive value, the passed entry will be\nskipped on the traversal (in pre mode). A negative value stops the\nwalk.\n","group":"tree"},"git_submodule_lookup":{"type":"function","file":"submodule.h","line":154,"lineto":157,"args":[{"name":"submodule","type":"git_submodule **","comment":"Pointer to submodule description object pointer.."},{"name":"repo","type":"git_repository *","comment":"The repository."},{"name":"name","type":"const char *","comment":"The name of the submodule. Trailing slashes will be ignored."}],"argline":"git_submodule **submodule,\n\tgit_repository *repo,\n\tconst char *name","sig":"git_submodule **::git_repository *::const char *","return":{"type":"int","comment":"0 on success, GIT_ENOTFOUND if submodule does not exist, GIT_EEXISTS if submodule exists in working directory only, -1 on other errors."},"description":"Lookup submodule information by name or path.","comments":"Given either the submodule name or path (they are usually the same), this\nreturns a structure describing the submodule.\n\nThere are two expected error scenarios:\n\n- The submodule is not mentioned in the HEAD, the index, and the config,\n but does \"exist\" in the working directory (i.e. there is a subdirectory\n that is a valid self-contained git repo). In this case, this function\n returns GIT_EEXISTS to indicate the the submodule exists but not in a\n state where a git_submodule can be instantiated.\n- The submodule is not mentioned in the HEAD, index, or config and the\n working directory doesn't contain a value git repo at that path.\n There may or may not be anything else at that path, but nothing that\n looks like a submodule. In this case, this returns GIT_ENOTFOUND.\n\nThe submodule object is owned by the containing repo and will be freed\nwhen the repo is freed. The caller need not free the submodule.\n","group":"submodule"},"git_submodule_foreach":{"type":"function","file":"submodule.h","line":177,"lineto":180,"args":[{"name":"repo","type":"git_repository *","comment":"The repository"},{"name":"callback","type":"int (*)(git_submodule *sm, const char *name, void *payload)","comment":"Function to be called with the name of each submodule. Return a non-zero value to terminate the iteration."},{"name":"payload","type":"void *","comment":"Extra data to pass to callback"}],"argline":"git_repository *repo,\n\tint (*callback)(git_submodule *sm, const char *name, void *payload),\n\tvoid *payload","sig":"git_repository *::int (*)(git_submodule *sm, const char *name, void *payload)::void *","return":{"type":"int","comment":"0 on success, -1 on error, or non-zero return value of callback"},"description":"Iterate over all tracked submodules of a repository.","comments":"See the note on `git_submodule` above. This iterates over the tracked\nsubmodules as decribed therein.\n\nIf you are concerned about items in the working directory that look like\nsubmodules but are not tracked, the diff API will generate a diff record\nfor workdir items that look like submodules but are not tracked, showing\nthem as added in the workdir. Also, the status API will treat the entire\nsubdirectory of a contained git repo as a single GIT_STATUS_WT_NEW item.\n","group":"submodule"},"git_submodule_add_setup":{"type":"function","file":"submodule.h","line":205,"lineto":210,"args":[{"name":"submodule","type":"git_submodule **","comment":"The newly created submodule ready to open for clone"},{"name":"repo","type":"git_repository *","comment":"Superproject repository to contain the new submodule"},{"name":"url","type":"const char *","comment":"URL for the submodules remote"},{"name":"path","type":"const char *","comment":"Path at which the submodule should be created"},{"name":"use_gitlink","type":"int","comment":"Should workdir contain a gitlink to the repo in .git/modules vs. repo directly in workdir."}],"argline":"git_submodule **submodule,\n\tgit_repository *repo,\n\tconst char *url,\n\tconst char *path,\n\tint use_gitlink","sig":"git_submodule **::git_repository *::const char *::const char *::int","return":{"type":"int","comment":"0 on success, GIT_EEXISTS if submodule already exists, -1 on other errors."},"description":"Set up a new git submodule for checkout.","comments":"This does \"git submodule add\" up to the fetch and checkout of the\nsubmodule contents. It preps a new submodule, creates an entry in\n.gitmodules and creates an empty initialized repository either at the\ngiven path in the working directory or in .git/modules with a gitlink\nfrom the working directory to the new repo.\n\nTo fully emulate \"git submodule add\" call this function, then open the\nsubmodule repo and perform the clone step as needed. Lastly, call\n`git_submodule_add_finalize()` to wrap up adding the new submodule and\n.gitmodules to the index to be ready to commit.\n","group":"submodule"},"git_submodule_add_finalize":{"type":"function","file":"submodule.h","line":222,"lineto":222,"args":[{"name":"submodule","type":"git_submodule *","comment":"The submodule to finish adding."}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"int"},"description":"Resolve the setup of a new git submodule.","comments":"This should be called on a submodule once you have called add setup\nand done the clone of the submodule. This adds the .gitmodules file\nand the newly cloned submodule to the index to be ready to be committed\n(but doesn't actually do the commit).\n","group":"submodule"},"git_submodule_add_to_index":{"type":"function","file":"submodule.h","line":234,"lineto":236,"args":[{"name":"submodule","type":"git_submodule *","comment":"The submodule to add to the index"},{"name":"write_index","type":"int","comment":"Boolean if this should immediately write the index file. If you pass this as false, you will have to get the git_index and explicitly call `git_index_write()` on it to save the change."}],"argline":"git_submodule *submodule,\n\tint write_index","sig":"git_submodule *::int","return":{"type":"int","comment":"0 on success, <0 on failure"},"description":"Add current submodule HEAD commit to index of superproject.","comments":"","group":"submodule"},"git_submodule_save":{"type":"function","file":"submodule.h","line":250,"lineto":250,"args":[{"name":"submodule","type":"git_submodule *","comment":"The submodule to write."}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"int","comment":"0 on success, <0 on failure."},"description":"Write submodule settings to .gitmodules file.","comments":"This commits any in-memory changes to the submodule to the gitmodules\nfile on disk. You may also be interested in `git_submodule_init()` which\nwrites submodule info to \".git/config\" (which is better for local changes\nto submodule settings) and/or `git_submodule_sync()` which writes\nsettings about remotes to the actual submodule repository.\n","group":"submodule"},"git_submodule_owner":{"type":"function","file":"submodule.h","line":263,"lineto":263,"args":[{"name":"submodule","type":"git_submodule *","comment":"Pointer to submodule object"}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"git_repository *","comment":"Pointer to `git_repository`"},"description":"Get the containing repository for a submodule.","comments":"This returns a pointer to the repository that contains the submodule.\nThis is a just a reference to the repository that was passed to the\noriginal `git_submodule_lookup()` call, so if that repository has been\nfreed, then this may be a dangling reference.\n","group":"submodule"},"git_submodule_name":{"type":"function","file":"submodule.h","line":271,"lineto":271,"args":[{"name":"submodule","type":"git_submodule *","comment":"Pointer to submodule object"}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"const char *","comment":"Pointer to the submodule name"},"description":"Get the name of submodule.","comments":"","group":"submodule"},"git_submodule_path":{"type":"function","file":"submodule.h","line":282,"lineto":282,"args":[{"name":"submodule","type":"git_submodule *","comment":"Pointer to submodule object"}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"const char *","comment":"Pointer to the submodule path"},"description":"Get the path to the submodule.","comments":"The path is almost always the same as the submodule name, but the\ntwo are actually not required to match.\n","group":"submodule"},"git_submodule_url":{"type":"function","file":"submodule.h","line":290,"lineto":290,"args":[{"name":"submodule","type":"git_submodule *","comment":"Pointer to submodule object"}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"const char *","comment":"Pointer to the submodule url"},"description":"Get the URL for the submodule.","comments":"","group":"submodule"},"git_submodule_set_url":{"type":"function","file":"submodule.h","line":306,"lineto":306,"args":[{"name":"submodule","type":"git_submodule *","comment":"Pointer to the submodule object"},{"name":"url","type":"const char *","comment":"URL that should be used for the submodule"}],"argline":"git_submodule *submodule, const char *url","sig":"git_submodule *::const char *","return":{"type":"int","comment":"0 on success, <0 on failure"},"description":"Set the URL for the submodule.","comments":"This sets the URL in memory for the submodule. This will be used for\nany following submodule actions while this submodule data is in memory.\n\nAfter calling this, you may wish to call `git_submodule_save()` to write\nthe changes back to the \".gitmodules\" file and `git_submodule_sync()` to\nwrite the changes to the checked out submodule repository.\n","group":"submodule"},"git_submodule_index_oid":{"type":"function","file":"submodule.h","line":314,"lineto":314,"args":[{"name":"submodule","type":"git_submodule *","comment":"Pointer to submodule object"}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"const git_oid *","comment":"Pointer to git_oid or NULL if submodule is not in index."},"description":"Get the OID for the submodule in the index.","comments":"","group":"submodule"},"git_submodule_head_oid":{"type":"function","file":"submodule.h","line":322,"lineto":322,"args":[{"name":"submodule","type":"git_submodule *","comment":"Pointer to submodule object"}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"const git_oid *","comment":"Pointer to git_oid or NULL if submodule is not in the HEAD."},"description":"Get the OID for the submodule in the current HEAD tree.","comments":"","group":"submodule"},"git_submodule_wd_oid":{"type":"function","file":"submodule.h","line":335,"lineto":335,"args":[{"name":"submodule","type":"git_submodule *","comment":"Pointer to submodule object"}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"const git_oid *","comment":"Pointer to git_oid or NULL if submodule is not checked out."},"description":"Get the OID for the submodule in the current working directory.","comments":"This returns the OID that corresponds to looking up 'HEAD' in the checked\nout submodule. If there are pending changes in the index or anything\nelse, this won't notice that. You should call `git_submodule_status()`\nfor a more complete picture about the state of the working directory.\n","group":"submodule"},"git_submodule_ignore":{"type":"function","file":"submodule.h","line":355,"lineto":356,"args":[],"argline":"_t) git_submodule_ignore(\n\tgit_submodule *submodule)","sig":"","return":{"type":"GIT_EXTERN("},"description":"Get the ignore rule for the submodule.","comments":"There are four ignore values:\n\n - **GIT_SUBMODULE_IGNORE_NONE** will consider any change to the contents\n of the submodule from a clean checkout to be dirty, including the\n addition of untracked files. This is the default if unspecified.\n - **GIT_SUBMODULE_IGNORE_UNTRACKED** examines the contents of the\n working tree (i.e. call `git_status_foreach()` on the submodule) but\n UNTRACKED files will not count as making the submodule dirty.\n - **GIT_SUBMODULE_IGNORE_DIRTY** means to only check if the HEAD of the\n submodule has moved for status. This is fast since it does not need to\n scan the working tree of the submodule at all.\n - **GIT_SUBMODULE_IGNORE_ALL** means not to open the submodule repo.\n The working directory will be consider clean so long as there is a\n checked out version present.","group":"submodule"},"git_submodule_set_ignore":{"type":"function","file":"submodule.h","line":372,"lineto":374,"args":[{"name":"submodule","type":"git_submodule *"},{"name":"ignore","type":"git_submodule_ignore_t"}],"argline":"git_submodule *submodule,\n\tgit_submodule_ignore_t ignore","sig":"git_submodule *::git_submodule_ignore_t","return":{"type":"git_submodule_ignore_t","comment":"old value for ignore"},"description":"Set the ignore rule for the submodule.","comments":"This sets the ignore rule in memory for the submodule. This will be used\nfor any following actions (such as `git_submodule_status()`) while the\nsubmodule is in memory. You should call `git_submodule_save()` if you\nwant to persist the new ignore role.\n\nCalling this again with GIT_SUBMODULE_IGNORE_DEFAULT or calling\n`git_submodule_reload()` will revert the rule to the value that was in the\noriginal config.\n","group":"submodule"},"git_submodule_update":{"type":"function","file":"submodule.h","line":379,"lineto":380,"args":[],"argline":"_t) git_submodule_update(\n\tgit_submodule *submodule)","sig":"","return":{"type":"GIT_EXTERN("},"description":"Get the update rule for the submodule.","comments":"","group":"submodule"},"git_submodule_set_update":{"type":"function","file":"submodule.h","line":394,"lineto":396,"args":[{"name":"submodule","type":"git_submodule *"},{"name":"update","type":"git_submodule_update_t"}],"argline":"git_submodule *submodule,\n\tgit_submodule_update_t update","sig":"git_submodule *::git_submodule_update_t","return":{"type":"git_submodule_update_t","comment":"old value for update"},"description":"Set the update rule for the submodule.","comments":"This sets the update rule in memory for the submodule. You should call\n`git_submodule_save()` if you want to persist the new update rule.\n\nCalling this again with GIT_SUBMODULE_UPDATE_DEFAULT or calling\n`git_submodule_reload()` will revert the rule to the value that was in the\noriginal config.\n","group":"submodule"},"git_submodule_fetch_recurse_submodules":{"type":"function","file":"submodule.h","line":409,"lineto":410,"args":[{"name":"submodule","type":"git_submodule *"}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"int","comment":"0 if fetchRecurseSubmodules is false, 1 if true"},"description":"Read the fetchRecurseSubmodules rule for a submodule.","comments":"This accesses the submodule..fetchRecurseSubmodules value for\nthe submodule that controls fetching behavior for the submodule.\n\nNote that at this time, libgit2 does not honor this setting and the\nfetch functionality current ignores submodules.\n","group":"submodule"},"git_submodule_set_fetch_recurse_submodules":{"type":"function","file":"submodule.h","line":423,"lineto":425,"args":[{"name":"submodule","type":"git_submodule *","comment":"The submodule to modify"},{"name":"fetch_recurse_submodules","type":"int","comment":"Boolean value"}],"argline":"git_submodule *submodule,\n\tint fetch_recurse_submodules","sig":"git_submodule *::int","return":{"type":"int","comment":"old value for fetchRecurseSubmodules"},"description":"Set the fetchRecurseSubmodules rule for a submodule.","comments":"This sets the submodule..fetchRecurseSubmodules value for\nthe submodule. You should call `git_submodule_save()` if you want\nto persist the new value.\n","group":"submodule"},"git_submodule_init":{"type":"function","file":"submodule.h","line":440,"lineto":440,"args":[{"name":"submodule","type":"git_submodule *","comment":"The submodule to write into the superproject config"},{"name":"overwrite","type":"int","comment":"By default, existing entries will not be overwritten, but setting this to true forces them to be updated."}],"argline":"git_submodule *submodule, int overwrite","sig":"git_submodule *::int","return":{"type":"int","comment":"0 on success, <0 on failure."},"description":"Copy submodule info into \".git/config\" file.","comments":"Just like \"git submodule init\", this copies information about the\nsubmodule into \".git/config\". You can use the accessor functions\nabove to alter the in-memory git_submodule object and control what\nis written to the config, overriding what is in .gitmodules.\n","group":"submodule"},"git_submodule_sync":{"type":"function","file":"submodule.h","line":450,"lineto":450,"args":[{"name":"submodule","type":"git_submodule *"}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"int"},"description":"Copy submodule remote info into submodule repo.","comments":"This copies the information about the submodules URL into the checked out\nsubmodule config, acting like \"git submodule sync\". This is useful if\nyou have altered the URL for the submodule (or it has been altered by a\nfetch of upstream changes) and you need to update your local repo.","group":"submodule"},"git_submodule_open":{"type":"function","file":"submodule.h","line":464,"lineto":466,"args":[{"name":"repo","type":"git_repository **"},{"name":"submodule","type":"git_submodule *","comment":"Submodule to be opened"}],"argline":"git_repository **repo,\n\tgit_submodule *submodule","sig":"git_repository **::git_submodule *","return":{"type":"int","comment":"0 on success, <0 if submodule repo could not be opened."},"description":"Open the repository for a submodule.","comments":"This is a newly opened repository object. The caller is responsible for\ncalling `git_repository_free()` on it when done. Multiple calls to this\nfunction will return distinct `git_repository` objects. This will only\nwork if the submodule is checked out into the working directory.\n","group":"submodule"},"git_submodule_reload":{"type":"function","file":"submodule.h","line":474,"lineto":474,"args":[{"name":"submodule","type":"git_submodule *"}],"argline":"git_submodule *submodule","sig":"git_submodule *","return":{"type":"int"},"description":"Reread submodule info from config, index, and HEAD.","comments":"Call this to reread cached submodule information for this submodule if\nyou have reason to believe that it has changed.","group":"submodule"},"git_submodule_reload_all":{"type":"function","file":"submodule.h","line":481,"lineto":481,"args":[{"name":"repo","type":"git_repository *"}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"int"},"description":"Reread all submodule info.","comments":"Call this to reload all cached submodule information for the repo.","group":"submodule"},"git_submodule_status":{"type":"function","file":"submodule.h","line":496,"lineto":498,"args":[{"name":"status","type":"unsigned int *","comment":"Combination of `GIT_SUBMODULE_STATUS` flags"},{"name":"submodule","type":"git_submodule *","comment":"Submodule for which to get status"}],"argline":"unsigned int *status,\n\tgit_submodule *submodule","sig":"unsigned int *::git_submodule *","return":{"type":"int","comment":"0 on success, <0 on error"},"description":"Get the status for a submodule.","comments":"This looks at a submodule and tries to determine the status. It\nwill return a combination of the `GIT_SUBMODULE_STATUS` values above.\nHow deeply it examines the working directory to do this will depend\non the `git_submodule_ignore_t` value for the submodule - which can be\nset either temporarily or permanently with `git_submodule_set_ignore()`.\n","group":"submodule"},"git_ignore_add_rule":{"type":"function","file":"ignore.h","line":37,"lineto":39,"args":[{"name":"repo","type":"git_repository *","comment":"The repository to add ignore rules to."},{"name":"rules","type":"const char *","comment":"Text of rules, a la the contents of a .gitignore file. It is okay to have multiple rules in the text; if so, each rule should be terminated with a newline."}],"argline":"git_repository *repo,\n\tconst char *rules","sig":"git_repository *::const char *","return":{"type":"int","comment":"0 on success"},"description":"Add ignore rules for a repository.","comments":"Excludesfile rules (i.e. .gitignore rules) are generally read from\n.gitignore files in the repository tree or from a shared system file\nonly if a \"core.excludesfile\" config value is set. The library also\nkeeps a set of per-repository internal ignores that can be configured\nin-memory and will not persist. This function allows you to add to\nthat internal rules list.\n\nExample usage:\n\n error = git_ignore_add(myrepo, \"*.c\\ndir/\\nFile with space\\n\");\n\nThis would add three rules to the ignores.\n","group":"ignore"},"git_ignore_clear_internal_rules":{"type":"function","file":"ignore.h","line":51,"lineto":52,"args":[{"name":"repo","type":"git_repository *","comment":"The repository to remove ignore rules from."}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"int","comment":"0 on success"},"description":"Clear ignore rules that were explicitly added.","comments":"Clears the internal ignore rules that have been set up. This will not\nturn off the rules in .gitignore files that actually exist in the\nfilesystem.\n","group":"ignore"},"git_ignore_path_is_ignored":{"type":"function","file":"ignore.h","line":67,"lineto":74,"args":[{"name":"ignored","type":"int *","comment":"boolean returning 0 if the file is not ignored, 1 if it is"},{"name":"repo","type":"git_repository *","comment":"a repository object"},{"name":"path","type":"const char *","comment":"the file to check ignores for, relative to the repo's workdir."}],"argline":"int *ignored,\n\tgit_repository *repo,\n\tconst char *path","sig":"int *::git_repository *::const char *","return":{"type":"int","comment":"0 if ignore rules could be processed for the file (regardless of whether it exists or not), or an error < 0 if they could not."},"description":"Test if the ignore rules apply to a given path.","comments":"This function simply checks the ignore rules to see if they would apply\nto the given file. This indicates if the file would be ignored regardless\nof whether the file is already in the index or commited to the repository.\n","group":"ignore"},"git_message_prettify":{"type":"function","file":"message.h","line":39,"lineto":39,"args":[{"name":"message_out","type":"char *","comment":"The user allocated buffer which will be filled with the cleaned up message. Pass NULL if you just want to get the size of the prettified message as the output value."},{"name":"buffer_size","type":"size_t"},{"name":"message","type":"const char *","comment":"_out The user allocated buffer which will be filled with the cleaned up message. Pass NULL if you just want to get the size of the prettified message as the output value."},{"name":"strip_comments","type":"int","comment":"1 to remove lines starting with a \"#\", 0 otherwise."}],"argline":"char *message_out, size_t buffer_size, const char *message, int strip_comments","sig":"char *::size_t::const char *::int","return":{"type":"int","comment":"-1 on error, else number of characters in prettified message including the trailing NUL byte"},"description":"Clean up message from excess whitespace and make sure that the last line\nends with a '\\n'.","comments":"Optionally, can remove lines starting with a \"#\".\n","group":"message"},"git_odb_new":{"type":"function","file":"odb.h","line":34,"lineto":34,"args":[{"name":"out","type":"git_odb **","comment":"location to store the database pointer, if opened. Set to NULL if the open failed."}],"argline":"git_odb **out","sig":"git_odb **","return":{"type":"int","comment":"0 or an error code"},"description":"Create a new object database with no backends.","comments":"Before the ODB can be used for read/writing, a custom database\nbackend must be manually added using `git_odb_add_backend()`\n","group":"odb"},"git_odb_open":{"type":"function","file":"odb.h","line":52,"lineto":52,"args":[{"name":"out","type":"git_odb **","comment":"location to store the database pointer, if opened. Set to NULL if the open failed."},{"name":"objects_dir","type":"const char *","comment":"path of the backends' \"objects\" directory."}],"argline":"git_odb **out, const char *objects_dir","sig":"git_odb **::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Create a new object database and automatically add\nthe two default backends:","comments":"- git_odb_backend_loose: read and write loose object files\n\tfrom disk, assuming `objects_dir` as the Objects folder\n\n- git_odb_backend_pack: read objects from packfiles,\n\tassuming `objects_dir` as the Objects folder which\n\tcontains a 'pack/' folder with the corresponding data\n","group":"odb"},"git_odb_add_backend":{"type":"function","file":"odb.h","line":67,"lineto":67,"args":[{"name":"odb","type":"git_odb *","comment":"database to add the backend to"},{"name":"backend","type":"git_odb_backend *","comment":"pointer to a git_odb_backend instance"},{"name":"priority","type":"int","comment":"Value for ordering the backends queue"}],"argline":"git_odb *odb, git_odb_backend *backend, int priority","sig":"git_odb *::git_odb_backend *::int","return":{"type":"int","comment":"0 on success; error code otherwise"},"description":"Add a custom backend to an existing Object DB","comments":"The backends are checked in relative ordering, based on the\nvalue of the `priority` parameter.\n\nRead for more information.\n","group":"odb"},"git_odb_add_alternate":{"type":"function","file":"odb.h","line":88,"lineto":88,"args":[{"name":"odb","type":"git_odb *","comment":"database to add the backend to"},{"name":"backend","type":"git_odb_backend *","comment":"pointer to a git_odb_backend instance"},{"name":"priority","type":"int","comment":"Value for ordering the backends queue"}],"argline":"git_odb *odb, git_odb_backend *backend, int priority","sig":"git_odb *::git_odb_backend *::int","return":{"type":"int","comment":"0 on success; error code otherwise"},"description":"Add a custom backend to an existing Object DB; this\nbackend will work as an alternate.","comments":"Alternate backends are always checked for objects *after*\nall the main backends have been exhausted.\n\nThe backends are checked in relative ordering, based on the\nvalue of the `priority` parameter.\n\nWriting is disabled on alternate backends.\n\nRead for more information.\n","group":"odb"},"git_odb_free":{"type":"function","file":"odb.h","line":95,"lineto":95,"args":[{"name":"db","type":"git_odb *","comment":"database pointer to close. If NULL no action is taken."}],"argline":"git_odb *db","sig":"git_odb *","return":{"type":"void"},"description":"Close an open object database.","comments":"","group":"odb"},"git_odb_read":{"type":"function","file":"odb.h","line":114,"lineto":114,"args":[{"name":"out","type":"git_odb_object **","comment":"pointer where to store the read object"},{"name":"db","type":"git_odb *","comment":"database to search for the object in."},{"name":"id","type":"const git_oid *","comment":"identity of the object to read."}],"argline":"git_odb_object **out, git_odb *db, const git_oid *id","sig":"git_odb_object **::git_odb *::const git_oid *","return":{"type":"int","comment":"- 0 if the object was read; - GIT_ENOTFOUND if the object is not in the database."},"description":"Read an object from the database.","comments":"This method queries all available ODB backends\ntrying to read the given OID.\n\nThe returned object is reference counted and\ninternally cached, so it should be closed\nby the user once it's no longer in use.\n","group":"odb","examples":{"general.c":["ex/HEAD/general.html#git_odb_read-49"]}},"git_odb_read_prefix":{"type":"function","file":"odb.h","line":142,"lineto":142,"args":[{"name":"out","type":"git_odb_object **","comment":"pointer where to store the read object"},{"name":"db","type":"git_odb *","comment":"database to search for the object in."},{"name":"short_id","type":"const git_oid *","comment":"a prefix of the id of the object to read."},{"name":"len","type":"size_t","comment":"the length of the prefix"}],"argline":"git_odb_object **out, git_odb *db, const git_oid *short_id, size_t len","sig":"git_odb_object **::git_odb *::const git_oid *::size_t","return":{"type":"int","comment":"0 if the object was read; GIT_ENOTFOUND if the object is not in the database. GIT_EAMBIGUOUS if the prefix is ambiguous (several objects match the prefix)"},"description":"Read an object from the database, given a prefix\nof its identifier.","comments":"This method queries all available ODB backends\ntrying to match the 'len' first hexadecimal\ncharacters of the 'short_id'.\nThe remaining (GIT_OID_HEXSZ-len)*4 bits of\n'short_id' must be 0s.\n'len' must be at least GIT_OID_MINPREFIXLEN,\nand the prefix must be long enough to identify\na unique object in all the backends; the\nmethod will fail otherwise.\n\nThe returned object is reference counted and\ninternally cached, so it should be closed\nby the user once it's no longer in use.\n","group":"odb"},"git_odb_read_header":{"type":"function","file":"odb.h","line":162,"lineto":162,"args":[{"name":"len_p","type":"size_t *","comment":"pointer where to store the length"},{"name":"type_p","type":"git_otype *","comment":"pointer where to store the type"},{"name":"db","type":"git_odb *","comment":"database to search for the object in."},{"name":"id","type":"const git_oid *","comment":"identity of the object to read."}],"argline":"size_t *len_p, git_otype *type_p, git_odb *db, const git_oid *id","sig":"size_t *::git_otype *::git_odb *::const git_oid *","return":{"type":"int","comment":"- 0 if the object was read; - GIT_ENOTFOUND if the object is not in the database."},"description":"Read the header of an object from the database, without\nreading its full contents.","comments":"The header includes the length and the type of an object.\n\nNote that most backends do not support reading only the header\nof an object, so the whole object will be read and then the\nheader will be returned.\n","group":"odb"},"git_odb_exists":{"type":"function","file":"odb.h","line":173,"lineto":173,"args":[{"name":"db","type":"git_odb *","comment":"database to be searched for the given object."},{"name":"id","type":"const git_oid *","comment":"the object to search for."}],"argline":"git_odb *db, const git_oid *id","sig":"git_odb *::const git_oid *","return":{"type":"int","comment":"- 1, if the object was found - 0, otherwise"},"description":"Determine if the given object can be found in the object database.","comments":"","group":"odb"},"git_odb_foreach":{"type":"function","file":"odb.h","line":188,"lineto":188,"args":[{"name":"db","type":"git_odb *","comment":"database to use"},{"name":"cb","type":"int (*)(git_oid *oid, void *data)","comment":"the callback to call for each object"},{"name":"data","type":"void *","comment":"data to pass to the callback"}],"argline":"git_odb *db, int (*cb)(git_oid *oid, void *data), void *data","sig":"git_odb *::int (*)(git_oid *oid, void *data)::void *","return":{"type":"int","comment":"0 on success, GIT_EUSER on non-zero callback, or error code"},"description":"List all objects available in the database","comments":"The callback will be called for each object available in the\ndatabase. Note that the objects are likely to be returned in the index\norder, which would make accessing the objects in that order inefficient.\nReturn a non-zero value from the callback to stop looping.\n","group":"odb"},"git_odb_write":{"type":"function","file":"odb.h","line":208,"lineto":208,"args":[{"name":"oid","type":"git_oid *","comment":"pointer to store the OID result of the write"},{"name":"odb","type":"git_odb *","comment":"object database where to store the object"},{"name":"data","type":"const void *","comment":"buffer with the data to store"},{"name":"len","type":"size_t","comment":"size of the buffer"},{"name":"type","type":"git_otype","comment":"type of the data to store"}],"argline":"git_oid *oid, git_odb *odb, const void *data, size_t len, git_otype type","sig":"git_oid *::git_odb *::const void *::size_t::git_otype","return":{"type":"int","comment":"0 or an error code"},"description":"Write an object directly into the ODB","comments":"This method writes a full object straight into the ODB.\nFor most cases, it is preferred to write objects through a write\nstream, which is both faster and less memory intensive, specially\nfor big objects.\n\nThis method is provided for compatibility with custom backends\nwhich are not able to support streaming writes\n","group":"odb","examples":{"general.c":["ex/HEAD/general.html#git_odb_write-50"]}},"git_odb_open_wstream":{"type":"function","file":"odb.h","line":237,"lineto":237,"args":[{"name":"stream","type":"git_odb_stream **","comment":"pointer where to store the stream"},{"name":"db","type":"git_odb *","comment":"object database where the stream will write"},{"name":"size","type":"size_t","comment":"final size of the object that will be written"},{"name":"type","type":"git_otype","comment":"type of the object that will be written"}],"argline":"git_odb_stream **stream, git_odb *db, size_t size, git_otype type","sig":"git_odb_stream **::git_odb *::size_t::git_otype","return":{"type":"int","comment":"0 if the stream was created; error code otherwise"},"description":"Open a stream to write an object into the ODB","comments":"The type and final length of the object must be specified\nwhen opening the stream.\n\nThe returned stream will be of type `GIT_STREAM_WRONLY` and\nwill have the following methods:\n\n\t- stream->write: write `n` bytes into the stream\n\t- stream->finalize_write: close the stream and store the object in\n\t\tthe odb\n\t- stream->free: free the stream\n\nThe streaming write won't be effective until `stream->finalize_write`\nis called and returns without an error\n\nThe stream must always be free'd or will leak memory.\n\n@see git_odb_stream\n","group":"odb"},"git_odb_open_rstream":{"type":"function","file":"odb.h","line":263,"lineto":263,"args":[{"name":"stream","type":"git_odb_stream **","comment":"pointer where to store the stream"},{"name":"db","type":"git_odb *","comment":"object database where the stream will read from"},{"name":"oid","type":"const git_oid *","comment":"oid of the object the stream will read from"}],"argline":"git_odb_stream **stream, git_odb *db, const git_oid *oid","sig":"git_odb_stream **::git_odb *::const git_oid *","return":{"type":"int","comment":"0 if the stream was created; error code otherwise"},"description":"Open a stream to read an object from the ODB","comments":"Note that most backends do *not* support streaming reads\nbecause they store their objects as compressed/delta'ed blobs.\n\nIt's recommended to use `git_odb_read` instead, which is\nassured to work on all backends.\n\nThe returned stream will be of type `GIT_STREAM_RDONLY` and\nwill have the following methods:\n\n\t- stream->read: read `n` bytes from the stream\n\t- stream->free: free the stream\n\nThe stream must always be free'd or will leak memory.\n\n@see git_odb_stream\n","group":"odb"},"git_odb_hash":{"type":"function","file":"odb.h","line":277,"lineto":277,"args":[{"name":"id","type":"git_oid *","comment":"the resulting object-ID."},{"name":"data","type":"const void *","comment":"data to hash"},{"name":"len","type":"size_t","comment":"size of the data"},{"name":"type","type":"git_otype","comment":"of the data to hash"}],"argline":"git_oid *id, const void *data, size_t len, git_otype type","sig":"git_oid *::const void *::size_t::git_otype","return":{"type":"int","comment":"0 or an error code"},"description":"Determine the object-ID (sha1 hash) of a data buffer","comments":"The resulting SHA-1 OID will be the identifier for the data\nbuffer as if the data buffer it were to written to the ODB.\n","group":"odb"},"git_odb_hashfile":{"type":"function","file":"odb.h","line":290,"lineto":290,"args":[{"name":"out","type":"git_oid *","comment":"oid structure the result is written into."},{"name":"path","type":"const char *","comment":"file to read and determine object id for"},{"name":"type","type":"git_otype","comment":"the type of the object that will be hashed"}],"argline":"git_oid *out, const char *path, git_otype type","sig":"git_oid *::const char *::git_otype","return":{"type":"int","comment":"0 or an error code"},"description":"Read a file from disk and fill a git_oid with the object id\nthat the file would have if it were written to the Object\nDatabase as an object of the given type. Similar functionality\nto git.git's `git hash-object` without the `-w` flag.","comments":"","group":"odb"},"git_odb_object_free":{"type":"function","file":"odb.h","line":300,"lineto":300,"args":[{"name":"object","type":"git_odb_object *","comment":"object to close"}],"argline":"git_odb_object *object","sig":"git_odb_object *","return":{"type":"void"},"description":"Close an ODB object","comments":"This method must always be called once a `git_odb_object` is no\nlonger needed, otherwise memory will leak.\n","group":"odb","examples":{"general.c":["ex/HEAD/general.html#git_odb_object_free-51"]}},"git_odb_object_id":{"type":"function","file":"odb.h","line":310,"lineto":310,"args":[{"name":"object","type":"git_odb_object *","comment":"the object"}],"argline":"git_odb_object *object","sig":"git_odb_object *","return":{"type":"const git_oid *","comment":"a pointer to the OID"},"description":"Return the OID of an ODB object","comments":"This is the OID from which the object was read from\n","group":"odb"},"git_odb_object_data":{"type":"function","file":"odb.h","line":323,"lineto":323,"args":[{"name":"object","type":"git_odb_object *","comment":"the object"}],"argline":"git_odb_object *object","sig":"git_odb_object *","return":{"type":"const void *","comment":"a pointer to the data"},"description":"Return the data of an ODB object","comments":"This is the uncompressed, raw data as read from the ODB,\nwithout the leading header.\n\nThis pointer is owned by the object and shall not be free'd.\n","group":"odb","examples":{"general.c":["ex/HEAD/general.html#git_odb_object_data-52"]}},"git_odb_object_size":{"type":"function","file":"odb.h","line":334,"lineto":334,"args":[{"name":"object","type":"git_odb_object *","comment":"the object"}],"argline":"git_odb_object *object","sig":"git_odb_object *","return":{"type":"size_t","comment":"the size"},"description":"Return the size of an ODB object","comments":"This is the real size of the `data` buffer, not the\nactual size of the object.\n","group":"odb","examples":{"general.c":["ex/HEAD/general.html#git_odb_object_size-53"]}},"git_odb_object_type":{"type":"function","file":"odb.h","line":342,"lineto":342,"args":[{"name":"object","type":"git_odb_object *","comment":"the object"}],"argline":"git_odb_object *object","sig":"git_odb_object *","return":{"type":"git_otype","comment":"the type"},"description":"Return the type of an ODB object","comments":"","group":"odb","examples":{"general.c":["ex/HEAD/general.html#git_odb_object_type-54"]}},"git_threads_init":{"type":"function","file":"threads.h","line":31,"lineto":31,"args":[],"argline":"void","sig":"","return":{"type":"void"},"description":"Init the threading system.","comments":"If libgit2 has been built with GIT_THREADS\non, this function must be called once before\nany other library functions.\n\nIf libgit2 has been built without GIT_THREADS\nsupport, this function is a no-op.","group":"threads"},"git_threads_shutdown":{"type":"function","file":"threads.h","line":43,"lineto":43,"args":[],"argline":"void","sig":"","return":{"type":"void"},"description":"Shutdown the threading system.","comments":"If libgit2 has been built with GIT_THREADS\non, this function must be called before shutting\ndown the library.\n\nIf libgit2 has been built without GIT_THREADS\nsupport, this function is a no-op.","group":"threads"},"git_oid_fromstr":{"type":"function","file":"oid.h","line":48,"lineto":48,"args":[{"name":"out","type":"git_oid *","comment":"oid structure the result is written into."},{"name":"str","type":"const char *","comment":"input hex string; must be pointing at the start of the hex sequence and have at least the number of bytes needed for an oid encoded in hex (40 bytes)."}],"argline":"git_oid *out, const char *str","sig":"git_oid *::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Parse a hex formatted object id into a git_oid.","comments":"","group":"oid","examples":{"general.c":["ex/HEAD/general.html#git_oid_fromstr-55","ex/HEAD/general.html#git_oid_fromstr-56","ex/HEAD/general.html#git_oid_fromstr-57","ex/HEAD/general.html#git_oid_fromstr-58","ex/HEAD/general.html#git_oid_fromstr-59","ex/HEAD/general.html#git_oid_fromstr-60","ex/HEAD/general.html#git_oid_fromstr-61","ex/HEAD/general.html#git_oid_fromstr-62"]}},"git_oid_fromstrn":{"type":"function","file":"oid.h","line":61,"lineto":61,"args":[{"name":"out","type":"git_oid *","comment":"oid structure the result is written into."},{"name":"str","type":"const char *","comment":"input hex string of at least size `length`"},{"name":"length","type":"size_t","comment":"length of the input string"}],"argline":"git_oid *out, const char *str, size_t length","sig":"git_oid *::const char *::size_t","return":{"type":"int","comment":"0 or an error code"},"description":"Parse N characters of a hex formatted object id into a git_oid","comments":"If N is odd, N-1 characters will be parsed instead.\nThe remaining space in the git_oid will be set to zero.\n","group":"oid","examples":{"diff.c":["ex/HEAD/diff.html#git_oid_fromstrn-17"]}},"git_oid_fromraw":{"type":"function","file":"oid.h","line":69,"lineto":69,"args":[{"name":"out","type":"git_oid *","comment":"oid structure the result is written into."},{"name":"raw","type":"const unsigned char *","comment":"the raw input bytes to be copied."}],"argline":"git_oid *out, const unsigned char *raw","sig":"git_oid *::const unsigned char *","return":{"type":"void"},"description":"Copy an already raw oid into a git_oid structure.","comments":"","group":"oid"},"git_oid_fmt":{"type":"function","file":"oid.h","line":81,"lineto":81,"args":[{"name":"str","type":"char *","comment":"output hex string; must be pointing at the start of the hex sequence and have at least the number of bytes needed for an oid encoded in hex (40 bytes). Only the oid digits are written; a '\\\\0' terminator must be added by the caller if it is required."},{"name":"oid","type":"const git_oid *","comment":"oid structure to format."}],"argline":"char *str, const git_oid *oid","sig":"char *::const git_oid *","return":{"type":"void"},"description":"Format a git_oid into a hex string.","comments":"","group":"oid","examples":{"showindex.c":["ex/HEAD/showindex.html#git_oid_fmt-8"],"general.c":["ex/HEAD/general.html#git_oid_fmt-63","ex/HEAD/general.html#git_oid_fmt-64","ex/HEAD/general.html#git_oid_fmt-65","ex/HEAD/general.html#git_oid_fmt-66","ex/HEAD/general.html#git_oid_fmt-67"],"network/ls-remote.c":["ex/HEAD/ls-remote.html#git_oid_fmt-10"],"network/index-pack.c":["ex/HEAD/index-pack.html#git_oid_fmt-6"],"network/fetch.c":["ex/HEAD/fetch.html#git_oid_fmt-10","ex/HEAD/fetch.html#git_oid_fmt-11"]}},"git_oid_pathfmt":{"type":"function","file":"oid.h","line":96,"lineto":96,"args":[{"name":"str","type":"char *","comment":"output hex string; must be pointing at the start of the hex sequence and have at least the number of bytes needed for an oid encoded in hex (41 bytes). Only the oid digits are written; a '\\\\0' terminator must be added by the caller if it is required."},{"name":"oid","type":"const git_oid *","comment":"oid structure to format."}],"argline":"char *str, const git_oid *oid","sig":"char *::const git_oid *","return":{"type":"void"},"description":"Format a git_oid into a loose-object path string.","comments":"The resulting string is \"aa/...\", where \"aa\" is the first two\nhex digits of the oid and \"...\" is the remaining 38 digits.\n","group":"oid"},"git_oid_allocfmt":{"type":"function","file":"oid.h","line":105,"lineto":105,"args":[{"name":"oid","type":"const git_oid *","comment":"the oid structure to format"}],"argline":"const git_oid *oid","sig":"const git_oid *","return":{"type":"char *","comment":"the c-string; NULL if memory is exhausted. Caller must deallocate the string with git__free()."},"description":"Format a git_oid into a newly allocated c-string.","comments":"","group":"oid"},"git_oid_tostr":{"type":"function","file":"oid.h","line":122,"lineto":122,"args":[{"name":"out","type":"char *","comment":"the buffer into which the oid string is output."},{"name":"n","type":"size_t","comment":"the size of the out buffer."},{"name":"oid","type":"const git_oid *","comment":"the oid structure to format."}],"argline":"char *out, size_t n, const git_oid *oid","sig":"char *::size_t::const git_oid *","return":{"type":"char *","comment":"the out buffer pointer, assuming no input parameter errors, otherwise a pointer to an empty string."},"description":"Format a git_oid into a buffer as a hex format c-string.","comments":"If the buffer is smaller than GIT_OID_HEXSZ+1, then the resulting\noid c-string will be truncated to n-1 characters. If there are\nany input parameter errors (out == NULL, n == 0, oid == NULL),\nthen a pointer to an empty string is returned, so that the return\nvalue can always be printed.\n","group":"oid"},"git_oid_cpy":{"type":"function","file":"oid.h","line":130,"lineto":130,"args":[{"name":"out","type":"git_oid *","comment":"oid structure the result is written into."},{"name":"src","type":"const git_oid *","comment":"oid structure to copy from."}],"argline":"git_oid *out, const git_oid *src","sig":"git_oid *::const git_oid *","return":{"type":"void"},"description":"Copy an oid from one structure to another.","comments":"","group":"oid"},"git_oid_cmp":{"type":"function","file":"oid.h","line":139,"lineto":151,"args":[{"name":"a","type":"const git_oid *","comment":"first oid structure."},{"name":"b","type":"const git_oid *","comment":"second oid structure."}],"argline":"const git_oid *a, const git_oid *b","sig":"const git_oid *::const git_oid *","return":{"type":"int","comment":"<0, 0, >0 if a < b, a == b, a > b."},"description":"Compare two oid structures.","comments":"","group":"oid"},"git_oid_equal":{"type":"function","file":"oid.h","line":160,"lineto":163,"args":[{"name":"a","type":"const git_oid *","comment":"first oid structure."},{"name":"b","type":"const git_oid *","comment":"second oid structure."}],"argline":"const git_oid *a, const git_oid *b","sig":"const git_oid *::const git_oid *","return":{"type":"int","comment":"true if equal, false otherwise"},"description":"Compare two oid structures for equality","comments":"","group":"oid"},"git_oid_ncmp":{"type":"function","file":"oid.h","line":174,"lineto":174,"args":[{"name":"a","type":"const git_oid *","comment":"first oid structure."},{"name":"b","type":"const git_oid *","comment":"second oid structure."},{"name":"len","type":"size_t","comment":"the number of hex chars to compare"}],"argline":"const git_oid *a, const git_oid *b, size_t len","sig":"const git_oid *::const git_oid *::size_t","return":{"type":"int","comment":"0 in case of a match"},"description":"Compare the first 'len' hexadecimal characters (packets of 4 bits)\nof two oid structures.","comments":"","group":"oid"},"git_oid_streq":{"type":"function","file":"oid.h","line":184,"lineto":184,"args":[{"name":"a","type":"const git_oid *","comment":"oid structure."},{"name":"str","type":"const char *","comment":"input hex string of an object id."}],"argline":"const git_oid *a, const char *str","sig":"const git_oid *::const char *","return":{"type":"int","comment":"GIT_ENOTOID if str is not a valid hex string, 0 in case of a match, GIT_ERROR otherwise."},"description":"Check if an oid equals an hex formatted object id.","comments":"","group":"oid"},"git_oid_iszero":{"type":"function","file":"oid.h","line":191,"lineto":191,"args":[{"name":"a","type":"const git_oid *"}],"argline":"const git_oid *a","sig":"const git_oid *","return":{"type":"int","comment":"1 if all zeros, 0 otherwise."},"description":"Check is an oid is all zeros.","comments":"","group":"oid","examples":{"network/fetch.c":["ex/HEAD/fetch.html#git_oid_iszero-12"]}},"git_oid_shorten_new":{"type":"function","file":"oid.h","line":212,"lineto":212,"args":[{"name":"min_length","type":"size_t","comment":"The minimal length for all identifiers, which will be used even if shorter OIDs would still be unique."}],"argline":"size_t min_length","sig":"size_t","return":{"type":"git_oid_shorten *","comment":"a `git_oid_shorten` instance, NULL if OOM"},"description":"Create a new OID shortener.","comments":"The OID shortener is used to process a list of OIDs\nin text form and return the shortest length that would\nuniquely identify all of them.\n\nE.g. look at the result of `git log --abbrev`.\n","group":"oid"},"git_oid_shorten_add":{"type":"function","file":"oid.h","line":238,"lineto":238,"args":[{"name":"os","type":"git_oid_shorten *","comment":"a `git_oid_shorten` instance"},{"name":"text_oid","type":"const char *","comment":"an OID in text form"}],"argline":"git_oid_shorten *os, const char *text_oid","sig":"git_oid_shorten *::const char *","return":{"type":"int","comment":"the minimal length to uniquely identify all OIDs added so far to the set; or an error code (<0) if an error occurs."},"description":"Add a new OID to set of shortened OIDs and calculate\nthe minimal length to uniquely identify all the OIDs in\nthe set.","comments":"The OID is expected to be a 40-char hexadecimal string.\nThe OID is owned by the user and will not be modified\nor freed.\n\nFor performance reasons, there is a hard-limit of how many\nOIDs can be added to a single set (around ~22000, assuming\na mostly randomized distribution), which should be enough\nfor any kind of program, and keeps the algorithm fast and\nmemory-efficient.\n\nAttempting to add more than those OIDs will result in a\nGIT_ENOMEM error\n","group":"oid"},"git_oid_shorten_free":{"type":"function","file":"oid.h","line":245,"lineto":245,"args":[{"name":"os","type":"git_oid_shorten *","comment":"a `git_oid_shorten` instance"}],"argline":"git_oid_shorten *os","sig":"git_oid_shorten *","return":{"type":"void"},"description":"Free an OID shortener instance","comments":"","group":"oid"},"git_attr_get":{"type":"function","file":"attr.h","line":142,"lineto":147,"args":[{"name":"value_out","type":"const char **","comment":"Output of the value of the attribute. Use the GIT_ATTR_... macros to test for TRUE, FALSE, UNSPECIFIED, etc. or just use the string value for attributes set to a value. You should NOT modify or free this value."},{"name":"repo","type":"git_repository *","comment":"The repository containing the path."},{"name":"flags","type":"uint32_t","comment":"A combination of GIT_ATTR_CHECK... flags."},{"name":"path","type":"const char *","comment":"The path to check for attributes. Relative paths are interpreted relative to the repo root. The file does not have to exist, but if it does not, then it will be treated as a plain file (not a directory)."},{"name":"name","type":"const char *","comment":"The name of the attribute to look up."}],"argline":"const char **value_out,\n git_repository *repo,\n\tuint32_t flags,\n\tconst char *path,\n\tconst char *name","sig":"const char **::git_repository *::uint32_t::const char *::const char *","return":{"type":"int"},"description":"Look up the value of one git attribute for path.","comments":"","group":"attr"},"git_attr_get_many":{"type":"function","file":"attr.h","line":178,"lineto":184,"args":[{"name":"values_out","type":"const char **"},{"name":"repo","type":"git_repository *","comment":"The repository containing the path."},{"name":"flags","type":"uint32_t","comment":"A combination of GIT_ATTR_CHECK... flags."},{"name":"path","type":"const char *","comment":"The path inside the repo to check attributes. This does not have to exist, but if it does not, then it will be treated as a plain file (i.e. not a directory)."},{"name":"num_attr","type":"size_t","comment":"The number of attributes being looked up"},{"name":"names","type":"const char **","comment":"An array of num_attr strings containing attribute names."}],"argline":"const char **values_out,\n\tgit_repository *repo,\n\tuint32_t flags,\n\tconst char *path,\n\tsize_t num_attr,\n\tconst char **names","sig":"const char **::git_repository *::uint32_t::const char *::size_t::const char **","return":{"type":"int"},"description":"Look up a list of git attributes for path.","comments":"Use this if you have a known list of attributes that you want to\nlook up in a single call. This is somewhat more efficient than\ncalling `git_attr_get()` multiple times.\n\nFor example, you might write:\n\n const char *attrs[] = { \"crlf\", \"diff\", \"foo\" };\n const char **values[3];\n git_attr_get_many(values, repo, 0, \"my/fun/file.c\", 3, attrs);\n\nThen you could loop through the 3 values to get the settings for\nthe three attributes you asked about.\n","group":"attr"},"git_attr_foreach":{"type":"function","file":"attr.h","line":203,"lineto":208,"args":[{"name":"repo","type":"git_repository *","comment":"The repository containing the path."},{"name":"flags","type":"uint32_t","comment":"A combination of GIT_ATTR_CHECK... flags."},{"name":"path","type":"const char *","comment":"Path inside the repo to check attributes. This does not have to exist, but if it does not, then it will be treated as a plain file (i.e. not a directory)."},{"name":"callback","type":"int (*)(const char *name, const char *value, void *payload)","comment":"Function to invoke on each attribute name and value. The value may be NULL is the attribute is explicitly set to UNSPECIFIED using the '!' sign. Callback will be invoked only once per attribute name, even if there are multiple rules for a given file. The highest priority rule will be used. Return a non-zero value from this to stop looping."},{"name":"payload","type":"void *","comment":"Passed on as extra parameter to callback function."}],"argline":"git_repository *repo,\n\tuint32_t flags,\n\tconst char *path,\n\tint (*callback)(const char *name, const char *value, void *payload),\n\tvoid *payload","sig":"git_repository *::uint32_t::const char *::int (*)(const char *name, const char *value, void *payload)::void *","return":{"type":"int","comment":"0 on success, GIT_EUSER on non-zero callback, or error code"},"description":"Loop over all the git attributes for a path.","comments":"","group":"attr"},"git_attr_cache_flush":{"type":"function","file":"attr.h","line":218,"lineto":219,"args":[{"name":"repo","type":"git_repository *"}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"void"},"description":"Flush the gitattributes cache.","comments":"Call this if you have reason to believe that the attributes files on\ndisk no longer match the cached contents of memory. This will cause\nthe attributes files to be reloaded the next time that an attribute\naccess function is called.","group":"attr"},"git_attr_add_macro":{"type":"function","file":"attr.h","line":231,"lineto":234,"args":[{"name":"repo","type":"git_repository *"},{"name":"name","type":"const char *"},{"name":"values","type":"const char *"}],"argline":"git_repository *repo,\n\tconst char *name,\n\tconst char *values","sig":"git_repository *::const char *::const char *","return":{"type":"int"},"description":"Add a macro definition.","comments":"Macros will automatically be loaded from the top level `.gitattributes`\nfile of the repository (plus the build-in \"binary\" macro). This\nfunction allows you to add others. For example, to add the default\nmacro, you would call:\n\n git_attr_add_macro(repo, \"binary\", \"-diff -crlf\");","group":"attr"},"giterr_last":{"type":"function","file":"errors.h","line":67,"lineto":67,"args":[],"argline":"void","sig":"","return":{"type":"const git_error *","comment":"A git_error object."},"description":"Return the last `git_error` object that was generated for the\ncurrent thread or NULL if no error has occurred.","comments":"","group":"giterr","examples":{"network/git2.c":["ex/HEAD/git2.html#giterr_last-3","ex/HEAD/git2.html#giterr_last-4"]}},"giterr_clear":{"type":"function","file":"errors.h","line":72,"lineto":72,"args":[],"argline":"void","sig":"","return":{"type":"void"},"description":"Clear the last library error that occurred for this thread.","comments":"","group":"giterr"},"git_revwalk_new":{"type":"function","file":"revwalk.h","line":70,"lineto":70,"args":[{"name":"walker","type":"git_revwalk **","comment":"pointer to the new revision walker"},{"name":"repo","type":"git_repository *","comment":"the repo to walk through"}],"argline":"git_revwalk **walker, git_repository *repo","sig":"git_revwalk **::git_repository *","return":{"type":"int","comment":"0 or an error code"},"description":"Allocate a new revision walker to iterate through a repo.","comments":"This revision walker uses a custom memory pool and an internal\ncommit cache, so it is relatively expensive to allocate.\n\nFor maximum performance, this revision walker should be\nreused for different walks.\n\nThis revision walker is *not* thread safe: it may only be\nused to walk a repository on a single thread; however,\nit is possible to have several revision walkers in\nseveral different threads walking the same repository.\n","group":"revwalk","examples":{"general.c":["ex/HEAD/general.html#git_revwalk_new-68"]}},"git_revwalk_reset":{"type":"function","file":"revwalk.h","line":85,"lineto":85,"args":[{"name":"walker","type":"git_revwalk *","comment":"handle to reset."}],"argline":"git_revwalk *walker","sig":"git_revwalk *","return":{"type":"void"},"description":"Reset the revision walker for reuse.","comments":"This will clear all the pushed and hidden commits, and\nleave the walker in a blank state (just like at\ncreation) ready to receive new commit pushes and\nstart a new walk.\n\nThe revision walk is automatically reset when a walk\nis over.\n","group":"revwalk"},"git_revwalk_push":{"type":"function","file":"revwalk.h","line":102,"lineto":102,"args":[{"name":"walk","type":"git_revwalk *","comment":"the walker being used for the traversal."},{"name":"oid","type":"const git_oid *","comment":"the oid of the commit to start from."}],"argline":"git_revwalk *walk, const git_oid *oid","sig":"git_revwalk *::const git_oid *","return":{"type":"int","comment":"0 or an error code"},"description":"Mark a commit to start traversal from.","comments":"The given OID must belong to a commit on the walked\nrepository.\n\nThe given commit will be used as one of the roots\nwhen starting the revision walk. At least one commit\nmust be pushed the repository before a walk can\nbe started.\n","group":"revwalk","examples":{"general.c":["ex/HEAD/general.html#git_revwalk_push-69"]}},"git_revwalk_push_glob":{"type":"function","file":"revwalk.h","line":117,"lineto":117,"args":[{"name":"walk","type":"git_revwalk *","comment":"the walker being used for the traversal"},{"name":"glob","type":"const char *","comment":"the glob pattern references should match"}],"argline":"git_revwalk *walk, const char *glob","sig":"git_revwalk *::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Push matching references","comments":"The OIDs pointed to by the references that match the given glob\npattern will be pushed to the revision walker.\n\nA leading 'refs/' is implied if not present as well as a trailing\n'/ *' if the glob lacks '?', '*' or '['.\n","group":"revwalk"},"git_revwalk_push_head":{"type":"function","file":"revwalk.h","line":125,"lineto":125,"args":[{"name":"walk","type":"git_revwalk *","comment":"the walker being used for the traversal"}],"argline":"git_revwalk *walk","sig":"git_revwalk *","return":{"type":"int","comment":"0 or an error code"},"description":"Push the repository's HEAD","comments":"","group":"revwalk"},"git_revwalk_hide":{"type":"function","file":"revwalk.h","line":140,"lineto":140,"args":[{"name":"walk","type":"git_revwalk *","comment":"the walker being used for the traversal."},{"name":"oid","type":"const git_oid *","comment":"the oid of commit that will be ignored during the traversal"}],"argline":"git_revwalk *walk, const git_oid *oid","sig":"git_revwalk *::const git_oid *","return":{"type":"int","comment":"0 or an error code"},"description":"Mark a commit (and its ancestors) uninteresting for the output.","comments":"The given OID must belong to a commit on the walked\nrepository.\n\nThe resolved commit and all its parents will be hidden from the\noutput on the revision walk.\n","group":"revwalk"},"git_revwalk_hide_glob":{"type":"function","file":"revwalk.h","line":156,"lineto":156,"args":[{"name":"walk","type":"git_revwalk *","comment":"the walker being used for the traversal"},{"name":"glob","type":"const char *","comment":"the glob pattern references should match"}],"argline":"git_revwalk *walk, const char *glob","sig":"git_revwalk *::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Hide matching references.","comments":"The OIDs pointed to by the references that match the given glob\npattern and their ancestors will be hidden from the output on the\nrevision walk.\n\nA leading 'refs/' is implied if not present as well as a trailing\n'/ *' if the glob lacks '?', '*' or '['.\n","group":"revwalk"},"git_revwalk_hide_head":{"type":"function","file":"revwalk.h","line":164,"lineto":164,"args":[{"name":"walk","type":"git_revwalk *","comment":"the walker being used for the traversal"}],"argline":"git_revwalk *walk","sig":"git_revwalk *","return":{"type":"int","comment":"0 or an error code"},"description":"Hide the repository's HEAD","comments":"","group":"revwalk"},"git_revwalk_push_ref":{"type":"function","file":"revwalk.h","line":175,"lineto":175,"args":[{"name":"walk","type":"git_revwalk *","comment":"the walker being used for the traversal"},{"name":"refname","type":"const char *","comment":"the reference to push"}],"argline":"git_revwalk *walk, const char *refname","sig":"git_revwalk *::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Push the OID pointed to by a reference","comments":"The reference must point to a commit.\n","group":"revwalk"},"git_revwalk_hide_ref":{"type":"function","file":"revwalk.h","line":186,"lineto":186,"args":[{"name":"walk","type":"git_revwalk *","comment":"the walker being used for the traversal"},{"name":"refname","type":"const char *","comment":"the reference to hide"}],"argline":"git_revwalk *walk, const char *refname","sig":"git_revwalk *::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Hide the OID pointed to by a reference","comments":"The reference must point to a commit.\n","group":"revwalk"},"git_revwalk_next":{"type":"function","file":"revwalk.h","line":206,"lineto":206,"args":[{"name":"oid","type":"git_oid *","comment":"Pointer where to store the oid of the next commit"},{"name":"walk","type":"git_revwalk *","comment":"the walker to pop the commit from."}],"argline":"git_oid *oid, git_revwalk *walk","sig":"git_oid *::git_revwalk *","return":{"type":"int","comment":"0 if the next commit was found; GIT_ITEROVER if there are no commits left to iterate"},"description":"Get the next commit from the revision walk.","comments":"The initial call to this method is *not* blocking when\niterating through a repo with a time-sorting mode.\n\nIterating with Topological or inverted modes makes the initial\ncall blocking to preprocess the commit list, but this block should be\nmostly unnoticeable on most repositories (topological preprocessing\ntimes at 0.3s on the git.git repo).\n\nThe revision walker is reset when the walk is over.\n","group":"revwalk","examples":{"general.c":["ex/HEAD/general.html#git_revwalk_next-70"]}},"git_revwalk_sorting":{"type":"function","file":"revwalk.h","line":217,"lineto":217,"args":[{"name":"walk","type":"git_revwalk *","comment":"the walker being used for the traversal."},{"name":"sort_mode","type":"unsigned int","comment":"combination of GIT_SORT_XXX flags"}],"argline":"git_revwalk *walk, unsigned int sort_mode","sig":"git_revwalk *::unsigned int","return":{"type":"void"},"description":"Change the sorting mode when iterating through the\nrepository's contents.","comments":"Changing the sorting mode resets the walker.\n","group":"revwalk","examples":{"general.c":["ex/HEAD/general.html#git_revwalk_sorting-71"]}},"git_revwalk_free":{"type":"function","file":"revwalk.h","line":224,"lineto":224,"args":[{"name":"walk","type":"git_revwalk *","comment":"traversal handle to close. If NULL nothing occurs."}],"argline":"git_revwalk *walk","sig":"git_revwalk *","return":{"type":"void"},"description":"Free a revision walker previously allocated.","comments":"","group":"revwalk","examples":{"general.c":["ex/HEAD/general.html#git_revwalk_free-72"]}},"git_revwalk_repository":{"type":"function","file":"revwalk.h","line":233,"lineto":233,"args":[{"name":"walk","type":"git_revwalk *","comment":"the revision walker"}],"argline":"git_revwalk *walk","sig":"git_revwalk *","return":{"type":"git_repository *","comment":"the repository being walked"},"description":"Return the repository on which this walker\nis operating.","comments":"","group":"revwalk"},"git_object_lookup":{"type":"function","file":"object.h","line":41,"lineto":45,"args":[{"name":"object","type":"git_object **","comment":"pointer to the looked-up object"},{"name":"repo","type":"git_repository *","comment":"the repository to look up the object"},{"name":"id","type":"const git_oid *","comment":"the unique identifier for the object"},{"name":"type","type":"git_otype","comment":"the type of the object"}],"argline":"git_object **object,\n\t\tgit_repository *repo,\n\t\tconst git_oid *id,\n\t\tgit_otype type","sig":"git_object **::git_repository *::const git_oid *::git_otype","return":{"type":"int","comment":"a reference to the object"},"description":"Lookup a reference to one of the objects in a repository.","comments":"The generated reference is owned by the repository and\nshould be closed with the `git_object_free` method\ninstead of free'd manually.\n\nThe 'type' parameter must match the type of the object\nin the odb; the method will fail otherwise.\nThe special value 'GIT_OBJ_ANY' may be passed to let\nthe method guess the object's type.\n","group":"object","examples":{"diff.c":["ex/HEAD/diff.html#git_object_lookup-18"]}},"git_object_lookup_prefix":{"type":"function","file":"object.h","line":74,"lineto":79,"args":[{"name":"object_out","type":"git_object **","comment":"pointer where to store the looked-up object"},{"name":"repo","type":"git_repository *","comment":"the repository to look up the object"},{"name":"id","type":"const git_oid *","comment":"a short identifier for the object"},{"name":"len","type":"size_t","comment":"the length of the short identifier"},{"name":"type","type":"git_otype","comment":"the type of the object"}],"argline":"git_object **object_out,\n\t\tgit_repository *repo,\n\t\tconst git_oid *id,\n\t\tsize_t len,\n\t\tgit_otype type","sig":"git_object **::git_repository *::const git_oid *::size_t::git_otype","return":{"type":"int","comment":"0 or an error code"},"description":"Lookup a reference to one of the objects in a repository,\ngiven a prefix of its identifier (short id).","comments":"The object obtained will be so that its identifier\nmatches the first 'len' hexadecimal characters\n(packets of 4 bits) of the given 'id'.\n'len' must be at least GIT_OID_MINPREFIXLEN, and\nlong enough to identify a unique object matching\nthe prefix; otherwise the method will fail.\n\nThe generated reference is owned by the repository and\nshould be closed with the `git_object_free` method\ninstead of free'd manually.\n\nThe 'type' parameter must match the type of the object\nin the odb; the method will fail otherwise.\nThe special value 'GIT_OBJ_ANY' may be passed to let\nthe method guess the object's type.\n","group":"object","examples":{"diff.c":["ex/HEAD/diff.html#git_object_lookup_prefix-19"]}},"git_object_id":{"type":"function","file":"object.h","line":87,"lineto":87,"args":[{"name":"obj","type":"const git_object *","comment":"the repository object"}],"argline":"const git_object *obj","sig":"const git_object *","return":{"type":"const git_oid *","comment":"the SHA1 id"},"description":"Get the id (SHA1) of a repository object","comments":"","group":"object"},"git_object_type":{"type":"function","file":"object.h","line":95,"lineto":95,"args":[{"name":"obj","type":"const git_object *","comment":"the repository object"}],"argline":"const git_object *obj","sig":"const git_object *","return":{"type":"git_otype","comment":"the object's type"},"description":"Get the object type of an object","comments":"","group":"object","examples":{"diff.c":["ex/HEAD/diff.html#git_object_type-20"]}},"git_object_owner":{"type":"function","file":"object.h","line":109,"lineto":109,"args":[{"name":"obj","type":"const git_object *","comment":"the object"}],"argline":"const git_object *obj","sig":"const git_object *","return":{"type":"git_repository *","comment":"the repository who owns this object"},"description":"Get the repository that owns this object","comments":"Freeing or calling `git_repository_close` on the\nreturned pointer will invalidate the actual object.\n\nAny other operation may be run on the repository without\naffecting the object.\n","group":"object"},"git_object_free":{"type":"function","file":"object.h","line":126,"lineto":126,"args":[{"name":"object","type":"git_object *","comment":"the object to close"}],"argline":"git_object *object","sig":"git_object *","return":{"type":"void"},"description":"Close an open object","comments":"This method instructs the library to close an existing\nobject; note that git_objects are owned and cached by the repository\nso the object may or may not be freed after this library call,\ndepending on how aggressive is the caching mechanism used\nby the repository.\n\nIMPORTANT:\nIt *is* necessary to call this method when you stop using\nan object. Failure to do so will cause a memory leak.\n","group":"object","examples":{"general.c":["ex/HEAD/general.html#git_object_free-73"],"diff.c":["ex/HEAD/diff.html#git_object_free-21"]}},"git_object_type2string":{"type":"function","file":"object.h","line":137,"lineto":137,"args":[{"name":"type","type":"git_otype","comment":"object type to convert."}],"argline":"git_otype type","sig":"git_otype","return":{"type":"const char *","comment":"the corresponding string representation."},"description":"Convert an object type to it's string representation.","comments":"The result is a pointer to a string in static memory and\nshould not be free()'ed.\n","group":"object","examples":{"general.c":["ex/HEAD/general.html#git_object_type2string-74"]}},"git_object_string2type":{"type":"function","file":"object.h","line":145,"lineto":145,"args":[{"name":"str","type":"const char *","comment":"the string to convert."}],"argline":"const char *str","sig":"const char *","return":{"type":"git_otype","comment":"the corresponding git_otype."},"description":"Convert a string object type representation to it's git_otype.","comments":"","group":"object"},"git_object_typeisloose":{"type":"function","file":"object.h","line":154,"lineto":154,"args":[{"name":"type","type":"git_otype","comment":"object type to test."}],"argline":"git_otype type","sig":"git_otype","return":{"type":"int","comment":"true if the type represents a valid loose object type, false otherwise."},"description":"Determine if the given git_otype is a valid loose object type.","comments":"","group":"object"},"git_object__size":{"type":"function","file":"object.h","line":168,"lineto":168,"args":[{"name":"type","type":"git_otype","comment":"object type to get its size"}],"argline":"git_otype type","sig":"git_otype","return":{"type":"size_t","comment":"size in bytes of the object"},"description":"Get the size in bytes for the structure which\nacts as an in-memory representation of any given\nobject type.","comments":"For all the core types, this would the equivalent\nof calling `sizeof(git_commit)` if the core types\nwere not opaque on the external API.\n","group":"object"},"git_object_peel":{"type":"function","file":"object.h","line":185,"lineto":188,"args":[{"name":"peeled","type":"git_object **","comment":"Pointer to the peeled git_object"},{"name":"object","type":"git_object *","comment":"The object to be processed"},{"name":"target_type","type":"git_otype","comment":"The type of the requested object"}],"argline":"git_object **peeled,\n\t\tgit_object *object,\n\t\tgit_otype target_type","sig":"git_object **::git_object *::git_otype","return":{"type":"int","comment":"0 or an error code"},"description":"Recursively peel an object until an object of the specified type is met.","comments":"The retrieved `peeled` object is owned by the repository and should be\nclosed with the `git_object_free` method.\n\nIf you pass `GIT_OBJ_ANY` as the target type, then the object will be\npeeled until the type changes (e.g. a tag will be chased until the\nreferenced object is no longer a tag).\n","group":"object"},"git_reference_lookup":{"type":"function","file":"refs.h","line":33,"lineto":33,"args":[{"name":"reference_out","type":"git_reference **","comment":"pointer to the looked-up reference"},{"name":"repo","type":"git_repository *","comment":"the repository to look up the reference"},{"name":"name","type":"const char *","comment":"the long name for the reference (e.g. HEAD, ref/heads/master, refs/tags/v0.1.0, ...)"}],"argline":"git_reference **reference_out, git_repository *repo, const char *name","sig":"git_reference **::git_repository *::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Lookup a reference by its name in a repository.","comments":"The generated reference must be freed by the user.\n","group":"reference","examples":{"general.c":["ex/HEAD/general.html#git_reference_lookup-75"],"diff.c":["ex/HEAD/diff.html#git_reference_lookup-22"]}},"git_reference_name_to_oid":{"type":"function","file":"refs.h","line":43,"lineto":44,"args":[{"name":"out","type":"git_oid *"},{"name":"repo","type":"git_repository *","comment":"The repository in which to look up the reference"},{"name":"name","type":"const char *","comment":"The long name for the reference"}],"argline":"git_oid *out, git_repository *repo, const char *name","sig":"git_oid *::git_repository *::const char *","return":{"type":"int","comment":"0 on success, -1 if name could not be resolved"},"description":"Lookup a reference by name and resolve immediately to OID.","comments":"","group":"reference"},"git_reference_create_symbolic":{"type":"function","file":"refs.h","line":64,"lineto":64,"args":[{"name":"ref_out","type":"git_reference **","comment":"Pointer to the newly created reference"},{"name":"repo","type":"git_repository *","comment":"Repository where that reference will live"},{"name":"name","type":"const char *","comment":"The name of the reference"},{"name":"target","type":"const char *","comment":"The target of the reference"},{"name":"force","type":"int","comment":"Overwrite existing references"}],"argline":"git_reference **ref_out, git_repository *repo, const char *name, const char *target, int force","sig":"git_reference **::git_repository *::const char *::const char *::int","return":{"type":"int","comment":"0 or an error code"},"description":"Create a new symbolic reference.","comments":"The reference will be created in the repository and written\nto the disk.\n\nThe generated reference must be freed by the user.\n\nIf `force` is true and there already exists a reference\nwith the same name, it will be overwritten.\n","group":"reference"},"git_reference_create_oid":{"type":"function","file":"refs.h","line":84,"lineto":84,"args":[{"name":"ref_out","type":"git_reference **","comment":"Pointer to the newly created reference"},{"name":"repo","type":"git_repository *","comment":"Repository where that reference will live"},{"name":"name","type":"const char *","comment":"The name of the reference"},{"name":"id","type":"const git_oid *","comment":"The object id pointed to by the reference."},{"name":"force","type":"int","comment":"Overwrite existing references"}],"argline":"git_reference **ref_out, git_repository *repo, const char *name, const git_oid *id, int force","sig":"git_reference **::git_repository *::const char *::const git_oid *::int","return":{"type":"int","comment":"0 or an error code"},"description":"Create a new object id reference.","comments":"The reference will be created in the repository and written\nto the disk.\n\nThe generated reference must be freed by the user.\n\nIf `force` is true and there already exists a reference\nwith the same name, it will be overwritten.\n","group":"reference"},"git_reference_oid":{"type":"function","file":"refs.h","line":94,"lineto":94,"args":[{"name":"ref","type":"git_reference *","comment":"The reference"}],"argline":"git_reference *ref","sig":"git_reference *","return":{"type":"const git_oid *","comment":"a pointer to the oid if available, NULL otherwise"},"description":"Get the OID pointed to by a reference.","comments":"Only available if the reference is direct (i.e. not symbolic)\n","group":"reference","examples":{"general.c":["ex/HEAD/general.html#git_reference_oid-76"],"diff.c":["ex/HEAD/diff.html#git_reference_oid-23"]}},"git_reference_target":{"type":"function","file":"refs.h","line":104,"lineto":104,"args":[{"name":"ref","type":"git_reference *","comment":"The reference"}],"argline":"git_reference *ref","sig":"git_reference *","return":{"type":"const char *","comment":"a pointer to the name if available, NULL otherwise"},"description":"Get full name to the reference pointed by this reference","comments":"Only available if the reference is symbolic\n","group":"reference","examples":{"general.c":["ex/HEAD/general.html#git_reference_target-77"]}},"git_reference_type":{"type":"function","file":"refs.h","line":114,"lineto":114,"args":[{"name":"ref","type":"git_reference *","comment":"The reference"}],"argline":"git_reference *ref","sig":"git_reference *","return":{"type":"git_ref_t","comment":"the type"},"description":"Get the type of a reference","comments":"Either direct (GIT_REF_OID) or symbolic (GIT_REF_SYMBOLIC)\n","group":"reference","examples":{"general.c":["ex/HEAD/general.html#git_reference_type-78"]}},"git_reference_name":{"type":"function","file":"refs.h","line":122,"lineto":122,"args":[{"name":"ref","type":"git_reference *","comment":"The reference"}],"argline":"git_reference *ref","sig":"git_reference *","return":{"type":"const char *","comment":"the full name for the ref"},"description":"Get the full name of a reference","comments":"","group":"reference"},"git_reference_resolve":{"type":"function","file":"refs.h","line":142,"lineto":142,"args":[{"name":"resolved_ref","type":"git_reference **","comment":"Pointer to the peeled reference"},{"name":"ref","type":"git_reference *","comment":"The reference"}],"argline":"git_reference **resolved_ref, git_reference *ref","sig":"git_reference **::git_reference *","return":{"type":"int","comment":"0 or an error code"},"description":"Resolve a symbolic reference","comments":"This method iteratively peels a symbolic reference\nuntil it resolves to a direct reference to an OID.\n\nThe peeled reference is returned in the `resolved_ref`\nargument, and must be freed manually once it's no longer\nneeded.\n\nIf a direct reference is passed as an argument,\na copy of that reference is returned. This copy must\nbe manually freed too.\n","group":"reference","examples":{"diff.c":["ex/HEAD/diff.html#git_reference_resolve-24"]}},"git_reference_owner":{"type":"function","file":"refs.h","line":150,"lineto":150,"args":[{"name":"ref","type":"git_reference *","comment":"The reference"}],"argline":"git_reference *ref","sig":"git_reference *","return":{"type":"git_repository *","comment":"a pointer to the repo"},"description":"Get the repository where a reference resides","comments":"","group":"reference"},"git_reference_set_target":{"type":"function","file":"refs.h","line":165,"lineto":165,"args":[{"name":"ref","type":"git_reference *","comment":"The reference"},{"name":"target","type":"const char *","comment":"The new target for the reference"}],"argline":"git_reference *ref, const char *target","sig":"git_reference *::const char *","return":{"type":"int","comment":"0 or an error code"},"description":"Set the symbolic target of a reference.","comments":"The reference must be a symbolic reference, otherwise\nthis method will fail.\n\nThe reference will be automatically updated in\nmemory and on disk.\n","group":"reference"},"git_reference_set_oid":{"type":"function","file":"refs.h","line":180,"lineto":180,"args":[{"name":"ref","type":"git_reference *","comment":"The reference"},{"name":"id","type":"const git_oid *","comment":"The new target OID for the reference"}],"argline":"git_reference *ref, const git_oid *id","sig":"git_reference *::const git_oid *","return":{"type":"int","comment":"0 or an error code"},"description":"Set the OID target of a reference.","comments":"The reference must be a direct reference, otherwise\nthis method will fail.\n\nThe reference will be automatically updated in\nmemory and on disk.\n","group":"reference"},"git_reference_rename":{"type":"function","file":"refs.h","line":208,"lineto":208,"args":[{"name":"ref","type":"git_reference *","comment":"The reference to rename"},{"name":"new_name","type":"const char *","comment":"The new name for the reference"},{"name":"force","type":"int","comment":"Overwrite an existing reference"}],"argline":"git_reference *ref, const char *new_name, int force","sig":"git_reference *::const char *::int","return":{"type":"int","comment":"0 or an error code"},"description":"Rename an existing reference","comments":"This method works for both direct and symbolic references.\nThe new name will be checked for validity and may be\nmodified into a normalized form.\n\nThe given git_reference will be updated in place.\n\nThe reference will be immediately renamed in-memory\nand on disk.\n\nIf the `force` flag is not enabled, and there's already\na reference with the given name, the renaming will fail.\n\nIMPORTANT:\nThe user needs to write a proper reflog entry if the\nreflog is enabled for the repository. We only rename\nthe reflog if it exists.\n","group":"reference"},"git_reference_delete":{"type":"function","file":"refs.h","line":221,"lineto":221,"args":[{"name":"ref","type":"git_reference *","comment":"The reference to remove"}],"argline":"git_reference *ref","sig":"git_reference *","return":{"type":"int","comment":"0 or an error code"},"description":"Delete an existing reference","comments":"This method works for both direct and symbolic references.\n\nThe reference will be immediately removed on disk and from\nmemory. The given reference pointer will no longer be valid.\n","group":"reference"},"git_reference_packall":{"type":"function","file":"refs.h","line":236,"lineto":236,"args":[{"name":"repo","type":"git_repository *","comment":"Repository where the loose refs will be packed"}],"argline":"git_repository *repo","sig":"git_repository *","return":{"type":"int","comment":"0 or an error code"},"description":"Pack all the loose references in the repository","comments":"This method will load into the cache all the loose\nreferences on the repository and update the\n`packed-refs` file with them.\n\nOnce the `packed-refs` file has been written properly,\nthe loose references will be removed from disk.\n","group":"reference"},"git_reference_list":{"type":"function","file":"refs.h","line":259,"lineto":259,"args":[{"name":"array","type":"git_strarray *","comment":"Pointer to a git_strarray structure where the reference names will be stored"},{"name":"repo","type":"git_repository *","comment":"Repository where to find the refs"},{"name":"list_flags","type":"unsigned int","comment":"Filtering flags for the reference listing."}],"argline":"git_strarray *array, git_repository *repo, unsigned int list_flags","sig":"git_strarray *::git_repository *::unsigned int","return":{"type":"int","comment":"0 or an error code"},"description":"Fill a list with all the references that can be found\nin a repository.","comments":"The listed references may be filtered by type, or using\na bitwise OR of several types. Use the magic value\n`GIT_REF_LISTALL` to obtain all references, including\npacked ones.\n\nThe string array will be filled with the names of all\nreferences; these values are owned by the user and\nshould be free'd manually when no longer needed, using\n`git_strarray_free`.\n","group":"reference","examples":{"general.c":["ex/HEAD/general.html#git_reference_list-79"]}},"git_reference_foreach":{"type":"function","file":"refs.h","line":281,"lineto":281,"args":[{"name":"repo","type":"git_repository *","comment":"Repository where to find the refs"},{"name":"list_flags","type":"unsigned int","comment":"Filtering flags for the reference listing."},{"name":"callback","type":"int (*)(const char *, void *)","comment":"Function which will be called for every listed ref"},{"name":"payload","type":"void *","comment":"Additional data to pass to the callback"}],"argline":"git_repository *repo, unsigned int list_flags, int (*callback)(const char *, void *), void *payload","sig":"git_repository *::unsigned int::int (*)(const char *, void *)::void *","return":{"type":"int","comment":"0 on success, GIT_EUSER on non-zero callback, or error code"},"description":"Perform an operation on each reference in the repository","comments":"The processed references may be filtered by type, or using\na bitwise OR of several types. Use the magic value\n`GIT_REF_LISTALL` to obtain all references, including\npacked ones.\n\nThe `callback` function will be called for each of the references\nin the repository, and will receive the name of the reference and\nthe `payload` value passed to this method. Returning a non-zero\nvalue from the callback will terminate the iteration.\n","group":"reference"},"git_reference_is_packed":{"type":"function","file":"refs.h","line":289,"lineto":289,"args":[{"name":"ref","type":"git_reference *","comment":"A git reference"}],"argline":"git_reference *ref","sig":"git_reference *","return":{"type":"int","comment":"0 in case it's not packed; 1 otherwise"},"description":"Check if a reference has been loaded from a packfile","comments":"","group":"reference"},"git_reference_reload":{"type":"function","file":"refs.h","line":309,"lineto":309,"args":[{"name":"ref","type":"git_reference *","comment":"The reference to reload"}],"argline":"git_reference *ref","sig":"git_reference *","return":{"type":"int","comment":"0 on success, or an error code"},"description":"Reload a reference from disk","comments":"Reference pointers may become outdated if the Git\nrepository is accessed simultaneously by other clients\nwhile the library is open.\n\nThis method forces a reload of the reference from disk,\nto ensure that the provided information is still\nreliable.\n\nIf the reload fails (e.g. the reference no longer exists\non disk, or has become corrupted), an error code will be\nreturned and the reference pointer will be invalidated.\n","group":"reference"},"git_reference_free":{"type":"function","file":"refs.h","line":316,"lineto":316,"args":[{"name":"ref","type":"git_reference *","comment":"git_reference"}],"argline":"git_reference *ref","sig":"git_reference *","return":{"type":"void"},"description":"Free the given reference","comments":"","group":"reference","examples":{"diff.c":["ex/HEAD/diff.html#git_reference_free-25","ex/HEAD/diff.html#git_reference_free-26"]}},"git_reference_cmp":{"type":"function","file":"refs.h","line":325,"lineto":325,"args":[{"name":"ref1","type":"git_reference *","comment":"The first git_reference"},{"name":"ref2","type":"git_reference *","comment":"The second git_reference"}],"argline":"git_reference *ref1, git_reference *ref2","sig":"git_reference *::git_reference *","return":{"type":"int","comment":"0 if the same, else a stable but meaningless ordering."},"description":"Compare two references.","comments":"","group":"reference"},"git_reference_foreach_glob":{"type":"function","file":"refs.h","line":349,"lineto":357,"args":[{"name":"repo","type":"git_repository *","comment":"Repository where to find the references."},{"name":"glob","type":"const char *","comment":"Glob pattern references should match."},{"name":"list_flags","type":"unsigned int","comment":"Filtering flags for the reference listing."},{"name":"callback","type":"int (*)(\n\t\t\tconst char *reference_name,\n\t\t\tvoid *payload)","comment":"Callback to invoke per found reference."},{"name":"payload","type":"void *","comment":"Extra parameter to callback function."}],"argline":"git_repository *repo,\n\t\tconst char *glob,\n\t\tunsigned int list_flags,\n\t\tint (*callback)(\n\t\t\tconst char *reference_name,\n\t\t\tvoid *payload),\n\t\tvoid *payload","sig":"git_repository *::const char *::unsigned int::int (*)(\n\t\t\tconst char *reference_name,\n\t\t\tvoid *payload)::void *","return":{"type":"int","comment":"0 or an error code."},"description":"Loop over all the references and issue a callback for each one\nwhich name matches the given glob pattern.","comments":"The processed references may be filtered by type, or using\na bitwise OR of several types. Use the magic value\n`GIT_REF_LISTALL` to obtain all references, including\npacked ones.\n","group":"reference"},"git_reference_has_log":{"type":"function","file":"refs.h","line":367,"lineto":367,"args":[{"name":"ref","type":"git_reference *","comment":"A git reference"}],"argline":"git_reference *ref","sig":"git_reference *","return":{"type":"int","comment":"0 when no reflog can be found, 1 when it exists; otherwise an error code."},"description":"Check if a reflog exists for the specified reference.","comments":"","group":"reference"},"git_reference_is_branch":{"type":"function","file":"refs.h","line":377,"lineto":377,"args":[{"name":"ref","type":"git_reference *","comment":"A git reference"}],"argline":"git_reference *ref","sig":"git_reference *","return":{"type":"int","comment":"1 when the reference lives in the refs/heads namespace; 0 otherwise."},"description":"Check if a reference is a local branch.","comments":"","group":"reference"},"git_reference_is_remote":{"type":"function","file":"refs.h","line":387,"lineto":390,"args":[{"name":"ref","type":"git_reference *","comment":"A git reference"}],"argline":"git_reference *ref","sig":"git_reference *","return":{"type":"int","comment":"1 when the reference lives in the refs/remotes namespace; 0 otherwise."},"description":"Check if a reference is a remote tracking branch","comments":"","group":"reference"},"git_reference_normalize_name":{"type":"function","file":"refs.h","line":431,"lineto":435,"args":[{"name":"buffer_out","type":"char *","comment":"The user allocated buffer where the normalized name will be stored."},{"name":"buffer_size","type":"size_t","comment":"buffer_out size"},{"name":"name","type":"const char *","comment":"name to be checked."},{"name":"flags","type":"unsigned int","comment":"Flags to determine the options to be applied while checking the validatity of the name."}],"argline":"char *buffer_out,\n\tsize_t buffer_size,\n\tconst char *name,\n\tunsigned int flags","sig":"char *::size_t::const char *::unsigned int","return":{"type":"int","comment":"0 or an error code."},"description":"Normalize the reference name by removing any leading\nslash (/) characters and collapsing runs of adjacent slashes\nbetween name components into a single slash.","comments":"Once normalized, if the reference name is valid, it will be\nreturned in the user allocated buffer.\n\nTODO: Implement handling of GIT_REF_FORMAT_REFSPEC_PATTERN\n","group":"reference"},"git_reference_peel":{"type":"function","file":"refs.h","line":452,"lineto":455,"args":[{"name":"out","type":"git_object **"},{"name":"ref","type":"git_reference *","comment":"The reference to be processed"},{"name":"type","type":"git_otype"}],"argline":"git_object **out,\n\tgit_reference *ref,\n\tgit_otype type","sig":"git_object **::git_reference *::git_otype","return":{"type":"int","comment":"0 or an error code"},"description":"Recursively peel an reference until an object of the\nspecified type is met.","comments":"The retrieved `peeled` object is owned by the repository\nand should be closed with the `git_object_free` method.\n\nIf you pass `GIT_OBJ_ANY` as the target type, then the object\nwill be peeled until a non-tag object is met.\n","group":"reference"}},"globals":{"GIT_BEGIN_DECL":{"value":"","file":"common.h","line":24,"comments":"Start declarations in C mode"},"GIT_END_DECL":{"value":"","file":"common.h","line":26,"comments":"End declarations in C mode"},"GIT_EXTERN(type)":{"value":"extern __attribute__((visibility(\"default\"))) type","file":"common.h","line":30,"comments":"Declare a public function exported for application use."},"GIT_INLINE(type)":{"value":"static __inline type","file":"common.h","line":41,"comments":"Declare a function as always inlined."},"GIT_FORMAT_PRINTF(a,b)":{"value":"__attribute__((format (printf, a, b)))","file":"common.h","line":48,"comments":"Declare a function's takes printf style arguments."},"GIT_PATH_LIST_SEPARATOR":{"value":"';'","file":"common.h","line":77,"comments":"The separator used in path list strings (ie like in the PATH\nenvironment variable). A semi-colon \";\" is used on Windows, and\na colon \":\" for all other systems."},"GIT_PATH_MAX":{"value":"4096","file":"common.h","line":86,"comments":"The maximum length of a valid git path."},"GIT_CAP_THREADS":{"file":"common.h","line":110,"value":"( 1 << 0 )","comments":"Combinations of these values describe the capabilities of libgit2."},"GIT_CAP_HTTPS":{"file":"common.h","line":111,"value":"( 1 << 1 )\n","comments":"Combinations of these values describe the capabilities of libgit2."},"GIT_INDEXCAP_IGNORE_CASE":{"file":"index.h","line":96,"value":"1","comments":"Capabilities of system that affect index actions."},"GIT_INDEXCAP_NO_FILEMODE":{"file":"index.h","line":97,"value":"2","comments":"Capabilities of system that affect index actions."},"GIT_INDEXCAP_NO_SYMLINKS":{"file":"index.h","line":98,"value":"4","comments":"Capabilities of system that affect index actions."},"GIT_INDEXCAP_FROM_OWNER":{"file":"index.h","line":99,"value":"~0u\n","comments":"Capabilities of system that affect index actions."},"GIT_STREAM_RDONLY":{"file":"odb_backend.h","line":89,"value":"(1 << 1)","comments":"Streaming mode"},"GIT_STREAM_WRONLY":{"file":"odb_backend.h","line":90,"value":"(1 << 2)","comments":"Streaming mode"},"GIT_STREAM_RW":{"file":"odb_backend.h","line":91,"value":"(GIT_STREAM_RDONLY | GIT_STREAM_WRONLY)","comments":"Streaming mode"},"GIT_DIFF_NORMAL":{"file":"diff.h","line":37,"value":"0","comments":"Flags for diff options. A combination of these flags can be passed\nin via the `flags` value in the `git_diff_options`."},"GIT_DIFF_REVERSE":{"file":"diff.h","line":38,"value":"(1 << 0)","comments":"Flags for diff options. A combination of these flags can be passed\nin via the `flags` value in the `git_diff_options`."},"GIT_DIFF_FORCE_TEXT":{"file":"diff.h","line":39,"value":"(1 << 1)","comments":"Flags for diff options. A combination of these flags can be passed\nin via the `flags` value in the `git_diff_options`."},"GIT_DIFF_IGNORE_WHITESPACE":{"file":"diff.h","line":40,"value":"(1 << 2)","comments":"Flags for diff options. A combination of these flags can be passed\nin via the `flags` value in the `git_diff_options`."},"GIT_DIFF_IGNORE_WHITESPACE_CHANGE":{"file":"diff.h","line":41,"value":"(1 << 3)","comments":"Flags for diff options. A combination of these flags can be passed\nin via the `flags` value in the `git_diff_options`."},"GIT_DIFF_IGNORE_WHITESPACE_EOL":{"file":"diff.h","line":42,"value":"(1 << 4)","comments":"Flags for diff options. A combination of these flags can be passed\nin via the `flags` value in the `git_diff_options`."},"GIT_DIFF_IGNORE_SUBMODULES":{"file":"diff.h","line":43,"value":"(1 << 5)","comments":"Flags for diff options. A combination of these flags can be passed\nin via the `flags` value in the `git_diff_options`."},"GIT_DIFF_PATIENCE":{"file":"diff.h","line":44,"value":"(1 << 6)","comments":"Flags for diff options. A combination of these flags can be passed\nin via the `flags` value in the `git_diff_options`."},"GIT_DIFF_INCLUDE_IGNORED":{"file":"diff.h","line":45,"value":"(1 << 7)","comments":"Flags for diff options. A combination of these flags can be passed\nin via the `flags` value in the `git_diff_options`."},"GIT_DIFF_INCLUDE_UNTRACKED":{"file":"diff.h","line":46,"value":"(1 << 8)","comments":"Flags for diff options. A combination of these flags can be passed\nin via the `flags` value in the `git_diff_options`."},"GIT_DIFF_INCLUDE_UNMODIFIED":{"file":"diff.h","line":47,"value":"(1 << 9)","comments":"Flags for diff options. A combination of these flags can be passed\nin via the `flags` value in the `git_diff_options`."},"GIT_DIFF_RECURSE_UNTRACKED_DIRS":{"file":"diff.h","line":48,"value":"(1 << 10)","comments":"Flags for diff options. A combination of these flags can be passed\nin via the `flags` value in the `git_diff_options`."},"GIT_DIFF_DISABLE_PATHSPEC_MATCH":{"file":"diff.h","line":49,"value":"(1 << 11)","comments":"Flags for diff options. A combination of these flags can be passed\nin via the `flags` value in the `git_diff_options`."},"GIT_OID_RAWSZ":{"value":"20","file":"oid.h","line":23,"comments":"Size (in bytes) of a raw/binary oid"},"GIT_OID_HEXSZ":{"value":"(GIT_OID_RAWSZ * 2)","file":"oid.h","line":26,"comments":"Size (in bytes) of a hex formatted oid"},"GIT_OID_MINPREFIXLEN":{"value":"4","file":"oid.h","line":30,"comments":"Minimum length (in number of hex characters,\ni.e. packets of 4 bits) of an oid prefix"},"GIT_ATTR_TRUE(attr)":{"value":"(git_attr_value(attr) == GIT_ATTR_TRUE_T)","file":"attr.h","line":33,"comments":"GIT_ATTR_TRUE checks if an attribute is set on. In core git\nparlance, this the value for \"Set\" attributes.\n\nFor example, if the attribute file contains:\n\n *.c foo\n\nThen for file `xyz.c` looking up attribute \"foo\" gives a value for\nwhich `GIT_ATTR_TRUE(value)` is true."},"GIT_ATTR_FALSE(attr)":{"value":"(git_attr_value(attr) == GIT_ATTR_FALSE_T)","file":"attr.h","line":47,"comments":"GIT_ATTR_FALSE checks if an attribute is set off. In core git\nparlance, this is the value for attributes that are \"Unset\" (not to\nbe confused with values that a \"Unspecified\").\n\nFor example, if the attribute file contains:\n\n *.h -foo\n\nThen for file `zyx.h` looking up attribute \"foo\" gives a value for\nwhich `GIT_ATTR_FALSE(value)` is true."},"GIT_ATTR_UNSPECIFIED(attr)":{"value":"(git_attr_value(attr) == GIT_ATTR_UNSPECIFIED_T)","file":"attr.h","line":65,"comments":"GIT_ATTR_UNSPECIFIED checks if an attribute is unspecified. This\nmay be due to the attribute not being mentioned at all or because\nthe attribute was explicitly set unspecified via the `!` operator.\n\nFor example, if the attribute file contains:\n\n *.c foo\n *.h -foo\n onefile.c !foo\n\nThen for `onefile.c` looking up attribute \"foo\" yields a value with\n`GIT_ATTR_UNSPECIFIED(value)` of true. Also, looking up \"foo\" on\nfile `onefile.rb` or looking up \"bar\" on any file will all give\n`GIT_ATTR_UNSPECIFIED(value)` of true."},"GIT_ATTR_HAS_VALUE(attr)":{"value":"(git_attr_value(attr) == GIT_ATTR_VALUE_T)","file":"attr.h","line":77,"comments":"GIT_ATTR_HAS_VALUE checks if an attribute is set to a value (as\nopposed to TRUE, FALSE or UNSPECIFIED). This would be the case if\nfor a file with something like:\n\n *.txt eol=lf\n\nGiven this, looking up \"eol\" for `onefile.txt` will give back the\nstring \"lf\" and `GIT_ATTR_SET_TO_VALUE(attr)` will return true."},"GIT_ATTR_CHECK_NO_SYSTEM":{"value":"(1 << 2)","file":"attr.h","line":125,"comments":"Check attribute flags: Using the system attributes file.\n\nNormally, attribute checks include looking in the /etc (or system\nequivalent) directory for a `gitattributes` file. Passing this\nflag will cause attribute checks to ignore that file."},"GIT_OK":{"file":"errors.h","line":22,"value":"0","comments":"Generic return codes"},"GIT_ERROR":{"file":"errors.h","line":23,"value":"-1","comments":"Generic return codes"},"GIT_ENOTFOUND":{"file":"errors.h","line":24,"value":"-3","comments":"Generic return codes"},"GIT_EEXISTS":{"file":"errors.h","line":25,"value":"-4","comments":"Generic return codes"},"GIT_EAMBIGUOUS":{"file":"errors.h","line":26,"value":"-5","comments":"Generic return codes"},"GIT_EBUFS":{"file":"errors.h","line":27,"value":"-6","comments":"Generic return codes"},"GIT_EUSER":{"file":"errors.h","line":28,"value":"-7","comments":"Generic return codes"},"GIT_EBAREREPO":{"file":"errors.h","line":29,"value":"-8","comments":"Generic return codes"},"GIT_PASSTHROUGH":{"file":"errors.h","line":31,"value":"-30","comments":"Generic return codes"},"GIT_ITEROVER":{"file":"errors.h","line":32,"value":"-31","comments":"Generic return codes"},"GIT_SORT_NONE":{"value":"(0)","file":"revwalk.h","line":29,"comments":"Sort the repository contents in no particular ordering;\nthis sorting is arbitrary, implementation-specific\nand subject to change at any time.\nThis is the default sorting for new walkers."},"GIT_SORT_TOPOLOGICAL":{"value":"(1 << 0)","file":"revwalk.h","line":36,"comments":"Sort the repository contents in topological order\n(parents before children); this sorting mode\ncan be combined with time sorting."},"GIT_SORT_TIME":{"value":"(1 << 1)","file":"revwalk.h","line":43,"comments":"Sort the repository contents by commit time;\nthis sorting mode can be combined with\ntopological sorting."},"GIT_SORT_REVERSE":{"value":"(1 << 2)","file":"revwalk.h","line":50,"comments":"Iterate through the repository contents in reverse\norder; this sorting mode can be combined with\nany of the above."}},"types":[["GIT_ATTR_CHECK",{"type":"enum","file":"attr.h","line":114,"lineto":116,"block":"GIT_ATTR_CHECK_FILE_THEN_INDEX\nGIT_ATTR_CHECK_INDEX_THEN_FILE\nGIT_ATTR_CHECK_INDEX_ONLY","tdef":null,"comments":"Check attribute flags: Reading values from index and working directory.\n\nWhen checking attributes, it is possible to check attribute files\nin both the working directory (if there is one) and the index (if\nthere is one). You can explicitly choose where to check and in\nwhich order using the following flags.\n\nCore git usually checks the working directory then the index,\nexcept during a checkout when it checks the index first. It will\nuse index only for creating archives or for a bare repo (if an\nindex has been specified for the bare repo).","used":{"returns":[],"needs":[]}}],["GIT_DIFF_FILE",{"type":"enum","file":"diff.h","line":96,"lineto":104,"block":"GIT_DIFF_FILE_VALID_OID\nGIT_DIFF_FILE_FREE_PATH\nGIT_DIFF_FILE_BINARY\nGIT_DIFF_FILE_NOT_BINARY\nGIT_DIFF_FILE_FREE_DATA\nGIT_DIFF_FILE_UNMAP_DATA\nGIT_DIFF_FILE_NO_DATA","tdef":null,"comments":"Flags that can be set for the file on side of a diff.\n\nMost of the flags are just for internal consumption by libgit2,\nbut some of them may be interesting to external users. They are:\n\n- VALID_OID - the `oid` value is computed and correct\n- FREE_PATH - the `path` string is separated allocated memory\n- BINARY - this file should be considered binary data\n- NOT_BINARY - this file should be considered text data\n- FREE_DATA - the internal file data is kept in allocated memory\n- UNMAP_DATA - the internal file data is kept in mmap'ed memory\n- NO_DATA - this side of the diff should not be loaded","used":{"returns":[],"needs":[]}}],["GIT_DIFF_LINE",{"type":"enum","file":"diff.h","line":189,"lineto":204,"block":"GIT_DIFF_LINE_CONTEXT\nGIT_DIFF_LINE_ADDITION\nGIT_DIFF_LINE_DELETION\nGIT_DIFF_LINE_ADD_EOFNL\nGIT_DIFF_LINE_DEL_EOFNL\nGIT_DIFF_LINE_FILE_HDR\nGIT_DIFF_LINE_HUNK_HDR\nGIT_DIFF_LINE_BINARY","tdef":null,"comments":"Line origin constants.\n\nThese values describe where a line came from and will be passed to\nthe git_diff_data_fn when iterating over a diff. There are some\nspecial origin constants at the end that are used for the text\noutput callbacks to demarcate lines that are actually part of\nthe file or hunk headers.","used":{"returns":[],"needs":[]}}],["GIT_REPOSITORY_INIT",{"type":"enum","file":"repository.h","line":185,"lineto":192,"block":"GIT_REPOSITORY_INIT_BARE\nGIT_REPOSITORY_INIT_NO_REINIT\nGIT_REPOSITORY_INIT_NO_DOTGIT_DIR\nGIT_REPOSITORY_INIT_MKDIR\nGIT_REPOSITORY_INIT_MKPATH\nGIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE","tdef":null,"comments":"Option flags for `git_repository_init_ext`.\n\nThese flags configure extra behaviors to `git_repository_init_ext`.\nIn every case, the default behavior is the zero value (i.e. flag is\nnot set). Just OR the flag values together for the `flags` parameter\nwhen initializing a new repo. Details of individual values are:\n\n* BARE - Create a bare repository with no working directory.\n* NO_REINIT - Return an EEXISTS error if the repo_path appears to\n already be an git repository.\n* NO_DOTGIT_DIR - Normally a \"/.git/\" will be appended to the repo\n path for non-bare repos (if it is not already there), but\n passing this flag prevents that behavior.\n* MKDIR - Make the repo_path (and workdir_path) as needed. Init is\n always willing to create the \".git\" directory even without this\n flag. This flag tells init to create the trailing component of\n the repo and workdir paths as needed.\n* MKPATH - Recursively make all components of the repo and workdir\n paths as necessary.\n* EXTERNAL_TEMPLATE - libgit2 normally uses internal templates to\n initialize a new repo. This flags enables external templates,\n looking the \"template_path\" from the options if set, or the\n `init.templatedir` global config if not, or falling back on\n \"/usr/share/git-core/templates\" if it exists.","used":{"returns":[],"needs":[]}}],["GIT_REPOSITORY_INIT_SHARED",{"type":"enum","file":"repository.h","line":207,"lineto":211,"block":"GIT_REPOSITORY_INIT_SHARED_UMASK\nGIT_REPOSITORY_INIT_SHARED_GROUP\nGIT_REPOSITORY_INIT_SHARED_ALL","tdef":null,"comments":"Mode options for `git_repository_init_ext`.\n\nSet the mode field of the `git_repository_init_options` structure\neither to the custom mode that you would like, or to one of the\nfollowing modes:\n\n* SHARED_UMASK - Use permissions configured by umask - the default.\n* SHARED_GROUP - Use \"--shared=group\" behavior, chmod'ing the new repo\n to be group writable and \"g+sx\" for sticky group assignment.\n* SHARED_ALL - Use \"--shared=all\" behavior, adding world readability.\n* Anything else - Set to custom value.","used":{"returns":[],"needs":[]}}],["GIT_REPOSITORY_OPEN",{"type":"enum","file":"repository.h","line":98,"lineto":101,"block":"GIT_REPOSITORY_OPEN_NO_SEARCH\nGIT_REPOSITORY_OPEN_CROSS_FS","tdef":null,"comments":"Option flags for `git_repository_open_ext`.\n\n* GIT_REPOSITORY_OPEN_NO_SEARCH - Only open the repository if it can be\n immediately found in the start_path. Do not walk up from the\n start_path looking at parent directories.\n* GIT_REPOSITORY_OPEN_CROSS_FS - Unless this flag is set, open will not\n continue searching across filesystem boundaries (i.e. when `st_dev`\n changes from the `stat` system call). (E.g. Searching in a user's home\n directory \"/home/user/source/\" will not return \"/.git/\" as the found\n repo if \"/\" is a different filesystem than \"/home\".)","used":{"returns":[],"needs":[]}}],["GIT_STATUS_OPT",{"type":"enum","file":"status.h","line":102,"lineto":109,"block":"GIT_STATUS_OPT_INCLUDE_UNTRACKED\nGIT_STATUS_OPT_INCLUDE_IGNORED\nGIT_STATUS_OPT_INCLUDE_UNMODIFIED\nGIT_STATUS_OPT_EXCLUDE_SUBMODULES\nGIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS\nGIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH","tdef":null,"comments":"Flags to control status callbacks\n\n- GIT_STATUS_OPT_INCLUDE_UNTRACKED says that callbacks should\n be made on untracked files. These will only be made if the\n workdir files are included in the status \"show\" option.\n- GIT_STATUS_OPT_INCLUDE_IGNORED says that ignored files should\n get callbacks. Again, these callbacks will only be made if\n the workdir files are included in the status \"show\" option.\n Right now, there is no option to include all files in\n directories that are ignored completely.\n- GIT_STATUS_OPT_INCLUDE_UNMODIFIED indicates that callback\n should be made even on unmodified files.\n- GIT_STATUS_OPT_EXCLUDE_SUBMODULES indicates that directories\n which appear to be submodules should just be skipped over.\n- GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS indicates that the\n contents of untracked directories should be included in the\n status. Normally if an entire directory is new, then just\n the top-level directory will be included (with a trailing\n slash on the entry name). Given this flag, the directory\n itself will not be included, but all the files in it will.\n- GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH indicates that the given\n path will be treated as a literal path, and not as a pathspec.","used":{"returns":[],"needs":[]}}],["git_blob",{"type":"struct","value":"git_blob","file":"types.h","line":108,"lineto":108,"block":"","tdef":"typedef","comments":"In-memory representation of a blob object.","used":{"returns":[],"needs":["git_blob_free","git_blob_lookup","git_blob_lookup_prefix","git_blob_rawcontent","git_blob_rawsize","git_diff_blobs"]}}],["git_branch_t",{"type":"enum","file":"types.h","line":167,"lineto":170,"block":"GIT_BRANCH_LOCAL\nGIT_BRANCH_REMOTE","tdef":"typedef","comments":"Basic type of any Git branch.","used":{"returns":[],"needs":["git_branch_foreach","git_branch_lookup"]}}],["git_commit",{"type":"struct","value":"git_commit","file":"types.h","line":111,"lineto":111,"block":"","tdef":"typedef","comments":"Parsed representation of a commit object.","used":{"returns":[],"needs":["git_commit_author","git_commit_committer","git_commit_create","git_commit_free","git_commit_id","git_commit_lookup","git_commit_lookup_prefix","git_commit_message","git_commit_message_encoding","git_commit_nth_gen_ancestor","git_commit_parent","git_commit_parent_oid","git_commit_parentcount","git_commit_time","git_commit_time_offset","git_commit_tree","git_commit_tree_oid"]}}],["git_config",{"type":"struct","value":"git_config","file":"types.h","line":126,"lineto":126,"block":"","tdef":"typedef","comments":"Memory representation of a set of config files","used":{"returns":[],"needs":["git_config_add_file","git_config_add_file_ondisk","git_config_delete","git_config_foreach","git_config_foreach_match","git_config_free","git_config_get_bool","git_config_get_int32","git_config_get_int64","git_config_get_mapped","git_config_get_multivar","git_config_get_string","git_config_new","git_config_open_default","git_config_open_ondisk","git_config_set_bool","git_config_set_int32","git_config_set_int64","git_config_set_multivar","git_config_set_string","git_repository_config","git_repository_set_config"]}}],["git_config_file",{"type":"struct","value":"git_config_file","file":"types.h","line":129,"lineto":129,"block":"","tdef":"typedef","comments":"Interface to access a configuration file","used":{"returns":[],"needs":["git_config_add_file","git_config_file__ondisk"]}}],["git_delta_t",{"type":"enum","file":"diff.h","line":109,"lineto":118,"block":"GIT_DELTA_UNMODIFIED\nGIT_DELTA_ADDED\nGIT_DELTA_DELETED\nGIT_DELTA_MODIFIED\nGIT_DELTA_RENAMED\nGIT_DELTA_COPIED\nGIT_DELTA_IGNORED\nGIT_DELTA_UNTRACKED","tdef":"typedef","comments":"What type of change is described by a git_diff_delta?","used":{"returns":[],"needs":[]}}],["git_diff_data_fn",{"type":"function pointer","value":"git_diff_data_fn","file":"diff.h","line":214,"lineto":220,"comments":"When iterating over a diff, callback that will be made per text diff\nline. In this context, the provided range will be NULL.\n\nWhen printing a diff, callback that will be made to output each line\nof text. This uses some extra GIT_DIFF_LINE_... constants for output\nof lines of file and hunk headers.","used":{"returns":[],"needs":["git_diff_blobs","git_diff_foreach","git_diff_print_compact","git_diff_print_patch"]}}],["git_diff_delta",{"type":"struct","value":"git_diff_delta","file":"diff.h","line":144,"lineto":150,"block":"git_diff_file old_file\ngit_diff_file new_file\ngit_delta_t status\nunsigned int similarity\nint binary","tdef":"typedef","comments":"Description of changes to one file.\n\nWhen iterating over a diff list object, this will generally be passed to\nmost callback functions and you can use the contents to understand\nexactly what has changed.\n\nUnder some circumstances, not all fields will be filled in, but the code\ngenerally tries to fill in as much as possible. One example is that the\n\"binary\" field will not actually look at file contents if you do not\npass in hunk and/or line callbacks to the diff foreach iteration function.\nIt will just use the git attributes for those files.","used":{"returns":[],"needs":["git_diff_iterator_next_file"]}}],["git_diff_file",{"type":"struct","value":"git_diff_file","file":"diff.h","line":123,"lineto":129,"block":"git_oid oid\nchar *path\ngit_off_t size\nunsigned int flags\nuint16_t mode","tdef":"typedef","comments":"Description of one side of a diff.","used":{"returns":[],"needs":[]}}],["git_diff_file_fn",{"type":"function pointer","value":"git_diff_file_fn","file":"diff.h","line":155,"lineto":158,"comments":"When iterating over a diff, callback that will be made per file.","used":{"returns":[],"needs":["git_diff_blobs","git_diff_foreach"]}}],["git_diff_hunk_fn",{"type":"function pointer","value":"git_diff_hunk_fn","file":"diff.h","line":173,"lineto":178,"comments":"When iterating over a diff, callback that will be made per hunk.","used":{"returns":[],"needs":["git_diff_blobs","git_diff_foreach"]}}],["git_diff_iterator",{"type":"struct","value":"git_diff_iterator","file":"diff.h","line":225,"lineto":225,"block":"","tdef":"typedef","comments":"The diff iterator object is used to scan a diff list.","used":{"returns":[],"needs":["git_diff_iterator_free","git_diff_iterator_new","git_diff_iterator_next_file","git_diff_iterator_next_hunk","git_diff_iterator_next_line","git_diff_iterator_num_hunks_in_file","git_diff_iterator_num_lines_in_hunk","git_diff_iterator_progress"]}}],["git_diff_list",{"type":"struct","value":"git_diff_list","file":"diff.h","line":80,"lineto":80,"block":"","tdef":"typedef","comments":"The diff list object that contains all individual file deltas.","used":{"returns":[],"needs":["git_diff_entrycount","git_diff_foreach","git_diff_index_to_tree","git_diff_iterator_new","git_diff_list_free","git_diff_merge","git_diff_print_compact","git_diff_print_patch","git_diff_tree_to_tree","git_diff_workdir_to_index","git_diff_workdir_to_tree"]}}],["git_diff_options",{"type":"struct","value":"git_diff_options","file":"diff.h","line":67,"lineto":75,"block":"uint32_t flags\nuint16_t context_lines\nuint16_t interhunk_lines\nchar *old_prefix\nchar *new_prefix\ngit_strarray pathspec\ngit_off_t max_size","tdef":"typedef","comments":"Structure describing options about how the diff should be executed.\n\nSetting all values of the structure to zero will yield the default\nvalues. Similarly, passing NULL for the options structure will\ngive the defaults. The default values are marked below.\n\n- flags: a combination of the GIT_DIFF_... values above\n- context_lines: number of lines of context to show around diffs\n- interhunk_lines: min lines between diff hunks to merge them\n- old_prefix: \"directory\" to prefix to old file names (default \"a\")\n- new_prefix: \"directory\" to prefix to new file names (default \"b\")\n- pathspec: array of paths / patterns to constrain diff\n- max_size: maximum blob size to diff, above this treated as binary","used":{"returns":[],"needs":["git_diff_blobs","git_diff_index_to_tree","git_diff_tree_to_tree","git_diff_workdir_to_index","git_diff_workdir_to_tree"]}}],["git_diff_range",{"type":"struct","value":"git_diff_range","file":"diff.h","line":163,"lineto":168,"block":"int old_start\nint old_lines\nint new_start\nint new_lines","tdef":"typedef","comments":"Structure describing a hunk of a diff.","used":{"returns":[],"needs":["git_diff_iterator_next_hunk"]}}],["git_error_t",{"type":"enum","file":"errors.h","line":41,"lineto":59,"block":"GITERR_NOMEMORY\nGITERR_OS\nGITERR_INVALID\nGITERR_REFERENCE\nGITERR_ZLIB\nGITERR_REPOSITORY\nGITERR_CONFIG\nGITERR_REGEX\nGITERR_ODB\nGITERR_INDEX\nGITERR_OBJECT\nGITERR_NET\nGITERR_TAG\nGITERR_TREE\nGITERR_INDEXER\nGITERR_SSL\nGITERR_SUBMODULE","tdef":"typedef","comments":"Error classes","used":{"returns":[],"needs":[]}}],["git_filemode_t",{"type":"enum","file":"types.h","line":180,"lineto":193,"block":"GIT_FILEMODE_NEW\nGIT_FILEMODE_TREE\nGIT_FILEMODE_BLOB\nGIT_FILEMODE_BLOB_EXECUTABLE\nGIT_FILEMODE_LINK\nGIT_FILEMODE_COMMIT","tdef":"typedef","comments":"Valid modes for index and tree entries.","used":{"returns":[],"needs":["git_treebuilder_insert"]}}],["git_headlist_cb",{"type":"function pointer","value":"git_headlist_cb","file":"net.h","line":47,"lineto":47,"comments":"Callback for listing the remote heads","used":{"returns":[],"needs":["git_remote_ls"]}}],["git_index",{"type":"struct","value":"git_index","file":"types.h","line":123,"lineto":123,"block":"","tdef":"typedef","comments":"Memory representation of an index file.","used":{"returns":[],"needs":["git_index_add","git_index_add2","git_index_append","git_index_append2","git_index_caps","git_index_clear","git_index_entrycount","git_index_entrycount_unmerged","git_index_find","git_index_free","git_index_get","git_index_get_unmerged_byindex","git_index_get_unmerged_bypath","git_index_open","git_index_read","git_index_read_tree","git_index_remove","git_index_set_caps","git_index_uniq","git_index_write","git_repository_index","git_repository_set_index","git_tree_create_fromindex"]}}],["git_index_entry",{"type":"struct","value":"git_index_entry","file":"index.h","line":68,"lineto":85,"block":"git_index_time ctime\ngit_index_time mtime\nunsigned int dev\nunsigned int ino\nunsigned int mode\nunsigned int uid\nunsigned int gid\ngit_off_t file_size\ngit_oid oid\nunsigned short flags\nunsigned short flags_extended\nchar *path","tdef":"typedef","comments":"Memory representation of a file entry in the index.","used":{"returns":["git_index_get"],"needs":["git_index_add2","git_index_append2","git_index_entry_stage"]}}],["git_index_entry_unmerged",{"type":"struct","value":"git_index_entry_unmerged","file":"index.h","line":88,"lineto":92,"block":"unsigned int mode[3]\ngit_oid oid[3]\nchar *path","tdef":"typedef","comments":"Representation of an unmerged file entry in the index.","used":{"returns":["git_index_get_unmerged_byindex","git_index_get_unmerged_bypath"],"needs":[]}}],["git_index_time",{"type":"struct","value":"git_index_time","file":"index.h","line":61,"lineto":65,"block":"git_time_t seconds\nunsigned int nanoseconds","tdef":"typedef","comments":"Time used in a git index entry","used":{"returns":[],"needs":[]}}],["git_indexer_stats",{"type":"struct","value":"git_indexer_stats","file":"indexer.h","line":19,"lineto":27,"block":"unsigned int total\nunsigned int processed\nunsigned int received","tdef":"typedef","comments":"This is passed as the first argument to the callback to allow the\nuser to see the progress.","used":{"returns":[],"needs":["git_checkout_head","git_checkout_index","git_checkout_tree","git_clone","git_clone_bare","git_index_read_tree","git_indexer_run","git_indexer_stream_add","git_indexer_stream_finalize","git_remote_download"]}}],["git_note",{"type":"struct","value":"git_note","file":"types.h","line":138,"lineto":138,"block":"","tdef":"typedef","comments":"Representation of a git note","used":{"returns":[],"needs":["git_note_free","git_note_message","git_note_oid","git_note_read"]}}],["git_note_data",{"type":"struct","value":"git_note_data","file":"notes.h","line":113,"lineto":116,"block":"git_oid blob_oid\ngit_oid annotated_object_oid","tdef":"typedef","comments":"Basic components of a note\n\n - Oid of the blob containing the message\n - Oid of the git object being annotated","used":{"returns":[],"needs":["git_note_foreach"]}}],["git_object",{"type":"struct","value":"git_object","file":"types.h","line":99,"lineto":99,"block":"","tdef":"typedef","comments":"Representation of a generic object in a repository","used":{"returns":[],"needs":["git_branch_create","git_checkout_tree","git_object_free","git_object_id","git_object_lookup","git_object_lookup_prefix","git_object_owner","git_object_peel","git_object_type","git_reference_peel","git_reset","git_revparse_single","git_tag_create","git_tag_create_lightweight","git_tag_peel","git_tag_target","git_tree_entry_to_object"]}}],["git_odb",{"type":"struct","value":"git_odb","file":"types.h","line":81,"lineto":81,"block":"","tdef":"typedef","comments":"An open object database handle.","used":{"returns":[],"needs":["git_odb_add_alternate","git_odb_add_backend","git_odb_exists","git_odb_foreach","git_odb_free","git_odb_new","git_odb_open","git_odb_open_rstream","git_odb_open_wstream","git_odb_read","git_odb_read_header","git_odb_read_prefix","git_odb_write","git_repository_odb","git_repository_set_odb","git_repository_wrap_odb"]}}],["git_odb_backend",{"type":"struct","value":"git_odb_backend","file":"types.h","line":84,"lineto":84,"block":"","tdef":"typedef","comments":"A custom backend in an ODB","used":{"returns":[],"needs":["git_odb_add_alternate","git_odb_add_backend"]}}],["git_odb_object",{"type":"struct","value":"git_odb_object","file":"types.h","line":87,"lineto":87,"block":"","tdef":"typedef","comments":"An object read from the ODB","used":{"returns":[],"needs":["git_odb_object_data","git_odb_object_free","git_odb_object_id","git_odb_object_size","git_odb_object_type","git_odb_read","git_odb_read_prefix"]}}],["git_odb_stream",{"type":"struct","value":"git_odb_stream","file":"types.h","line":90,"lineto":90,"block":"","tdef":"typedef","comments":"A stream to read/write from the ODB","used":{"returns":[],"needs":["git_odb_open_rstream","git_odb_open_wstream"]}}],["git_oid",{"type":"struct","value":"git_oid","file":"oid.h","line":33,"lineto":37,"block":"","tdef":"typedef","comments":"Unique identity of any object (commit, tree, blob, tag).","used":{"returns":["git_commit_id","git_commit_parent_oid","git_commit_tree_oid","git_indexer_hash","git_indexer_stream_hash","git_note_oid","git_object_id","git_odb_object_id","git_reference_oid","git_reflog_entry_oidnew","git_reflog_entry_oidold","git_submodule_head_oid","git_submodule_index_oid","git_submodule_wd_oid","git_tag_id","git_tag_target_oid","git_tree_entry_id","git_tree_id"],"needs":["git_blob_create_frombuffer","git_blob_create_fromchunks","git_blob_create_fromdisk","git_blob_create_fromfile","git_blob_lookup","git_blob_lookup_prefix","git_commit_create","git_commit_create_v","git_commit_lookup","git_commit_lookup_prefix","git_merge_base","git_merge_base_many","git_note_create","git_note_read","git_note_remove","git_object_lookup","git_object_lookup_prefix","git_odb_exists","git_odb_foreach","git_odb_hash","git_odb_hashfile","git_odb_open_rstream","git_odb_read","git_odb_read_header","git_odb_read_prefix","git_odb_write","git_oid_allocfmt","git_oid_cmp","git_oid_cpy","git_oid_equal","git_oid_fmt","git_oid_fromraw","git_oid_fromstr","git_oid_fromstrn","git_oid_iszero","git_oid_ncmp","git_oid_pathfmt","git_oid_streq","git_oid_tostr","git_reference_create_oid","git_reference_name_to_oid","git_reference_set_oid","git_reflog_append","git_repository_hashfile","git_repository_set_head_detached","git_revwalk_hide","git_revwalk_next","git_revwalk_push","git_tag_create","git_tag_create_frombuffer","git_tag_create_lightweight","git_tag_lookup","git_tag_lookup_prefix","git_tree_create_fromindex","git_tree_entry_byoid","git_tree_lookup","git_tree_lookup_prefix","git_treebuilder_insert","git_treebuilder_write"]}}],["git_oid_shorten",{"type":"struct","value":"git_oid_shorten","file":"oid.h","line":196,"lineto":196,"block":"","tdef":"typedef","comments":"OID Shortener object","used":{"returns":["git_oid_shorten_new"],"needs":["git_oid_shorten_add","git_oid_shorten_free"]}}],["git_otype",{"type":"enum","file":"types.h","line":67,"lineto":78,"block":"GIT_OBJ_ANY\nGIT_OBJ_BAD\nGIT_OBJ__EXT1\nGIT_OBJ_COMMIT\nGIT_OBJ_TREE\nGIT_OBJ_BLOB\nGIT_OBJ_TAG\nGIT_OBJ__EXT2\nGIT_OBJ_OFS_DELTA\nGIT_OBJ_REF_DELTA","tdef":"typedef","comments":"Basic type (loose or packed) of any Git object.","used":{"returns":[],"needs":["git_object__size","git_object_lookup","git_object_lookup_prefix","git_object_peel","git_object_type2string","git_object_typeisloose","git_odb_hash","git_odb_hashfile","git_odb_open_wstream","git_odb_read_header","git_odb_write","git_reference_peel","git_repository_hashfile"]}}],["git_ref_t",{"type":"enum","file":"types.h","line":157,"lineto":164,"block":"GIT_REF_INVALID\nGIT_REF_OID\nGIT_REF_SYMBOLIC\nGIT_REF_PACKED\nGIT_REF_HAS_PEEL\nGIT_REF_LISTALL","tdef":"typedef","comments":"Basic type of any Git reference.","used":{"returns":[],"needs":[]}}],["git_reference",{"type":"struct","value":"git_reference","file":"types.h","line":154,"lineto":154,"block":"","tdef":"typedef","comments":"In-memory representation of a reference.","used":{"returns":[],"needs":["git_branch_create","git_branch_delete","git_branch_lookup","git_branch_move","git_branch_tracking","git_reference_cmp","git_reference_create_oid","git_reference_create_symbolic","git_reference_delete","git_reference_free","git_reference_has_log","git_reference_is_branch","git_reference_is_packed","git_reference_is_remote","git_reference_lookup","git_reference_name","git_reference_oid","git_reference_owner","git_reference_peel","git_reference_reload","git_reference_rename","git_reference_resolve","git_reference_set_oid","git_reference_set_target","git_reference_target","git_reference_type","git_reflog_delete","git_reflog_read","git_reflog_rename","git_repository_head"]}}],["git_reflog",{"type":"struct","value":"git_reflog","file":"types.h","line":135,"lineto":135,"block":"","tdef":"typedef","comments":"Representation of a reference log","used":{"returns":[],"needs":["git_reflog_append","git_reflog_drop","git_reflog_entry_byindex","git_reflog_entrycount","git_reflog_free","git_reflog_read","git_reflog_write"]}}],["git_reflog_entry",{"type":"struct","value":"git_reflog_entry","file":"types.h","line":132,"lineto":132,"block":"","tdef":"typedef","comments":"Representation of a reference log entry","used":{"returns":["git_reflog_entry_byindex"],"needs":["git_reflog_entry_committer","git_reflog_entry_msg","git_reflog_entry_oidnew","git_reflog_entry_oidold"]}}],["git_remote_callbacks",{"type":"struct","value":"git_remote_callbacks","file":"remote.h","line":289,"lineto":294,"block":"void (*progress)(const char *str, int len, void *data)\nint (*completion)(git_remote_completion_type type, void *data)\nint (*update_tips)(const char *refname, const git_oid *a, const git_oid *b, void *data)\nvoid *data","tdef":null,"comments":"The callback settings structure\n\nSet the calbacks to be called by the remote.","used":{"returns":[],"needs":["git_remote_set_callbacks"]}}],["git_remote_head",{"type":"struct","value":"git_remote_head","file":"net.h","line":37,"lineto":42,"block":"int local:1\ngit_oid oid\ngit_oid loid\nchar *name","tdef":null,"comments":"Remote head description, given out on `ls` calls.","used":{"returns":[],"needs":[]}}],["git_repository",{"type":"struct","value":"git_repository","file":"types.h","line":96,"lineto":96,"block":"","tdef":"typedef","comments":"Representation of an existing git repository,\nincluding all its object contents","used":{"returns":["git_object_owner","git_reference_owner","git_revwalk_repository","git_submodule_owner"],"needs":["git_attr_add_macro","git_attr_cache_flush","git_attr_foreach","git_attr_get","git_attr_get_many","git_blob_create_frombuffer","git_blob_create_fromchunks","git_blob_create_fromdisk","git_blob_create_fromfile","git_blob_lookup","git_blob_lookup_prefix","git_branch_create","git_branch_foreach","git_branch_lookup","git_checkout_head","git_checkout_index","git_checkout_tree","git_clone","git_clone_bare","git_commit_create","git_commit_create_v","git_commit_lookup","git_commit_lookup_prefix","git_diff_index_to_tree","git_diff_tree_to_tree","git_diff_workdir_to_index","git_diff_workdir_to_tree","git_ignore_add_rule","git_ignore_clear_internal_rules","git_ignore_path_is_ignored","git_merge_base","git_merge_base_many","git_note_create","git_note_default_ref","git_note_foreach","git_note_read","git_note_remove","git_object_lookup","git_object_lookup_prefix","git_reference_create_oid","git_reference_create_symbolic","git_reference_foreach","git_reference_foreach_glob","git_reference_list","git_reference_lookup","git_reference_name_to_oid","git_reference_packall","git_remote_add","git_remote_list","git_remote_load","git_remote_new","git_repository_config","git_repository_detach_head","git_repository_free","git_repository_hashfile","git_repository_head","git_repository_head_detached","git_repository_head_orphan","git_repository_index","git_repository_init","git_repository_init_ext","git_repository_is_bare","git_repository_is_empty","git_repository_message","git_repository_message_remove","git_repository_odb","git_repository_open","git_repository_open_ext","git_repository_path","git_repository_set_config","git_repository_set_head","git_repository_set_head_detached","git_repository_set_index","git_repository_set_odb","git_repository_set_workdir","git_repository_workdir","git_repository_wrap_odb","git_reset","git_revparse_single","git_revwalk_new","git_status_file","git_status_foreach","git_status_foreach_ext","git_status_should_ignore","git_submodule_add_setup","git_submodule_foreach","git_submodule_lookup","git_submodule_open","git_submodule_reload_all","git_tag_create","git_tag_create_frombuffer","git_tag_create_lightweight","git_tag_delete","git_tag_list","git_tag_list_match","git_tag_lookup","git_tag_lookup_prefix","git_tree_entry_to_object","git_tree_lookup","git_tree_lookup_prefix","git_treebuilder_write"]}}],["git_repository_init_options",{"type":"struct","value":"git_repository_init_options","file":"repository.h","line":241,"lineto":249,"block":"uint32_t flags\nuint32_t mode\nconst char *workdir_path\nconst char *description\nconst char *template_path\nconst char *initial_head\nconst char *origin_url","tdef":"typedef","comments":"Extended options structure for `git_repository_init_ext`.\n\nThis contains extra options for `git_repository_init_ext` that enable\nadditional initialization features. The fields are:\n\n* flags - Combination of GIT_REPOSITORY_INIT flags above.\n* mode - Set to one of the standard GIT_REPOSITORY_INIT_SHARED_...\n constants above, or to a custom value that you would like.\n* workdir_path - The path to the working dir or NULL for default (i.e.\n repo_path parent on non-bare repos). IF THIS IS RELATIVE PATH,\n IT WILL BE EVALUATED RELATIVE TO THE REPO_PATH. If this is not\n the \"natural\" working directory, a .git gitlink file will be\n created here linking to the repo_path.\n* description - If set, this will be used to initialize the \"description\"\n file in the repository, instead of using the template content.\n* template_path - When GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE is set,\n this contains the path to use for the template directory. If\n this is NULL, the config or default directory options will be\n used instead.\n* initial_head - The name of the head to point HEAD at. If NULL, then\n this will be treated as \"master\" and the HEAD ref will be set\n to \"refs/heads/master\". If this begins with \"refs/\" it will be\n used verbatim; otherwise \"refs/heads/\" will be prefixed.\n* origin_url - If this is non-NULL, then after the rest of the\n repository initialization is completed, an \"origin\" remote\n will be added pointing to this URL.","used":{"returns":[],"needs":["git_repository_init_ext"]}}],["git_reset_type",{"type":"enum","file":"types.h","line":173,"lineto":177,"block":"GIT_RESET_SOFT\nGIT_RESET_MIXED\nGIT_RESET_HARD","tdef":"typedef","comments":"Kinds of reset operation.","used":{"returns":[],"needs":["git_reset"]}}],["git_revwalk",{"type":"struct","value":"git_revwalk","file":"types.h","line":102,"lineto":102,"block":"","tdef":"typedef","comments":"Representation of an in-progress walk through the commits in a repo","used":{"returns":[],"needs":["git_revwalk_free","git_revwalk_hide","git_revwalk_hide_glob","git_revwalk_hide_head","git_revwalk_hide_ref","git_revwalk_new","git_revwalk_next","git_revwalk_push","git_revwalk_push_glob","git_revwalk_push_head","git_revwalk_push_ref","git_revwalk_repository","git_revwalk_reset","git_revwalk_sorting"]}}],["git_signature",{"type":"struct","value":"git_signature","file":"types.h","line":147,"lineto":151,"block":"char *name\nchar *email\ngit_time when","tdef":"typedef","comments":"An action signature (e.g. for committers, taggers, etc)","used":{"returns":["git_commit_author","git_commit_committer","git_reflog_entry_committer","git_signature_dup","git_tag_tagger"],"needs":["git_commit_create","git_commit_create_v","git_note_create","git_note_remove","git_reflog_append","git_signature_dup","git_signature_free","git_signature_new","git_signature_now","git_tag_create"]}}],["git_status_options",{"type":"struct","value":"git_status_options","file":"status.h","line":116,"lineto":120,"block":"git_status_show_t show\nunsigned int flags\ngit_strarray pathspec","tdef":"typedef","comments":"Options to control how callbacks will be made by\n`git_status_foreach_ext()`.","used":{"returns":[],"needs":["git_status_foreach_ext"]}}],["git_status_show_t",{"type":"enum","file":"status.h","line":71,"lineto":76,"block":"GIT_STATUS_SHOW_INDEX_AND_WORKDIR\nGIT_STATUS_SHOW_INDEX_ONLY\nGIT_STATUS_SHOW_WORKDIR_ONLY\nGIT_STATUS_SHOW_INDEX_THEN_WORKDIR","tdef":"typedef","comments":"Select the files on which to report status.\n\n- GIT_STATUS_SHOW_INDEX_AND_WORKDIR is the default. This is the\n rough equivalent of `git status --porcelain` where each file\n will receive a callback indicating its status in the index and\n in the workdir.\n- GIT_STATUS_SHOW_INDEX_ONLY will only make callbacks for index\n side of status. The status of the index contents relative to\n the HEAD will be given.\n- GIT_STATUS_SHOW_WORKDIR_ONLY will only make callbacks for the\n workdir side of status, reporting the status of workdir content\n relative to the index.\n- GIT_STATUS_SHOW_INDEX_THEN_WORKDIR behaves like index-only\n followed by workdir-only, causing two callbacks to be issued\n per file (first index then workdir). This is slightly more\n efficient than making separate calls. This makes it easier to\n emulate the output of a plain `git status`.","used":{"returns":[],"needs":[]}}],["git_submodule",{"type":"struct","value":"git_submodule","file":"submodule.h","line":32,"lineto":32,"block":"","tdef":"typedef","comments":"Opaque structure representing a submodule.\n\nSubmodule support in libgit2 builds a list of known submodules and keeps\nit in the repository. The list is built from the .gitmodules file, the\n.git/config file, the index, and the HEAD tree. Items in the working\ndirectory that look like submodules (i.e. a git repo) but are not\nmentioned in those places won't be tracked.","used":{"returns":[],"needs":["git_submodule_add_finalize","git_submodule_add_setup","git_submodule_add_to_index","git_submodule_fetch_recurse_submodules","git_submodule_foreach","git_submodule_head_oid","git_submodule_ignore","git_submodule_index_oid","git_submodule_init","git_submodule_lookup","git_submodule_name","git_submodule_open","git_submodule_owner","git_submodule_path","git_submodule_reload","git_submodule_save","git_submodule_set_fetch_recurse_submodules","git_submodule_set_ignore","git_submodule_set_update","git_submodule_set_url","git_submodule_status","git_submodule_sync","git_submodule_update","git_submodule_url","git_submodule_wd_oid"]}}],["git_submodule_ignore_t",{"type":"enum","file":"submodule.h","line":55,"lineto":61,"block":"GIT_SUBMODULE_IGNORE_DEFAULT\nGIT_SUBMODULE_IGNORE_NONE\nGIT_SUBMODULE_IGNORE_UNTRACKED\nGIT_SUBMODULE_IGNORE_DIRTY\nGIT_SUBMODULE_IGNORE_ALL","tdef":"typedef","comments":"Values that could be specified for how closely to examine the\nworking directory when getting submodule status.\n\nUse the DEFUALT value if you have altered the ignore value via\n`git_submodule_set_ignore()` and wish to reset to the original value.","used":{"returns":[],"needs":["git_submodule_set_ignore"]}}],["git_submodule_status_t",{"type":"enum","file":"submodule.h","line":105,"lineto":124,"block":"GIT_SUBMODULE_STATUS_IN_HEAD\nGIT_SUBMODULE_STATUS_IN_INDEX\nGIT_SUBMODULE_STATUS_IN_CONFIG\nGIT_SUBMODULE_STATUS_IN_WD\nGIT_SUBMODULE_STATUS_INDEX_ADDED\nGIT_SUBMODULE_STATUS_INDEX_DELETED\nGIT_SUBMODULE_STATUS_INDEX_MODIFIED\nGIT_SUBMODULE_STATUS_WD_UNINITIALIZED\nGIT_SUBMODULE_STATUS_WD_ADDED\nGIT_SUBMODULE_STATUS_WD_DELETED\nGIT_SUBMODULE_STATUS_WD_MODIFIED\nGIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED\nGIT_SUBMODULE_STATUS_WD_WD_MODIFIED\nGIT_SUBMODULE_STATUS_WD_UNTRACKED","tdef":"typedef","comments":"Return codes for submodule status.\n\nA combination of these flags will be returned to describe the status of a\nsubmodule. Depending on the \"ignore\" property of the submodule, some of\nthe flags may never be returned because they indicate changes that are\nsupposed to be ignored.\n\nSubmodule info is contained in 4 places: the HEAD tree, the index, config\nfiles (both .git/config and .gitmodules), and the working directory. Any\nor all of those places might be missing information about the submodule\ndepending on what state the repo is in. We consider all four places to\nbuild the combination of status flags.\n\nThere are four values that are not really status, but give basic info\nabout what sources of submodule data are available. These will be\nreturned even if ignore is set to \"ALL\".\n\n* IN_HEAD - superproject head contains submodule\n* IN_INDEX - superproject index contains submodule\n* IN_CONFIG - superproject gitmodules has submodule\n* IN_WD - superproject workdir has submodule\n\nThe following values will be returned so long as ignore is not \"ALL\".\n\n* INDEX_ADDED - in index, not in head\n* INDEX_DELETED - in head, not in index\n* INDEX_MODIFIED - index and head don't match\n* WD_UNINITIALIZED - workdir contains empty directory\n* WD_ADDED - in workdir, not index\n* WD_DELETED - in index, not workdir\n* WD_MODIFIED - index and workdir head don't match\n\nThe following can only be returned if ignore is \"NONE\" or \"UNTRACKED\".\n\n* WD_INDEX_MODIFIED - submodule workdir index is dirty\n* WD_WD_MODIFIED - submodule workdir has modified files\n\nLastly, the following will only be returned for ignore \"NONE\".\n\n* WD_UNTRACKED - wd contains untracked files","used":{"returns":[],"needs":[]}}],["git_submodule_update_t",{"type":"enum","file":"submodule.h","line":40,"lineto":46,"block":"GIT_SUBMODULE_UPDATE_DEFAULT\nGIT_SUBMODULE_UPDATE_CHECKOUT\nGIT_SUBMODULE_UPDATE_REBASE\nGIT_SUBMODULE_UPDATE_MERGE\nGIT_SUBMODULE_UPDATE_NONE","tdef":"typedef","comments":"Values that could be specified for the update rule of a submodule.\n\nUse the DEFAULT value if you have altered the update value via\n`git_submodule_set_update()` and wish to reset to the original default.","used":{"returns":[],"needs":["git_submodule_set_update"]}}],["git_tag",{"type":"struct","value":"git_tag","file":"types.h","line":105,"lineto":105,"block":"","tdef":"typedef","comments":"Parsed representation of a tag object.","used":{"returns":[],"needs":["git_tag_free","git_tag_id","git_tag_lookup","git_tag_lookup_prefix","git_tag_message","git_tag_name","git_tag_peel","git_tag_tagger","git_tag_target","git_tag_target_oid","git_tag_type"]}}],["git_time",{"type":"struct","value":"git_time","file":"types.h","line":141,"lineto":144,"block":"git_time_t time\nint offset","tdef":"typedef","comments":"Time in a signature","used":{"returns":[],"needs":[]}}],["git_tree",{"type":"struct","value":"git_tree","file":"types.h","line":117,"lineto":117,"block":"","tdef":"typedef","comments":"Representation of a tree object.","used":{"returns":[],"needs":["git_commit_create","git_commit_create_v","git_commit_tree","git_diff_index_to_tree","git_diff_tree_to_tree","git_diff_workdir_to_tree","git_index_read_tree","git_tree_entry_byindex","git_tree_entry_byname","git_tree_entry_byoid","git_tree_entry_bypath","git_tree_entrycount","git_tree_free","git_tree_id","git_tree_lookup","git_tree_lookup_prefix","git_tree_walk","git_treebuilder_create"]}}],["git_tree_entry",{"type":"struct","value":"git_tree_entry","file":"types.h","line":114,"lineto":114,"block":"","tdef":"typedef","comments":"Representation of each one of the entries in a tree object.","used":{"returns":["git_tree_entry_byindex","git_tree_entry_byname","git_tree_entry_byoid","git_tree_entry_dup","git_treebuilder_get"],"needs":["git_tree_entry_bypath","git_tree_entry_dup","git_tree_entry_filemode","git_tree_entry_free","git_tree_entry_id","git_tree_entry_name","git_tree_entry_to_object","git_tree_entry_type","git_treebuilder_filter","git_treebuilder_insert"]}}],["git_treebuilder",{"type":"struct","value":"git_treebuilder","file":"types.h","line":120,"lineto":120,"block":"","tdef":"typedef","comments":"Constructor for in-memory trees","used":{"returns":[],"needs":["git_treebuilder_clear","git_treebuilder_create","git_treebuilder_filter","git_treebuilder_free","git_treebuilder_get","git_treebuilder_insert","git_treebuilder_remove","git_treebuilder_write"]}}],["git_treewalk_cb",{"type":"function pointer","value":"git_treewalk_cb","file":"tree.h","line":342,"lineto":342,"comments":"Callback for the tree traversal method","used":{"returns":[],"needs":["git_tree_walk"]}}]],"prefix":"include/git2","groups":[["attr",["git_attr_add_macro","git_attr_cache_flush","git_attr_foreach","git_attr_get","git_attr_get_many"]],["blob",["git_blob_create_frombuffer","git_blob_create_fromchunks","git_blob_create_fromdisk","git_blob_create_fromfile","git_blob_free","git_blob_lookup","git_blob_lookup_prefix","git_blob_rawcontent","git_blob_rawsize"]],["branch",["git_branch_create","git_branch_delete","git_branch_foreach","git_branch_lookup","git_branch_move","git_branch_tracking"]],["checkout",["git_checkout_head","git_checkout_index","git_checkout_tree"]],["clone",["git_clone","git_clone_bare"]],["commit",["git_commit_author","git_commit_committer","git_commit_create","git_commit_create_v","git_commit_free","git_commit_id","git_commit_lookup","git_commit_lookup_prefix","git_commit_message","git_commit_message_encoding","git_commit_nth_gen_ancestor","git_commit_parent","git_commit_parent_oid","git_commit_parentcount","git_commit_time","git_commit_time_offset","git_commit_tree","git_commit_tree_oid"]],["config",["git_config_add_file","git_config_add_file_ondisk","git_config_delete","git_config_file__ondisk","git_config_find_global","git_config_find_system","git_config_foreach","git_config_foreach_match","git_config_free","git_config_get_bool","git_config_get_int32","git_config_get_int64","git_config_get_mapped","git_config_get_multivar","git_config_get_string","git_config_new","git_config_open_default","git_config_open_ondisk","git_config_set_bool","git_config_set_int32","git_config_set_int64","git_config_set_multivar","git_config_set_string"]],["diff",["git_diff_blobs","git_diff_entrycount","git_diff_foreach","git_diff_index_to_tree","git_diff_iterator_free","git_diff_iterator_new","git_diff_iterator_next_file","git_diff_iterator_next_hunk","git_diff_iterator_next_line","git_diff_iterator_num_hunks_in_file","git_diff_iterator_num_lines_in_hunk","git_diff_iterator_progress","git_diff_list_free","git_diff_merge","git_diff_print_compact","git_diff_print_patch","git_diff_tree_to_tree","git_diff_workdir_to_index","git_diff_workdir_to_tree"]],["giterr",["giterr_clear","giterr_last"]],["ignore",["git_ignore_add_rule","git_ignore_clear_internal_rules","git_ignore_path_is_ignored"]],["index",["git_index_add","git_index_add2","git_index_append","git_index_append2","git_index_caps","git_index_clear","git_index_entry_stage","git_index_entrycount","git_index_entrycount_unmerged","git_index_find","git_index_free","git_index_get","git_index_get_unmerged_byindex","git_index_get_unmerged_bypath","git_index_open","git_index_read","git_index_read_tree","git_index_remove","git_index_set_caps","git_index_uniq","git_index_write"]],["indexer",["git_indexer_free","git_indexer_hash","git_indexer_new","git_indexer_run","git_indexer_stream_add","git_indexer_stream_finalize","git_indexer_stream_free","git_indexer_stream_hash","git_indexer_stream_new","git_indexer_write"]],["libgit2",["git_libgit2_capabilities","git_libgit2_version"]],["merge",["git_merge_base","git_merge_base_many"]],["message",["git_message_prettify"]],["note",["git_note_create","git_note_default_ref","git_note_foreach","git_note_free","git_note_message","git_note_oid","git_note_read","git_note_remove"]],["object",["git_object__size","git_object_free","git_object_id","git_object_lookup","git_object_lookup_prefix","git_object_owner","git_object_peel","git_object_string2type","git_object_type","git_object_type2string","git_object_typeisloose"]],["odb",["git_odb_add_alternate","git_odb_add_backend","git_odb_exists","git_odb_foreach","git_odb_free","git_odb_hash","git_odb_hashfile","git_odb_new","git_odb_object_data","git_odb_object_free","git_odb_object_id","git_odb_object_size","git_odb_object_type","git_odb_open","git_odb_open_rstream","git_odb_open_wstream","git_odb_read","git_odb_read_header","git_odb_read_prefix","git_odb_write"]],["oid",["git_oid_allocfmt","git_oid_cmp","git_oid_cpy","git_oid_equal","git_oid_fmt","git_oid_fromraw","git_oid_fromstr","git_oid_fromstrn","git_oid_iszero","git_oid_ncmp","git_oid_pathfmt","git_oid_shorten_add","git_oid_shorten_free","git_oid_shorten_new","git_oid_streq","git_oid_tostr"]],["reference",["git_reference_cmp","git_reference_create_oid","git_reference_create_symbolic","git_reference_delete","git_reference_foreach","git_reference_foreach_glob","git_reference_free","git_reference_has_log","git_reference_is_branch","git_reference_is_packed","git_reference_is_remote","git_reference_list","git_reference_lookup","git_reference_name","git_reference_name_to_oid","git_reference_normalize_name","git_reference_oid","git_reference_owner","git_reference_packall","git_reference_peel","git_reference_reload","git_reference_rename","git_reference_resolve","git_reference_set_oid","git_reference_set_target","git_reference_target","git_reference_type"]],["reflog",["git_reflog_append","git_reflog_delete","git_reflog_drop","git_reflog_entry_byindex","git_reflog_entry_committer","git_reflog_entry_msg","git_reflog_entry_oidnew","git_reflog_entry_oidold","git_reflog_entrycount","git_reflog_free","git_reflog_read","git_reflog_rename","git_reflog_write"]],["refspec",["git_refspec_dst","git_refspec_force","git_refspec_parse","git_refspec_src","git_refspec_src_matches","git_refspec_transform"]],["remote",["git_remote_add","git_remote_check_cert","git_remote_connect","git_remote_connected","git_remote_disconnect","git_remote_download","git_remote_fetchspec","git_remote_free","git_remote_list","git_remote_load","git_remote_ls","git_remote_name","git_remote_new","git_remote_pushspec","git_remote_pushurl","git_remote_save","git_remote_set_callbacks","git_remote_set_fetchspec","git_remote_set_pushspec","git_remote_set_pushurl","git_remote_set_url","git_remote_supported_url","git_remote_update_tips","git_remote_url","git_remote_valid_url"]],["repository",["git_repository_config","git_repository_detach_head","git_repository_discover","git_repository_free","git_repository_hashfile","git_repository_head","git_repository_head_detached","git_repository_head_orphan","git_repository_index","git_repository_init","git_repository_init_ext","git_repository_is_bare","git_repository_is_empty","git_repository_message","git_repository_message_remove","git_repository_odb","git_repository_open","git_repository_open_ext","git_repository_path","git_repository_set_config","git_repository_set_head","git_repository_set_head_detached","git_repository_set_index","git_repository_set_odb","git_repository_set_workdir","git_repository_workdir","git_repository_wrap_odb"]],["reset",["git_reset"]],["revparse",["git_revparse_single"]],["revwalk",["git_revwalk_free","git_revwalk_hide","git_revwalk_hide_glob","git_revwalk_hide_head","git_revwalk_hide_ref","git_revwalk_new","git_revwalk_next","git_revwalk_push","git_revwalk_push_glob","git_revwalk_push_head","git_revwalk_push_ref","git_revwalk_repository","git_revwalk_reset","git_revwalk_sorting"]],["signature",["git_signature_dup","git_signature_free","git_signature_new","git_signature_now"]],["status",["git_status_file","git_status_foreach","git_status_foreach_ext","git_status_should_ignore"]],["submodule",["git_submodule_add_finalize","git_submodule_add_setup","git_submodule_add_to_index","git_submodule_fetch_recurse_submodules","git_submodule_foreach","git_submodule_head_oid","git_submodule_ignore","git_submodule_index_oid","git_submodule_init","git_submodule_lookup","git_submodule_name","git_submodule_open","git_submodule_owner","git_submodule_path","git_submodule_reload","git_submodule_reload_all","git_submodule_save","git_submodule_set_fetch_recurse_submodules","git_submodule_set_ignore","git_submodule_set_update","git_submodule_set_url","git_submodule_status","git_submodule_sync","git_submodule_update","git_submodule_url","git_submodule_wd_oid"]],["tag",["git_tag_create","git_tag_create_frombuffer","git_tag_create_lightweight","git_tag_delete","git_tag_free","git_tag_id","git_tag_list","git_tag_list_match","git_tag_lookup","git_tag_lookup_prefix","git_tag_message","git_tag_name","git_tag_peel","git_tag_tagger","git_tag_target","git_tag_target_oid","git_tag_type"]],["threads",["git_threads_init","git_threads_shutdown"]],["tree",["git_tree_create_fromindex","git_tree_entry_byindex","git_tree_entry_byname","git_tree_entry_byoid","git_tree_entry_bypath","git_tree_entry_dup","git_tree_entry_filemode","git_tree_entry_free","git_tree_entry_id","git_tree_entry_name","git_tree_entry_to_object","git_tree_entry_type","git_tree_entrycount","git_tree_free","git_tree_id","git_tree_lookup","git_tree_lookup_prefix","git_tree_walk"]],["treebuilder",["git_treebuilder_clear","git_treebuilder_create","git_treebuilder_filter","git_treebuilder_free","git_treebuilder_get","git_treebuilder_insert","git_treebuilder_remove","git_treebuilder_write"]]],"examples":[["showindex.c","ex/HEAD/showindex.html"],["general.c","ex/HEAD/general.html"],["network/ls-remote.c","ex/HEAD/ls-remote.html"],["network/git2.c","ex/HEAD/git2.html"],["network/clone.c","ex/HEAD/clone.html"],["network/index-pack.c","ex/HEAD/index-pack.html"],["network/fetch.c","ex/HEAD/fetch.html"],["diff.c","ex/HEAD/diff.html"]]} \ No newline at end of file diff --git a/Makefile.embed b/Makefile.embed deleted file mode 100644 index f46eaa4c1d7..00000000000 --- a/Makefile.embed +++ /dev/null @@ -1,42 +0,0 @@ -PLATFORM=$(shell uname -o) - -rm=rm -f -AR=ar cq -RANLIB=ranlib -LIBNAME=libgit2.a -ifeq ($(PLATFORM),Msys) - CC=gcc -else - CC=cc -endif - -INCLUDES= -I. -Isrc -Iinclude -Ideps/http-parser -Ideps/zlib - -DEFINES= $(INCLUDES) -DNO_VIZ -DSTDC -DNO_GZIP -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE $(EXTRA_DEFINES) -CFLAGS= -g $(DEFINES) -Wall -Wextra -O2 $(EXTRA_CFLAGS) - -SRCS = $(wildcard src/*.c) $(wildcard src/transports/*.c) $(wildcard src/xdiff/*.c) $(wildcard deps/http-parser/*.c) $(wildcard deps/zlib/*.c) - -ifeq ($(PLATFORM),Msys) - SRCS += $(wildcard src/win32/*.c) $(wildcard src/compat/*.c) deps/regex/regex.c - INCLUDES += -Ideps/regex - DEFINES += -DWIN32 -D_WIN32_WINNT=0x0501 -else - SRCS += $(wildcard src/unix/*.c) - CFLAGS += -fPIC -endif - -OBJS = $(patsubst %.c,%.o,$(SRCS)) - -%.c.o: - $(CC) $(CFLAGS) -c $*.c - -all: $(LIBNAME) - -$(LIBNAME): $(OBJS) - $(rm) $@ - $(AR) $@ $(OBJS) - $(RANLIB) $@ - -clean: - $(rm) $(OBJS) $(LIBNAME) diff --git a/README.md b/README.md deleted file mode 100644 index 0075e53dbea..00000000000 --- a/README.md +++ /dev/null @@ -1,144 +0,0 @@ -libgit2 - the Git linkable library -====================== - -[![Build Status](https://secure.travis-ci.org/libgit2/libgit2.png?branch=development)](http://travis-ci.org/libgit2/libgit2) - -libgit2 is a portable, pure C implementation of the Git core methods provided as a -re-entrant linkable library with a solid API, allowing you to write native -speed custom Git applications in any language with bindings. - -libgit2 is licensed under a **very permissive license** (GPLv2 with a special Linking Exception). -This basically means that you can link it (unmodified) with any kind of software without having to -release its source code. - -* Mailing list: - * Archives: -* Website: -* API documentation: -* Usage guide: - -What It Can Do -================================== - -libgit2 is already very usable. - -* SHA conversions, formatting and shortening -* abstracted ODB backend system -* commit, tag, tree and blob parsing, editing, and write-back -* tree traversal -* revision walking -* index file (staging area) manipulation -* reference management (including packed references) -* config file management -* high level repository management -* thread safety and reentrancy -* descriptive and detailed error messages -* ...and more (over 175 different API calls) - -Building libgit2 - Using CMake -============================== - -libgit2 builds cleanly on most platforms without any external dependencies. -Under Unix-like systems, like Linux, \*BSD and Mac OS X, libgit2 expects `pthreads` to be available; -they should be installed by default on all systems. Under Windows, libgit2 uses the native Windows API -for threading. - -The libgit2 library is built using CMake 2.6+ () on all platforms. - -On most systems you can build the library using the following commands - - $ mkdir build && cd build - $ cmake .. - $ cmake --build . - -Alternatively you can point the CMake GUI tool to the CMakeLists.txt file and generate platform specific build project or IDE workspace. - -To install the library you can specify the install prefix by setting: - - $ cmake .. -DCMAKE_INSTALL_PREFIX=/install/prefix - $ cmake --build . --target install - -If you want to build a universal binary for Mac OS X, CMake sets it -all up for you if you use `-DCMAKE_OSX_ARCHITECTURES="i386;x86_64"` -when configuring. - -For more advanced use or questions about CMake please read . - -The following CMake variables are declared: - -- `INSTALL_BIN`: Where to install binaries to. -- `LIB_INSTALL_DIR`: Where to install libraries to. -- `INSTALL_INC`: Where to install headers to. -- `BUILD_SHARED_LIBS`: Build libgit2 as a Shared Library (defaults to ON) -- `BUILD_CLAR`: Build [Clar](https://github.com/tanoku/clar)-based test suite (defaults to ON) -- `THREADSAFE`: Build libgit2 with threading support (defaults to OFF) - -Language Bindings -================================== - -Here are the bindings to libgit2 that are currently available: - -* C++ - * libqgit2, Qt bindings -* Chicken Scheme - * chicken-git -* Delphi - * GitForDelphi -* Erlang - * Geef -* Go - * go-git -* GObject - * libgit2-glib -* Haskell - * hgit2 -* Lua - * luagit2 -* .NET - * libgit2net, low level bindings - * libgit2sharp -* Node.js - * node-gitteh - * nodegit -* Objective-C - * objective-git -* OCaml - * libgit2-ocaml -* Parrot Virtual Machine - * parrot-libgit2 -* Perl - * git-xs-pm -* PHP - * php-git -* Python - * pygit2 -* Ruby - * Rugged -* Vala - * libgit2.vapi - -If you start another language binding to libgit2, please let us know so -we can add it to the list. - -How Can I Contribute? -================================== - -Fork libgit2/libgit2 on GitHub, add your improvement, push it to a branch -in your fork named for the topic, send a pull request. If you change the -API or make other large changes, make a note of it in docs/rel-notes/ in a -file named after the next release. - -You can also file bugs or feature requests under the libgit2 project on -GitHub, or join us on the mailing list by sending an email to: - -libgit2@librelist.com - - -License -================================== -libgit2 is under GPL2 **with linking exemption**. This means you -can link to the library with any program, commercial, open source or -other. However, you cannot modify libgit2 and distribute it without -supplying the source. - -See the COPYING file for the full license text. diff --git a/api.docurium b/api.docurium deleted file mode 100644 index 9e17817dbec..00000000000 --- a/api.docurium +++ /dev/null @@ -1,13 +0,0 @@ -{ - "name": "libgit2", - "github": "libgit2/libgit2", - "input": "include/git2", - "prefix": "git_", - "output": "docs", - "branch": "gh-pages", - "examples": "examples", - "legacy": { - "input": {"src/git": ["v0.1.0"], - "src/git2": ["v0.2.0", "v0.3.0"]} - } -} diff --git a/css/style.css b/css/style.css new file mode 100644 index 00000000000..d4d9d2803f2 --- /dev/null +++ b/css/style.css @@ -0,0 +1,240 @@ +html { + height: 100%; +} + +/* Remove Below */ + +#header a.logo { + font-size: 35px; + font-weight: bold; + color: #014d65; + padding-top: 12px; +} + +#header { + height:81px; +} +#main { + background-position-y: -10px +} +#search-field { + margin: 0px; +} + +#versions li h3 { + padding: 10px; +} + +h3 #version { + display: inline; + color: #743; +} + +.category_index { float: left; margin: 0.25em; width:19em; } +.category_index h2 { background: #ddd; text-align: center; padding: 0.25em; margin-bottom: 0.5em; } +.category_index dt, .category_index dd { margin-right: 0.5em; } +.category_index dt { margin-left: 0.5em !important; } +.category_index dd { margin-left: 1.5em !important; } + + +/*********************/ +/* Sidebar */ +/*********************/ + +#guides .guide .sidebar h3 { + padding: 4px; + margin: .2em 0; +} +#guides .guide .sidebar h3:focus { outline: none; } + +.sidebar dl { padding: 0 0.5em 0.5em 0.5em; } +.sidebar dt { + font-weight: bold; + margin-top: 0.5em; +} + +.ui-icon { + display: inline-block; + width: 16px; + height: 16px; + background-color: white; + background-position: -2px 2px; + background-repeat: no-repeat; +} +.ui-icon-triangle-expand { background-image: url(../images/expand.png); } +.ui-icon-triangle-collapse { background-image: url(../images/collapse.png); } + +div.sidebar-shell { + margin: 0 0; +} + +div.sidebar-module { + width: 232px; +} +.content { + width: 660px; +} + +input.search { + font-size: 12px; + width: 200px; + padding: 5px 5px 5px 23px; + margin-bottom: 8px; + font-family: Helvetica,Arial,freesans,sans-serif; + border: 1px solid #DDD; + border-top-color: #CCC; + border-bottom-color: #EAEAEA; + -webkit-border-radius: 3px; + -moz-border-radius: 3px; + border-radius: 3px; + background: url(../images/search_icon.png) 5px 50% no-repeat white; +} + +a small { + font-size: 0.8em; + color: #aaa; +} + +h2 small { + font-size: 0.8em; + font-weight: normal; + color: #666; +} + +table.methods { + width: 100%; +} +table.methods tr td { + padding: 4px 8px; + border-bottom: 1px solid #eee; +} +table.methods tr td.methodName a { + font-weight: bold; +} + +table.funcTable tr td { + padding: 5px 10px; + border-bottom: 1px solid #eee; +} +table.funcTable tr td.comment { + color: #999; +} +table.funcTable tr td.var { + font-weight: bold; + color: #833; +} + +code.params { + white-space: pre-wrap; /* css-3 */ + white-space: -moz-pre-wrap; /* Mozilla, since 1999 */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: -o-pre-wrap; /* Opera 7 */ + word-wrap: break-word; /* Internet Explorer 5.5+ */ +} + +.example { + padding: 10px; + background: #efe; + margin-top: 10px; + margin-bottom: 10px; + border: 1px solid #7a7; +} +.example h3 { + margin: 8px 0; + margin-top: 0; + color: #585; +} + +.returns { margin-bottom: 15px; } + +h1.funcTitle { + font-size: 1.6em; +} +h3.funcDesc { + font-size: 1.0em; + font-weight: normal; + color: #686; + padding-bottom: 10px; + margin: 0; +} + +h1.funcTitle small { + font-size: 0.8em; + font-weight: normal; + color: #888; + margin-left: 10px; +} + +.also { + padding: 10px; + border-top: 1px solid #ddd; + background: #eee; +} + +.sidebar-module ul ul li span.divide { + background: #eee; + cursor: default; +} + +.fileLink { + padding: 10px; +} + +.signatures { + padding: 10px; +} + +.funcEx { + padding: 10px; +} + +.signatures a { + background: #ddd; + padding: 4px; + margin: 0; + color: #000; +} + +.signatures a.changed { + background: #ffd4aa; +} + +.signatures a.current { + border-bottom: 3px solid #933; +} + +.signatures h3 { + margin: 8px 0; + margin-top: 0; +} + +h2.funcGroup { + border: 0; + margin: 5px 0; + margin-top: 8px; + padding: 5px 0; + border-bottom: 1px solid #eee; +} +p.functionList { + border: 0; + margin: 0; + padding: 0; +} + +p.functionList a.changed { + background: #ffd4aa; +} + +p.functionList a.introd { + background: #cec; +} + +.changelog li.adds a { + color: #393; +} +.changelog li.changes a { + color: #993; +} +.changelog li.deletes { + color: #933; +} diff --git a/deps/http-parser/LICENSE-MIT b/deps/http-parser/LICENSE-MIT deleted file mode 100644 index 58010b38894..00000000000 --- a/deps/http-parser/LICENSE-MIT +++ /dev/null @@ -1,23 +0,0 @@ -http_parser.c is based on src/http/ngx_http_parse.c from NGINX copyright -Igor Sysoev. - -Additional changes are licensed under the same terms as NGINX and -copyright Joyent, Inc. and other Node contributors. All rights reserved. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. diff --git a/deps/http-parser/http_parser.c b/deps/http-parser/http_parser.c deleted file mode 100644 index 438e81becb8..00000000000 --- a/deps/http-parser/http_parser.c +++ /dev/null @@ -1,1778 +0,0 @@ -/* Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev - * - * Additional changes are licensed under the same terms as NGINX and - * copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -#include -#include -#include - - -#ifndef MIN -# define MIN(a,b) ((a) < (b) ? (a) : (b)) -#endif - - -#if HTTP_PARSER_DEBUG -#define SET_ERRNO(e) \ -do { \ - parser->http_errno = (e); \ - parser->error_lineno = __LINE__; \ -} while (0) -#else -#define SET_ERRNO(e) \ -do { \ - parser->http_errno = (e); \ -} while(0) -#endif - - -#define CALLBACK2(FOR) \ -do { \ - if (settings->on_##FOR) { \ - if (0 != settings->on_##FOR(parser)) { \ - SET_ERRNO(HPE_CB_##FOR); \ - return (p - data); \ - } \ - } \ -} while (0) - - -#define MARK(FOR) \ -do { \ - FOR##_mark = p; \ -} while (0) - -#define CALLBACK(FOR) \ -do { \ - if (FOR##_mark) { \ - if (settings->on_##FOR) { \ - if (0 != settings->on_##FOR(parser, \ - FOR##_mark, \ - p - FOR##_mark)) \ - { \ - SET_ERRNO(HPE_CB_##FOR); \ - return (p - data); \ - } \ - } \ - FOR##_mark = NULL; \ - } \ -} while (0) - - -#define PROXY_CONNECTION "proxy-connection" -#define CONNECTION "connection" -#define CONTENT_LENGTH "content-length" -#define TRANSFER_ENCODING "transfer-encoding" -#define UPGRADE "upgrade" -#define CHUNKED "chunked" -#define KEEP_ALIVE "keep-alive" -#define CLOSE "close" - - -static const char *method_strings[] = - { "DELETE" - , "GET" - , "HEAD" - , "POST" - , "PUT" - , "CONNECT" - , "OPTIONS" - , "TRACE" - , "COPY" - , "LOCK" - , "MKCOL" - , "MOVE" - , "PROPFIND" - , "PROPPATCH" - , "UNLOCK" - , "REPORT" - , "MKACTIVITY" - , "CHECKOUT" - , "MERGE" - , "M-SEARCH" - , "NOTIFY" - , "SUBSCRIBE" - , "UNSUBSCRIBE" - , "PATCH" - }; - - -/* Tokens as defined by rfc 2616. Also lowercases them. - * token = 1* - * separators = "(" | ")" | "<" | ">" | "@" - * | "," | ";" | ":" | "\" | <"> - * | "/" | "[" | "]" | "?" | "=" - * | "{" | "}" | SP | HT - */ -static const char tokens[256] = { -/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ - 0, 0, 0, 0, 0, 0, 0, 0, -/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ - 0, 0, 0, 0, 0, 0, 0, 0, -/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ - 0, 0, 0, 0, 0, 0, 0, 0, -/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ - 0, 0, 0, 0, 0, 0, 0, 0, -/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ - ' ', '!', '"', '#', '$', '%', '&', '\'', -/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ - 0, 0, '*', '+', 0, '-', '.', '/', -/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ - '0', '1', '2', '3', '4', '5', '6', '7', -/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ - '8', '9', 0, 0, 0, 0, 0, 0, -/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ - 0, 'a', 'b', 'c', 'd', 'e', 'f', 'g', -/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ - 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', -/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ - 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', -/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ - 'x', 'y', 'z', 0, 0, 0, '^', '_', -/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ - '`', 'a', 'b', 'c', 'd', 'e', 'f', 'g', -/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ - 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', -/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ - 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', -/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ - 'x', 'y', 'z', 0, '|', '}', '~', 0 }; - - -static const int8_t unhex[256] = - {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 - ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 - ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 - , 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1 - ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 - ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 - ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1 - ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 - }; - - -static const uint8_t normal_url_char[256] = { -/* 0 nul 1 soh 2 stx 3 etx 4 eot 5 enq 6 ack 7 bel */ - 0, 0, 0, 0, 0, 0, 0, 0, -/* 8 bs 9 ht 10 nl 11 vt 12 np 13 cr 14 so 15 si */ - 0, 0, 0, 0, 0, 0, 0, 0, -/* 16 dle 17 dc1 18 dc2 19 dc3 20 dc4 21 nak 22 syn 23 etb */ - 0, 0, 0, 0, 0, 0, 0, 0, -/* 24 can 25 em 26 sub 27 esc 28 fs 29 gs 30 rs 31 us */ - 0, 0, 0, 0, 0, 0, 0, 0, -/* 32 sp 33 ! 34 " 35 # 36 $ 37 % 38 & 39 ' */ - 0, 1, 1, 0, 1, 1, 1, 1, -/* 40 ( 41 ) 42 * 43 + 44 , 45 - 46 . 47 / */ - 1, 1, 1, 1, 1, 1, 1, 1, -/* 48 0 49 1 50 2 51 3 52 4 53 5 54 6 55 7 */ - 1, 1, 1, 1, 1, 1, 1, 1, -/* 56 8 57 9 58 : 59 ; 60 < 61 = 62 > 63 ? */ - 1, 1, 1, 1, 1, 1, 1, 0, -/* 64 @ 65 A 66 B 67 C 68 D 69 E 70 F 71 G */ - 1, 1, 1, 1, 1, 1, 1, 1, -/* 72 H 73 I 74 J 75 K 76 L 77 M 78 N 79 O */ - 1, 1, 1, 1, 1, 1, 1, 1, -/* 80 P 81 Q 82 R 83 S 84 T 85 U 86 V 87 W */ - 1, 1, 1, 1, 1, 1, 1, 1, -/* 88 X 89 Y 90 Z 91 [ 92 \ 93 ] 94 ^ 95 _ */ - 1, 1, 1, 1, 1, 1, 1, 1, -/* 96 ` 97 a 98 b 99 c 100 d 101 e 102 f 103 g */ - 1, 1, 1, 1, 1, 1, 1, 1, -/* 104 h 105 i 106 j 107 k 108 l 109 m 110 n 111 o */ - 1, 1, 1, 1, 1, 1, 1, 1, -/* 112 p 113 q 114 r 115 s 116 t 117 u 118 v 119 w */ - 1, 1, 1, 1, 1, 1, 1, 1, -/* 120 x 121 y 122 z 123 { 124 | 125 } 126 ~ 127 del */ - 1, 1, 1, 1, 1, 1, 1, 0, }; - - -enum state - { s_dead = 1 /* important that this is > 0 */ - - , s_start_req_or_res - , s_res_or_resp_H - , s_start_res - , s_res_H - , s_res_HT - , s_res_HTT - , s_res_HTTP - , s_res_first_http_major - , s_res_http_major - , s_res_first_http_minor - , s_res_http_minor - , s_res_first_status_code - , s_res_status_code - , s_res_status - , s_res_line_almost_done - - , s_start_req - - , s_req_method - , s_req_spaces_before_url - , s_req_schema - , s_req_schema_slash - , s_req_schema_slash_slash - , s_req_host - , s_req_port - , s_req_path - , s_req_query_string_start - , s_req_query_string - , s_req_fragment_start - , s_req_fragment - , s_req_http_start - , s_req_http_H - , s_req_http_HT - , s_req_http_HTT - , s_req_http_HTTP - , s_req_first_http_major - , s_req_http_major - , s_req_first_http_minor - , s_req_http_minor - , s_req_line_almost_done - - , s_header_field_start - , s_header_field - , s_header_value_start - , s_header_value - , s_header_value_lws - - , s_header_almost_done - - , s_chunk_size_start - , s_chunk_size - , s_chunk_parameters - , s_chunk_size_almost_done - - , s_headers_almost_done - /* Important: 's_headers_almost_done' must be the last 'header' state. All - * states beyond this must be 'body' states. It is used for overflow - * checking. See the PARSING_HEADER() macro. - */ - - , s_chunk_data - , s_chunk_data_almost_done - , s_chunk_data_done - - , s_body_identity - , s_body_identity_eof - }; - - -#define PARSING_HEADER(state) (state <= s_headers_almost_done) - - -enum header_states - { h_general = 0 - , h_C - , h_CO - , h_CON - - , h_matching_connection - , h_matching_proxy_connection - , h_matching_content_length - , h_matching_transfer_encoding - , h_matching_upgrade - - , h_connection - , h_content_length - , h_transfer_encoding - , h_upgrade - - , h_matching_transfer_encoding_chunked - , h_matching_connection_keep_alive - , h_matching_connection_close - - , h_transfer_encoding_chunked - , h_connection_keep_alive - , h_connection_close - }; - - -/* Macros for character classes; depends on strict-mode */ -#define CR '\r' -#define LF '\n' -#define LOWER(c) (unsigned char)(c | 0x20) -#define TOKEN(c) (tokens[(unsigned char)c]) -#define IS_ALPHA(c) (LOWER(c) >= 'a' && LOWER(c) <= 'z') -#define IS_NUM(c) ((c) >= '0' && (c) <= '9') -#define IS_ALPHANUM(c) (IS_ALPHA(c) || IS_NUM(c)) - -#if HTTP_PARSER_STRICT -#define IS_URL_CHAR(c) (normal_url_char[(unsigned char) (c)]) -#define IS_HOST_CHAR(c) (IS_ALPHANUM(c) || (c) == '.' || (c) == '-') -#else -#define IS_URL_CHAR(c) \ - (normal_url_char[(unsigned char) (c)] || ((c) & 0x80)) -#define IS_HOST_CHAR(c) \ - (IS_ALPHANUM(c) || (c) == '.' || (c) == '-' || (c) == '_') -#endif - - -#define start_state (parser->type == HTTP_REQUEST ? s_start_req : s_start_res) - - -#if HTTP_PARSER_STRICT -# define STRICT_CHECK(cond) \ -do { \ - if (cond) { \ - SET_ERRNO(HPE_STRICT); \ - goto error; \ - } \ -} while (0) -# define NEW_MESSAGE() (http_should_keep_alive(parser) ? start_state : s_dead) -#else -# define STRICT_CHECK(cond) -# define NEW_MESSAGE() start_state -#endif - - -/* Map errno values to strings for human-readable output */ -#define HTTP_STRERROR_GEN(n, s) { "HPE_" #n, s }, -static struct { - const char *name; - const char *description; -} http_strerror_tab[] = { - HTTP_ERRNO_MAP(HTTP_STRERROR_GEN) -}; -#undef HTTP_STRERROR_GEN - - -size_t http_parser_execute (http_parser *parser, - const http_parser_settings *settings, - const char *data, - size_t len) -{ - char c, ch; - int8_t unhex_val; - const char *p = data, *pe; - size_t to_read; - enum state state; - enum header_states header_state; - size_t index = parser->index; - size_t nread = parser->nread; - const char *header_field_mark, *header_value_mark, *url_mark; - const char *matcher; - - /* We're in an error state. Don't bother doing anything. */ - if (HTTP_PARSER_ERRNO(parser) != HPE_OK) { - return 0; - } - - state = (enum state) parser->state; - header_state = (enum header_states) parser->header_state; - - if (len == 0) { - switch (state) { - case s_body_identity_eof: - CALLBACK2(message_complete); - return 0; - - case s_dead: - case s_start_req_or_res: - case s_start_res: - case s_start_req: - return 0; - - default: - SET_ERRNO(HPE_INVALID_EOF_STATE); - return 1; - } - } - - /* technically we could combine all of these (except for url_mark) into one - variable, saving stack space, but it seems more clear to have them - separated. */ - header_field_mark = 0; - header_value_mark = 0; - url_mark = 0; - - if (state == s_header_field) - header_field_mark = data; - if (state == s_header_value) - header_value_mark = data; - if (state == s_req_path || state == s_req_schema || state == s_req_schema_slash - || state == s_req_schema_slash_slash || state == s_req_port - || state == s_req_query_string_start || state == s_req_query_string - || state == s_req_host - || state == s_req_fragment_start || state == s_req_fragment) - url_mark = data; - - for (p=data, pe=data+len; p != pe; p++) { - ch = *p; - - if (PARSING_HEADER(state)) { - ++nread; - /* Buffer overflow attack */ - if (nread > HTTP_MAX_HEADER_SIZE) { - SET_ERRNO(HPE_HEADER_OVERFLOW); - goto error; - } - } - - switch (state) { - - case s_dead: - /* this state is used after a 'Connection: close' message - * the parser will error out if it reads another message - */ - SET_ERRNO(HPE_CLOSED_CONNECTION); - goto error; - - case s_start_req_or_res: - { - if (ch == CR || ch == LF) - break; - parser->flags = 0; - parser->content_length = -1; - - CALLBACK2(message_begin); - - if (ch == 'H') - state = s_res_or_resp_H; - else { - parser->type = HTTP_REQUEST; - goto start_req_method_assign; - } - break; - } - - case s_res_or_resp_H: - if (ch == 'T') { - parser->type = HTTP_RESPONSE; - state = s_res_HT; - } else { - if (ch != 'E') { - SET_ERRNO(HPE_INVALID_CONSTANT); - goto error; - } - - parser->type = HTTP_REQUEST; - parser->method = HTTP_HEAD; - index = 2; - state = s_req_method; - } - break; - - case s_start_res: - { - parser->flags = 0; - parser->content_length = -1; - - CALLBACK2(message_begin); - - switch (ch) { - case 'H': - state = s_res_H; - break; - - case CR: - case LF: - break; - - default: - SET_ERRNO(HPE_INVALID_CONSTANT); - goto error; - } - break; - } - - case s_res_H: - STRICT_CHECK(ch != 'T'); - state = s_res_HT; - break; - - case s_res_HT: - STRICT_CHECK(ch != 'T'); - state = s_res_HTT; - break; - - case s_res_HTT: - STRICT_CHECK(ch != 'P'); - state = s_res_HTTP; - break; - - case s_res_HTTP: - STRICT_CHECK(ch != '/'); - state = s_res_first_http_major; - break; - - case s_res_first_http_major: - if (ch < '1' || ch > '9') { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_major = ch - '0'; - state = s_res_http_major; - break; - - /* major HTTP version or dot */ - case s_res_http_major: - { - if (ch == '.') { - state = s_res_first_http_minor; - break; - } - - if (!IS_NUM(ch)) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_major *= 10; - parser->http_major += ch - '0'; - - if (parser->http_major > 999) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - break; - } - - /* first digit of minor HTTP version */ - case s_res_first_http_minor: - if (!IS_NUM(ch)) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_minor = ch - '0'; - state = s_res_http_minor; - break; - - /* minor HTTP version or end of request line */ - case s_res_http_minor: - { - if (ch == ' ') { - state = s_res_first_status_code; - break; - } - - if (!IS_NUM(ch)) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_minor *= 10; - parser->http_minor += ch - '0'; - - if (parser->http_minor > 999) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - break; - } - - case s_res_first_status_code: - { - if (!IS_NUM(ch)) { - if (ch == ' ') { - break; - } - - SET_ERRNO(HPE_INVALID_STATUS); - goto error; - } - parser->status_code = ch - '0'; - state = s_res_status_code; - break; - } - - case s_res_status_code: - { - if (!IS_NUM(ch)) { - switch (ch) { - case ' ': - state = s_res_status; - break; - case CR: - state = s_res_line_almost_done; - break; - case LF: - state = s_header_field_start; - break; - default: - SET_ERRNO(HPE_INVALID_STATUS); - goto error; - } - break; - } - - parser->status_code *= 10; - parser->status_code += ch - '0'; - - if (parser->status_code > 999) { - SET_ERRNO(HPE_INVALID_STATUS); - goto error; - } - - break; - } - - case s_res_status: - /* the human readable status. e.g. "NOT FOUND" - * we are not humans so just ignore this */ - if (ch == CR) { - state = s_res_line_almost_done; - break; - } - - if (ch == LF) { - state = s_header_field_start; - break; - } - break; - - case s_res_line_almost_done: - STRICT_CHECK(ch != LF); - state = s_header_field_start; - break; - - case s_start_req: - { - if (ch == CR || ch == LF) - break; - parser->flags = 0; - parser->content_length = -1; - - CALLBACK2(message_begin); - - if (!IS_ALPHA(ch)) { - SET_ERRNO(HPE_INVALID_METHOD); - goto error; - } - - start_req_method_assign: - parser->method = (enum http_method) 0; - index = 1; - switch (ch) { - case 'C': parser->method = HTTP_CONNECT; /* or COPY, CHECKOUT */ break; - case 'D': parser->method = HTTP_DELETE; break; - case 'G': parser->method = HTTP_GET; break; - case 'H': parser->method = HTTP_HEAD; break; - case 'L': parser->method = HTTP_LOCK; break; - case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH */ break; - case 'N': parser->method = HTTP_NOTIFY; break; - case 'O': parser->method = HTTP_OPTIONS; break; - case 'P': parser->method = HTTP_POST; - /* or PROPFIND or PROPPATCH or PUT or PATCH */ - break; - case 'R': parser->method = HTTP_REPORT; break; - case 'S': parser->method = HTTP_SUBSCRIBE; break; - case 'T': parser->method = HTTP_TRACE; break; - case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE */ break; - default: - SET_ERRNO(HPE_INVALID_METHOD); - goto error; - } - state = s_req_method; - break; - } - - case s_req_method: - { - if (ch == '\0') { - SET_ERRNO(HPE_INVALID_METHOD); - goto error; - } - - matcher = method_strings[parser->method]; - if (ch == ' ' && matcher[index] == '\0') { - state = s_req_spaces_before_url; - } else if (ch == matcher[index]) { - ; /* nada */ - } else if (parser->method == HTTP_CONNECT) { - if (index == 1 && ch == 'H') { - parser->method = HTTP_CHECKOUT; - } else if (index == 2 && ch == 'P') { - parser->method = HTTP_COPY; - } else { - goto error; - } - } else if (parser->method == HTTP_MKCOL) { - if (index == 1 && ch == 'O') { - parser->method = HTTP_MOVE; - } else if (index == 1 && ch == 'E') { - parser->method = HTTP_MERGE; - } else if (index == 1 && ch == '-') { - parser->method = HTTP_MSEARCH; - } else if (index == 2 && ch == 'A') { - parser->method = HTTP_MKACTIVITY; - } else { - goto error; - } - } else if (index == 1 && parser->method == HTTP_POST) { - if (ch == 'R') { - parser->method = HTTP_PROPFIND; /* or HTTP_PROPPATCH */ - } else if (ch == 'U') { - parser->method = HTTP_PUT; - } else if (ch == 'A') { - parser->method = HTTP_PATCH; - } else { - goto error; - } - } else if (index == 2 && parser->method == HTTP_UNLOCK && ch == 'S') { - parser->method = HTTP_UNSUBSCRIBE; - } else if (index == 4 && parser->method == HTTP_PROPFIND && ch == 'P') { - parser->method = HTTP_PROPPATCH; - } else { - SET_ERRNO(HPE_INVALID_METHOD); - goto error; - } - - ++index; - break; - } - case s_req_spaces_before_url: - { - if (ch == ' ') break; - - if (ch == '/' || ch == '*') { - MARK(url); - state = s_req_path; - break; - } - - /* Proxied requests are followed by scheme of an absolute URI (alpha). - * CONNECT is followed by a hostname, which begins with alphanum. - * All other methods are followed by '/' or '*' (handled above). - */ - if (IS_ALPHA(ch) || (parser->method == HTTP_CONNECT && IS_NUM(ch))) { - MARK(url); - state = (parser->method == HTTP_CONNECT) ? s_req_host : s_req_schema; - break; - } - - SET_ERRNO(HPE_INVALID_URL); - goto error; - } - - case s_req_schema: - { - if (IS_ALPHA(ch)) break; - - if (ch == ':') { - state = s_req_schema_slash; - break; - } - - SET_ERRNO(HPE_INVALID_URL); - goto error; - } - - case s_req_schema_slash: - STRICT_CHECK(ch != '/'); - state = s_req_schema_slash_slash; - break; - - case s_req_schema_slash_slash: - STRICT_CHECK(ch != '/'); - state = s_req_host; - break; - - case s_req_host: - { - if (IS_HOST_CHAR(ch)) break; - switch (ch) { - case ':': - state = s_req_port; - break; - case '/': - state = s_req_path; - break; - case ' ': - /* The request line looks like: - * "GET http://foo.bar.com HTTP/1.1" - * That is, there is no path. - */ - CALLBACK(url); - state = s_req_http_start; - break; - case '?': - state = s_req_query_string_start; - break; - default: - SET_ERRNO(HPE_INVALID_HOST); - goto error; - } - break; - } - - case s_req_port: - { - if (IS_NUM(ch)) break; - switch (ch) { - case '/': - state = s_req_path; - break; - case ' ': - /* The request line looks like: - * "GET http://foo.bar.com:1234 HTTP/1.1" - * That is, there is no path. - */ - CALLBACK(url); - state = s_req_http_start; - break; - case '?': - state = s_req_query_string_start; - break; - default: - SET_ERRNO(HPE_INVALID_PORT); - goto error; - } - break; - } - - case s_req_path: - { - if (IS_URL_CHAR(ch)) break; - - switch (ch) { - case ' ': - CALLBACK(url); - state = s_req_http_start; - break; - case CR: - CALLBACK(url); - parser->http_major = 0; - parser->http_minor = 9; - state = s_req_line_almost_done; - break; - case LF: - CALLBACK(url); - parser->http_major = 0; - parser->http_minor = 9; - state = s_header_field_start; - break; - case '?': - state = s_req_query_string_start; - break; - case '#': - state = s_req_fragment_start; - break; - default: - SET_ERRNO(HPE_INVALID_PATH); - goto error; - } - break; - } - - case s_req_query_string_start: - { - if (IS_URL_CHAR(ch)) { - state = s_req_query_string; - break; - } - - switch (ch) { - case '?': - break; /* XXX ignore extra '?' ... is this right? */ - case ' ': - CALLBACK(url); - state = s_req_http_start; - break; - case CR: - CALLBACK(url); - parser->http_major = 0; - parser->http_minor = 9; - state = s_req_line_almost_done; - break; - case LF: - CALLBACK(url); - parser->http_major = 0; - parser->http_minor = 9; - state = s_header_field_start; - break; - case '#': - state = s_req_fragment_start; - break; - default: - SET_ERRNO(HPE_INVALID_QUERY_STRING); - goto error; - } - break; - } - - case s_req_query_string: - { - if (IS_URL_CHAR(ch)) break; - - switch (ch) { - case '?': - /* allow extra '?' in query string */ - break; - case ' ': - CALLBACK(url); - state = s_req_http_start; - break; - case CR: - CALLBACK(url); - parser->http_major = 0; - parser->http_minor = 9; - state = s_req_line_almost_done; - break; - case LF: - CALLBACK(url); - parser->http_major = 0; - parser->http_minor = 9; - state = s_header_field_start; - break; - case '#': - state = s_req_fragment_start; - break; - default: - SET_ERRNO(HPE_INVALID_QUERY_STRING); - goto error; - } - break; - } - - case s_req_fragment_start: - { - if (IS_URL_CHAR(ch)) { - state = s_req_fragment; - break; - } - - switch (ch) { - case ' ': - CALLBACK(url); - state = s_req_http_start; - break; - case CR: - CALLBACK(url); - parser->http_major = 0; - parser->http_minor = 9; - state = s_req_line_almost_done; - break; - case LF: - CALLBACK(url); - parser->http_major = 0; - parser->http_minor = 9; - state = s_header_field_start; - break; - case '?': - state = s_req_fragment; - break; - case '#': - break; - default: - SET_ERRNO(HPE_INVALID_FRAGMENT); - goto error; - } - break; - } - - case s_req_fragment: - { - if (IS_URL_CHAR(ch)) break; - - switch (ch) { - case ' ': - CALLBACK(url); - state = s_req_http_start; - break; - case CR: - CALLBACK(url); - parser->http_major = 0; - parser->http_minor = 9; - state = s_req_line_almost_done; - break; - case LF: - CALLBACK(url); - parser->http_major = 0; - parser->http_minor = 9; - state = s_header_field_start; - break; - case '?': - case '#': - break; - default: - SET_ERRNO(HPE_INVALID_FRAGMENT); - goto error; - } - break; - } - - case s_req_http_start: - switch (ch) { - case 'H': - state = s_req_http_H; - break; - case ' ': - break; - default: - SET_ERRNO(HPE_INVALID_CONSTANT); - goto error; - } - break; - - case s_req_http_H: - STRICT_CHECK(ch != 'T'); - state = s_req_http_HT; - break; - - case s_req_http_HT: - STRICT_CHECK(ch != 'T'); - state = s_req_http_HTT; - break; - - case s_req_http_HTT: - STRICT_CHECK(ch != 'P'); - state = s_req_http_HTTP; - break; - - case s_req_http_HTTP: - STRICT_CHECK(ch != '/'); - state = s_req_first_http_major; - break; - - /* first digit of major HTTP version */ - case s_req_first_http_major: - if (ch < '1' || ch > '9') { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_major = ch - '0'; - state = s_req_http_major; - break; - - /* major HTTP version or dot */ - case s_req_http_major: - { - if (ch == '.') { - state = s_req_first_http_minor; - break; - } - - if (!IS_NUM(ch)) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_major *= 10; - parser->http_major += ch - '0'; - - if (parser->http_major > 999) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - break; - } - - /* first digit of minor HTTP version */ - case s_req_first_http_minor: - if (!IS_NUM(ch)) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_minor = ch - '0'; - state = s_req_http_minor; - break; - - /* minor HTTP version or end of request line */ - case s_req_http_minor: - { - if (ch == CR) { - state = s_req_line_almost_done; - break; - } - - if (ch == LF) { - state = s_header_field_start; - break; - } - - /* XXX allow spaces after digit? */ - - if (!IS_NUM(ch)) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - parser->http_minor *= 10; - parser->http_minor += ch - '0'; - - if (parser->http_minor > 999) { - SET_ERRNO(HPE_INVALID_VERSION); - goto error; - } - - break; - } - - /* end of request line */ - case s_req_line_almost_done: - { - if (ch != LF) { - SET_ERRNO(HPE_LF_EXPECTED); - goto error; - } - - state = s_header_field_start; - break; - } - - case s_header_field_start: - header_field_start: - { - if (ch == CR) { - state = s_headers_almost_done; - break; - } - - if (ch == LF) { - /* they might be just sending \n instead of \r\n so this would be - * the second \n to denote the end of headers*/ - state = s_headers_almost_done; - goto headers_almost_done; - } - - c = TOKEN(ch); - - if (!c) { - SET_ERRNO(HPE_INVALID_HEADER_TOKEN); - goto error; - } - - MARK(header_field); - - index = 0; - state = s_header_field; - - switch (c) { - case 'c': - header_state = h_C; - break; - - case 'p': - header_state = h_matching_proxy_connection; - break; - - case 't': - header_state = h_matching_transfer_encoding; - break; - - case 'u': - header_state = h_matching_upgrade; - break; - - default: - header_state = h_general; - break; - } - break; - } - - case s_header_field: - { - c = TOKEN(ch); - - if (c) { - switch (header_state) { - case h_general: - break; - - case h_C: - index++; - header_state = (c == 'o' ? h_CO : h_general); - break; - - case h_CO: - index++; - header_state = (c == 'n' ? h_CON : h_general); - break; - - case h_CON: - index++; - switch (c) { - case 'n': - header_state = h_matching_connection; - break; - case 't': - header_state = h_matching_content_length; - break; - default: - header_state = h_general; - break; - } - break; - - /* connection */ - - case h_matching_connection: - index++; - if (index > sizeof(CONNECTION)-1 - || c != CONNECTION[index]) { - header_state = h_general; - } else if (index == sizeof(CONNECTION)-2) { - header_state = h_connection; - } - break; - - /* proxy-connection */ - - case h_matching_proxy_connection: - index++; - if (index > sizeof(PROXY_CONNECTION)-1 - || c != PROXY_CONNECTION[index]) { - header_state = h_general; - } else if (index == sizeof(PROXY_CONNECTION)-2) { - header_state = h_connection; - } - break; - - /* content-length */ - - case h_matching_content_length: - index++; - if (index > sizeof(CONTENT_LENGTH)-1 - || c != CONTENT_LENGTH[index]) { - header_state = h_general; - } else if (index == sizeof(CONTENT_LENGTH)-2) { - header_state = h_content_length; - } - break; - - /* transfer-encoding */ - - case h_matching_transfer_encoding: - index++; - if (index > sizeof(TRANSFER_ENCODING)-1 - || c != TRANSFER_ENCODING[index]) { - header_state = h_general; - } else if (index == sizeof(TRANSFER_ENCODING)-2) { - header_state = h_transfer_encoding; - } - break; - - /* upgrade */ - - case h_matching_upgrade: - index++; - if (index > sizeof(UPGRADE)-1 - || c != UPGRADE[index]) { - header_state = h_general; - } else if (index == sizeof(UPGRADE)-2) { - header_state = h_upgrade; - } - break; - - case h_connection: - case h_content_length: - case h_transfer_encoding: - case h_upgrade: - if (ch != ' ') header_state = h_general; - break; - - default: - assert(0 && "Unknown header_state"); - break; - } - break; - } - - if (ch == ':') { - CALLBACK(header_field); - state = s_header_value_start; - break; - } - - if (ch == CR) { - state = s_header_almost_done; - CALLBACK(header_field); - break; - } - - if (ch == LF) { - CALLBACK(header_field); - state = s_header_field_start; - break; - } - - SET_ERRNO(HPE_INVALID_HEADER_TOKEN); - goto error; - } - - case s_header_value_start: - { - if (ch == ' ' || ch == '\t') break; - - MARK(header_value); - - state = s_header_value; - index = 0; - - if (ch == CR) { - CALLBACK(header_value); - header_state = h_general; - state = s_header_almost_done; - break; - } - - if (ch == LF) { - CALLBACK(header_value); - state = s_header_field_start; - break; - } - - c = LOWER(ch); - - switch (header_state) { - case h_upgrade: - parser->flags |= F_UPGRADE; - header_state = h_general; - break; - - case h_transfer_encoding: - /* looking for 'Transfer-Encoding: chunked' */ - if ('c' == c) { - header_state = h_matching_transfer_encoding_chunked; - } else { - header_state = h_general; - } - break; - - case h_content_length: - if (!IS_NUM(ch)) { - SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); - goto error; - } - - parser->content_length = ch - '0'; - break; - - case h_connection: - /* looking for 'Connection: keep-alive' */ - if (c == 'k') { - header_state = h_matching_connection_keep_alive; - /* looking for 'Connection: close' */ - } else if (c == 'c') { - header_state = h_matching_connection_close; - } else { - header_state = h_general; - } - break; - - default: - header_state = h_general; - break; - } - break; - } - - case s_header_value: - { - - if (ch == CR) { - CALLBACK(header_value); - state = s_header_almost_done; - break; - } - - if (ch == LF) { - CALLBACK(header_value); - goto header_almost_done; - } - - c = LOWER(ch); - - switch (header_state) { - case h_general: - break; - - case h_connection: - case h_transfer_encoding: - assert(0 && "Shouldn't get here."); - break; - - case h_content_length: - if (ch == ' ') break; - if (!IS_NUM(ch)) { - SET_ERRNO(HPE_INVALID_CONTENT_LENGTH); - goto error; - } - - parser->content_length *= 10; - parser->content_length += ch - '0'; - break; - - /* Transfer-Encoding: chunked */ - case h_matching_transfer_encoding_chunked: - index++; - if (index > sizeof(CHUNKED)-1 - || c != CHUNKED[index]) { - header_state = h_general; - } else if (index == sizeof(CHUNKED)-2) { - header_state = h_transfer_encoding_chunked; - } - break; - - /* looking for 'Connection: keep-alive' */ - case h_matching_connection_keep_alive: - index++; - if (index > sizeof(KEEP_ALIVE)-1 - || c != KEEP_ALIVE[index]) { - header_state = h_general; - } else if (index == sizeof(KEEP_ALIVE)-2) { - header_state = h_connection_keep_alive; - } - break; - - /* looking for 'Connection: close' */ - case h_matching_connection_close: - index++; - if (index > sizeof(CLOSE)-1 || c != CLOSE[index]) { - header_state = h_general; - } else if (index == sizeof(CLOSE)-2) { - header_state = h_connection_close; - } - break; - - case h_transfer_encoding_chunked: - case h_connection_keep_alive: - case h_connection_close: - if (ch != ' ') header_state = h_general; - break; - - default: - state = s_header_value; - header_state = h_general; - break; - } - break; - } - - case s_header_almost_done: - header_almost_done: - { - STRICT_CHECK(ch != LF); - - state = s_header_value_lws; - - switch (header_state) { - case h_connection_keep_alive: - parser->flags |= F_CONNECTION_KEEP_ALIVE; - break; - case h_connection_close: - parser->flags |= F_CONNECTION_CLOSE; - break; - case h_transfer_encoding_chunked: - parser->flags |= F_CHUNKED; - break; - default: - break; - } - break; - } - - case s_header_value_lws: - { - if (ch == ' ' || ch == '\t') - state = s_header_value_start; - else - { - state = s_header_field_start; - goto header_field_start; - } - break; - } - - case s_headers_almost_done: - headers_almost_done: - { - STRICT_CHECK(ch != LF); - - if (parser->flags & F_TRAILING) { - /* End of a chunked request */ - CALLBACK2(message_complete); - state = NEW_MESSAGE(); - break; - } - - nread = 0; - - if (parser->flags & F_UPGRADE || parser->method == HTTP_CONNECT) { - parser->upgrade = 1; - } - - /* Here we call the headers_complete callback. This is somewhat - * different than other callbacks because if the user returns 1, we - * will interpret that as saying that this message has no body. This - * is needed for the annoying case of recieving a response to a HEAD - * request. - */ - if (settings->on_headers_complete) { - switch (settings->on_headers_complete(parser)) { - case 0: - break; - - case 1: - parser->flags |= F_SKIPBODY; - break; - - default: - parser->state = state; - SET_ERRNO(HPE_CB_headers_complete); - return p - data; /* Error */ - } - } - - /* Exit, the rest of the connect is in a different protocol. */ - if (parser->upgrade) { - CALLBACK2(message_complete); - return (p - data) + 1; - } - - if (parser->flags & F_SKIPBODY) { - CALLBACK2(message_complete); - state = NEW_MESSAGE(); - } else if (parser->flags & F_CHUNKED) { - /* chunked encoding - ignore Content-Length header */ - state = s_chunk_size_start; - } else { - if (parser->content_length == 0) { - /* Content-Length header given but zero: Content-Length: 0\r\n */ - CALLBACK2(message_complete); - state = NEW_MESSAGE(); - } else if (parser->content_length > 0) { - /* Content-Length header given and non-zero */ - state = s_body_identity; - } else { - if (parser->type == HTTP_REQUEST || http_should_keep_alive(parser)) { - /* Assume content-length 0 - read the next */ - CALLBACK2(message_complete); - state = NEW_MESSAGE(); - } else { - /* Read body until EOF */ - state = s_body_identity_eof; - } - } - } - - break; - } - - case s_body_identity: - to_read = (size_t)MIN(pe - p, parser->content_length); - if (to_read > 0) { - if (settings->on_body) settings->on_body(parser, p, to_read); - p += to_read - 1; - parser->content_length -= to_read; - if (parser->content_length == 0) { - CALLBACK2(message_complete); - state = NEW_MESSAGE(); - } - } - break; - - /* read until EOF */ - case s_body_identity_eof: - to_read = pe - p; - if (to_read > 0) { - if (settings->on_body) settings->on_body(parser, p, to_read); - p += to_read - 1; - } - break; - - case s_chunk_size_start: - { - assert(nread == 1); - assert(parser->flags & F_CHUNKED); - - unhex_val = unhex[(unsigned char)ch]; - if (unhex_val == -1) { - SET_ERRNO(HPE_INVALID_CHUNK_SIZE); - goto error; - } - - parser->content_length = unhex_val; - state = s_chunk_size; - break; - } - - case s_chunk_size: - { - assert(parser->flags & F_CHUNKED); - - if (ch == CR) { - state = s_chunk_size_almost_done; - break; - } - - unhex_val = unhex[(unsigned char)ch]; - - if (unhex_val == -1) { - if (ch == ';' || ch == ' ') { - state = s_chunk_parameters; - break; - } - - SET_ERRNO(HPE_INVALID_CHUNK_SIZE); - goto error; - } - - parser->content_length *= 16; - parser->content_length += unhex_val; - break; - } - - case s_chunk_parameters: - { - assert(parser->flags & F_CHUNKED); - /* just ignore this shit. TODO check for overflow */ - if (ch == CR) { - state = s_chunk_size_almost_done; - break; - } - break; - } - - case s_chunk_size_almost_done: - { - assert(parser->flags & F_CHUNKED); - STRICT_CHECK(ch != LF); - - nread = 0; - - if (parser->content_length == 0) { - parser->flags |= F_TRAILING; - state = s_header_field_start; - } else { - state = s_chunk_data; - } - break; - } - - case s_chunk_data: - { - assert(parser->flags & F_CHUNKED); - - to_read = (size_t)MIN(pe - p, parser->content_length); - - if (to_read > 0) { - if (settings->on_body) settings->on_body(parser, p, to_read); - p += to_read - 1; - } - - if ((signed)to_read == parser->content_length) { - state = s_chunk_data_almost_done; - } - - parser->content_length -= to_read; - break; - } - - case s_chunk_data_almost_done: - assert(parser->flags & F_CHUNKED); - STRICT_CHECK(ch != CR); - state = s_chunk_data_done; - break; - - case s_chunk_data_done: - assert(parser->flags & F_CHUNKED); - STRICT_CHECK(ch != LF); - state = s_chunk_size_start; - break; - - default: - assert(0 && "unhandled state"); - SET_ERRNO(HPE_INVALID_INTERNAL_STATE); - goto error; - } - } - - CALLBACK(header_field); - CALLBACK(header_value); - CALLBACK(url); - - parser->state = state; - parser->header_state = header_state; - parser->index = (unsigned char) index; - parser->nread = nread; - - return len; - -error: - if (HTTP_PARSER_ERRNO(parser) == HPE_OK) { - SET_ERRNO(HPE_UNKNOWN); - } - - return (p - data); -} - - -int -http_should_keep_alive (http_parser *parser) -{ - if (parser->http_major > 0 && parser->http_minor > 0) { - /* HTTP/1.1 */ - if (parser->flags & F_CONNECTION_CLOSE) { - return 0; - } else { - return 1; - } - } else { - /* HTTP/1.0 or earlier */ - if (parser->flags & F_CONNECTION_KEEP_ALIVE) { - return 1; - } else { - return 0; - } - } -} - - -const char * http_method_str (enum http_method m) -{ - return method_strings[m]; -} - - -void -http_parser_init (http_parser *parser, enum http_parser_type t) -{ - parser->type = t; - parser->state = (t == HTTP_REQUEST ? s_start_req : (t == HTTP_RESPONSE ? s_start_res : s_start_req_or_res)); - parser->nread = 0; - parser->upgrade = 0; - parser->flags = 0; - parser->method = 0; - parser->http_errno = 0; -} - -const char * -http_errno_name(enum http_errno err) { - assert(err < (sizeof(http_strerror_tab)/sizeof(http_strerror_tab[0]))); - return http_strerror_tab[err].name; -} - -const char * -http_errno_description(enum http_errno err) { - assert(err < (sizeof(http_strerror_tab)/sizeof(http_strerror_tab[0]))); - return http_strerror_tab[err].description; -} diff --git a/deps/http-parser/http_parser.h b/deps/http-parser/http_parser.h deleted file mode 100644 index b6f6e997806..00000000000 --- a/deps/http-parser/http_parser.h +++ /dev/null @@ -1,267 +0,0 @@ -/* Copyright Joyent, Inc. and other Node contributors. All rights reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ -#ifndef http_parser_h -#define http_parser_h -#ifdef __cplusplus -extern "C" { -#endif - -#define HTTP_PARSER_VERSION_MAJOR 1 -#define HTTP_PARSER_VERSION_MINOR 0 - -#ifdef _MSC_VER - /* disable silly warnings */ -# pragma warning(disable: 4127 4214) -#endif - -#include -#include "git2/common.h" - -/* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run - * faster - */ -#ifndef HTTP_PARSER_STRICT -# define HTTP_PARSER_STRICT 1 -#endif - -/* Compile with -DHTTP_PARSER_DEBUG=1 to add extra debugging information to - * the error reporting facility. - */ -#ifndef HTTP_PARSER_DEBUG -# define HTTP_PARSER_DEBUG 0 -#endif - - -/* Maximium header size allowed */ -#define HTTP_MAX_HEADER_SIZE (80*1024) - - -typedef struct http_parser http_parser; -typedef struct http_parser_settings http_parser_settings; -typedef struct http_parser_result http_parser_result; - - -/* Callbacks should return non-zero to indicate an error. The parser will - * then halt execution. - * - * The one exception is on_headers_complete. In a HTTP_RESPONSE parser - * returning '1' from on_headers_complete will tell the parser that it - * should not expect a body. This is used when receiving a response to a - * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding: - * chunked' headers that indicate the presence of a body. - * - * http_data_cb does not return data chunks. It will be call arbitrarally - * many times for each string. E.G. you might get 10 callbacks for "on_path" - * each providing just a few characters more data. - */ -typedef int (*http_data_cb) (http_parser*, const char *at, size_t length); -typedef int (*http_cb) (http_parser*); - - -/* Request Methods */ -enum http_method - { HTTP_DELETE = 0 - , HTTP_GET - , HTTP_HEAD - , HTTP_POST - , HTTP_PUT - /* pathological */ - , HTTP_CONNECT - , HTTP_OPTIONS - , HTTP_TRACE - /* webdav */ - , HTTP_COPY - , HTTP_LOCK - , HTTP_MKCOL - , HTTP_MOVE - , HTTP_PROPFIND - , HTTP_PROPPATCH - , HTTP_UNLOCK - /* subversion */ - , HTTP_REPORT - , HTTP_MKACTIVITY - , HTTP_CHECKOUT - , HTTP_MERGE - /* upnp */ - , HTTP_MSEARCH - , HTTP_NOTIFY - , HTTP_SUBSCRIBE - , HTTP_UNSUBSCRIBE - /* RFC-5789 */ - , HTTP_PATCH - }; - - -enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH }; - - -/* Flag values for http_parser.flags field */ -enum flags - { F_CHUNKED = 1 << 0 - , F_CONNECTION_KEEP_ALIVE = 1 << 1 - , F_CONNECTION_CLOSE = 1 << 2 - , F_TRAILING = 1 << 3 - , F_UPGRADE = 1 << 4 - , F_SKIPBODY = 1 << 5 - }; - - -/* Map for errno-related constants - * - * The provided argument should be a macro that takes 2 arguments. - */ -#define HTTP_ERRNO_MAP(XX) \ - /* No error */ \ - XX(OK, "success") \ - \ - /* Callback-related errors */ \ - XX(CB_message_begin, "the on_message_begin callback failed") \ - XX(CB_path, "the on_path callback failed") \ - XX(CB_query_string, "the on_query_string callback failed") \ - XX(CB_url, "the on_url callback failed") \ - XX(CB_fragment, "the on_fragment callback failed") \ - XX(CB_header_field, "the on_header_field callback failed") \ - XX(CB_header_value, "the on_header_value callback failed") \ - XX(CB_headers_complete, "the on_headers_complete callback failed") \ - XX(CB_body, "the on_body callback failed") \ - XX(CB_message_complete, "the on_message_complete callback failed") \ - \ - /* Parsing-related errors */ \ - XX(INVALID_EOF_STATE, "stream ended at an unexpected time") \ - XX(HEADER_OVERFLOW, \ - "too many header bytes seen; overflow detected") \ - XX(CLOSED_CONNECTION, \ - "data received after completed connection: close message") \ - XX(INVALID_VERSION, "invalid HTTP version") \ - XX(INVALID_STATUS, "invalid HTTP status code") \ - XX(INVALID_METHOD, "invalid HTTP method") \ - XX(INVALID_URL, "invalid URL") \ - XX(INVALID_HOST, "invalid host") \ - XX(INVALID_PORT, "invalid port") \ - XX(INVALID_PATH, "invalid path") \ - XX(INVALID_QUERY_STRING, "invalid query string") \ - XX(INVALID_FRAGMENT, "invalid fragment") \ - XX(LF_EXPECTED, "LF character expected") \ - XX(INVALID_HEADER_TOKEN, "invalid character in header") \ - XX(INVALID_CONTENT_LENGTH, \ - "invalid character in content-length header") \ - XX(INVALID_CHUNK_SIZE, \ - "invalid character in chunk size header") \ - XX(INVALID_CONSTANT, "invalid constant string") \ - XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\ - XX(STRICT, "strict mode assertion failed") \ - XX(UNKNOWN, "an unknown error occurred") - - -/* Define HPE_* values for each errno value above */ -#define HTTP_ERRNO_GEN(n, s) HPE_##n, -enum http_errno { - HTTP_ERRNO_MAP(HTTP_ERRNO_GEN) -}; -#undef HTTP_ERRNO_GEN - - -/* Get an http_errno value from an http_parser */ -#define HTTP_PARSER_ERRNO(p) ((enum http_errno) (p)->http_errno) - -/* Get the line number that generated the current error */ -#if HTTP_PARSER_DEBUG -#define HTTP_PARSER_ERRNO_LINE(p) ((p)->error_lineno) -#else -#define HTTP_PARSER_ERRNO_LINE(p) 0 -#endif - - -struct http_parser { - /** PRIVATE **/ - unsigned char type : 2; - unsigned char flags : 6; /* F_* values from 'flags' enum; semi-public */ - unsigned char state; - unsigned char header_state; - unsigned char index; - - size_t nread; - int64_t content_length; - - /** READ-ONLY **/ - unsigned short http_major; - unsigned short http_minor; - unsigned short status_code; /* responses only */ - unsigned char method; /* requests only */ - unsigned char http_errno : 7; - - /* 1 = Upgrade header was present and the parser has exited because of that. - * 0 = No upgrade header present. - * Should be checked when http_parser_execute() returns in addition to - * error checking. - */ - unsigned char upgrade : 1; - -#if HTTP_PARSER_DEBUG - uint32_t error_lineno; -#endif - - /** PUBLIC **/ - void *data; /* A pointer to get hook to the "connection" or "socket" object */ -}; - - -struct http_parser_settings { - http_cb on_message_begin; - http_data_cb on_url; - http_data_cb on_header_field; - http_data_cb on_header_value; - http_cb on_headers_complete; - http_data_cb on_body; - http_cb on_message_complete; -}; - - -void http_parser_init(http_parser *parser, enum http_parser_type type); - - -size_t http_parser_execute(http_parser *parser, - const http_parser_settings *settings, - const char *data, - size_t len); - - -/* If http_should_keep_alive() in the on_headers_complete or - * on_message_complete callback returns true, then this will be should be - * the last message on the connection. - * If you are the server, respond with the "Connection: close" header. - * If you are the client, close the connection. - */ -int http_should_keep_alive(http_parser *parser); - -/* Returns a string version of the HTTP method. */ -const char *http_method_str(enum http_method m); - -/* Return a string name of the given error */ -const char *http_errno_name(enum http_errno err); - -/* Return a string description of the given error */ -const char *http_errno_description(enum http_errno err); - -#ifdef __cplusplus -} -#endif -#endif diff --git a/deps/regex/config.h b/deps/regex/config.h deleted file mode 100644 index 95370690e02..00000000000 --- a/deps/regex/config.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _REGEX_CONFIG_H_ -#define _REGEX_CONFIG_H_ - -# define GAWK -# define NO_MBSUPPORT - -#endif diff --git a/deps/regex/regcomp.c b/deps/regex/regcomp.c deleted file mode 100644 index 7373fbc2286..00000000000 --- a/deps/regex/regcomp.c +++ /dev/null @@ -1,3856 +0,0 @@ -/* Extended regular expression matching and search library. - Copyright (C) 2002-2007,2009,2010 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Isamu Hasegawa . - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. */ - -static reg_errcode_t re_compile_internal (regex_t *preg, const char * pattern, - size_t length, reg_syntax_t syntax); -static void re_compile_fastmap_iter (regex_t *bufp, - const re_dfastate_t *init_state, - char *fastmap); -static reg_errcode_t init_dfa (re_dfa_t *dfa, size_t pat_len); -#ifdef RE_ENABLE_I18N -static void free_charset (re_charset_t *cset); -#endif /* RE_ENABLE_I18N */ -static void free_workarea_compile (regex_t *preg); -static reg_errcode_t create_initial_state (re_dfa_t *dfa); -#ifdef RE_ENABLE_I18N -static void optimize_utf8 (re_dfa_t *dfa); -#endif -static reg_errcode_t analyze (regex_t *preg); -static reg_errcode_t preorder (bin_tree_t *root, - reg_errcode_t (fn (void *, bin_tree_t *)), - void *extra); -static reg_errcode_t postorder (bin_tree_t *root, - reg_errcode_t (fn (void *, bin_tree_t *)), - void *extra); -static reg_errcode_t optimize_subexps (void *extra, bin_tree_t *node); -static reg_errcode_t lower_subexps (void *extra, bin_tree_t *node); -static bin_tree_t *lower_subexp (reg_errcode_t *err, regex_t *preg, - bin_tree_t *node); -static reg_errcode_t calc_first (void *extra, bin_tree_t *node); -static reg_errcode_t calc_next (void *extra, bin_tree_t *node); -static reg_errcode_t link_nfa_nodes (void *extra, bin_tree_t *node); -static int duplicate_node (re_dfa_t *dfa, int org_idx, unsigned int constraint); -static int search_duplicated_node (const re_dfa_t *dfa, int org_node, - unsigned int constraint); -static reg_errcode_t calc_eclosure (re_dfa_t *dfa); -static reg_errcode_t calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, - int node, int root); -static reg_errcode_t calc_inveclosure (re_dfa_t *dfa); -static int fetch_number (re_string_t *input, re_token_t *token, - reg_syntax_t syntax); -static int peek_token (re_token_t *token, re_string_t *input, - reg_syntax_t syntax) internal_function; -static bin_tree_t *parse (re_string_t *regexp, regex_t *preg, - reg_syntax_t syntax, reg_errcode_t *err); -static bin_tree_t *parse_reg_exp (re_string_t *regexp, regex_t *preg, - re_token_t *token, reg_syntax_t syntax, - int nest, reg_errcode_t *err); -static bin_tree_t *parse_branch (re_string_t *regexp, regex_t *preg, - re_token_t *token, reg_syntax_t syntax, - int nest, reg_errcode_t *err); -static bin_tree_t *parse_expression (re_string_t *regexp, regex_t *preg, - re_token_t *token, reg_syntax_t syntax, - int nest, reg_errcode_t *err); -static bin_tree_t *parse_sub_exp (re_string_t *regexp, regex_t *preg, - re_token_t *token, reg_syntax_t syntax, - int nest, reg_errcode_t *err); -static bin_tree_t *parse_dup_op (bin_tree_t *dup_elem, re_string_t *regexp, - re_dfa_t *dfa, re_token_t *token, - reg_syntax_t syntax, reg_errcode_t *err); -static bin_tree_t *parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, - re_token_t *token, reg_syntax_t syntax, - reg_errcode_t *err); -static reg_errcode_t parse_bracket_element (bracket_elem_t *elem, - re_string_t *regexp, - re_token_t *token, int token_len, - re_dfa_t *dfa, - reg_syntax_t syntax, - int accept_hyphen); -static reg_errcode_t parse_bracket_symbol (bracket_elem_t *elem, - re_string_t *regexp, - re_token_t *token); -#ifdef RE_ENABLE_I18N -static reg_errcode_t build_equiv_class (bitset_t sbcset, - re_charset_t *mbcset, - int *equiv_class_alloc, - const unsigned char *name); -static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans, - bitset_t sbcset, - re_charset_t *mbcset, - int *char_class_alloc, - const char *class_name, - reg_syntax_t syntax); -#else /* not RE_ENABLE_I18N */ -static reg_errcode_t build_equiv_class (bitset_t sbcset, - const unsigned char *name); -static reg_errcode_t build_charclass (RE_TRANSLATE_TYPE trans, - bitset_t sbcset, - const char *class_name, - reg_syntax_t syntax); -#endif /* not RE_ENABLE_I18N */ -static bin_tree_t *build_charclass_op (re_dfa_t *dfa, - RE_TRANSLATE_TYPE trans, - const char *class_name, - const char *extra, - int non_match, reg_errcode_t *err); -static bin_tree_t *create_tree (re_dfa_t *dfa, - bin_tree_t *left, bin_tree_t *right, - re_token_type_t type); -static bin_tree_t *create_token_tree (re_dfa_t *dfa, - bin_tree_t *left, bin_tree_t *right, - const re_token_t *token); -static bin_tree_t *duplicate_tree (const bin_tree_t *src, re_dfa_t *dfa); -static void free_token (re_token_t *node); -static reg_errcode_t free_tree (void *extra, bin_tree_t *node); -static reg_errcode_t mark_opt_subexp (void *extra, bin_tree_t *node); - -/* This table gives an error message for each of the error codes listed - in regex.h. Obviously the order here has to be same as there. - POSIX doesn't require that we do anything for REG_NOERROR, - but why not be nice? */ - -const char __re_error_msgid[] attribute_hidden = - { -#define REG_NOERROR_IDX 0 - gettext_noop ("Success") /* REG_NOERROR */ - "\0" -#define REG_NOMATCH_IDX (REG_NOERROR_IDX + sizeof "Success") - gettext_noop ("No match") /* REG_NOMATCH */ - "\0" -#define REG_BADPAT_IDX (REG_NOMATCH_IDX + sizeof "No match") - gettext_noop ("Invalid regular expression") /* REG_BADPAT */ - "\0" -#define REG_ECOLLATE_IDX (REG_BADPAT_IDX + sizeof "Invalid regular expression") - gettext_noop ("Invalid collation character") /* REG_ECOLLATE */ - "\0" -#define REG_ECTYPE_IDX (REG_ECOLLATE_IDX + sizeof "Invalid collation character") - gettext_noop ("Invalid character class name") /* REG_ECTYPE */ - "\0" -#define REG_EESCAPE_IDX (REG_ECTYPE_IDX + sizeof "Invalid character class name") - gettext_noop ("Trailing backslash") /* REG_EESCAPE */ - "\0" -#define REG_ESUBREG_IDX (REG_EESCAPE_IDX + sizeof "Trailing backslash") - gettext_noop ("Invalid back reference") /* REG_ESUBREG */ - "\0" -#define REG_EBRACK_IDX (REG_ESUBREG_IDX + sizeof "Invalid back reference") - gettext_noop ("Unmatched [ or [^") /* REG_EBRACK */ - "\0" -#define REG_EPAREN_IDX (REG_EBRACK_IDX + sizeof "Unmatched [ or [^") - gettext_noop ("Unmatched ( or \\(") /* REG_EPAREN */ - "\0" -#define REG_EBRACE_IDX (REG_EPAREN_IDX + sizeof "Unmatched ( or \\(") - gettext_noop ("Unmatched \\{") /* REG_EBRACE */ - "\0" -#define REG_BADBR_IDX (REG_EBRACE_IDX + sizeof "Unmatched \\{") - gettext_noop ("Invalid content of \\{\\}") /* REG_BADBR */ - "\0" -#define REG_ERANGE_IDX (REG_BADBR_IDX + sizeof "Invalid content of \\{\\}") - gettext_noop ("Invalid range end") /* REG_ERANGE */ - "\0" -#define REG_ESPACE_IDX (REG_ERANGE_IDX + sizeof "Invalid range end") - gettext_noop ("Memory exhausted") /* REG_ESPACE */ - "\0" -#define REG_BADRPT_IDX (REG_ESPACE_IDX + sizeof "Memory exhausted") - gettext_noop ("Invalid preceding regular expression") /* REG_BADRPT */ - "\0" -#define REG_EEND_IDX (REG_BADRPT_IDX + sizeof "Invalid preceding regular expression") - gettext_noop ("Premature end of regular expression") /* REG_EEND */ - "\0" -#define REG_ESIZE_IDX (REG_EEND_IDX + sizeof "Premature end of regular expression") - gettext_noop ("Regular expression too big") /* REG_ESIZE */ - "\0" -#define REG_ERPAREN_IDX (REG_ESIZE_IDX + sizeof "Regular expression too big") - gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */ - }; - -const size_t __re_error_msgid_idx[] attribute_hidden = - { - REG_NOERROR_IDX, - REG_NOMATCH_IDX, - REG_BADPAT_IDX, - REG_ECOLLATE_IDX, - REG_ECTYPE_IDX, - REG_EESCAPE_IDX, - REG_ESUBREG_IDX, - REG_EBRACK_IDX, - REG_EPAREN_IDX, - REG_EBRACE_IDX, - REG_BADBR_IDX, - REG_ERANGE_IDX, - REG_ESPACE_IDX, - REG_BADRPT_IDX, - REG_EEND_IDX, - REG_ESIZE_IDX, - REG_ERPAREN_IDX - }; - -/* Entry points for GNU code. */ - - -#ifdef ZOS_USS - -/* For ZOS USS we must define btowc */ - -wchar_t -btowc (int c) -{ - wchar_t wtmp[2]; - char tmp[2]; - - tmp[0] = c; - tmp[1] = 0; - - mbtowc (wtmp, tmp, 1); - return wtmp[0]; -} -#endif - -/* re_compile_pattern is the GNU regular expression compiler: it - compiles PATTERN (of length LENGTH) and puts the result in BUFP. - Returns 0 if the pattern was valid, otherwise an error string. - - Assumes the `allocated' (and perhaps `buffer') and `translate' fields - are set in BUFP on entry. */ - -const char * -re_compile_pattern (const char *pattern, - size_t length, - struct re_pattern_buffer *bufp) -{ - reg_errcode_t ret; - - /* And GNU code determines whether or not to get register information - by passing null for the REGS argument to re_match, etc., not by - setting no_sub, unless RE_NO_SUB is set. */ - bufp->no_sub = !!(re_syntax_options & RE_NO_SUB); - - /* Match anchors at newline. */ - bufp->newline_anchor = 1; - - ret = re_compile_internal (bufp, pattern, length, re_syntax_options); - - if (!ret) - return NULL; - return gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]); -} -#ifdef _LIBC -weak_alias (__re_compile_pattern, re_compile_pattern) -#endif - -/* Set by `re_set_syntax' to the current regexp syntax to recognize. Can - also be assigned to arbitrarily: each pattern buffer stores its own - syntax, so it can be changed between regex compilations. */ -/* This has no initializer because initialized variables in Emacs - become read-only after dumping. */ -reg_syntax_t re_syntax_options; - - -/* Specify the precise syntax of regexps for compilation. This provides - for compatibility for various utilities which historically have - different, incompatible syntaxes. - - The argument SYNTAX is a bit mask comprised of the various bits - defined in regex.h. We return the old syntax. */ - -reg_syntax_t -re_set_syntax (reg_syntax_t syntax) -{ - reg_syntax_t ret = re_syntax_options; - - re_syntax_options = syntax; - return ret; -} -#ifdef _LIBC -weak_alias (__re_set_syntax, re_set_syntax) -#endif - -int -re_compile_fastmap (struct re_pattern_buffer *bufp) -{ - re_dfa_t *dfa = (re_dfa_t *) bufp->buffer; - char *fastmap = bufp->fastmap; - - memset (fastmap, '\0', sizeof (char) * SBC_MAX); - re_compile_fastmap_iter (bufp, dfa->init_state, fastmap); - if (dfa->init_state != dfa->init_state_word) - re_compile_fastmap_iter (bufp, dfa->init_state_word, fastmap); - if (dfa->init_state != dfa->init_state_nl) - re_compile_fastmap_iter (bufp, dfa->init_state_nl, fastmap); - if (dfa->init_state != dfa->init_state_begbuf) - re_compile_fastmap_iter (bufp, dfa->init_state_begbuf, fastmap); - bufp->fastmap_accurate = 1; - return 0; -} -#ifdef _LIBC -weak_alias (__re_compile_fastmap, re_compile_fastmap) -#endif - -static inline void -__attribute ((always_inline)) -re_set_fastmap (char *fastmap, int icase, int ch) -{ - fastmap[ch] = 1; - if (icase) - fastmap[tolower (ch)] = 1; -} - -/* Helper function for re_compile_fastmap. - Compile fastmap for the initial_state INIT_STATE. */ - -static void -re_compile_fastmap_iter (regex_t *bufp, const re_dfastate_t *init_state, - char *fastmap) -{ - volatile re_dfa_t *dfa = (re_dfa_t *) bufp->buffer; - int node_cnt; - int icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE)); - for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt) - { - int node = init_state->nodes.elems[node_cnt]; - re_token_type_t type = dfa->nodes[node].type; - - if (type == CHARACTER) - { - re_set_fastmap (fastmap, icase, dfa->nodes[node].opr.c); -#ifdef RE_ENABLE_I18N - if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1) - { - unsigned char *buf = re_malloc (unsigned char, dfa->mb_cur_max), *p; - wchar_t wc; - mbstate_t state; - - p = buf; - *p++ = dfa->nodes[node].opr.c; - while (++node < dfa->nodes_len - && dfa->nodes[node].type == CHARACTER - && dfa->nodes[node].mb_partial) - *p++ = dfa->nodes[node].opr.c; - memset (&state, '\0', sizeof (state)); - if (__mbrtowc (&wc, (const char *) buf, p - buf, - &state) == p - buf - && (__wcrtomb ((char *) buf, towlower (wc), &state) - != (size_t) -1)) - re_set_fastmap (fastmap, 0, buf[0]); - re_free (buf); - } -#endif - } - else if (type == SIMPLE_BRACKET) - { - int i, ch; - for (i = 0, ch = 0; i < BITSET_WORDS; ++i) - { - int j; - bitset_word_t w = dfa->nodes[node].opr.sbcset[i]; - for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch) - if (w & ((bitset_word_t) 1 << j)) - re_set_fastmap (fastmap, icase, ch); - } - } -#ifdef RE_ENABLE_I18N - else if (type == COMPLEX_BRACKET) - { - re_charset_t *cset = dfa->nodes[node].opr.mbcset; - int i; - -# ifdef _LIBC - /* See if we have to try all bytes which start multiple collation - elements. - e.g. In da_DK, we want to catch 'a' since "aa" is a valid - collation element, and don't catch 'b' since 'b' is - the only collation element which starts from 'b' (and - it is caught by SIMPLE_BRACKET). */ - if (_NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES) != 0 - && (cset->ncoll_syms || cset->nranges)) - { - const int32_t *table = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); - for (i = 0; i < SBC_MAX; ++i) - if (table[i] < 0) - re_set_fastmap (fastmap, icase, i); - } -# endif /* _LIBC */ - - /* See if we have to start the match at all multibyte characters, - i.e. where we would not find an invalid sequence. This only - applies to multibyte character sets; for single byte character - sets, the SIMPLE_BRACKET again suffices. */ - if (dfa->mb_cur_max > 1 - && (cset->nchar_classes || cset->non_match || cset->nranges -# ifdef _LIBC - || cset->nequiv_classes -# endif /* _LIBC */ - )) - { - unsigned char c = 0; - do - { - mbstate_t mbs; - memset (&mbs, 0, sizeof (mbs)); - if (__mbrtowc (NULL, (char *) &c, 1, &mbs) == (size_t) -2) - re_set_fastmap (fastmap, false, (int) c); - } - while (++c != 0); - } - - else - { - /* ... Else catch all bytes which can start the mbchars. */ - for (i = 0; i < cset->nmbchars; ++i) - { - char buf[256]; - mbstate_t state; - memset (&state, '\0', sizeof (state)); - if (__wcrtomb (buf, cset->mbchars[i], &state) != (size_t) -1) - re_set_fastmap (fastmap, icase, *(unsigned char *) buf); - if ((bufp->syntax & RE_ICASE) && dfa->mb_cur_max > 1) - { - if (__wcrtomb (buf, towlower (cset->mbchars[i]), &state) - != (size_t) -1) - re_set_fastmap (fastmap, false, *(unsigned char *) buf); - } - } - } - } -#endif /* RE_ENABLE_I18N */ - else if (type == OP_PERIOD -#ifdef RE_ENABLE_I18N - || type == OP_UTF8_PERIOD -#endif /* RE_ENABLE_I18N */ - || type == END_OF_RE) - { - memset (fastmap, '\1', sizeof (char) * SBC_MAX); - if (type == END_OF_RE) - bufp->can_be_null = 1; - return; - } - } -} - -/* Entry point for POSIX code. */ -/* regcomp takes a regular expression as a string and compiles it. - - PREG is a regex_t *. We do not expect any fields to be initialized, - since POSIX says we shouldn't. Thus, we set - - `buffer' to the compiled pattern; - `used' to the length of the compiled pattern; - `syntax' to RE_SYNTAX_POSIX_EXTENDED if the - REG_EXTENDED bit in CFLAGS is set; otherwise, to - RE_SYNTAX_POSIX_BASIC; - `newline_anchor' to REG_NEWLINE being set in CFLAGS; - `fastmap' to an allocated space for the fastmap; - `fastmap_accurate' to zero; - `re_nsub' to the number of subexpressions in PATTERN. - - PATTERN is the address of the pattern string. - - CFLAGS is a series of bits which affect compilation. - - If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we - use POSIX basic syntax. - - If REG_NEWLINE is set, then . and [^...] don't match newline. - Also, regexec will try a match beginning after every newline. - - If REG_ICASE is set, then we considers upper- and lowercase - versions of letters to be equivalent when matching. - - If REG_NOSUB is set, then when PREG is passed to regexec, that - routine will report only success or failure, and nothing about the - registers. - - It returns 0 if it succeeds, nonzero if it doesn't. (See regex.h for - the return codes and their meanings.) */ - -int -regcomp (regex_t *__restrict preg, - const char *__restrict pattern, - int cflags) -{ - reg_errcode_t ret; - reg_syntax_t syntax = ((cflags & REG_EXTENDED) ? RE_SYNTAX_POSIX_EXTENDED - : RE_SYNTAX_POSIX_BASIC); - - preg->buffer = NULL; - preg->allocated = 0; - preg->used = 0; - - /* Try to allocate space for the fastmap. */ - preg->fastmap = re_malloc (char, SBC_MAX); - if (BE (preg->fastmap == NULL, 0)) - return REG_ESPACE; - - syntax |= (cflags & REG_ICASE) ? RE_ICASE : 0; - - /* If REG_NEWLINE is set, newlines are treated differently. */ - if (cflags & REG_NEWLINE) - { /* REG_NEWLINE implies neither . nor [^...] match newline. */ - syntax &= ~RE_DOT_NEWLINE; - syntax |= RE_HAT_LISTS_NOT_NEWLINE; - /* It also changes the matching behavior. */ - preg->newline_anchor = 1; - } - else - preg->newline_anchor = 0; - preg->no_sub = !!(cflags & REG_NOSUB); - preg->translate = NULL; - - ret = re_compile_internal (preg, pattern, strlen (pattern), syntax); - - /* POSIX doesn't distinguish between an unmatched open-group and an - unmatched close-group: both are REG_EPAREN. */ - if (ret == REG_ERPAREN) - ret = REG_EPAREN; - - /* We have already checked preg->fastmap != NULL. */ - if (BE (ret == REG_NOERROR, 1)) - /* Compute the fastmap now, since regexec cannot modify the pattern - buffer. This function never fails in this implementation. */ - (void) re_compile_fastmap (preg); - else - { - /* Some error occurred while compiling the expression. */ - re_free (preg->fastmap); - preg->fastmap = NULL; - } - - return (int) ret; -} -#ifdef _LIBC -weak_alias (__regcomp, regcomp) -#endif - -/* Returns a message corresponding to an error code, ERRCODE, returned - from either regcomp or regexec. We don't use PREG here. */ - -size_t -regerror(int errcode, const regex_t *__restrict preg, - char *__restrict errbuf, size_t errbuf_size) -{ - const char *msg; - size_t msg_size; - - if (BE (errcode < 0 - || errcode >= (int) (sizeof (__re_error_msgid_idx) - / sizeof (__re_error_msgid_idx[0])), 0)) - /* Only error codes returned by the rest of the code should be passed - to this routine. If we are given anything else, or if other regex - code generates an invalid error code, then the program has a bug. - Dump core so we can fix it. */ - abort (); - - msg = gettext (__re_error_msgid + __re_error_msgid_idx[errcode]); - - msg_size = strlen (msg) + 1; /* Includes the null. */ - - if (BE (errbuf_size != 0, 1)) - { - if (BE (msg_size > errbuf_size, 0)) - { - memcpy (errbuf, msg, errbuf_size - 1); - errbuf[errbuf_size - 1] = 0; - } - else - memcpy (errbuf, msg, msg_size); - } - - return msg_size; -} -#ifdef _LIBC -weak_alias (__regerror, regerror) -#endif - - -#ifdef RE_ENABLE_I18N -/* This static array is used for the map to single-byte characters when - UTF-8 is used. Otherwise we would allocate memory just to initialize - it the same all the time. UTF-8 is the preferred encoding so this is - a worthwhile optimization. */ -#if __GNUC__ >= 3 -static const bitset_t utf8_sb_map = { - /* Set the first 128 bits. */ - [0 ... 0x80 / BITSET_WORD_BITS - 1] = BITSET_WORD_MAX -}; -#else /* ! (__GNUC__ >= 3) */ -static bitset_t utf8_sb_map; -#endif /* __GNUC__ >= 3 */ -#endif /* RE_ENABLE_I18N */ - - -static void -free_dfa_content (re_dfa_t *dfa) -{ - unsigned int i; - int j; - - if (dfa->nodes) - for (i = 0; i < dfa->nodes_len; ++i) - free_token (dfa->nodes + i); - re_free (dfa->nexts); - for (i = 0; i < dfa->nodes_len; ++i) - { - if (dfa->eclosures != NULL) - re_node_set_free (dfa->eclosures + i); - if (dfa->inveclosures != NULL) - re_node_set_free (dfa->inveclosures + i); - if (dfa->edests != NULL) - re_node_set_free (dfa->edests + i); - } - re_free (dfa->edests); - re_free (dfa->eclosures); - re_free (dfa->inveclosures); - re_free (dfa->nodes); - - if (dfa->state_table) - for (i = 0; i <= dfa->state_hash_mask; ++i) - { - struct re_state_table_entry *entry = dfa->state_table + i; - for (j = 0; j < entry->num; ++j) - { - re_dfastate_t *state = entry->array[j]; - free_state (state); - } - re_free (entry->array); - } - re_free (dfa->state_table); -#ifdef RE_ENABLE_I18N - if (dfa->sb_char != utf8_sb_map) - re_free (dfa->sb_char); -#endif - re_free (dfa->subexp_map); -#ifdef DEBUG - re_free (dfa->re_str); -#endif - - re_free (dfa); -} - - -/* Free dynamically allocated space used by PREG. */ - -void -regfree (regex_t *preg) -{ - re_dfa_t *dfa = (re_dfa_t *) preg->buffer; - if (BE (dfa != NULL, 1)) - free_dfa_content (dfa); - preg->buffer = NULL; - preg->allocated = 0; - - re_free (preg->fastmap); - preg->fastmap = NULL; - - re_free (preg->translate); - preg->translate = NULL; -} -#ifdef _LIBC -weak_alias (__regfree, regfree) -#endif - -/* Entry points compatible with 4.2 BSD regex library. We don't define - them unless specifically requested. */ - -#if defined _REGEX_RE_COMP || defined _LIBC - -/* BSD has one and only one pattern buffer. */ -static struct re_pattern_buffer re_comp_buf; - -char * -# ifdef _LIBC -/* Make these definitions weak in libc, so POSIX programs can redefine - these names if they don't use our functions, and still use - regcomp/regexec above without link errors. */ -weak_function -# endif -re_comp (s) - const char *s; -{ - reg_errcode_t ret; - char *fastmap; - - if (!s) - { - if (!re_comp_buf.buffer) - return gettext ("No previous regular expression"); - return 0; - } - - if (re_comp_buf.buffer) - { - fastmap = re_comp_buf.fastmap; - re_comp_buf.fastmap = NULL; - __regfree (&re_comp_buf); - memset (&re_comp_buf, '\0', sizeof (re_comp_buf)); - re_comp_buf.fastmap = fastmap; - } - - if (re_comp_buf.fastmap == NULL) - { - re_comp_buf.fastmap = (char *) malloc (SBC_MAX); - if (re_comp_buf.fastmap == NULL) - return (char *) gettext (__re_error_msgid - + __re_error_msgid_idx[(int) REG_ESPACE]); - } - - /* Since `re_exec' always passes NULL for the `regs' argument, we - don't need to initialize the pattern buffer fields which affect it. */ - - /* Match anchors at newlines. */ - re_comp_buf.newline_anchor = 1; - - ret = re_compile_internal (&re_comp_buf, s, strlen (s), re_syntax_options); - - if (!ret) - return NULL; - - /* Yes, we're discarding `const' here if !HAVE_LIBINTL. */ - return (char *) gettext (__re_error_msgid + __re_error_msgid_idx[(int) ret]); -} - -#ifdef _LIBC -libc_freeres_fn (free_mem) -{ - __regfree (&re_comp_buf); -} -#endif - -#endif /* _REGEX_RE_COMP */ - -/* Internal entry point. - Compile the regular expression PATTERN, whose length is LENGTH. - SYNTAX indicate regular expression's syntax. */ - -static reg_errcode_t -re_compile_internal (regex_t *preg, const char * pattern, size_t length, - reg_syntax_t syntax) -{ - reg_errcode_t err = REG_NOERROR; - re_dfa_t *dfa; - re_string_t regexp; - - /* Initialize the pattern buffer. */ - preg->fastmap_accurate = 0; - preg->syntax = syntax; - preg->not_bol = preg->not_eol = 0; - preg->used = 0; - preg->re_nsub = 0; - preg->can_be_null = 0; - preg->regs_allocated = REGS_UNALLOCATED; - - /* Initialize the dfa. */ - dfa = (re_dfa_t *) preg->buffer; - if (BE (preg->allocated < sizeof (re_dfa_t), 0)) - { - /* If zero allocated, but buffer is non-null, try to realloc - enough space. This loses if buffer's address is bogus, but - that is the user's responsibility. If ->buffer is NULL this - is a simple allocation. */ - dfa = re_realloc (preg->buffer, re_dfa_t, 1); - if (dfa == NULL) - return REG_ESPACE; - preg->allocated = sizeof (re_dfa_t); - preg->buffer = (unsigned char *) dfa; - } - preg->used = sizeof (re_dfa_t); - - err = init_dfa (dfa, length); - if (BE (err != REG_NOERROR, 0)) - { - free_dfa_content (dfa); - preg->buffer = NULL; - preg->allocated = 0; - return err; - } -#ifdef DEBUG - /* Note: length+1 will not overflow since it is checked in init_dfa. */ - dfa->re_str = re_malloc (char, length + 1); - strncpy (dfa->re_str, pattern, length + 1); -#endif - - __libc_lock_init (dfa->lock); - - err = re_string_construct (®exp, pattern, length, preg->translate, - syntax & RE_ICASE, dfa); - if (BE (err != REG_NOERROR, 0)) - { - re_compile_internal_free_return: - free_workarea_compile (preg); - re_string_destruct (®exp); - free_dfa_content (dfa); - preg->buffer = NULL; - preg->allocated = 0; - return err; - } - - /* Parse the regular expression, and build a structure tree. */ - preg->re_nsub = 0; - dfa->str_tree = parse (®exp, preg, syntax, &err); - if (BE (dfa->str_tree == NULL, 0)) - goto re_compile_internal_free_return; - - /* Analyze the tree and create the nfa. */ - err = analyze (preg); - if (BE (err != REG_NOERROR, 0)) - goto re_compile_internal_free_return; - -#ifdef RE_ENABLE_I18N - /* If possible, do searching in single byte encoding to speed things up. */ - if (dfa->is_utf8 && !(syntax & RE_ICASE) && preg->translate == NULL) - optimize_utf8 (dfa); -#endif - - /* Then create the initial state of the dfa. */ - err = create_initial_state (dfa); - - /* Release work areas. */ - free_workarea_compile (preg); - re_string_destruct (®exp); - - if (BE (err != REG_NOERROR, 0)) - { - free_dfa_content (dfa); - preg->buffer = NULL; - preg->allocated = 0; - } - - return err; -} - -/* Initialize DFA. We use the length of the regular expression PAT_LEN - as the initial length of some arrays. */ - -static reg_errcode_t -init_dfa (re_dfa_t *dfa, size_t pat_len) -{ - unsigned int table_size; - - memset (dfa, '\0', sizeof (re_dfa_t)); - - /* Force allocation of str_tree_storage the first time. */ - dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE; - - /* Avoid overflows. */ - if (pat_len == SIZE_MAX) - return REG_ESPACE; - - dfa->nodes_alloc = pat_len + 1; - dfa->nodes = re_malloc (re_token_t, dfa->nodes_alloc); - - /* table_size = 2 ^ ceil(log pat_len) */ - for (table_size = 1; ; table_size <<= 1) - if (table_size > pat_len) - break; - - dfa->state_table = calloc (sizeof (struct re_state_table_entry), table_size); - dfa->state_hash_mask = table_size - 1; - - dfa->mb_cur_max = MB_CUR_MAX; -#ifdef _LIBC - if (dfa->mb_cur_max == 6 - && strcmp (_NL_CURRENT (LC_CTYPE, _NL_CTYPE_CODESET_NAME), "UTF-8") == 0) - dfa->is_utf8 = 1; - dfa->map_notascii = (_NL_CURRENT_WORD (LC_CTYPE, _NL_CTYPE_MAP_TO_NONASCII) - != 0); -#else - dfa->is_utf8 = 1; - /* We check exhaustively in the loop below if this charset is a - superset of ASCII. */ - dfa->map_notascii = 0; -#endif - -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - { - if (dfa->is_utf8) - { -#if !defined(__GNUC__) || __GNUC__ < 3 - static short utf8_sb_map_inited = 0; - - if (! utf8_sb_map_inited) - { - int i; - - utf8_sb_map_inited = 0; - for (i = 0; i <= 0x80 / BITSET_WORD_BITS - 1; i++) - utf8_sb_map[i] = BITSET_WORD_MAX; - } -#endif - dfa->sb_char = (re_bitset_ptr_t) utf8_sb_map; - } - else - { - int i, j, ch; - - dfa->sb_char = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); - if (BE (dfa->sb_char == NULL, 0)) - return REG_ESPACE; - - /* Set the bits corresponding to single byte chars. */ - for (i = 0, ch = 0; i < BITSET_WORDS; ++i) - for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch) - { - wint_t wch = __btowc (ch); - if (wch != WEOF) - dfa->sb_char[i] |= (bitset_word_t) 1 << j; -# ifndef _LIBC - if (isascii (ch) && wch != ch) - dfa->map_notascii = 1; -# endif - } - } - } -#endif - - if (BE (dfa->nodes == NULL || dfa->state_table == NULL, 0)) - return REG_ESPACE; - return REG_NOERROR; -} - -/* Initialize WORD_CHAR table, which indicate which character is - "word". In this case "word" means that it is the word construction - character used by some operators like "\<", "\>", etc. */ - -static void -internal_function -init_word_char (re_dfa_t *dfa) -{ - int i, j, ch; - dfa->word_ops_used = 1; - for (i = 0, ch = 0; i < BITSET_WORDS; ++i) - for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch) - if (isalnum (ch) || ch == '_') - dfa->word_char[i] |= (bitset_word_t) 1 << j; -} - -/* Free the work area which are only used while compiling. */ - -static void -free_workarea_compile (regex_t *preg) -{ - re_dfa_t *dfa = (re_dfa_t *) preg->buffer; - bin_tree_storage_t *storage, *next; - for (storage = dfa->str_tree_storage; storage; storage = next) - { - next = storage->next; - re_free (storage); - } - dfa->str_tree_storage = NULL; - dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE; - dfa->str_tree = NULL; - re_free (dfa->org_indices); - dfa->org_indices = NULL; -} - -/* Create initial states for all contexts. */ - -static reg_errcode_t -create_initial_state (re_dfa_t *dfa) -{ - int first, i; - reg_errcode_t err; - re_node_set init_nodes; - - /* Initial states have the epsilon closure of the node which is - the first node of the regular expression. */ - first = dfa->str_tree->first->node_idx; - dfa->init_node = first; - err = re_node_set_init_copy (&init_nodes, dfa->eclosures + first); - if (BE (err != REG_NOERROR, 0)) - return err; - - /* The back-references which are in initial states can epsilon transit, - since in this case all of the subexpressions can be null. - Then we add epsilon closures of the nodes which are the next nodes of - the back-references. */ - if (dfa->nbackref > 0) - for (i = 0; i < init_nodes.nelem; ++i) - { - int node_idx = init_nodes.elems[i]; - re_token_type_t type = dfa->nodes[node_idx].type; - - int clexp_idx; - if (type != OP_BACK_REF) - continue; - for (clexp_idx = 0; clexp_idx < init_nodes.nelem; ++clexp_idx) - { - re_token_t *clexp_node; - clexp_node = dfa->nodes + init_nodes.elems[clexp_idx]; - if (clexp_node->type == OP_CLOSE_SUBEXP - && clexp_node->opr.idx == dfa->nodes[node_idx].opr.idx) - break; - } - if (clexp_idx == init_nodes.nelem) - continue; - - if (type == OP_BACK_REF) - { - int dest_idx = dfa->edests[node_idx].elems[0]; - if (!re_node_set_contains (&init_nodes, dest_idx)) - { - reg_errcode_t err = re_node_set_merge (&init_nodes, - dfa->eclosures - + dest_idx); - if (err != REG_NOERROR) - return err; - i = 0; - } - } - } - - /* It must be the first time to invoke acquire_state. */ - dfa->init_state = re_acquire_state_context (&err, dfa, &init_nodes, 0); - /* We don't check ERR here, since the initial state must not be NULL. */ - if (BE (dfa->init_state == NULL, 0)) - return err; - if (dfa->init_state->has_constraint) - { - dfa->init_state_word = re_acquire_state_context (&err, dfa, &init_nodes, - CONTEXT_WORD); - dfa->init_state_nl = re_acquire_state_context (&err, dfa, &init_nodes, - CONTEXT_NEWLINE); - dfa->init_state_begbuf = re_acquire_state_context (&err, dfa, - &init_nodes, - CONTEXT_NEWLINE - | CONTEXT_BEGBUF); - if (BE (dfa->init_state_word == NULL || dfa->init_state_nl == NULL - || dfa->init_state_begbuf == NULL, 0)) - return err; - } - else - dfa->init_state_word = dfa->init_state_nl - = dfa->init_state_begbuf = dfa->init_state; - - re_node_set_free (&init_nodes); - return REG_NOERROR; -} - -#ifdef RE_ENABLE_I18N -/* If it is possible to do searching in single byte encoding instead of UTF-8 - to speed things up, set dfa->mb_cur_max to 1, clear is_utf8 and change - DFA nodes where needed. */ - -static void -optimize_utf8 (re_dfa_t *dfa) -{ - int node, i, mb_chars = 0, has_period = 0; - - for (node = 0; node < dfa->nodes_len; ++node) - switch (dfa->nodes[node].type) - { - case CHARACTER: - if (dfa->nodes[node].opr.c >= 0x80) - mb_chars = 1; - break; - case ANCHOR: - switch (dfa->nodes[node].opr.ctx_type) - { - case LINE_FIRST: - case LINE_LAST: - case BUF_FIRST: - case BUF_LAST: - break; - default: - /* Word anchors etc. cannot be handled. It's okay to test - opr.ctx_type since constraints (for all DFA nodes) are - created by ORing one or more opr.ctx_type values. */ - return; - } - break; - case OP_PERIOD: - has_period = 1; - break; - case OP_BACK_REF: - case OP_ALT: - case END_OF_RE: - case OP_DUP_ASTERISK: - case OP_OPEN_SUBEXP: - case OP_CLOSE_SUBEXP: - break; - case COMPLEX_BRACKET: - return; - case SIMPLE_BRACKET: - /* Just double check. The non-ASCII range starts at 0x80. */ - assert (0x80 % BITSET_WORD_BITS == 0); - for (i = 0x80 / BITSET_WORD_BITS; i < BITSET_WORDS; ++i) - if (dfa->nodes[node].opr.sbcset[i]) - return; - break; - default: - abort (); - } - - if (mb_chars || has_period) - for (node = 0; node < dfa->nodes_len; ++node) - { - if (dfa->nodes[node].type == CHARACTER - && dfa->nodes[node].opr.c >= 0x80) - dfa->nodes[node].mb_partial = 0; - else if (dfa->nodes[node].type == OP_PERIOD) - dfa->nodes[node].type = OP_UTF8_PERIOD; - } - - /* The search can be in single byte locale. */ - dfa->mb_cur_max = 1; - dfa->is_utf8 = 0; - dfa->has_mb_node = dfa->nbackref > 0 || has_period; -} -#endif - -/* Analyze the structure tree, and calculate "first", "next", "edest", - "eclosure", and "inveclosure". */ - -static reg_errcode_t -analyze (regex_t *preg) -{ - re_dfa_t *dfa = (re_dfa_t *) preg->buffer; - reg_errcode_t ret; - - /* Allocate arrays. */ - dfa->nexts = re_malloc (int, dfa->nodes_alloc); - dfa->org_indices = re_malloc (int, dfa->nodes_alloc); - dfa->edests = re_malloc (re_node_set, dfa->nodes_alloc); - dfa->eclosures = re_malloc (re_node_set, dfa->nodes_alloc); - if (BE (dfa->nexts == NULL || dfa->org_indices == NULL || dfa->edests == NULL - || dfa->eclosures == NULL, 0)) - return REG_ESPACE; - - dfa->subexp_map = re_malloc (int, preg->re_nsub); - if (dfa->subexp_map != NULL) - { - unsigned int i; - for (i = 0; i < preg->re_nsub; i++) - dfa->subexp_map[i] = i; - preorder (dfa->str_tree, optimize_subexps, dfa); - for (i = 0; i < preg->re_nsub; i++) - if (dfa->subexp_map[i] != i) - break; - if (i == preg->re_nsub) - { - free (dfa->subexp_map); - dfa->subexp_map = NULL; - } - } - - ret = postorder (dfa->str_tree, lower_subexps, preg); - if (BE (ret != REG_NOERROR, 0)) - return ret; - ret = postorder (dfa->str_tree, calc_first, dfa); - if (BE (ret != REG_NOERROR, 0)) - return ret; - preorder (dfa->str_tree, calc_next, dfa); - ret = preorder (dfa->str_tree, link_nfa_nodes, dfa); - if (BE (ret != REG_NOERROR, 0)) - return ret; - ret = calc_eclosure (dfa); - if (BE (ret != REG_NOERROR, 0)) - return ret; - - /* We only need this during the prune_impossible_nodes pass in regexec.c; - skip it if p_i_n will not run, as calc_inveclosure can be quadratic. */ - if ((!preg->no_sub && preg->re_nsub > 0 && dfa->has_plural_match) - || dfa->nbackref) - { - dfa->inveclosures = re_malloc (re_node_set, dfa->nodes_len); - if (BE (dfa->inveclosures == NULL, 0)) - return REG_ESPACE; - ret = calc_inveclosure (dfa); - } - - return ret; -} - -/* Our parse trees are very unbalanced, so we cannot use a stack to - implement parse tree visits. Instead, we use parent pointers and - some hairy code in these two functions. */ -static reg_errcode_t -postorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)), - void *extra) -{ - bin_tree_t *node, *prev; - - for (node = root; ; ) - { - /* Descend down the tree, preferably to the left (or to the right - if that's the only child). */ - while (node->left || node->right) - if (node->left) - node = node->left; - else - node = node->right; - - do - { - reg_errcode_t err = fn (extra, node); - if (BE (err != REG_NOERROR, 0)) - return err; - if (node->parent == NULL) - return REG_NOERROR; - prev = node; - node = node->parent; - } - /* Go up while we have a node that is reached from the right. */ - while (node->right == prev || node->right == NULL); - node = node->right; - } -} - -static reg_errcode_t -preorder (bin_tree_t *root, reg_errcode_t (fn (void *, bin_tree_t *)), - void *extra) -{ - bin_tree_t *node; - - for (node = root; ; ) - { - reg_errcode_t err = fn (extra, node); - if (BE (err != REG_NOERROR, 0)) - return err; - - /* Go to the left node, or up and to the right. */ - if (node->left) - node = node->left; - else - { - bin_tree_t *prev = NULL; - while (node->right == prev || node->right == NULL) - { - prev = node; - node = node->parent; - if (!node) - return REG_NOERROR; - } - node = node->right; - } - } -} - -/* Optimization pass: if a SUBEXP is entirely contained, strip it and tell - re_search_internal to map the inner one's opr.idx to this one's. Adjust - backreferences as well. Requires a preorder visit. */ -static reg_errcode_t -optimize_subexps (void *extra, bin_tree_t *node) -{ - re_dfa_t *dfa = (re_dfa_t *) extra; - - if (node->token.type == OP_BACK_REF && dfa->subexp_map) - { - int idx = node->token.opr.idx; - node->token.opr.idx = dfa->subexp_map[idx]; - dfa->used_bkref_map |= 1 << node->token.opr.idx; - } - - else if (node->token.type == SUBEXP - && node->left && node->left->token.type == SUBEXP) - { - int other_idx = node->left->token.opr.idx; - - node->left = node->left->left; - if (node->left) - node->left->parent = node; - - dfa->subexp_map[other_idx] = dfa->subexp_map[node->token.opr.idx]; - if (other_idx < BITSET_WORD_BITS) - dfa->used_bkref_map &= ~((bitset_word_t) 1 << other_idx); - } - - return REG_NOERROR; -} - -/* Lowering pass: Turn each SUBEXP node into the appropriate concatenation - of OP_OPEN_SUBEXP, the body of the SUBEXP (if any) and OP_CLOSE_SUBEXP. */ -static reg_errcode_t -lower_subexps (void *extra, bin_tree_t *node) -{ - regex_t *preg = (regex_t *) extra; - reg_errcode_t err = REG_NOERROR; - - if (node->left && node->left->token.type == SUBEXP) - { - node->left = lower_subexp (&err, preg, node->left); - if (node->left) - node->left->parent = node; - } - if (node->right && node->right->token.type == SUBEXP) - { - node->right = lower_subexp (&err, preg, node->right); - if (node->right) - node->right->parent = node; - } - - return err; -} - -static bin_tree_t * -lower_subexp (reg_errcode_t *err, regex_t *preg, bin_tree_t *node) -{ - re_dfa_t *dfa = (re_dfa_t *) preg->buffer; - bin_tree_t *body = node->left; - bin_tree_t *op, *cls, *tree1, *tree; - - if (preg->no_sub - /* We do not optimize empty subexpressions, because otherwise we may - have bad CONCAT nodes with NULL children. This is obviously not - very common, so we do not lose much. An example that triggers - this case is the sed "script" /\(\)/x. */ - && node->left != NULL - && (node->token.opr.idx >= BITSET_WORD_BITS - || !(dfa->used_bkref_map - & ((bitset_word_t) 1 << node->token.opr.idx)))) - return node->left; - - /* Convert the SUBEXP node to the concatenation of an - OP_OPEN_SUBEXP, the contents, and an OP_CLOSE_SUBEXP. */ - op = create_tree (dfa, NULL, NULL, OP_OPEN_SUBEXP); - cls = create_tree (dfa, NULL, NULL, OP_CLOSE_SUBEXP); - tree1 = body ? create_tree (dfa, body, cls, CONCAT) : cls; - tree = create_tree (dfa, op, tree1, CONCAT); - if (BE (tree == NULL || tree1 == NULL || op == NULL || cls == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - - op->token.opr.idx = cls->token.opr.idx = node->token.opr.idx; - op->token.opt_subexp = cls->token.opt_subexp = node->token.opt_subexp; - return tree; -} - -/* Pass 1 in building the NFA: compute FIRST and create unlinked automaton - nodes. Requires a postorder visit. */ -static reg_errcode_t -calc_first (void *extra, bin_tree_t *node) -{ - re_dfa_t *dfa = (re_dfa_t *) extra; - if (node->token.type == CONCAT) - { - node->first = node->left->first; - node->node_idx = node->left->node_idx; - } - else - { - node->first = node; - node->node_idx = re_dfa_add_node (dfa, node->token); - if (BE (node->node_idx == -1, 0)) - return REG_ESPACE; - if (node->token.type == ANCHOR) - dfa->nodes[node->node_idx].constraint = node->token.opr.ctx_type; - } - return REG_NOERROR; -} - -/* Pass 2: compute NEXT on the tree. Preorder visit. */ -static reg_errcode_t -calc_next (void *extra, bin_tree_t *node) -{ - switch (node->token.type) - { - case OP_DUP_ASTERISK: - node->left->next = node; - break; - case CONCAT: - node->left->next = node->right->first; - node->right->next = node->next; - break; - default: - if (node->left) - node->left->next = node->next; - if (node->right) - node->right->next = node->next; - break; - } - return REG_NOERROR; -} - -/* Pass 3: link all DFA nodes to their NEXT node (any order will do). */ -static reg_errcode_t -link_nfa_nodes (void *extra, bin_tree_t *node) -{ - re_dfa_t *dfa = (re_dfa_t *) extra; - int idx = node->node_idx; - reg_errcode_t err = REG_NOERROR; - - switch (node->token.type) - { - case CONCAT: - break; - - case END_OF_RE: - assert (node->next == NULL); - break; - - case OP_DUP_ASTERISK: - case OP_ALT: - { - int left, right; - dfa->has_plural_match = 1; - if (node->left != NULL) - left = node->left->first->node_idx; - else - left = node->next->node_idx; - if (node->right != NULL) - right = node->right->first->node_idx; - else - right = node->next->node_idx; - assert (left > -1); - assert (right > -1); - err = re_node_set_init_2 (dfa->edests + idx, left, right); - } - break; - - case ANCHOR: - case OP_OPEN_SUBEXP: - case OP_CLOSE_SUBEXP: - err = re_node_set_init_1 (dfa->edests + idx, node->next->node_idx); - break; - - case OP_BACK_REF: - dfa->nexts[idx] = node->next->node_idx; - if (node->token.type == OP_BACK_REF) - err = re_node_set_init_1 (dfa->edests + idx, dfa->nexts[idx]); - break; - - default: - assert (!IS_EPSILON_NODE (node->token.type)); - dfa->nexts[idx] = node->next->node_idx; - break; - } - - return err; -} - -/* Duplicate the epsilon closure of the node ROOT_NODE. - Note that duplicated nodes have constraint INIT_CONSTRAINT in addition - to their own constraint. */ - -static reg_errcode_t -internal_function -duplicate_node_closure (re_dfa_t *dfa, int top_org_node, int top_clone_node, - int root_node, unsigned int init_constraint) -{ - int org_node, clone_node, ret; - unsigned int constraint = init_constraint; - for (org_node = top_org_node, clone_node = top_clone_node;;) - { - int org_dest, clone_dest; - if (dfa->nodes[org_node].type == OP_BACK_REF) - { - /* If the back reference epsilon-transit, its destination must - also have the constraint. Then duplicate the epsilon closure - of the destination of the back reference, and store it in - edests of the back reference. */ - org_dest = dfa->nexts[org_node]; - re_node_set_empty (dfa->edests + clone_node); - clone_dest = duplicate_node (dfa, org_dest, constraint); - if (BE (clone_dest == -1, 0)) - return REG_ESPACE; - dfa->nexts[clone_node] = dfa->nexts[org_node]; - ret = re_node_set_insert (dfa->edests + clone_node, clone_dest); - if (BE (ret < 0, 0)) - return REG_ESPACE; - } - else if (dfa->edests[org_node].nelem == 0) - { - /* In case of the node can't epsilon-transit, don't duplicate the - destination and store the original destination as the - destination of the node. */ - dfa->nexts[clone_node] = dfa->nexts[org_node]; - break; - } - else if (dfa->edests[org_node].nelem == 1) - { - /* In case of the node can epsilon-transit, and it has only one - destination. */ - org_dest = dfa->edests[org_node].elems[0]; - re_node_set_empty (dfa->edests + clone_node); - /* If the node is root_node itself, it means the epsilon clsoure - has a loop. Then tie it to the destination of the root_node. */ - if (org_node == root_node && clone_node != org_node) - { - ret = re_node_set_insert (dfa->edests + clone_node, org_dest); - if (BE (ret < 0, 0)) - return REG_ESPACE; - break; - } - /* In case of the node has another constraint, add it. */ - constraint |= dfa->nodes[org_node].constraint; - clone_dest = duplicate_node (dfa, org_dest, constraint); - if (BE (clone_dest == -1, 0)) - return REG_ESPACE; - ret = re_node_set_insert (dfa->edests + clone_node, clone_dest); - if (BE (ret < 0, 0)) - return REG_ESPACE; - } - else /* dfa->edests[org_node].nelem == 2 */ - { - /* In case of the node can epsilon-transit, and it has two - destinations. In the bin_tree_t and DFA, that's '|' and '*'. */ - org_dest = dfa->edests[org_node].elems[0]; - re_node_set_empty (dfa->edests + clone_node); - /* Search for a duplicated node which satisfies the constraint. */ - clone_dest = search_duplicated_node (dfa, org_dest, constraint); - if (clone_dest == -1) - { - /* There is no such duplicated node, create a new one. */ - reg_errcode_t err; - clone_dest = duplicate_node (dfa, org_dest, constraint); - if (BE (clone_dest == -1, 0)) - return REG_ESPACE; - ret = re_node_set_insert (dfa->edests + clone_node, clone_dest); - if (BE (ret < 0, 0)) - return REG_ESPACE; - err = duplicate_node_closure (dfa, org_dest, clone_dest, - root_node, constraint); - if (BE (err != REG_NOERROR, 0)) - return err; - } - else - { - /* There is a duplicated node which satisfies the constraint, - use it to avoid infinite loop. */ - ret = re_node_set_insert (dfa->edests + clone_node, clone_dest); - if (BE (ret < 0, 0)) - return REG_ESPACE; - } - - org_dest = dfa->edests[org_node].elems[1]; - clone_dest = duplicate_node (dfa, org_dest, constraint); - if (BE (clone_dest == -1, 0)) - return REG_ESPACE; - ret = re_node_set_insert (dfa->edests + clone_node, clone_dest); - if (BE (ret < 0, 0)) - return REG_ESPACE; - } - org_node = org_dest; - clone_node = clone_dest; - } - return REG_NOERROR; -} - -/* Search for a node which is duplicated from the node ORG_NODE, and - satisfies the constraint CONSTRAINT. */ - -static int -search_duplicated_node (const re_dfa_t *dfa, int org_node, - unsigned int constraint) -{ - int idx; - for (idx = dfa->nodes_len - 1; dfa->nodes[idx].duplicated && idx > 0; --idx) - { - if (org_node == dfa->org_indices[idx] - && constraint == dfa->nodes[idx].constraint) - return idx; /* Found. */ - } - return -1; /* Not found. */ -} - -/* Duplicate the node whose index is ORG_IDX and set the constraint CONSTRAINT. - Return the index of the new node, or -1 if insufficient storage is - available. */ - -static int -duplicate_node (re_dfa_t *dfa, int org_idx, unsigned int constraint) -{ - int dup_idx = re_dfa_add_node (dfa, dfa->nodes[org_idx]); - if (BE (dup_idx != -1, 1)) - { - dfa->nodes[dup_idx].constraint = constraint; - dfa->nodes[dup_idx].constraint |= dfa->nodes[org_idx].constraint; - dfa->nodes[dup_idx].duplicated = 1; - - /* Store the index of the original node. */ - dfa->org_indices[dup_idx] = org_idx; - } - return dup_idx; -} - -static reg_errcode_t -calc_inveclosure (re_dfa_t *dfa) -{ - int ret; - unsigned int src, idx; - for (idx = 0; idx < dfa->nodes_len; ++idx) - re_node_set_init_empty (dfa->inveclosures + idx); - - for (src = 0; src < dfa->nodes_len; ++src) - { - int *elems = dfa->eclosures[src].elems; - int idx; - for (idx = 0; idx < dfa->eclosures[src].nelem; ++idx) - { - ret = re_node_set_insert_last (dfa->inveclosures + elems[idx], src); - if (BE (ret == -1, 0)) - return REG_ESPACE; - } - } - - return REG_NOERROR; -} - -/* Calculate "eclosure" for all the node in DFA. */ - -static reg_errcode_t -calc_eclosure (re_dfa_t *dfa) -{ - int node_idx, incomplete; -#ifdef DEBUG - assert (dfa->nodes_len > 0); -#endif - incomplete = 0; - /* For each nodes, calculate epsilon closure. */ - for (node_idx = 0; ; ++node_idx) - { - reg_errcode_t err; - re_node_set eclosure_elem; - if (node_idx == dfa->nodes_len) - { - if (!incomplete) - break; - incomplete = 0; - node_idx = 0; - } - -#ifdef DEBUG - assert (dfa->eclosures[node_idx].nelem != -1); -#endif - - /* If we have already calculated, skip it. */ - if (dfa->eclosures[node_idx].nelem != 0) - continue; - /* Calculate epsilon closure of `node_idx'. */ - err = calc_eclosure_iter (&eclosure_elem, dfa, node_idx, 1); - if (BE (err != REG_NOERROR, 0)) - return err; - - if (dfa->eclosures[node_idx].nelem == 0) - { - incomplete = 1; - re_node_set_free (&eclosure_elem); - } - } - return REG_NOERROR; -} - -/* Calculate epsilon closure of NODE. */ - -static reg_errcode_t -calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, int node, int root) -{ - reg_errcode_t err; - int i; - re_node_set eclosure; - int ret; - int incomplete = 0; - err = re_node_set_alloc (&eclosure, dfa->edests[node].nelem + 1); - if (BE (err != REG_NOERROR, 0)) - return err; - - /* This indicates that we are calculating this node now. - We reference this value to avoid infinite loop. */ - dfa->eclosures[node].nelem = -1; - - /* If the current node has constraints, duplicate all nodes - since they must inherit the constraints. */ - if (dfa->nodes[node].constraint - && dfa->edests[node].nelem - && !dfa->nodes[dfa->edests[node].elems[0]].duplicated) - { - err = duplicate_node_closure (dfa, node, node, node, - dfa->nodes[node].constraint); - if (BE (err != REG_NOERROR, 0)) - return err; - } - - /* Expand each epsilon destination nodes. */ - if (IS_EPSILON_NODE(dfa->nodes[node].type)) - for (i = 0; i < dfa->edests[node].nelem; ++i) - { - re_node_set eclosure_elem; - int edest = dfa->edests[node].elems[i]; - /* If calculating the epsilon closure of `edest' is in progress, - return intermediate result. */ - if (dfa->eclosures[edest].nelem == -1) - { - incomplete = 1; - continue; - } - /* If we haven't calculated the epsilon closure of `edest' yet, - calculate now. Otherwise use calculated epsilon closure. */ - if (dfa->eclosures[edest].nelem == 0) - { - err = calc_eclosure_iter (&eclosure_elem, dfa, edest, 0); - if (BE (err != REG_NOERROR, 0)) - return err; - } - else - eclosure_elem = dfa->eclosures[edest]; - /* Merge the epsilon closure of `edest'. */ - err = re_node_set_merge (&eclosure, &eclosure_elem); - if (BE (err != REG_NOERROR, 0)) - return err; - /* If the epsilon closure of `edest' is incomplete, - the epsilon closure of this node is also incomplete. */ - if (dfa->eclosures[edest].nelem == 0) - { - incomplete = 1; - re_node_set_free (&eclosure_elem); - } - } - - /* An epsilon closure includes itself. */ - ret = re_node_set_insert (&eclosure, node); - if (BE (ret < 0, 0)) - return REG_ESPACE; - if (incomplete && !root) - dfa->eclosures[node].nelem = 0; - else - dfa->eclosures[node] = eclosure; - *new_set = eclosure; - return REG_NOERROR; -} - -/* Functions for token which are used in the parser. */ - -/* Fetch a token from INPUT. - We must not use this function inside bracket expressions. */ - -static void -internal_function -fetch_token (re_token_t *result, re_string_t *input, reg_syntax_t syntax) -{ - re_string_skip_bytes (input, peek_token (result, input, syntax)); -} - -/* Peek a token from INPUT, and return the length of the token. - We must not use this function inside bracket expressions. */ - -static int -internal_function -peek_token (re_token_t *token, re_string_t *input, reg_syntax_t syntax) -{ - unsigned char c; - - if (re_string_eoi (input)) - { - token->type = END_OF_RE; - return 0; - } - - c = re_string_peek_byte (input, 0); - token->opr.c = c; - - token->word_char = 0; -#ifdef RE_ENABLE_I18N - token->mb_partial = 0; - if (input->mb_cur_max > 1 && - !re_string_first_byte (input, re_string_cur_idx (input))) - { - token->type = CHARACTER; - token->mb_partial = 1; - return 1; - } -#endif - if (c == '\\') - { - unsigned char c2; - if (re_string_cur_idx (input) + 1 >= re_string_length (input)) - { - token->type = BACK_SLASH; - return 1; - } - - c2 = re_string_peek_byte_case (input, 1); - token->opr.c = c2; - token->type = CHARACTER; -#ifdef RE_ENABLE_I18N - if (input->mb_cur_max > 1) - { - wint_t wc = re_string_wchar_at (input, - re_string_cur_idx (input) + 1); - token->word_char = IS_WIDE_WORD_CHAR (wc) != 0; - } - else -#endif - token->word_char = IS_WORD_CHAR (c2) != 0; - - switch (c2) - { - case '|': - if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_NO_BK_VBAR)) - token->type = OP_ALT; - break; - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - if (!(syntax & RE_NO_BK_REFS)) - { - token->type = OP_BACK_REF; - token->opr.idx = c2 - '1'; - } - break; - case '<': - if (!(syntax & RE_NO_GNU_OPS)) - { - token->type = ANCHOR; - token->opr.ctx_type = WORD_FIRST; - } - break; - case '>': - if (!(syntax & RE_NO_GNU_OPS)) - { - token->type = ANCHOR; - token->opr.ctx_type = WORD_LAST; - } - break; - case 'b': - if (!(syntax & RE_NO_GNU_OPS)) - { - token->type = ANCHOR; - token->opr.ctx_type = WORD_DELIM; - } - break; - case 'B': - if (!(syntax & RE_NO_GNU_OPS)) - { - token->type = ANCHOR; - token->opr.ctx_type = NOT_WORD_DELIM; - } - break; - case 'w': - if (!(syntax & RE_NO_GNU_OPS)) - token->type = OP_WORD; - break; - case 'W': - if (!(syntax & RE_NO_GNU_OPS)) - token->type = OP_NOTWORD; - break; - case 's': - if (!(syntax & RE_NO_GNU_OPS)) - token->type = OP_SPACE; - break; - case 'S': - if (!(syntax & RE_NO_GNU_OPS)) - token->type = OP_NOTSPACE; - break; - case '`': - if (!(syntax & RE_NO_GNU_OPS)) - { - token->type = ANCHOR; - token->opr.ctx_type = BUF_FIRST; - } - break; - case '\'': - if (!(syntax & RE_NO_GNU_OPS)) - { - token->type = ANCHOR; - token->opr.ctx_type = BUF_LAST; - } - break; - case '(': - if (!(syntax & RE_NO_BK_PARENS)) - token->type = OP_OPEN_SUBEXP; - break; - case ')': - if (!(syntax & RE_NO_BK_PARENS)) - token->type = OP_CLOSE_SUBEXP; - break; - case '+': - if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM)) - token->type = OP_DUP_PLUS; - break; - case '?': - if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM)) - token->type = OP_DUP_QUESTION; - break; - case '{': - if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES))) - token->type = OP_OPEN_DUP_NUM; - break; - case '}': - if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES))) - token->type = OP_CLOSE_DUP_NUM; - break; - default: - break; - } - return 2; - } - - token->type = CHARACTER; -#ifdef RE_ENABLE_I18N - if (input->mb_cur_max > 1) - { - wint_t wc = re_string_wchar_at (input, re_string_cur_idx (input)); - token->word_char = IS_WIDE_WORD_CHAR (wc) != 0; - } - else -#endif - token->word_char = IS_WORD_CHAR (token->opr.c); - - switch (c) - { - case '\n': - if (syntax & RE_NEWLINE_ALT) - token->type = OP_ALT; - break; - case '|': - if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_NO_BK_VBAR)) - token->type = OP_ALT; - break; - case '*': - token->type = OP_DUP_ASTERISK; - break; - case '+': - if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM)) - token->type = OP_DUP_PLUS; - break; - case '?': - if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM)) - token->type = OP_DUP_QUESTION; - break; - case '{': - if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES)) - token->type = OP_OPEN_DUP_NUM; - break; - case '}': - if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES)) - token->type = OP_CLOSE_DUP_NUM; - break; - case '(': - if (syntax & RE_NO_BK_PARENS) - token->type = OP_OPEN_SUBEXP; - break; - case ')': - if (syntax & RE_NO_BK_PARENS) - token->type = OP_CLOSE_SUBEXP; - break; - case '[': - token->type = OP_OPEN_BRACKET; - break; - case '.': - token->type = OP_PERIOD; - break; - case '^': - if (!(syntax & (RE_CONTEXT_INDEP_ANCHORS | RE_CARET_ANCHORS_HERE)) && - re_string_cur_idx (input) != 0) - { - char prev = re_string_peek_byte (input, -1); - if (!(syntax & RE_NEWLINE_ALT) || prev != '\n') - break; - } - token->type = ANCHOR; - token->opr.ctx_type = LINE_FIRST; - break; - case '$': - if (!(syntax & RE_CONTEXT_INDEP_ANCHORS) && - re_string_cur_idx (input) + 1 != re_string_length (input)) - { - re_token_t next; - re_string_skip_bytes (input, 1); - peek_token (&next, input, syntax); - re_string_skip_bytes (input, -1); - if (next.type != OP_ALT && next.type != OP_CLOSE_SUBEXP) - break; - } - token->type = ANCHOR; - token->opr.ctx_type = LINE_LAST; - break; - default: - break; - } - return 1; -} - -/* Peek a token from INPUT, and return the length of the token. - We must not use this function out of bracket expressions. */ - -static int -internal_function -peek_token_bracket (re_token_t *token, re_string_t *input, reg_syntax_t syntax) -{ - unsigned char c; - if (re_string_eoi (input)) - { - token->type = END_OF_RE; - return 0; - } - c = re_string_peek_byte (input, 0); - token->opr.c = c; - -#ifdef RE_ENABLE_I18N - if (input->mb_cur_max > 1 && - !re_string_first_byte (input, re_string_cur_idx (input))) - { - token->type = CHARACTER; - return 1; - } -#endif /* RE_ENABLE_I18N */ - - if (c == '\\' && (syntax & RE_BACKSLASH_ESCAPE_IN_LISTS) - && re_string_cur_idx (input) + 1 < re_string_length (input)) - { - /* In this case, '\' escape a character. */ - unsigned char c2; - re_string_skip_bytes (input, 1); - c2 = re_string_peek_byte (input, 0); - token->opr.c = c2; - token->type = CHARACTER; - return 1; - } - if (c == '[') /* '[' is a special char in a bracket exps. */ - { - unsigned char c2; - int token_len; - if (re_string_cur_idx (input) + 1 < re_string_length (input)) - c2 = re_string_peek_byte (input, 1); - else - c2 = 0; - token->opr.c = c2; - token_len = 2; - switch (c2) - { - case '.': - token->type = OP_OPEN_COLL_ELEM; - break; - case '=': - token->type = OP_OPEN_EQUIV_CLASS; - break; - case ':': - if (syntax & RE_CHAR_CLASSES) - { - token->type = OP_OPEN_CHAR_CLASS; - break; - } - /* else fall through. */ - default: - token->type = CHARACTER; - token->opr.c = c; - token_len = 1; - break; - } - return token_len; - } - switch (c) - { - case '-': - token->type = OP_CHARSET_RANGE; - break; - case ']': - token->type = OP_CLOSE_BRACKET; - break; - case '^': - token->type = OP_NON_MATCH_LIST; - break; - default: - token->type = CHARACTER; - } - return 1; -} - -/* Functions for parser. */ - -/* Entry point of the parser. - Parse the regular expression REGEXP and return the structure tree. - If an error is occured, ERR is set by error code, and return NULL. - This function build the following tree, from regular expression : - CAT - / \ - / \ - EOR - - CAT means concatenation. - EOR means end of regular expression. */ - -static bin_tree_t * -parse (re_string_t *regexp, regex_t *preg, reg_syntax_t syntax, - reg_errcode_t *err) -{ - re_dfa_t *dfa = (re_dfa_t *) preg->buffer; - bin_tree_t *tree, *eor, *root; - re_token_t current_token; - dfa->syntax = syntax; - fetch_token (¤t_token, regexp, syntax | RE_CARET_ANCHORS_HERE); - tree = parse_reg_exp (regexp, preg, ¤t_token, syntax, 0, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - eor = create_tree (dfa, NULL, NULL, END_OF_RE); - if (tree != NULL) - root = create_tree (dfa, tree, eor, CONCAT); - else - root = eor; - if (BE (eor == NULL || root == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - return root; -} - -/* This function build the following tree, from regular expression - |: - ALT - / \ - / \ - - - ALT means alternative, which represents the operator `|'. */ - -static bin_tree_t * -parse_reg_exp (re_string_t *regexp, regex_t *preg, re_token_t *token, - reg_syntax_t syntax, int nest, reg_errcode_t *err) -{ - re_dfa_t *dfa = (re_dfa_t *) preg->buffer; - bin_tree_t *tree, *branch = NULL; - tree = parse_branch (regexp, preg, token, syntax, nest, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - - while (token->type == OP_ALT) - { - fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE); - if (token->type != OP_ALT && token->type != END_OF_RE - && (nest == 0 || token->type != OP_CLOSE_SUBEXP)) - { - branch = parse_branch (regexp, preg, token, syntax, nest, err); - if (BE (*err != REG_NOERROR && branch == NULL, 0)) - return NULL; - } - else - branch = NULL; - tree = create_tree (dfa, tree, branch, OP_ALT); - if (BE (tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - } - return tree; -} - -/* This function build the following tree, from regular expression - : - CAT - / \ - / \ - - - CAT means concatenation. */ - -static bin_tree_t * -parse_branch (re_string_t *regexp, regex_t *preg, re_token_t *token, - reg_syntax_t syntax, int nest, reg_errcode_t *err) -{ - bin_tree_t *tree, *exp; - re_dfa_t *dfa = (re_dfa_t *) preg->buffer; - tree = parse_expression (regexp, preg, token, syntax, nest, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - - while (token->type != OP_ALT && token->type != END_OF_RE - && (nest == 0 || token->type != OP_CLOSE_SUBEXP)) - { - exp = parse_expression (regexp, preg, token, syntax, nest, err); - if (BE (*err != REG_NOERROR && exp == NULL, 0)) - { - return NULL; - } - if (tree != NULL && exp != NULL) - { - tree = create_tree (dfa, tree, exp, CONCAT); - if (tree == NULL) - { - *err = REG_ESPACE; - return NULL; - } - } - else if (tree == NULL) - tree = exp; - /* Otherwise exp == NULL, we don't need to create new tree. */ - } - return tree; -} - -/* This function build the following tree, from regular expression a*: - * - | - a -*/ - -static bin_tree_t * -parse_expression (re_string_t *regexp, regex_t *preg, re_token_t *token, - reg_syntax_t syntax, int nest, reg_errcode_t *err) -{ - re_dfa_t *dfa = (re_dfa_t *) preg->buffer; - bin_tree_t *tree; - switch (token->type) - { - case CHARACTER: - tree = create_token_tree (dfa, NULL, NULL, token); - if (BE (tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - { - while (!re_string_eoi (regexp) - && !re_string_first_byte (regexp, re_string_cur_idx (regexp))) - { - bin_tree_t *mbc_remain; - fetch_token (token, regexp, syntax); - mbc_remain = create_token_tree (dfa, NULL, NULL, token); - tree = create_tree (dfa, tree, mbc_remain, CONCAT); - if (BE (mbc_remain == NULL || tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - } - } -#endif - break; - case OP_OPEN_SUBEXP: - tree = parse_sub_exp (regexp, preg, token, syntax, nest + 1, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - break; - case OP_OPEN_BRACKET: - tree = parse_bracket_exp (regexp, dfa, token, syntax, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - break; - case OP_BACK_REF: - if (!BE (dfa->completed_bkref_map & (1 << token->opr.idx), 1)) - { - *err = REG_ESUBREG; - return NULL; - } - dfa->used_bkref_map |= 1 << token->opr.idx; - tree = create_token_tree (dfa, NULL, NULL, token); - if (BE (tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - ++dfa->nbackref; - dfa->has_mb_node = 1; - break; - case OP_OPEN_DUP_NUM: - if (syntax & RE_CONTEXT_INVALID_DUP) - { - *err = REG_BADRPT; - return NULL; - } - /* FALLTHROUGH */ - case OP_DUP_ASTERISK: - case OP_DUP_PLUS: - case OP_DUP_QUESTION: - if (syntax & RE_CONTEXT_INVALID_OPS) - { - *err = REG_BADRPT; - return NULL; - } - else if (syntax & RE_CONTEXT_INDEP_OPS) - { - fetch_token (token, regexp, syntax); - return parse_expression (regexp, preg, token, syntax, nest, err); - } - /* else fall through */ - case OP_CLOSE_SUBEXP: - if ((token->type == OP_CLOSE_SUBEXP) && - !(syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)) - { - *err = REG_ERPAREN; - return NULL; - } - /* else fall through */ - case OP_CLOSE_DUP_NUM: - /* We treat it as a normal character. */ - - /* Then we can these characters as normal characters. */ - token->type = CHARACTER; - /* mb_partial and word_char bits should be initialized already - by peek_token. */ - tree = create_token_tree (dfa, NULL, NULL, token); - if (BE (tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - break; - case ANCHOR: - if ((token->opr.ctx_type - & (WORD_DELIM | NOT_WORD_DELIM | WORD_FIRST | WORD_LAST)) - && dfa->word_ops_used == 0) - init_word_char (dfa); - if (token->opr.ctx_type == WORD_DELIM - || token->opr.ctx_type == NOT_WORD_DELIM) - { - bin_tree_t *tree_first, *tree_last; - if (token->opr.ctx_type == WORD_DELIM) - { - token->opr.ctx_type = WORD_FIRST; - tree_first = create_token_tree (dfa, NULL, NULL, token); - token->opr.ctx_type = WORD_LAST; - } - else - { - token->opr.ctx_type = INSIDE_WORD; - tree_first = create_token_tree (dfa, NULL, NULL, token); - token->opr.ctx_type = INSIDE_NOTWORD; - } - tree_last = create_token_tree (dfa, NULL, NULL, token); - tree = create_tree (dfa, tree_first, tree_last, OP_ALT); - if (BE (tree_first == NULL || tree_last == NULL || tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - } - else - { - tree = create_token_tree (dfa, NULL, NULL, token); - if (BE (tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - } - /* We must return here, since ANCHORs can't be followed - by repetition operators. - eg. RE"^*" is invalid or "", - it must not be "". */ - fetch_token (token, regexp, syntax); - return tree; - case OP_PERIOD: - tree = create_token_tree (dfa, NULL, NULL, token); - if (BE (tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - if (dfa->mb_cur_max > 1) - dfa->has_mb_node = 1; - break; - case OP_WORD: - case OP_NOTWORD: - tree = build_charclass_op (dfa, regexp->trans, - "alnum", - "_", - token->type == OP_NOTWORD, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - break; - case OP_SPACE: - case OP_NOTSPACE: - tree = build_charclass_op (dfa, regexp->trans, - "space", - "", - token->type == OP_NOTSPACE, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - break; - case OP_ALT: - case END_OF_RE: - return NULL; - case BACK_SLASH: - *err = REG_EESCAPE; - return NULL; - default: - /* Must not happen? */ -#ifdef DEBUG - assert (0); -#endif - return NULL; - } - fetch_token (token, regexp, syntax); - - while (token->type == OP_DUP_ASTERISK || token->type == OP_DUP_PLUS - || token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM) - { - tree = parse_dup_op (tree, regexp, dfa, token, syntax, err); - if (BE (*err != REG_NOERROR && tree == NULL, 0)) - return NULL; - /* In BRE consecutive duplications are not allowed. */ - if ((syntax & RE_CONTEXT_INVALID_DUP) - && (token->type == OP_DUP_ASTERISK - || token->type == OP_OPEN_DUP_NUM)) - { - *err = REG_BADRPT; - return NULL; - } - } - - return tree; -} - -/* This function build the following tree, from regular expression - (): - SUBEXP - | - -*/ - -static bin_tree_t * -parse_sub_exp (re_string_t *regexp, regex_t *preg, re_token_t *token, - reg_syntax_t syntax, int nest, reg_errcode_t *err) -{ - re_dfa_t *dfa = (re_dfa_t *) preg->buffer; - bin_tree_t *tree; - size_t cur_nsub; - cur_nsub = preg->re_nsub++; - - fetch_token (token, regexp, syntax | RE_CARET_ANCHORS_HERE); - - /* The subexpression may be a null string. */ - if (token->type == OP_CLOSE_SUBEXP) - tree = NULL; - else - { - tree = parse_reg_exp (regexp, preg, token, syntax, nest, err); - if (BE (*err == REG_NOERROR && token->type != OP_CLOSE_SUBEXP, 0)) - *err = REG_EPAREN; - if (BE (*err != REG_NOERROR, 0)) - return NULL; - } - - if (cur_nsub <= '9' - '1') - dfa->completed_bkref_map |= 1 << cur_nsub; - - tree = create_tree (dfa, tree, NULL, SUBEXP); - if (BE (tree == NULL, 0)) - { - *err = REG_ESPACE; - return NULL; - } - tree->token.opr.idx = cur_nsub; - return tree; -} - -/* This function parse repetition operators like "*", "+", "{1,3}" etc. */ - -static bin_tree_t * -parse_dup_op (bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa, - re_token_t *token, reg_syntax_t syntax, reg_errcode_t *err) -{ - bin_tree_t *tree = NULL, *old_tree = NULL; - int i, start, end, start_idx = re_string_cur_idx (regexp); -#ifndef RE_TOKEN_INIT_BUG - re_token_t start_token = *token; -#else - re_token_t start_token; - - memcpy ((void *) &start_token, (void *) token, sizeof start_token); -#endif - - if (token->type == OP_OPEN_DUP_NUM) - { - end = 0; - start = fetch_number (regexp, token, syntax); - if (start == -1) - { - if (token->type == CHARACTER && token->opr.c == ',') - start = 0; /* We treat "{,m}" as "{0,m}". */ - else - { - *err = REG_BADBR; /* {} is invalid. */ - return NULL; - } - } - if (BE (start != -2, 1)) - { - /* We treat "{n}" as "{n,n}". */ - end = ((token->type == OP_CLOSE_DUP_NUM) ? start - : ((token->type == CHARACTER && token->opr.c == ',') - ? fetch_number (regexp, token, syntax) : -2)); - } - if (BE (start == -2 || end == -2, 0)) - { - /* Invalid sequence. */ - if (BE (!(syntax & RE_INVALID_INTERVAL_ORD), 0)) - { - if (token->type == END_OF_RE) - *err = REG_EBRACE; - else - *err = REG_BADBR; - - return NULL; - } - - /* If the syntax bit is set, rollback. */ - re_string_set_index (regexp, start_idx); - *token = start_token; - token->type = CHARACTER; - /* mb_partial and word_char bits should be already initialized by - peek_token. */ - return elem; - } - - if (BE ((end != -1 && start > end) || token->type != OP_CLOSE_DUP_NUM, 0)) - { - /* First number greater than second. */ - *err = REG_BADBR; - return NULL; - } - } - else - { - start = (token->type == OP_DUP_PLUS) ? 1 : 0; - end = (token->type == OP_DUP_QUESTION) ? 1 : -1; - } - - fetch_token (token, regexp, syntax); - - if (BE (elem == NULL, 0)) - return NULL; - if (BE (start == 0 && end == 0, 0)) - { - postorder (elem, free_tree, NULL); - return NULL; - } - - /* Extract "{n,m}" to "...{0,}". */ - if (BE (start > 0, 0)) - { - tree = elem; - for (i = 2; i <= start; ++i) - { - elem = duplicate_tree (elem, dfa); - tree = create_tree (dfa, tree, elem, CONCAT); - if (BE (elem == NULL || tree == NULL, 0)) - goto parse_dup_op_espace; - } - - if (start == end) - return tree; - - /* Duplicate ELEM before it is marked optional. */ - elem = duplicate_tree (elem, dfa); - old_tree = tree; - } - else - old_tree = NULL; - - if (elem->token.type == SUBEXP) - postorder (elem, mark_opt_subexp, (void *) (long) elem->token.opr.idx); - - tree = create_tree (dfa, elem, NULL, (end == -1 ? OP_DUP_ASTERISK : OP_ALT)); - if (BE (tree == NULL, 0)) - goto parse_dup_op_espace; - - /* This loop is actually executed only when end != -1, - to rewrite {0,n} as ((...?)?)?... We have - already created the start+1-th copy. */ - for (i = start + 2; i <= end; ++i) - { - elem = duplicate_tree (elem, dfa); - tree = create_tree (dfa, tree, elem, CONCAT); - if (BE (elem == NULL || tree == NULL, 0)) - goto parse_dup_op_espace; - - tree = create_tree (dfa, tree, NULL, OP_ALT); - if (BE (tree == NULL, 0)) - goto parse_dup_op_espace; - } - - if (old_tree) - tree = create_tree (dfa, old_tree, tree, CONCAT); - - return tree; - - parse_dup_op_espace: - *err = REG_ESPACE; - return NULL; -} - -/* Size of the names for collating symbol/equivalence_class/character_class. - I'm not sure, but maybe enough. */ -#define BRACKET_NAME_BUF_SIZE 32 - -#ifndef _LIBC - /* Local function for parse_bracket_exp only used in case of NOT _LIBC. - Build the range expression which starts from START_ELEM, and ends - at END_ELEM. The result are written to MBCSET and SBCSET. - RANGE_ALLOC is the allocated size of mbcset->range_starts, and - mbcset->range_ends, is a pointer argument sinse we may - update it. */ - -static reg_errcode_t -internal_function -# ifdef RE_ENABLE_I18N -build_range_exp (bitset_t sbcset, re_charset_t *mbcset, int *range_alloc, - bracket_elem_t *start_elem, bracket_elem_t *end_elem) -# else /* not RE_ENABLE_I18N */ -build_range_exp (bitset_t sbcset, bracket_elem_t *start_elem, - bracket_elem_t *end_elem) -# endif /* not RE_ENABLE_I18N */ -{ - unsigned int start_ch, end_ch; - /* Equivalence Classes and Character Classes can't be a range start/end. */ - if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS - || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS, - 0)) - return REG_ERANGE; - - /* We can handle no multi character collating elements without libc - support. */ - if (BE ((start_elem->type == COLL_SYM - && strlen ((char *) start_elem->opr.name) > 1) - || (end_elem->type == COLL_SYM - && strlen ((char *) end_elem->opr.name) > 1), 0)) - return REG_ECOLLATE; - -# ifdef RE_ENABLE_I18N - { - wchar_t wc; - wint_t start_wc; - wint_t end_wc; - wchar_t cmp_buf[6] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'}; - - start_ch = ((start_elem->type == SB_CHAR) ? start_elem->opr.ch - : ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0] - : 0)); - end_ch = ((end_elem->type == SB_CHAR) ? end_elem->opr.ch - : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0] - : 0)); -#ifdef GAWK - /* - * Fedora Core 2, maybe others, have broken `btowc' that returns -1 - * for any value > 127. Sigh. Note that `start_ch' and `end_ch' are - * unsigned, so we don't have sign extension problems. - */ - start_wc = ((start_elem->type == SB_CHAR || start_elem->type == COLL_SYM) - ? start_ch : start_elem->opr.wch); - end_wc = ((end_elem->type == SB_CHAR || end_elem->type == COLL_SYM) - ? end_ch : end_elem->opr.wch); -#else - start_wc = ((start_elem->type == SB_CHAR || start_elem->type == COLL_SYM) - ? __btowc (start_ch) : start_elem->opr.wch); - end_wc = ((end_elem->type == SB_CHAR || end_elem->type == COLL_SYM) - ? __btowc (end_ch) : end_elem->opr.wch); -#endif - if (start_wc == WEOF || end_wc == WEOF) - return REG_ECOLLATE; - cmp_buf[0] = start_wc; - cmp_buf[4] = end_wc; - if (wcscoll (cmp_buf, cmp_buf + 4) > 0) - return REG_ERANGE; - - /* Got valid collation sequence values, add them as a new entry. - However, for !_LIBC we have no collation elements: if the - character set is single byte, the single byte character set - that we build below suffices. parse_bracket_exp passes - no MBCSET if dfa->mb_cur_max == 1. */ - if (mbcset) - { - /* Check the space of the arrays. */ - if (BE (*range_alloc == mbcset->nranges, 0)) - { - /* There is not enough space, need realloc. */ - wchar_t *new_array_start, *new_array_end; - int new_nranges; - - /* +1 in case of mbcset->nranges is 0. */ - new_nranges = 2 * mbcset->nranges + 1; - /* Use realloc since mbcset->range_starts and mbcset->range_ends - are NULL if *range_alloc == 0. */ - new_array_start = re_realloc (mbcset->range_starts, wchar_t, - new_nranges); - new_array_end = re_realloc (mbcset->range_ends, wchar_t, - new_nranges); - - if (BE (new_array_start == NULL || new_array_end == NULL, 0)) - return REG_ESPACE; - - mbcset->range_starts = new_array_start; - mbcset->range_ends = new_array_end; - *range_alloc = new_nranges; - } - - mbcset->range_starts[mbcset->nranges] = start_wc; - mbcset->range_ends[mbcset->nranges++] = end_wc; - } - - /* Build the table for single byte characters. */ - for (wc = 0; wc < SBC_MAX; ++wc) - { - cmp_buf[2] = wc; - if (wcscoll (cmp_buf, cmp_buf + 2) <= 0 - && wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0) - bitset_set (sbcset, wc); - } - } -# else /* not RE_ENABLE_I18N */ - { - unsigned int ch; - start_ch = ((start_elem->type == SB_CHAR ) ? start_elem->opr.ch - : ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0] - : 0)); - end_ch = ((end_elem->type == SB_CHAR ) ? end_elem->opr.ch - : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0] - : 0)); - if (start_ch > end_ch) - return REG_ERANGE; - /* Build the table for single byte characters. */ - for (ch = 0; ch < SBC_MAX; ++ch) - if (start_ch <= ch && ch <= end_ch) - bitset_set (sbcset, ch); - } -# endif /* not RE_ENABLE_I18N */ - return REG_NOERROR; -} -#endif /* not _LIBC */ - -#ifndef _LIBC -/* Helper function for parse_bracket_exp only used in case of NOT _LIBC.. - Build the collating element which is represented by NAME. - The result are written to MBCSET and SBCSET. - COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a - pointer argument since we may update it. */ - -static reg_errcode_t -internal_function -# ifdef RE_ENABLE_I18N -build_collating_symbol (bitset_t sbcset, re_charset_t *mbcset, - int *coll_sym_alloc, const unsigned char *name) -# else /* not RE_ENABLE_I18N */ -build_collating_symbol (bitset_t sbcset, const unsigned char *name) -# endif /* not RE_ENABLE_I18N */ -{ - size_t name_len = strlen ((const char *) name); - if (BE (name_len != 1, 0)) - return REG_ECOLLATE; - else - { - bitset_set (sbcset, name[0]); - return REG_NOERROR; - } -} -#endif /* not _LIBC */ - -/* This function parse bracket expression like "[abc]", "[a-c]", - "[[.a-a.]]" etc. */ - -static bin_tree_t * -parse_bracket_exp (re_string_t *regexp, re_dfa_t *dfa, re_token_t *token, - reg_syntax_t syntax, reg_errcode_t *err) -{ -#ifdef _LIBC - const unsigned char *collseqmb; - const char *collseqwc; - uint32_t nrules; - int32_t table_size; - const int32_t *symb_table; - const unsigned char *extra; - - /* Local function for parse_bracket_exp used in _LIBC environement. - Seek the collating symbol entry correspondings to NAME. - Return the index of the symbol in the SYMB_TABLE. */ - - auto inline int32_t - __attribute ((always_inline)) - seek_collating_symbol_entry (name, name_len) - const unsigned char *name; - size_t name_len; - { - int32_t hash = elem_hash ((const char *) name, name_len); - int32_t elem = hash % table_size; - if (symb_table[2 * elem] != 0) - { - int32_t second = hash % (table_size - 2) + 1; - - do - { - /* First compare the hashing value. */ - if (symb_table[2 * elem] == hash - /* Compare the length of the name. */ - && name_len == extra[symb_table[2 * elem + 1]] - /* Compare the name. */ - && memcmp (name, &extra[symb_table[2 * elem + 1] + 1], - name_len) == 0) - { - /* Yep, this is the entry. */ - break; - } - - /* Next entry. */ - elem += second; - } - while (symb_table[2 * elem] != 0); - } - return elem; - } - - /* Local function for parse_bracket_exp used in _LIBC environment. - Look up the collation sequence value of BR_ELEM. - Return the value if succeeded, UINT_MAX otherwise. */ - - auto inline unsigned int - __attribute ((always_inline)) - lookup_collation_sequence_value (br_elem) - bracket_elem_t *br_elem; - { - if (br_elem->type == SB_CHAR) - { - /* - if (MB_CUR_MAX == 1) - */ - if (nrules == 0) - return collseqmb[br_elem->opr.ch]; - else - { - wint_t wc = __btowc (br_elem->opr.ch); - return __collseq_table_lookup (collseqwc, wc); - } - } - else if (br_elem->type == MB_CHAR) - { - if (nrules != 0) - return __collseq_table_lookup (collseqwc, br_elem->opr.wch); - } - else if (br_elem->type == COLL_SYM) - { - size_t sym_name_len = strlen ((char *) br_elem->opr.name); - if (nrules != 0) - { - int32_t elem, idx; - elem = seek_collating_symbol_entry (br_elem->opr.name, - sym_name_len); - if (symb_table[2 * elem] != 0) - { - /* We found the entry. */ - idx = symb_table[2 * elem + 1]; - /* Skip the name of collating element name. */ - idx += 1 + extra[idx]; - /* Skip the byte sequence of the collating element. */ - idx += 1 + extra[idx]; - /* Adjust for the alignment. */ - idx = (idx + 3) & ~3; - /* Skip the multibyte collation sequence value. */ - idx += sizeof (unsigned int); - /* Skip the wide char sequence of the collating element. */ - idx += sizeof (unsigned int) * - (1 + *(unsigned int *) (extra + idx)); - /* Return the collation sequence value. */ - return *(unsigned int *) (extra + idx); - } - else if (symb_table[2 * elem] == 0 && sym_name_len == 1) - { - /* No valid character. Match it as a single byte - character. */ - return collseqmb[br_elem->opr.name[0]]; - } - } - else if (sym_name_len == 1) - return collseqmb[br_elem->opr.name[0]]; - } - return UINT_MAX; - } - - /* Local function for parse_bracket_exp used in _LIBC environement. - Build the range expression which starts from START_ELEM, and ends - at END_ELEM. The result are written to MBCSET and SBCSET. - RANGE_ALLOC is the allocated size of mbcset->range_starts, and - mbcset->range_ends, is a pointer argument sinse we may - update it. */ - - auto inline reg_errcode_t - __attribute ((always_inline)) - build_range_exp (sbcset, mbcset, range_alloc, start_elem, end_elem) - re_charset_t *mbcset; - int *range_alloc; - bitset_t sbcset; - bracket_elem_t *start_elem, *end_elem; - { - unsigned int ch; - uint32_t start_collseq; - uint32_t end_collseq; - - /* Equivalence Classes and Character Classes can't be a range - start/end. */ - if (BE (start_elem->type == EQUIV_CLASS || start_elem->type == CHAR_CLASS - || end_elem->type == EQUIV_CLASS || end_elem->type == CHAR_CLASS, - 0)) - return REG_ERANGE; - - start_collseq = lookup_collation_sequence_value (start_elem); - end_collseq = lookup_collation_sequence_value (end_elem); - /* Check start/end collation sequence values. */ - if (BE (start_collseq == UINT_MAX || end_collseq == UINT_MAX, 0)) - return REG_ECOLLATE; - if (BE ((syntax & RE_NO_EMPTY_RANGES) && start_collseq > end_collseq, 0)) - return REG_ERANGE; - - /* Got valid collation sequence values, add them as a new entry. - However, if we have no collation elements, and the character set - is single byte, the single byte character set that we - build below suffices. */ - if (nrules > 0 || dfa->mb_cur_max > 1) - { - /* Check the space of the arrays. */ - if (BE (*range_alloc == mbcset->nranges, 0)) - { - /* There is not enough space, need realloc. */ - uint32_t *new_array_start; - uint32_t *new_array_end; - int new_nranges; - - /* +1 in case of mbcset->nranges is 0. */ - new_nranges = 2 * mbcset->nranges + 1; - new_array_start = re_realloc (mbcset->range_starts, uint32_t, - new_nranges); - new_array_end = re_realloc (mbcset->range_ends, uint32_t, - new_nranges); - - if (BE (new_array_start == NULL || new_array_end == NULL, 0)) - return REG_ESPACE; - - mbcset->range_starts = new_array_start; - mbcset->range_ends = new_array_end; - *range_alloc = new_nranges; - } - - mbcset->range_starts[mbcset->nranges] = start_collseq; - mbcset->range_ends[mbcset->nranges++] = end_collseq; - } - - /* Build the table for single byte characters. */ - for (ch = 0; ch < SBC_MAX; ch++) - { - uint32_t ch_collseq; - /* - if (MB_CUR_MAX == 1) - */ - if (nrules == 0) - ch_collseq = collseqmb[ch]; - else - ch_collseq = __collseq_table_lookup (collseqwc, __btowc (ch)); - if (start_collseq <= ch_collseq && ch_collseq <= end_collseq) - bitset_set (sbcset, ch); - } - return REG_NOERROR; - } - - /* Local function for parse_bracket_exp used in _LIBC environement. - Build the collating element which is represented by NAME. - The result are written to MBCSET and SBCSET. - COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a - pointer argument sinse we may update it. */ - - auto inline reg_errcode_t - __attribute ((always_inline)) - build_collating_symbol (sbcset, mbcset, coll_sym_alloc, name) - re_charset_t *mbcset; - int *coll_sym_alloc; - bitset_t sbcset; - const unsigned char *name; - { - int32_t elem, idx; - size_t name_len = strlen ((const char *) name); - if (nrules != 0) - { - elem = seek_collating_symbol_entry (name, name_len); - if (symb_table[2 * elem] != 0) - { - /* We found the entry. */ - idx = symb_table[2 * elem + 1]; - /* Skip the name of collating element name. */ - idx += 1 + extra[idx]; - } - else if (symb_table[2 * elem] == 0 && name_len == 1) - { - /* No valid character, treat it as a normal - character. */ - bitset_set (sbcset, name[0]); - return REG_NOERROR; - } - else - return REG_ECOLLATE; - - /* Got valid collation sequence, add it as a new entry. */ - /* Check the space of the arrays. */ - if (BE (*coll_sym_alloc == mbcset->ncoll_syms, 0)) - { - /* Not enough, realloc it. */ - /* +1 in case of mbcset->ncoll_syms is 0. */ - int new_coll_sym_alloc = 2 * mbcset->ncoll_syms + 1; - /* Use realloc since mbcset->coll_syms is NULL - if *alloc == 0. */ - int32_t *new_coll_syms = re_realloc (mbcset->coll_syms, int32_t, - new_coll_sym_alloc); - if (BE (new_coll_syms == NULL, 0)) - return REG_ESPACE; - mbcset->coll_syms = new_coll_syms; - *coll_sym_alloc = new_coll_sym_alloc; - } - mbcset->coll_syms[mbcset->ncoll_syms++] = idx; - return REG_NOERROR; - } - else - { - if (BE (name_len != 1, 0)) - return REG_ECOLLATE; - else - { - bitset_set (sbcset, name[0]); - return REG_NOERROR; - } - } - } -#endif - - re_token_t br_token; - re_bitset_ptr_t sbcset; -#ifdef RE_ENABLE_I18N - re_charset_t *mbcset; - int coll_sym_alloc = 0, range_alloc = 0, mbchar_alloc = 0; - int equiv_class_alloc = 0, char_class_alloc = 0; -#endif /* not RE_ENABLE_I18N */ - int non_match = 0; - bin_tree_t *work_tree; - int token_len; - int first_round = 1; -#ifdef _LIBC - collseqmb = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB); - nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); - if (nrules) - { - /* - if (MB_CUR_MAX > 1) - */ - collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC); - table_size = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_SYMB_HASH_SIZEMB); - symb_table = (const int32_t *) _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_SYMB_TABLEMB); - extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_SYMB_EXTRAMB); - } -#endif - sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); -#ifdef RE_ENABLE_I18N - mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); -#endif /* RE_ENABLE_I18N */ -#ifdef RE_ENABLE_I18N - if (BE (sbcset == NULL || mbcset == NULL, 0)) -#else - if (BE (sbcset == NULL, 0)) -#endif /* RE_ENABLE_I18N */ - { - *err = REG_ESPACE; - return NULL; - } - - token_len = peek_token_bracket (token, regexp, syntax); - if (BE (token->type == END_OF_RE, 0)) - { - *err = REG_BADPAT; - goto parse_bracket_exp_free_return; - } - if (token->type == OP_NON_MATCH_LIST) - { -#ifdef RE_ENABLE_I18N - mbcset->non_match = 1; -#endif /* not RE_ENABLE_I18N */ - non_match = 1; - if (syntax & RE_HAT_LISTS_NOT_NEWLINE) - bitset_set (sbcset, '\n'); - re_string_skip_bytes (regexp, token_len); /* Skip a token. */ - token_len = peek_token_bracket (token, regexp, syntax); - if (BE (token->type == END_OF_RE, 0)) - { - *err = REG_BADPAT; - goto parse_bracket_exp_free_return; - } - } - - /* We treat the first ']' as a normal character. */ - if (token->type == OP_CLOSE_BRACKET) - token->type = CHARACTER; - - while (1) - { - bracket_elem_t start_elem, end_elem; - unsigned char start_name_buf[BRACKET_NAME_BUF_SIZE]; - unsigned char end_name_buf[BRACKET_NAME_BUF_SIZE]; - reg_errcode_t ret; - int token_len2 = 0, is_range_exp = 0; - re_token_t token2; - - start_elem.opr.name = start_name_buf; - ret = parse_bracket_element (&start_elem, regexp, token, token_len, dfa, - syntax, first_round); - if (BE (ret != REG_NOERROR, 0)) - { - *err = ret; - goto parse_bracket_exp_free_return; - } - first_round = 0; - - /* Get information about the next token. We need it in any case. */ - token_len = peek_token_bracket (token, regexp, syntax); - - /* Do not check for ranges if we know they are not allowed. */ - if (start_elem.type != CHAR_CLASS && start_elem.type != EQUIV_CLASS) - { - if (BE (token->type == END_OF_RE, 0)) - { - *err = REG_EBRACK; - goto parse_bracket_exp_free_return; - } - if (token->type == OP_CHARSET_RANGE) - { - re_string_skip_bytes (regexp, token_len); /* Skip '-'. */ - token_len2 = peek_token_bracket (&token2, regexp, syntax); - if (BE (token2.type == END_OF_RE, 0)) - { - *err = REG_EBRACK; - goto parse_bracket_exp_free_return; - } - if (token2.type == OP_CLOSE_BRACKET) - { - /* We treat the last '-' as a normal character. */ - re_string_skip_bytes (regexp, -token_len); - token->type = CHARACTER; - } - else - is_range_exp = 1; - } - } - - if (is_range_exp == 1) - { - end_elem.opr.name = end_name_buf; - ret = parse_bracket_element (&end_elem, regexp, &token2, token_len2, - dfa, syntax, 1); - if (BE (ret != REG_NOERROR, 0)) - { - *err = ret; - goto parse_bracket_exp_free_return; - } - - token_len = peek_token_bracket (token, regexp, syntax); - -#ifdef _LIBC - *err = build_range_exp (sbcset, mbcset, &range_alloc, - &start_elem, &end_elem); -#else -# ifdef RE_ENABLE_I18N - *err = build_range_exp (sbcset, - dfa->mb_cur_max > 1 ? mbcset : NULL, - &range_alloc, &start_elem, &end_elem); -# else - *err = build_range_exp (sbcset, &start_elem, &end_elem); -# endif -#endif /* RE_ENABLE_I18N */ - if (BE (*err != REG_NOERROR, 0)) - goto parse_bracket_exp_free_return; - } - else - { - switch (start_elem.type) - { - case SB_CHAR: - bitset_set (sbcset, start_elem.opr.ch); - break; -#ifdef RE_ENABLE_I18N - case MB_CHAR: - /* Check whether the array has enough space. */ - if (BE (mbchar_alloc == mbcset->nmbchars, 0)) - { - wchar_t *new_mbchars; - /* Not enough, realloc it. */ - /* +1 in case of mbcset->nmbchars is 0. */ - mbchar_alloc = 2 * mbcset->nmbchars + 1; - /* Use realloc since array is NULL if *alloc == 0. */ - new_mbchars = re_realloc (mbcset->mbchars, wchar_t, - mbchar_alloc); - if (BE (new_mbchars == NULL, 0)) - goto parse_bracket_exp_espace; - mbcset->mbchars = new_mbchars; - } - mbcset->mbchars[mbcset->nmbchars++] = start_elem.opr.wch; - break; -#endif /* RE_ENABLE_I18N */ - case EQUIV_CLASS: - *err = build_equiv_class (sbcset, -#ifdef RE_ENABLE_I18N - mbcset, &equiv_class_alloc, -#endif /* RE_ENABLE_I18N */ - start_elem.opr.name); - if (BE (*err != REG_NOERROR, 0)) - goto parse_bracket_exp_free_return; - break; - case COLL_SYM: - *err = build_collating_symbol (sbcset, -#ifdef RE_ENABLE_I18N - mbcset, &coll_sym_alloc, -#endif /* RE_ENABLE_I18N */ - start_elem.opr.name); - if (BE (*err != REG_NOERROR, 0)) - goto parse_bracket_exp_free_return; - break; - case CHAR_CLASS: - *err = build_charclass (regexp->trans, sbcset, -#ifdef RE_ENABLE_I18N - mbcset, &char_class_alloc, -#endif /* RE_ENABLE_I18N */ - (const char *) start_elem.opr.name, syntax); - if (BE (*err != REG_NOERROR, 0)) - goto parse_bracket_exp_free_return; - break; - default: - assert (0); - break; - } - } - if (BE (token->type == END_OF_RE, 0)) - { - *err = REG_EBRACK; - goto parse_bracket_exp_free_return; - } - if (token->type == OP_CLOSE_BRACKET) - break; - } - - re_string_skip_bytes (regexp, token_len); /* Skip a token. */ - - /* If it is non-matching list. */ - if (non_match) - bitset_not (sbcset); - -#ifdef RE_ENABLE_I18N - /* Ensure only single byte characters are set. */ - if (dfa->mb_cur_max > 1) - bitset_mask (sbcset, dfa->sb_char); - - if (mbcset->nmbchars || mbcset->ncoll_syms || mbcset->nequiv_classes - || mbcset->nranges || (dfa->mb_cur_max > 1 && (mbcset->nchar_classes - || mbcset->non_match))) - { - bin_tree_t *mbc_tree; - int sbc_idx; - /* Build a tree for complex bracket. */ - dfa->has_mb_node = 1; - br_token.type = COMPLEX_BRACKET; - br_token.opr.mbcset = mbcset; - mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token); - if (BE (mbc_tree == NULL, 0)) - goto parse_bracket_exp_espace; - for (sbc_idx = 0; sbc_idx < BITSET_WORDS; ++sbc_idx) - if (sbcset[sbc_idx]) - break; - /* If there are no bits set in sbcset, there is no point - of having both SIMPLE_BRACKET and COMPLEX_BRACKET. */ - if (sbc_idx < BITSET_WORDS) - { - /* Build a tree for simple bracket. */ - br_token.type = SIMPLE_BRACKET; - br_token.opr.sbcset = sbcset; - work_tree = create_token_tree (dfa, NULL, NULL, &br_token); - if (BE (work_tree == NULL, 0)) - goto parse_bracket_exp_espace; - - /* Then join them by ALT node. */ - work_tree = create_tree (dfa, work_tree, mbc_tree, OP_ALT); - if (BE (work_tree == NULL, 0)) - goto parse_bracket_exp_espace; - } - else - { - re_free (sbcset); - work_tree = mbc_tree; - } - } - else -#endif /* not RE_ENABLE_I18N */ - { -#ifdef RE_ENABLE_I18N - free_charset (mbcset); -#endif - /* Build a tree for simple bracket. */ - br_token.type = SIMPLE_BRACKET; - br_token.opr.sbcset = sbcset; - work_tree = create_token_tree (dfa, NULL, NULL, &br_token); - if (BE (work_tree == NULL, 0)) - goto parse_bracket_exp_espace; - } - return work_tree; - - parse_bracket_exp_espace: - *err = REG_ESPACE; - parse_bracket_exp_free_return: - re_free (sbcset); -#ifdef RE_ENABLE_I18N - free_charset (mbcset); -#endif /* RE_ENABLE_I18N */ - return NULL; -} - -/* Parse an element in the bracket expression. */ - -static reg_errcode_t -parse_bracket_element (bracket_elem_t *elem, re_string_t *regexp, - re_token_t *token, int token_len, re_dfa_t *dfa, - reg_syntax_t syntax, int accept_hyphen) -{ -#ifdef RE_ENABLE_I18N - int cur_char_size; - cur_char_size = re_string_char_size_at (regexp, re_string_cur_idx (regexp)); - if (cur_char_size > 1) - { - elem->type = MB_CHAR; - elem->opr.wch = re_string_wchar_at (regexp, re_string_cur_idx (regexp)); - re_string_skip_bytes (regexp, cur_char_size); - return REG_NOERROR; - } -#endif /* RE_ENABLE_I18N */ - re_string_skip_bytes (regexp, token_len); /* Skip a token. */ - if (token->type == OP_OPEN_COLL_ELEM || token->type == OP_OPEN_CHAR_CLASS - || token->type == OP_OPEN_EQUIV_CLASS) - return parse_bracket_symbol (elem, regexp, token); - if (BE (token->type == OP_CHARSET_RANGE, 0) && !accept_hyphen) - { - /* A '-' must only appear as anything but a range indicator before - the closing bracket. Everything else is an error. */ - re_token_t token2; - (void) peek_token_bracket (&token2, regexp, syntax); - if (token2.type != OP_CLOSE_BRACKET) - /* The actual error value is not standardized since this whole - case is undefined. But ERANGE makes good sense. */ - return REG_ERANGE; - } - elem->type = SB_CHAR; - elem->opr.ch = token->opr.c; - return REG_NOERROR; -} - -/* Parse a bracket symbol in the bracket expression. Bracket symbols are - such as [::], [..], and - [==]. */ - -static reg_errcode_t -parse_bracket_symbol (bracket_elem_t *elem, re_string_t *regexp, - re_token_t *token) -{ - unsigned char ch, delim = token->opr.c; - int i = 0; - if (re_string_eoi(regexp)) - return REG_EBRACK; - for (;; ++i) - { - if (i >= BRACKET_NAME_BUF_SIZE) - return REG_EBRACK; - if (token->type == OP_OPEN_CHAR_CLASS) - ch = re_string_fetch_byte_case (regexp); - else - ch = re_string_fetch_byte (regexp); - if (re_string_eoi(regexp)) - return REG_EBRACK; - if (ch == delim && re_string_peek_byte (regexp, 0) == ']') - break; - elem->opr.name[i] = ch; - } - re_string_skip_bytes (regexp, 1); - elem->opr.name[i] = '\0'; - switch (token->type) - { - case OP_OPEN_COLL_ELEM: - elem->type = COLL_SYM; - break; - case OP_OPEN_EQUIV_CLASS: - elem->type = EQUIV_CLASS; - break; - case OP_OPEN_CHAR_CLASS: - elem->type = CHAR_CLASS; - break; - default: - break; - } - return REG_NOERROR; -} - - /* Helper function for parse_bracket_exp. - Build the equivalence class which is represented by NAME. - The result are written to MBCSET and SBCSET. - EQUIV_CLASS_ALLOC is the allocated size of mbcset->equiv_classes, - is a pointer argument sinse we may update it. */ - -static reg_errcode_t -#ifdef RE_ENABLE_I18N -build_equiv_class (bitset_t sbcset, re_charset_t *mbcset, - int *equiv_class_alloc, const unsigned char *name) -#else /* not RE_ENABLE_I18N */ -build_equiv_class (bitset_t sbcset, const unsigned char *name) -#endif /* not RE_ENABLE_I18N */ -{ -#ifdef _LIBC - uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); - if (nrules != 0) - { - const int32_t *table, *indirect; - const unsigned char *weights, *extra, *cp; - unsigned char char_buf[2]; - int32_t idx1, idx2; - unsigned int ch; - size_t len; - /* This #include defines a local function! */ -# include - /* Calculate the index for equivalence class. */ - cp = name; - table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); - weights = (const unsigned char *) _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_WEIGHTMB); - extra = (const unsigned char *) _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_EXTRAMB); - indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_INDIRECTMB); - idx1 = findidx (&cp); - if (BE (idx1 == 0 || cp < name + strlen ((const char *) name), 0)) - /* This isn't a valid character. */ - return REG_ECOLLATE; - - /* Build single byte matcing table for this equivalence class. */ - char_buf[1] = (unsigned char) '\0'; - len = weights[idx1 & 0xffffff]; - for (ch = 0; ch < SBC_MAX; ++ch) - { - char_buf[0] = ch; - cp = char_buf; - idx2 = findidx (&cp); -/* - idx2 = table[ch]; -*/ - if (idx2 == 0) - /* This isn't a valid character. */ - continue; - /* Compare only if the length matches and the collation rule - index is the same. */ - if (len == weights[idx2 & 0xffffff] && (idx1 >> 24) == (idx2 >> 24)) - { - int cnt = 0; - - while (cnt <= len && - weights[(idx1 & 0xffffff) + 1 + cnt] - == weights[(idx2 & 0xffffff) + 1 + cnt]) - ++cnt; - - if (cnt > len) - bitset_set (sbcset, ch); - } - } - /* Check whether the array has enough space. */ - if (BE (*equiv_class_alloc == mbcset->nequiv_classes, 0)) - { - /* Not enough, realloc it. */ - /* +1 in case of mbcset->nequiv_classes is 0. */ - int new_equiv_class_alloc = 2 * mbcset->nequiv_classes + 1; - /* Use realloc since the array is NULL if *alloc == 0. */ - int32_t *new_equiv_classes = re_realloc (mbcset->equiv_classes, - int32_t, - new_equiv_class_alloc); - if (BE (new_equiv_classes == NULL, 0)) - return REG_ESPACE; - mbcset->equiv_classes = new_equiv_classes; - *equiv_class_alloc = new_equiv_class_alloc; - } - mbcset->equiv_classes[mbcset->nequiv_classes++] = idx1; - } - else -#endif /* _LIBC */ - { - if (BE (strlen ((const char *) name) != 1, 0)) - return REG_ECOLLATE; - bitset_set (sbcset, *name); - } - return REG_NOERROR; -} - - /* Helper function for parse_bracket_exp. - Build the character class which is represented by NAME. - The result are written to MBCSET and SBCSET. - CHAR_CLASS_ALLOC is the allocated size of mbcset->char_classes, - is a pointer argument sinse we may update it. */ - -static reg_errcode_t -#ifdef RE_ENABLE_I18N -build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset, - re_charset_t *mbcset, int *char_class_alloc, - const char *class_name, reg_syntax_t syntax) -#else /* not RE_ENABLE_I18N */ -build_charclass (RE_TRANSLATE_TYPE trans, bitset_t sbcset, - const char *class_name, reg_syntax_t syntax) -#endif /* not RE_ENABLE_I18N */ -{ - int i; - - /* In case of REG_ICASE "upper" and "lower" match the both of - upper and lower cases. */ - if ((syntax & RE_ICASE) - && (strcmp (class_name, "upper") == 0 || strcmp (class_name, "lower") == 0)) - class_name = "alpha"; - -#ifdef RE_ENABLE_I18N - /* Check the space of the arrays. */ - if (BE (*char_class_alloc == mbcset->nchar_classes, 0)) - { - /* Not enough, realloc it. */ - /* +1 in case of mbcset->nchar_classes is 0. */ - int new_char_class_alloc = 2 * mbcset->nchar_classes + 1; - /* Use realloc since array is NULL if *alloc == 0. */ - wctype_t *new_char_classes = re_realloc (mbcset->char_classes, wctype_t, - new_char_class_alloc); - if (BE (new_char_classes == NULL, 0)) - return REG_ESPACE; - mbcset->char_classes = new_char_classes; - *char_class_alloc = new_char_class_alloc; - } - mbcset->char_classes[mbcset->nchar_classes++] = __wctype (class_name); -#endif /* RE_ENABLE_I18N */ - -#define BUILD_CHARCLASS_LOOP(ctype_func) \ - do { \ - if (BE (trans != NULL, 0)) \ - { \ - for (i = 0; i < SBC_MAX; ++i) \ - if (ctype_func (i)) \ - bitset_set (sbcset, trans[i]); \ - } \ - else \ - { \ - for (i = 0; i < SBC_MAX; ++i) \ - if (ctype_func (i)) \ - bitset_set (sbcset, i); \ - } \ - } while (0) - - if (strcmp (class_name, "alnum") == 0) - BUILD_CHARCLASS_LOOP (isalnum); - else if (strcmp (class_name, "cntrl") == 0) - BUILD_CHARCLASS_LOOP (iscntrl); - else if (strcmp (class_name, "lower") == 0) - BUILD_CHARCLASS_LOOP (islower); - else if (strcmp (class_name, "space") == 0) - BUILD_CHARCLASS_LOOP (isspace); - else if (strcmp (class_name, "alpha") == 0) - BUILD_CHARCLASS_LOOP (isalpha); - else if (strcmp (class_name, "digit") == 0) - BUILD_CHARCLASS_LOOP (isdigit); - else if (strcmp (class_name, "print") == 0) - BUILD_CHARCLASS_LOOP (isprint); - else if (strcmp (class_name, "upper") == 0) - BUILD_CHARCLASS_LOOP (isupper); - else if (strcmp (class_name, "blank") == 0) -#ifndef GAWK - BUILD_CHARCLASS_LOOP (isblank); -#else - /* see comments above */ - BUILD_CHARCLASS_LOOP (is_blank); -#endif - else if (strcmp (class_name, "graph") == 0) - BUILD_CHARCLASS_LOOP (isgraph); - else if (strcmp (class_name, "punct") == 0) - BUILD_CHARCLASS_LOOP (ispunct); - else if (strcmp (class_name, "xdigit") == 0) - BUILD_CHARCLASS_LOOP (isxdigit); - else - return REG_ECTYPE; - - return REG_NOERROR; -} - -static bin_tree_t * -build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans, - const char *class_name, - const char *extra, int non_match, - reg_errcode_t *err) -{ - re_bitset_ptr_t sbcset; -#ifdef RE_ENABLE_I18N - re_charset_t *mbcset; - int alloc = 0; -#endif /* not RE_ENABLE_I18N */ - reg_errcode_t ret; - re_token_t br_token; - bin_tree_t *tree; - - sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); -#ifdef RE_ENABLE_I18N - mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); -#endif /* RE_ENABLE_I18N */ - -#ifdef RE_ENABLE_I18N - if (BE (sbcset == NULL || mbcset == NULL, 0)) -#else /* not RE_ENABLE_I18N */ - if (BE (sbcset == NULL, 0)) -#endif /* not RE_ENABLE_I18N */ - { - *err = REG_ESPACE; - return NULL; - } - - if (non_match) - { -#ifdef RE_ENABLE_I18N - mbcset->non_match = 1; -#endif /* not RE_ENABLE_I18N */ - } - - /* We don't care the syntax in this case. */ - ret = build_charclass (trans, sbcset, -#ifdef RE_ENABLE_I18N - mbcset, &alloc, -#endif /* RE_ENABLE_I18N */ - class_name, 0); - - if (BE (ret != REG_NOERROR, 0)) - { - re_free (sbcset); -#ifdef RE_ENABLE_I18N - free_charset (mbcset); -#endif /* RE_ENABLE_I18N */ - *err = ret; - return NULL; - } - /* \w match '_' also. */ - for (; *extra; extra++) - bitset_set (sbcset, *extra); - - /* If it is non-matching list. */ - if (non_match) - bitset_not (sbcset); - -#ifdef RE_ENABLE_I18N - /* Ensure only single byte characters are set. */ - if (dfa->mb_cur_max > 1) - bitset_mask (sbcset, dfa->sb_char); -#endif - - /* Build a tree for simple bracket. */ - br_token.type = SIMPLE_BRACKET; - br_token.opr.sbcset = sbcset; - tree = create_token_tree (dfa, NULL, NULL, &br_token); - if (BE (tree == NULL, 0)) - goto build_word_op_espace; - -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - { - bin_tree_t *mbc_tree; - /* Build a tree for complex bracket. */ - br_token.type = COMPLEX_BRACKET; - br_token.opr.mbcset = mbcset; - dfa->has_mb_node = 1; - mbc_tree = create_token_tree (dfa, NULL, NULL, &br_token); - if (BE (mbc_tree == NULL, 0)) - goto build_word_op_espace; - /* Then join them by ALT node. */ - tree = create_tree (dfa, tree, mbc_tree, OP_ALT); - if (BE (mbc_tree != NULL, 1)) - return tree; - } - else - { - free_charset (mbcset); - return tree; - } -#else /* not RE_ENABLE_I18N */ - return tree; -#endif /* not RE_ENABLE_I18N */ - - build_word_op_espace: - re_free (sbcset); -#ifdef RE_ENABLE_I18N - free_charset (mbcset); -#endif /* RE_ENABLE_I18N */ - *err = REG_ESPACE; - return NULL; -} - -/* This is intended for the expressions like "a{1,3}". - Fetch a number from `input', and return the number. - Return -1, if the number field is empty like "{,1}". - Return -2, If an error is occured. */ - -static int -fetch_number (re_string_t *input, re_token_t *token, reg_syntax_t syntax) -{ - int num = -1; - unsigned char c; - while (1) - { - fetch_token (token, input, syntax); - c = token->opr.c; - if (BE (token->type == END_OF_RE, 0)) - return -2; - if (token->type == OP_CLOSE_DUP_NUM || c == ',') - break; - num = ((token->type != CHARACTER || c < '0' || '9' < c || num == -2) - ? -2 : ((num == -1) ? c - '0' : num * 10 + c - '0')); - num = (num > RE_DUP_MAX) ? -2 : num; - } - return num; -} - -#ifdef RE_ENABLE_I18N -static void -free_charset (re_charset_t *cset) -{ - re_free (cset->mbchars); -# ifdef _LIBC - re_free (cset->coll_syms); - re_free (cset->equiv_classes); - re_free (cset->range_starts); - re_free (cset->range_ends); -# endif - re_free (cset->char_classes); - re_free (cset); -} -#endif /* RE_ENABLE_I18N */ - -/* Functions for binary tree operation. */ - -/* Create a tree node. */ - -static bin_tree_t * -create_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right, - re_token_type_t type) -{ - re_token_t t; - t.type = type; - return create_token_tree (dfa, left, right, &t); -} - -static bin_tree_t * -create_token_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right, - const re_token_t *token) -{ - bin_tree_t *tree; - if (BE (dfa->str_tree_storage_idx == BIN_TREE_STORAGE_SIZE, 0)) - { - bin_tree_storage_t *storage = re_malloc (bin_tree_storage_t, 1); - - if (storage == NULL) - return NULL; - storage->next = dfa->str_tree_storage; - dfa->str_tree_storage = storage; - dfa->str_tree_storage_idx = 0; - } - tree = &dfa->str_tree_storage->data[dfa->str_tree_storage_idx++]; - - tree->parent = NULL; - tree->left = left; - tree->right = right; - tree->token = *token; - tree->token.duplicated = 0; - tree->token.opt_subexp = 0; - tree->first = NULL; - tree->next = NULL; - tree->node_idx = -1; - - if (left != NULL) - left->parent = tree; - if (right != NULL) - right->parent = tree; - return tree; -} - -/* Mark the tree SRC as an optional subexpression. - To be called from preorder or postorder. */ - -static reg_errcode_t -mark_opt_subexp (void *extra, bin_tree_t *node) -{ - int idx = (int) (long) extra; - if (node->token.type == SUBEXP && node->token.opr.idx == idx) - node->token.opt_subexp = 1; - - return REG_NOERROR; -} - -/* Free the allocated memory inside NODE. */ - -static void -free_token (re_token_t *node) -{ -#ifdef RE_ENABLE_I18N - if (node->type == COMPLEX_BRACKET && node->duplicated == 0) - free_charset (node->opr.mbcset); - else -#endif /* RE_ENABLE_I18N */ - if (node->type == SIMPLE_BRACKET && node->duplicated == 0) - re_free (node->opr.sbcset); -} - -/* Worker function for tree walking. Free the allocated memory inside NODE - and its children. */ - -static reg_errcode_t -free_tree (void *extra, bin_tree_t *node) -{ - free_token (&node->token); - return REG_NOERROR; -} - - -/* Duplicate the node SRC, and return new node. This is a preorder - visit similar to the one implemented by the generic visitor, but - we need more infrastructure to maintain two parallel trees --- so, - it's easier to duplicate. */ - -static bin_tree_t * -duplicate_tree (const bin_tree_t *root, re_dfa_t *dfa) -{ - const bin_tree_t *node; - bin_tree_t *dup_root; - bin_tree_t **p_new = &dup_root, *dup_node = root->parent; - - for (node = root; ; ) - { - /* Create a new tree and link it back to the current parent. */ - *p_new = create_token_tree (dfa, NULL, NULL, &node->token); - if (*p_new == NULL) - return NULL; - (*p_new)->parent = dup_node; - (*p_new)->token.duplicated = 1; - dup_node = *p_new; - - /* Go to the left node, or up and to the right. */ - if (node->left) - { - node = node->left; - p_new = &dup_node->left; - } - else - { - const bin_tree_t *prev = NULL; - while (node->right == prev || node->right == NULL) - { - prev = node; - node = node->parent; - dup_node = dup_node->parent; - if (!node) - return dup_root; - } - node = node->right; - p_new = &dup_node->right; - } - } -} diff --git a/deps/regex/regex.c b/deps/regex/regex.c deleted file mode 100644 index f9a8c9bf1c2..00000000000 --- a/deps/regex/regex.c +++ /dev/null @@ -1,85 +0,0 @@ -/* Extended regular expression matching and search library. - Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Isamu Hasegawa . - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. */ - -#include "config.h" - -/* Make sure noone compiles this code with a C++ compiler. */ -#ifdef __cplusplus -# error "This is C code, use a C compiler" -#endif - -#ifdef _LIBC -/* We have to keep the namespace clean. */ -# define regfree(preg) __regfree (preg) -# define regexec(pr, st, nm, pm, ef) __regexec (pr, st, nm, pm, ef) -# define regcomp(preg, pattern, cflags) __regcomp (preg, pattern, cflags) -# define regerror(errcode, preg, errbuf, errbuf_size) \ - __regerror(errcode, preg, errbuf, errbuf_size) -# define re_set_registers(bu, re, nu, st, en) \ - __re_set_registers (bu, re, nu, st, en) -# define re_match_2(bufp, string1, size1, string2, size2, pos, regs, stop) \ - __re_match_2 (bufp, string1, size1, string2, size2, pos, regs, stop) -# define re_match(bufp, string, size, pos, regs) \ - __re_match (bufp, string, size, pos, regs) -# define re_search(bufp, string, size, startpos, range, regs) \ - __re_search (bufp, string, size, startpos, range, regs) -# define re_compile_pattern(pattern, length, bufp) \ - __re_compile_pattern (pattern, length, bufp) -# define re_set_syntax(syntax) __re_set_syntax (syntax) -# define re_search_2(bufp, st1, s1, st2, s2, startpos, range, regs, stop) \ - __re_search_2 (bufp, st1, s1, st2, s2, startpos, range, regs, stop) -# define re_compile_fastmap(bufp) __re_compile_fastmap (bufp) - -# include "../locale/localeinfo.h" -#endif - -#if defined (_MSC_VER) -#include /* for size_t */ -#endif - -/* On some systems, limits.h sets RE_DUP_MAX to a lower value than - GNU regex allows. Include it before , which correctly - #undefs RE_DUP_MAX and sets it to the right value. */ -#include - -#ifdef GAWK -#undef alloca -#define alloca alloca_is_bad_you_should_never_use_it -#endif -#include -#include "regex_internal.h" - -#include "regex_internal.c" -#ifdef GAWK -#define bool int -#define true (1) -#define false (0) -#endif -#include "regcomp.c" -#include "regexec.c" - -/* Binary backward compatibility. */ -#if _LIBC -# include -# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3) -link_warning (re_max_failures, "the 're_max_failures' variable is obsolete and will go away.") -int re_max_failures = 2000; -# endif -#endif diff --git a/deps/regex/regex.h b/deps/regex/regex.h deleted file mode 100644 index 61c96838721..00000000000 --- a/deps/regex/regex.h +++ /dev/null @@ -1,582 +0,0 @@ -#include -#include - -/* Definitions for data structures and routines for the regular - expression library. - Copyright (C) 1985,1989-93,1995-98,2000,2001,2002,2003,2005,2006,2008 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. */ - -#ifndef _REGEX_H -#define _REGEX_H 1 - -#ifdef HAVE_STDDEF_H -#include -#endif - -#ifdef HAVE_SYS_TYPES_H -#include -#endif - -#ifndef _LIBC -#define __USE_GNU 1 -#endif - -/* Allow the use in C++ code. */ -#ifdef __cplusplus -extern "C" { -#endif - -/* The following two types have to be signed and unsigned integer type - wide enough to hold a value of a pointer. For most ANSI compilers - ptrdiff_t and size_t should be likely OK. Still size of these two - types is 2 for Microsoft C. Ugh... */ -typedef long int s_reg_t; -typedef unsigned long int active_reg_t; - -/* The following bits are used to determine the regexp syntax we - recognize. The set/not-set meanings are chosen so that Emacs syntax - remains the value 0. The bits are given in alphabetical order, and - the definitions shifted by one from the previous bit; thus, when we - add or remove a bit, only one other definition need change. */ -typedef unsigned long int reg_syntax_t; - -#ifdef __USE_GNU -/* If this bit is not set, then \ inside a bracket expression is literal. - If set, then such a \ quotes the following character. */ -# define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1) - -/* If this bit is not set, then + and ? are operators, and \+ and \? are - literals. - If set, then \+ and \? are operators and + and ? are literals. */ -# define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1) - -/* If this bit is set, then character classes are supported. They are: - [:alpha:], [:upper:], [:lower:], [:digit:], [:alnum:], [:xdigit:], - [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:]. - If not set, then character classes are not supported. */ -# define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1) - -/* If this bit is set, then ^ and $ are always anchors (outside bracket - expressions, of course). - If this bit is not set, then it depends: - ^ is an anchor if it is at the beginning of a regular - expression or after an open-group or an alternation operator; - $ is an anchor if it is at the end of a regular expression, or - before a close-group or an alternation operator. - - This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because - POSIX draft 11.2 says that * etc. in leading positions is undefined. - We already implemented a previous draft which made those constructs - invalid, though, so we haven't changed the code back. */ -# define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1) - -/* If this bit is set, then special characters are always special - regardless of where they are in the pattern. - If this bit is not set, then special characters are special only in - some contexts; otherwise they are ordinary. Specifically, - * + ? and intervals are only special when not after the beginning, - open-group, or alternation operator. */ -# define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1) - -/* If this bit is set, then *, +, ?, and { cannot be first in an re or - immediately after an alternation or begin-group operator. */ -# define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1) - -/* If this bit is set, then . matches newline. - If not set, then it doesn't. */ -# define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1) - -/* If this bit is set, then . doesn't match NUL. - If not set, then it does. */ -# define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1) - -/* If this bit is set, nonmatching lists [^...] do not match newline. - If not set, they do. */ -# define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1) - -/* If this bit is set, either \{...\} or {...} defines an - interval, depending on RE_NO_BK_BRACES. - If not set, \{, \}, {, and } are literals. */ -# define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1) - -/* If this bit is set, +, ? and | aren't recognized as operators. - If not set, they are. */ -# define RE_LIMITED_OPS (RE_INTERVALS << 1) - -/* If this bit is set, newline is an alternation operator. - If not set, newline is literal. */ -# define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1) - -/* If this bit is set, then `{...}' defines an interval, and \{ and \} - are literals. - If not set, then `\{...\}' defines an interval. */ -# define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1) - -/* If this bit is set, (...) defines a group, and \( and \) are literals. - If not set, \(...\) defines a group, and ( and ) are literals. */ -# define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1) - -/* If this bit is set, then \ matches . - If not set, then \ is a back-reference. */ -# define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1) - -/* If this bit is set, then | is an alternation operator, and \| is literal. - If not set, then \| is an alternation operator, and | is literal. */ -# define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1) - -/* If this bit is set, then an ending range point collating higher - than the starting range point, as in [z-a], is invalid. - If not set, then when ending range point collates higher than the - starting range point, the range is ignored. */ -# define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1) - -/* If this bit is set, then an unmatched ) is ordinary. - If not set, then an unmatched ) is invalid. */ -# define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1) - -/* If this bit is set, succeed as soon as we match the whole pattern, - without further backtracking. */ -# define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1) - -/* If this bit is set, do not process the GNU regex operators. - If not set, then the GNU regex operators are recognized. */ -# define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1) - -/* If this bit is set, a syntactically invalid interval is treated as - a string of ordinary characters. For example, the ERE 'a{1' is - treated as 'a\{1'. */ -# define RE_INVALID_INTERVAL_ORD (RE_NO_GNU_OPS << 1) - -/* If this bit is set, then ignore case when matching. - If not set, then case is significant. */ -# define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1) - -/* This bit is used internally like RE_CONTEXT_INDEP_ANCHORS but only - for ^, because it is difficult to scan the regex backwards to find - whether ^ should be special. */ -# define RE_CARET_ANCHORS_HERE (RE_ICASE << 1) - -/* If this bit is set, then \{ cannot be first in an bre or - immediately after an alternation or begin-group operator. */ -# define RE_CONTEXT_INVALID_DUP (RE_CARET_ANCHORS_HERE << 1) - -/* If this bit is set, then no_sub will be set to 1 during - re_compile_pattern. */ -#define RE_NO_SUB (RE_CONTEXT_INVALID_DUP << 1) -#endif - -/* This global variable defines the particular regexp syntax to use (for - some interfaces). When a regexp is compiled, the syntax used is - stored in the pattern buffer, so changing this does not affect - already-compiled regexps. */ -extern reg_syntax_t re_syntax_options; - -#ifdef __USE_GNU -/* Define combinations of the above bits for the standard possibilities. - (The [[[ comments delimit what gets put into the Texinfo file, so - don't delete them!) */ -/* [[[begin syntaxes]]] */ -#define RE_SYNTAX_EMACS 0 - -#define RE_SYNTAX_AWK \ - (RE_BACKSLASH_ESCAPE_IN_LISTS | RE_DOT_NOT_NULL \ - | RE_NO_BK_PARENS | RE_NO_BK_REFS \ - | RE_NO_BK_VBAR | RE_NO_EMPTY_RANGES \ - | RE_DOT_NEWLINE | RE_CONTEXT_INDEP_ANCHORS \ - | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS) - -#define RE_SYNTAX_GNU_AWK \ - ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \ - | RE_INVALID_INTERVAL_ORD) \ - & ~(RE_DOT_NOT_NULL | RE_CONTEXT_INDEP_OPS \ - | RE_CONTEXT_INVALID_OPS )) - -#define RE_SYNTAX_POSIX_AWK \ - (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS \ - | RE_INTERVALS | RE_NO_GNU_OPS \ - | RE_INVALID_INTERVAL_ORD) - -#define RE_SYNTAX_GREP \ - (RE_BK_PLUS_QM | RE_CHAR_CLASSES \ - | RE_HAT_LISTS_NOT_NEWLINE | RE_INTERVALS \ - | RE_NEWLINE_ALT) - -#define RE_SYNTAX_EGREP \ - (RE_CHAR_CLASSES | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INDEP_OPS | RE_HAT_LISTS_NOT_NEWLINE \ - | RE_NEWLINE_ALT | RE_NO_BK_PARENS \ - | RE_NO_BK_VBAR) - -#define RE_SYNTAX_POSIX_EGREP \ - (RE_SYNTAX_EGREP | RE_INTERVALS | RE_NO_BK_BRACES \ - | RE_INVALID_INTERVAL_ORD) - -/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff. */ -#define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC - -#define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC - -/* Syntax bits common to both basic and extended POSIX regex syntax. */ -#define _RE_SYNTAX_POSIX_COMMON \ - (RE_CHAR_CLASSES | RE_DOT_NEWLINE | RE_DOT_NOT_NULL \ - | RE_INTERVALS | RE_NO_EMPTY_RANGES) - -#define RE_SYNTAX_POSIX_BASIC \ - (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM | RE_CONTEXT_INVALID_DUP) - -/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes - RE_LIMITED_OPS, i.e., \? \+ \| are not recognized. Actually, this - isn't minimal, since other operators, such as \`, aren't disabled. */ -#define RE_SYNTAX_POSIX_MINIMAL_BASIC \ - (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS) - -#define RE_SYNTAX_POSIX_EXTENDED \ - (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INDEP_OPS | RE_NO_BK_BRACES \ - | RE_NO_BK_PARENS | RE_NO_BK_VBAR \ - | RE_CONTEXT_INVALID_OPS | RE_UNMATCHED_RIGHT_PAREN_ORD) - -/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INDEP_OPS is - removed and RE_NO_BK_REFS is added. */ -#define RE_SYNTAX_POSIX_MINIMAL_EXTENDED \ - (_RE_SYNTAX_POSIX_COMMON | RE_CONTEXT_INDEP_ANCHORS \ - | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES \ - | RE_NO_BK_PARENS | RE_NO_BK_REFS \ - | RE_NO_BK_VBAR | RE_UNMATCHED_RIGHT_PAREN_ORD) -/* [[[end syntaxes]]] */ - -/* Maximum number of duplicates an interval can allow. Some systems - (erroneously) define this in other header files, but we want our - value, so remove any previous define. */ -# ifdef RE_DUP_MAX -# undef RE_DUP_MAX -# endif -/* If sizeof(int) == 2, then ((1 << 15) - 1) overflows. */ -# define RE_DUP_MAX (0x7fff) -#endif - - -/* POSIX `cflags' bits (i.e., information for `regcomp'). */ - -/* If this bit is set, then use extended regular expression syntax. - If not set, then use basic regular expression syntax. */ -#define REG_EXTENDED 1 - -/* If this bit is set, then ignore case when matching. - If not set, then case is significant. */ -#define REG_ICASE (REG_EXTENDED << 1) - -/* If this bit is set, then anchors do not match at newline - characters in the string. - If not set, then anchors do match at newlines. */ -#define REG_NEWLINE (REG_ICASE << 1) - -/* If this bit is set, then report only success or fail in regexec. - If not set, then returns differ between not matching and errors. */ -#define REG_NOSUB (REG_NEWLINE << 1) - - -/* POSIX `eflags' bits (i.e., information for regexec). */ - -/* If this bit is set, then the beginning-of-line operator doesn't match - the beginning of the string (presumably because it's not the - beginning of a line). - If not set, then the beginning-of-line operator does match the - beginning of the string. */ -#define REG_NOTBOL 1 - -/* Like REG_NOTBOL, except for the end-of-line. */ -#define REG_NOTEOL (1 << 1) - -/* Use PMATCH[0] to delimit the start and end of the search in the - buffer. */ -#define REG_STARTEND (1 << 2) - - -/* If any error codes are removed, changed, or added, update the - `re_error_msg' table in regex.c. */ -typedef enum -{ -#if defined _XOPEN_SOURCE || defined __USE_XOPEN2K - REG_ENOSYS = -1, /* This will never happen for this implementation. */ -#endif - - REG_NOERROR = 0, /* Success. */ - REG_NOMATCH, /* Didn't find a match (for regexec). */ - - /* POSIX regcomp return error codes. (In the order listed in the - standard.) */ - REG_BADPAT, /* Invalid pattern. */ - REG_ECOLLATE, /* Inalid collating element. */ - REG_ECTYPE, /* Invalid character class name. */ - REG_EESCAPE, /* Trailing backslash. */ - REG_ESUBREG, /* Invalid back reference. */ - REG_EBRACK, /* Unmatched left bracket. */ - REG_EPAREN, /* Parenthesis imbalance. */ - REG_EBRACE, /* Unmatched \{. */ - REG_BADBR, /* Invalid contents of \{\}. */ - REG_ERANGE, /* Invalid range end. */ - REG_ESPACE, /* Ran out of memory. */ - REG_BADRPT, /* No preceding re for repetition op. */ - - /* Error codes we've added. */ - REG_EEND, /* Premature end. */ - REG_ESIZE, /* Compiled pattern bigger than 2^16 bytes. */ - REG_ERPAREN /* Unmatched ) or \); not returned from regcomp. */ -} reg_errcode_t; - -/* This data structure represents a compiled pattern. Before calling - the pattern compiler, the fields `buffer', `allocated', `fastmap', - `translate', and `no_sub' can be set. After the pattern has been - compiled, the `re_nsub' field is available. All other fields are - private to the regex routines. */ - -#ifndef RE_TRANSLATE_TYPE -# define __RE_TRANSLATE_TYPE unsigned char * -# ifdef __USE_GNU -# define RE_TRANSLATE_TYPE __RE_TRANSLATE_TYPE -# endif -#endif - -#ifdef __USE_GNU -# define __REPB_PREFIX(name) name -#else -# define __REPB_PREFIX(name) __##name -#endif - -struct re_pattern_buffer -{ - /* Space that holds the compiled pattern. It is declared as - `unsigned char *' because its elements are sometimes used as - array indexes. */ - unsigned char *__REPB_PREFIX(buffer); - - /* Number of bytes to which `buffer' points. */ - unsigned long int __REPB_PREFIX(allocated); - - /* Number of bytes actually used in `buffer'. */ - unsigned long int __REPB_PREFIX(used); - - /* Syntax setting with which the pattern was compiled. */ - reg_syntax_t __REPB_PREFIX(syntax); - - /* Pointer to a fastmap, if any, otherwise zero. re_search uses the - fastmap, if there is one, to skip over impossible starting points - for matches. */ - char *__REPB_PREFIX(fastmap); - - /* Either a translate table to apply to all characters before - comparing them, or zero for no translation. The translation is - applied to a pattern when it is compiled and to a string when it - is matched. */ - __RE_TRANSLATE_TYPE __REPB_PREFIX(translate); - - /* Number of subexpressions found by the compiler. */ - size_t re_nsub; - - /* Zero if this pattern cannot match the empty string, one else. - Well, in truth it's used only in `re_search_2', to see whether or - not we should use the fastmap, so we don't set this absolutely - perfectly; see `re_compile_fastmap' (the `duplicate' case). */ - unsigned __REPB_PREFIX(can_be_null) : 1; - - /* If REGS_UNALLOCATED, allocate space in the `regs' structure - for `max (RE_NREGS, re_nsub + 1)' groups. - If REGS_REALLOCATE, reallocate space if necessary. - If REGS_FIXED, use what's there. */ -#ifdef __USE_GNU -# define REGS_UNALLOCATED 0 -# define REGS_REALLOCATE 1 -# define REGS_FIXED 2 -#endif - unsigned __REPB_PREFIX(regs_allocated) : 2; - - /* Set to zero when `regex_compile' compiles a pattern; set to one - by `re_compile_fastmap' if it updates the fastmap. */ - unsigned __REPB_PREFIX(fastmap_accurate) : 1; - - /* If set, `re_match_2' does not return information about - subexpressions. */ - unsigned __REPB_PREFIX(no_sub) : 1; - - /* If set, a beginning-of-line anchor doesn't match at the beginning - of the string. */ - unsigned __REPB_PREFIX(not_bol) : 1; - - /* Similarly for an end-of-line anchor. */ - unsigned __REPB_PREFIX(not_eol) : 1; - - /* If true, an anchor at a newline matches. */ - unsigned __REPB_PREFIX(newline_anchor) : 1; -}; - -typedef struct re_pattern_buffer regex_t; - -/* Type for byte offsets within the string. POSIX mandates this. */ -typedef int regoff_t; - - -#ifdef __USE_GNU -/* This is the structure we store register match data in. See - regex.texinfo for a full description of what registers match. */ -struct re_registers -{ - unsigned num_regs; - regoff_t *start; - regoff_t *end; -}; - - -/* If `regs_allocated' is REGS_UNALLOCATED in the pattern buffer, - `re_match_2' returns information about at least this many registers - the first time a `regs' structure is passed. */ -# ifndef RE_NREGS -# define RE_NREGS 30 -# endif -#endif - - -/* POSIX specification for registers. Aside from the different names than - `re_registers', POSIX uses an array of structures, instead of a - structure of arrays. */ -typedef struct -{ - regoff_t rm_so; /* Byte offset from string's start to substring's start. */ - regoff_t rm_eo; /* Byte offset from string's start to substring's end. */ -} regmatch_t; - -/* Declarations for routines. */ - -#ifdef __USE_GNU -/* Sets the current default syntax to SYNTAX, and return the old syntax. - You can also simply assign to the `re_syntax_options' variable. */ -extern reg_syntax_t re_set_syntax (reg_syntax_t __syntax); - -/* Compile the regular expression PATTERN, with length LENGTH - and syntax given by the global `re_syntax_options', into the buffer - BUFFER. Return NULL if successful, and an error string if not. */ -extern const char *re_compile_pattern (const char *__pattern, size_t __length, - struct re_pattern_buffer *__buffer); - - -/* Compile a fastmap for the compiled pattern in BUFFER; used to - accelerate searches. Return 0 if successful and -2 if was an - internal error. */ -extern int re_compile_fastmap (struct re_pattern_buffer *__buffer); - - -/* Search in the string STRING (with length LENGTH) for the pattern - compiled into BUFFER. Start searching at position START, for RANGE - characters. Return the starting position of the match, -1 for no - match, or -2 for an internal error. Also return register - information in REGS (if REGS and BUFFER->no_sub are nonzero). */ -extern int re_search (struct re_pattern_buffer *__buffer, const char *__cstring, - int __length, int __start, int __range, - struct re_registers *__regs); - - -/* Like `re_search', but search in the concatenation of STRING1 and - STRING2. Also, stop searching at index START + STOP. */ -extern int re_search_2 (struct re_pattern_buffer *__buffer, - const char *__string1, int __length1, - const char *__string2, int __length2, int __start, - int __range, struct re_registers *__regs, int __stop); - - -/* Like `re_search', but return how many characters in STRING the regexp - in BUFFER matched, starting at position START. */ -extern int re_match (struct re_pattern_buffer *__buffer, const char *__cstring, - int __length, int __start, struct re_registers *__regs); - - -/* Relates to `re_match' as `re_search_2' relates to `re_search'. */ -extern int re_match_2 (struct re_pattern_buffer *__buffer, - const char *__string1, int __length1, - const char *__string2, int __length2, int __start, - struct re_registers *__regs, int __stop); - - -/* Set REGS to hold NUM_REGS registers, storing them in STARTS and - ENDS. Subsequent matches using BUFFER and REGS will use this memory - for recording register information. STARTS and ENDS must be - allocated with malloc, and must each be at least `NUM_REGS * sizeof - (regoff_t)' bytes long. - - If NUM_REGS == 0, then subsequent matches should allocate their own - register data. - - Unless this function is called, the first search or match using - PATTERN_BUFFER will allocate its own register data, without - freeing the old data. */ -extern void re_set_registers (struct re_pattern_buffer *__buffer, - struct re_registers *__regs, - unsigned int __num_regs, - regoff_t *__starts, regoff_t *__ends); -#endif /* Use GNU */ - -#if defined _REGEX_RE_COMP || (defined _LIBC && defined __USE_BSD) -# ifndef _CRAY -/* 4.2 bsd compatibility. */ -extern char *re_comp (const char *); -extern int re_exec (const char *); -# endif -#endif - -/* GCC 2.95 and later have "__restrict"; C99 compilers have - "restrict", and "configure" may have defined "restrict". */ -#ifndef __restrict -# if ! (2 < __GNUC__ || (2 == __GNUC__ && 95 <= __GNUC_MINOR__)) -# if defined restrict || 199901L <= __STDC_VERSION__ -# define __restrict restrict -# else -# define __restrict -# endif -# endif -#endif -/* gcc 3.1 and up support the [restrict] syntax. */ -#ifndef __restrict_arr -# if (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) \ - && !defined __GNUG__ -# define __restrict_arr __restrict -# else -# define __restrict_arr -# endif -#endif - -/* POSIX compatibility. */ -extern int regcomp (regex_t *__restrict __preg, - const char *__restrict __pattern, - int __cflags); - -extern int regexec (const regex_t *__restrict __preg, - const char *__restrict __cstring, size_t __nmatch, - regmatch_t __pmatch[__restrict_arr], - int __eflags); - -extern size_t regerror (int __errcode, const regex_t *__restrict __preg, - char *__restrict __errbuf, size_t __errbuf_size); - -extern void regfree (regex_t *__preg); - - -#ifdef __cplusplus -} -#endif /* C++ */ - -#endif /* regex.h */ diff --git a/deps/regex/regex_internal.c b/deps/regex/regex_internal.c deleted file mode 100644 index 193854cf5b6..00000000000 --- a/deps/regex/regex_internal.c +++ /dev/null @@ -1,1744 +0,0 @@ -/* Extended regular expression matching and search library. - Copyright (C) 2002-2006, 2010 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Isamu Hasegawa . - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. */ - -static void re_string_construct_common (const char *str, int len, - re_string_t *pstr, - RE_TRANSLATE_TYPE trans, int icase, - const re_dfa_t *dfa) internal_function; -static re_dfastate_t *create_ci_newstate (const re_dfa_t *dfa, - const re_node_set *nodes, - unsigned int hash) internal_function; -static re_dfastate_t *create_cd_newstate (const re_dfa_t *dfa, - const re_node_set *nodes, - unsigned int context, - unsigned int hash) internal_function; - -#ifdef GAWK -#undef MAX /* safety */ -static int -MAX(size_t a, size_t b) -{ - return (a > b ? a : b); -} -#endif - -/* Functions for string operation. */ - -/* This function allocate the buffers. It is necessary to call - re_string_reconstruct before using the object. */ - -static reg_errcode_t -internal_function -re_string_allocate (re_string_t *pstr, const char *str, int len, int init_len, - RE_TRANSLATE_TYPE trans, int icase, const re_dfa_t *dfa) -{ - reg_errcode_t ret; - int init_buf_len; - - /* Ensure at least one character fits into the buffers. */ - if (init_len < dfa->mb_cur_max) - init_len = dfa->mb_cur_max; - init_buf_len = (len + 1 < init_len) ? len + 1: init_len; - re_string_construct_common (str, len, pstr, trans, icase, dfa); - - ret = re_string_realloc_buffers (pstr, init_buf_len); - if (BE (ret != REG_NOERROR, 0)) - return ret; - - pstr->word_char = dfa->word_char; - pstr->word_ops_used = dfa->word_ops_used; - pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str; - pstr->valid_len = (pstr->mbs_allocated || dfa->mb_cur_max > 1) ? 0 : len; - pstr->valid_raw_len = pstr->valid_len; - return REG_NOERROR; -} - -/* This function allocate the buffers, and initialize them. */ - -static reg_errcode_t -internal_function -re_string_construct (re_string_t *pstr, const char *str, int len, - RE_TRANSLATE_TYPE trans, int icase, const re_dfa_t *dfa) -{ - reg_errcode_t ret; - memset (pstr, '\0', sizeof (re_string_t)); - re_string_construct_common (str, len, pstr, trans, icase, dfa); - - if (len > 0) - { - ret = re_string_realloc_buffers (pstr, len + 1); - if (BE (ret != REG_NOERROR, 0)) - return ret; - } - pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str; - - if (icase) - { -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - { - while (1) - { - ret = build_wcs_upper_buffer (pstr); - if (BE (ret != REG_NOERROR, 0)) - return ret; - if (pstr->valid_raw_len >= len) - break; - if (pstr->bufs_len > pstr->valid_len + dfa->mb_cur_max) - break; - ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2); - if (BE (ret != REG_NOERROR, 0)) - return ret; - } - } - else -#endif /* RE_ENABLE_I18N */ - build_upper_buffer (pstr); - } - else - { -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - build_wcs_buffer (pstr); - else -#endif /* RE_ENABLE_I18N */ - { - if (trans != NULL) - re_string_translate_buffer (pstr); - else - { - pstr->valid_len = pstr->bufs_len; - pstr->valid_raw_len = pstr->bufs_len; - } - } - } - - return REG_NOERROR; -} - -/* Helper functions for re_string_allocate, and re_string_construct. */ - -static reg_errcode_t -internal_function -re_string_realloc_buffers (re_string_t *pstr, int new_buf_len) -{ -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1) - { - wint_t *new_wcs; - - /* Avoid overflow in realloc. */ - const size_t max_object_size = MAX (sizeof (wint_t), sizeof (int)); - if (BE (SIZE_MAX / max_object_size < new_buf_len, 0)) - return REG_ESPACE; - - new_wcs = re_realloc (pstr->wcs, wint_t, new_buf_len); - if (BE (new_wcs == NULL, 0)) - return REG_ESPACE; - pstr->wcs = new_wcs; - if (pstr->offsets != NULL) - { - int *new_offsets = re_realloc (pstr->offsets, int, new_buf_len); - if (BE (new_offsets == NULL, 0)) - return REG_ESPACE; - pstr->offsets = new_offsets; - } - } -#endif /* RE_ENABLE_I18N */ - if (pstr->mbs_allocated) - { - unsigned char *new_mbs = re_realloc (pstr->mbs, unsigned char, - new_buf_len); - if (BE (new_mbs == NULL, 0)) - return REG_ESPACE; - pstr->mbs = new_mbs; - } - pstr->bufs_len = new_buf_len; - return REG_NOERROR; -} - - -static void -internal_function -re_string_construct_common (const char *str, int len, re_string_t *pstr, - RE_TRANSLATE_TYPE trans, int icase, - const re_dfa_t *dfa) -{ - pstr->raw_mbs = (const unsigned char *) str; - pstr->len = len; - pstr->raw_len = len; - pstr->trans = trans; - pstr->icase = icase ? 1 : 0; - pstr->mbs_allocated = (trans != NULL || icase); - pstr->mb_cur_max = dfa->mb_cur_max; - pstr->is_utf8 = dfa->is_utf8; - pstr->map_notascii = dfa->map_notascii; - pstr->stop = pstr->len; - pstr->raw_stop = pstr->stop; -} - -#ifdef RE_ENABLE_I18N - -/* Build wide character buffer PSTR->WCS. - If the byte sequence of the string are: - (0), (1), (0), (1), - Then wide character buffer will be: - , WEOF , , WEOF , - We use WEOF for padding, they indicate that the position isn't - a first byte of a multibyte character. - - Note that this function assumes PSTR->VALID_LEN elements are already - built and starts from PSTR->VALID_LEN. */ - -static void -internal_function -build_wcs_buffer (re_string_t *pstr) -{ -#ifdef _LIBC - unsigned char buf[MB_LEN_MAX]; - assert (MB_LEN_MAX >= pstr->mb_cur_max); -#else - unsigned char buf[64]; -#endif - mbstate_t prev_st; - int byte_idx, end_idx, remain_len; - size_t mbclen; - - /* Build the buffers from pstr->valid_len to either pstr->len or - pstr->bufs_len. */ - end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; - for (byte_idx = pstr->valid_len; byte_idx < end_idx;) - { - wchar_t wc; - const char *p; - - remain_len = end_idx - byte_idx; - prev_st = pstr->cur_state; - /* Apply the translation if we need. */ - if (BE (pstr->trans != NULL, 0)) - { - int i, ch; - - for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i) - { - ch = pstr->raw_mbs [pstr->raw_mbs_idx + byte_idx + i]; - buf[i] = pstr->mbs[byte_idx + i] = pstr->trans[ch]; - } - p = (const char *) buf; - } - else - p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx; - mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state); - if (BE (mbclen == (size_t) -2, 0)) - { - /* The buffer doesn't have enough space, finish to build. */ - pstr->cur_state = prev_st; - break; - } - else if (BE (mbclen == (size_t) -1 || mbclen == 0, 0)) - { - /* We treat these cases as a singlebyte character. */ - mbclen = 1; - wc = (wchar_t) pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]; - if (BE (pstr->trans != NULL, 0)) - wc = pstr->trans[wc]; - pstr->cur_state = prev_st; - } - - /* Write wide character and padding. */ - pstr->wcs[byte_idx++] = wc; - /* Write paddings. */ - for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;) - pstr->wcs[byte_idx++] = WEOF; - } - pstr->valid_len = byte_idx; - pstr->valid_raw_len = byte_idx; -} - -/* Build wide character buffer PSTR->WCS like build_wcs_buffer, - but for REG_ICASE. */ - -static reg_errcode_t -internal_function -build_wcs_upper_buffer (re_string_t *pstr) -{ - mbstate_t prev_st; - int src_idx, byte_idx, end_idx, remain_len; - size_t mbclen; -#ifdef _LIBC - char buf[MB_LEN_MAX]; - assert (MB_LEN_MAX >= pstr->mb_cur_max); -#else - char buf[64]; -#endif - - byte_idx = pstr->valid_len; - end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; - - /* The following optimization assumes that ASCII characters can be - mapped to wide characters with a simple cast. */ - if (! pstr->map_notascii && pstr->trans == NULL && !pstr->offsets_needed) - { - while (byte_idx < end_idx) - { - wchar_t wc; - - if (isascii (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]) - && mbsinit (&pstr->cur_state)) - { - /* In case of a singlebyte character. */ - pstr->mbs[byte_idx] - = toupper (pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]); - /* The next step uses the assumption that wchar_t is encoded - ASCII-safe: all ASCII values can be converted like this. */ - pstr->wcs[byte_idx] = (wchar_t) pstr->mbs[byte_idx]; - ++byte_idx; - continue; - } - - remain_len = end_idx - byte_idx; - prev_st = pstr->cur_state; - mbclen = __mbrtowc (&wc, - ((const char *) pstr->raw_mbs + pstr->raw_mbs_idx - + byte_idx), remain_len, &pstr->cur_state); - if (BE (mbclen + 2 > 2, 1)) - { - wchar_t wcu = wc; - if (iswlower (wc)) - { - size_t mbcdlen; - - wcu = towupper (wc); - mbcdlen = wcrtomb (buf, wcu, &prev_st); - if (BE (mbclen == mbcdlen, 1)) - memcpy (pstr->mbs + byte_idx, buf, mbclen); - else - { - src_idx = byte_idx; - goto offsets_needed; - } - } - else - memcpy (pstr->mbs + byte_idx, - pstr->raw_mbs + pstr->raw_mbs_idx + byte_idx, mbclen); - pstr->wcs[byte_idx++] = wcu; - /* Write paddings. */ - for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;) - pstr->wcs[byte_idx++] = WEOF; - } - else if (mbclen == (size_t) -1 || mbclen == 0) - { - /* It is an invalid character or '\0'. Just use the byte. */ - int ch = pstr->raw_mbs[pstr->raw_mbs_idx + byte_idx]; - pstr->mbs[byte_idx] = ch; - /* And also cast it to wide char. */ - pstr->wcs[byte_idx++] = (wchar_t) ch; - if (BE (mbclen == (size_t) -1, 0)) - pstr->cur_state = prev_st; - } - else - { - /* The buffer doesn't have enough space, finish to build. */ - pstr->cur_state = prev_st; - break; - } - } - pstr->valid_len = byte_idx; - pstr->valid_raw_len = byte_idx; - return REG_NOERROR; - } - else - for (src_idx = pstr->valid_raw_len; byte_idx < end_idx;) - { - wchar_t wc; - const char *p; - offsets_needed: - remain_len = end_idx - byte_idx; - prev_st = pstr->cur_state; - if (BE (pstr->trans != NULL, 0)) - { - int i, ch; - - for (i = 0; i < pstr->mb_cur_max && i < remain_len; ++i) - { - ch = pstr->raw_mbs [pstr->raw_mbs_idx + src_idx + i]; - buf[i] = pstr->trans[ch]; - } - p = (const char *) buf; - } - else - p = (const char *) pstr->raw_mbs + pstr->raw_mbs_idx + src_idx; - mbclen = __mbrtowc (&wc, p, remain_len, &pstr->cur_state); - if (BE (mbclen + 2 > 2, 1)) - { - wchar_t wcu = wc; - if (iswlower (wc)) - { - size_t mbcdlen; - - wcu = towupper (wc); - mbcdlen = wcrtomb ((char *) buf, wcu, &prev_st); - if (BE (mbclen == mbcdlen, 1)) - memcpy (pstr->mbs + byte_idx, buf, mbclen); - else if (mbcdlen != (size_t) -1) - { - size_t i; - - if (byte_idx + mbcdlen > pstr->bufs_len) - { - pstr->cur_state = prev_st; - break; - } - - if (pstr->offsets == NULL) - { - pstr->offsets = re_malloc (int, pstr->bufs_len); - - if (pstr->offsets == NULL) - return REG_ESPACE; - } - if (!pstr->offsets_needed) - { - for (i = 0; i < (size_t) byte_idx; ++i) - pstr->offsets[i] = i; - pstr->offsets_needed = 1; - } - - memcpy (pstr->mbs + byte_idx, buf, mbcdlen); - pstr->wcs[byte_idx] = wcu; - pstr->offsets[byte_idx] = src_idx; - for (i = 1; i < mbcdlen; ++i) - { - pstr->offsets[byte_idx + i] - = src_idx + (i < mbclen ? i : mbclen - 1); - pstr->wcs[byte_idx + i] = WEOF; - } - pstr->len += mbcdlen - mbclen; - if (pstr->raw_stop > src_idx) - pstr->stop += mbcdlen - mbclen; - end_idx = (pstr->bufs_len > pstr->len) - ? pstr->len : pstr->bufs_len; - byte_idx += mbcdlen; - src_idx += mbclen; - continue; - } - else - memcpy (pstr->mbs + byte_idx, p, mbclen); - } - else - memcpy (pstr->mbs + byte_idx, p, mbclen); - - if (BE (pstr->offsets_needed != 0, 0)) - { - size_t i; - for (i = 0; i < mbclen; ++i) - pstr->offsets[byte_idx + i] = src_idx + i; - } - src_idx += mbclen; - - pstr->wcs[byte_idx++] = wcu; - /* Write paddings. */ - for (remain_len = byte_idx + mbclen - 1; byte_idx < remain_len ;) - pstr->wcs[byte_idx++] = WEOF; - } - else if (mbclen == (size_t) -1 || mbclen == 0) - { - /* It is an invalid character or '\0'. Just use the byte. */ - int ch = pstr->raw_mbs[pstr->raw_mbs_idx + src_idx]; - - if (BE (pstr->trans != NULL, 0)) - ch = pstr->trans [ch]; - pstr->mbs[byte_idx] = ch; - - if (BE (pstr->offsets_needed != 0, 0)) - pstr->offsets[byte_idx] = src_idx; - ++src_idx; - - /* And also cast it to wide char. */ - pstr->wcs[byte_idx++] = (wchar_t) ch; - if (BE (mbclen == (size_t) -1, 0)) - pstr->cur_state = prev_st; - } - else - { - /* The buffer doesn't have enough space, finish to build. */ - pstr->cur_state = prev_st; - break; - } - } - pstr->valid_len = byte_idx; - pstr->valid_raw_len = src_idx; - return REG_NOERROR; -} - -/* Skip characters until the index becomes greater than NEW_RAW_IDX. - Return the index. */ - -static int -internal_function -re_string_skip_chars (re_string_t *pstr, int new_raw_idx, wint_t *last_wc) -{ - mbstate_t prev_st; - int rawbuf_idx; - size_t mbclen; - wint_t wc = WEOF; - - /* Skip the characters which are not necessary to check. */ - for (rawbuf_idx = pstr->raw_mbs_idx + pstr->valid_raw_len; - rawbuf_idx < new_raw_idx;) - { - wchar_t wc2; - int remain_len = pstr->len - rawbuf_idx; - prev_st = pstr->cur_state; - mbclen = __mbrtowc (&wc2, (const char *) pstr->raw_mbs + rawbuf_idx, - remain_len, &pstr->cur_state); - if (BE (mbclen == (size_t) -2 || mbclen == (size_t) -1 || mbclen == 0, 0)) - { - /* We treat these cases as a single byte character. */ - if (mbclen == 0 || remain_len == 0) - wc = L'\0'; - else - wc = *(unsigned char *) (pstr->raw_mbs + rawbuf_idx); - mbclen = 1; - pstr->cur_state = prev_st; - } - else - wc = (wint_t) wc2; - /* Then proceed the next character. */ - rawbuf_idx += mbclen; - } - *last_wc = (wint_t) wc; - return rawbuf_idx; -} -#endif /* RE_ENABLE_I18N */ - -/* Build the buffer PSTR->MBS, and apply the translation if we need. - This function is used in case of REG_ICASE. */ - -static void -internal_function -build_upper_buffer (re_string_t *pstr) -{ - int char_idx, end_idx; - end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; - - for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx) - { - int ch = pstr->raw_mbs[pstr->raw_mbs_idx + char_idx]; - if (BE (pstr->trans != NULL, 0)) - ch = pstr->trans[ch]; - if (islower (ch)) - pstr->mbs[char_idx] = toupper (ch); - else - pstr->mbs[char_idx] = ch; - } - pstr->valid_len = char_idx; - pstr->valid_raw_len = char_idx; -} - -/* Apply TRANS to the buffer in PSTR. */ - -static void -internal_function -re_string_translate_buffer (re_string_t *pstr) -{ - int buf_idx, end_idx; - end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len; - - for (buf_idx = pstr->valid_len; buf_idx < end_idx; ++buf_idx) - { - int ch = pstr->raw_mbs[pstr->raw_mbs_idx + buf_idx]; - pstr->mbs[buf_idx] = pstr->trans[ch]; - } - - pstr->valid_len = buf_idx; - pstr->valid_raw_len = buf_idx; -} - -/* This function re-construct the buffers. - Concretely, convert to wide character in case of pstr->mb_cur_max > 1, - convert to upper case in case of REG_ICASE, apply translation. */ - -static reg_errcode_t -internal_function -re_string_reconstruct (re_string_t *pstr, int idx, int eflags) -{ - int offset = idx - pstr->raw_mbs_idx; - if (BE (offset < 0, 0)) - { - /* Reset buffer. */ -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1) - memset (&pstr->cur_state, '\0', sizeof (mbstate_t)); -#endif /* RE_ENABLE_I18N */ - pstr->len = pstr->raw_len; - pstr->stop = pstr->raw_stop; - pstr->valid_len = 0; - pstr->raw_mbs_idx = 0; - pstr->valid_raw_len = 0; - pstr->offsets_needed = 0; - pstr->tip_context = ((eflags & REG_NOTBOL) ? CONTEXT_BEGBUF - : CONTEXT_NEWLINE | CONTEXT_BEGBUF); - if (!pstr->mbs_allocated) - pstr->mbs = (unsigned char *) pstr->raw_mbs; - offset = idx; - } - - if (BE (offset != 0, 1)) - { - /* Should the already checked characters be kept? */ - if (BE (offset < pstr->valid_raw_len, 1)) - { - /* Yes, move them to the front of the buffer. */ -#ifdef RE_ENABLE_I18N - if (BE (pstr->offsets_needed, 0)) - { - int low = 0, high = pstr->valid_len, mid; - do - { - mid = (high + low) / 2; - if (pstr->offsets[mid] > offset) - high = mid; - else if (pstr->offsets[mid] < offset) - low = mid + 1; - else - break; - } - while (low < high); - if (pstr->offsets[mid] < offset) - ++mid; - pstr->tip_context = re_string_context_at (pstr, mid - 1, - eflags); - /* This can be quite complicated, so handle specially - only the common and easy case where the character with - different length representation of lower and upper - case is present at or after offset. */ - if (pstr->valid_len > offset - && mid == offset && pstr->offsets[mid] == offset) - { - memmove (pstr->wcs, pstr->wcs + offset, - (pstr->valid_len - offset) * sizeof (wint_t)); - memmove (pstr->mbs, pstr->mbs + offset, pstr->valid_len - offset); - pstr->valid_len -= offset; - pstr->valid_raw_len -= offset; - for (low = 0; low < pstr->valid_len; low++) - pstr->offsets[low] = pstr->offsets[low + offset] - offset; - } - else - { - /* Otherwise, just find out how long the partial multibyte - character at offset is and fill it with WEOF/255. */ - pstr->len = pstr->raw_len - idx + offset; - pstr->stop = pstr->raw_stop - idx + offset; - pstr->offsets_needed = 0; - while (mid > 0 && pstr->offsets[mid - 1] == offset) - --mid; - while (mid < pstr->valid_len) - if (pstr->wcs[mid] != WEOF) - break; - else - ++mid; - if (mid == pstr->valid_len) - pstr->valid_len = 0; - else - { - pstr->valid_len = pstr->offsets[mid] - offset; - if (pstr->valid_len) - { - for (low = 0; low < pstr->valid_len; ++low) - pstr->wcs[low] = WEOF; - memset (pstr->mbs, 255, pstr->valid_len); - } - } - pstr->valid_raw_len = pstr->valid_len; - } - } - else -#endif - { - pstr->tip_context = re_string_context_at (pstr, offset - 1, - eflags); -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1) - memmove (pstr->wcs, pstr->wcs + offset, - (pstr->valid_len - offset) * sizeof (wint_t)); -#endif /* RE_ENABLE_I18N */ - if (BE (pstr->mbs_allocated, 0)) - memmove (pstr->mbs, pstr->mbs + offset, - pstr->valid_len - offset); - pstr->valid_len -= offset; - pstr->valid_raw_len -= offset; -#if DEBUG - assert (pstr->valid_len > 0); -#endif - } - } - else - { -#ifdef RE_ENABLE_I18N - /* No, skip all characters until IDX. */ - int prev_valid_len = pstr->valid_len; - - if (BE (pstr->offsets_needed, 0)) - { - pstr->len = pstr->raw_len - idx + offset; - pstr->stop = pstr->raw_stop - idx + offset; - pstr->offsets_needed = 0; - } -#endif - pstr->valid_len = 0; -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1) - { - int wcs_idx; - wint_t wc = WEOF; - - if (pstr->is_utf8) - { - const unsigned char *raw, *p, *end; - - /* Special case UTF-8. Multi-byte chars start with any - byte other than 0x80 - 0xbf. */ - raw = pstr->raw_mbs + pstr->raw_mbs_idx; - end = raw + (offset - pstr->mb_cur_max); - if (end < pstr->raw_mbs) - end = pstr->raw_mbs; - p = raw + offset - 1; -#ifdef _LIBC - /* We know the wchar_t encoding is UCS4, so for the simple - case, ASCII characters, skip the conversion step. */ - if (isascii (*p) && BE (pstr->trans == NULL, 1)) - { - memset (&pstr->cur_state, '\0', sizeof (mbstate_t)); - /* pstr->valid_len = 0; */ - wc = (wchar_t) *p; - } - else -#endif - for (; p >= end; --p) - if ((*p & 0xc0) != 0x80) - { - mbstate_t cur_state; - wchar_t wc2; - int mlen = raw + pstr->len - p; - unsigned char buf[6]; - size_t mbclen; - - if (BE (pstr->trans != NULL, 0)) - { - int i = mlen < 6 ? mlen : 6; - while (--i >= 0) - buf[i] = pstr->trans[p[i]]; - } - /* XXX Don't use mbrtowc, we know which conversion - to use (UTF-8 -> UCS4). */ - memset (&cur_state, 0, sizeof (cur_state)); - mbclen = __mbrtowc (&wc2, (const char *) p, mlen, - &cur_state); - if (raw + offset - p <= mbclen - && mbclen < (size_t) -2) - { - memset (&pstr->cur_state, '\0', - sizeof (mbstate_t)); - pstr->valid_len = mbclen - (raw + offset - p); - wc = wc2; - } - break; - } - } - - if (wc == WEOF) - pstr->valid_len = re_string_skip_chars (pstr, idx, &wc) - idx; - if (wc == WEOF) - pstr->tip_context - = re_string_context_at (pstr, prev_valid_len - 1, eflags); - else - pstr->tip_context = ((BE (pstr->word_ops_used != 0, 0) - && IS_WIDE_WORD_CHAR (wc)) - ? CONTEXT_WORD - : ((IS_WIDE_NEWLINE (wc) - && pstr->newline_anchor) - ? CONTEXT_NEWLINE : 0)); - if (BE (pstr->valid_len, 0)) - { - for (wcs_idx = 0; wcs_idx < pstr->valid_len; ++wcs_idx) - pstr->wcs[wcs_idx] = WEOF; - if (pstr->mbs_allocated) - memset (pstr->mbs, 255, pstr->valid_len); - } - pstr->valid_raw_len = pstr->valid_len; - } - else -#endif /* RE_ENABLE_I18N */ - { - int c = pstr->raw_mbs[pstr->raw_mbs_idx + offset - 1]; - pstr->valid_raw_len = 0; - if (pstr->trans) - c = pstr->trans[c]; - pstr->tip_context = (bitset_contain (pstr->word_char, c) - ? CONTEXT_WORD - : ((IS_NEWLINE (c) && pstr->newline_anchor) - ? CONTEXT_NEWLINE : 0)); - } - } - if (!BE (pstr->mbs_allocated, 0)) - pstr->mbs += offset; - } - pstr->raw_mbs_idx = idx; - pstr->len -= offset; - pstr->stop -= offset; - - /* Then build the buffers. */ -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1) - { - if (pstr->icase) - { - reg_errcode_t ret = build_wcs_upper_buffer (pstr); - if (BE (ret != REG_NOERROR, 0)) - return ret; - } - else - build_wcs_buffer (pstr); - } - else -#endif /* RE_ENABLE_I18N */ - if (BE (pstr->mbs_allocated, 0)) - { - if (pstr->icase) - build_upper_buffer (pstr); - else if (pstr->trans != NULL) - re_string_translate_buffer (pstr); - } - else - pstr->valid_len = pstr->len; - - pstr->cur_idx = 0; - return REG_NOERROR; -} - -static unsigned char -internal_function __attribute ((pure)) -re_string_peek_byte_case (const re_string_t *pstr, int idx) -{ - int ch, off; - - /* Handle the common (easiest) cases first. */ - if (BE (!pstr->mbs_allocated, 1)) - return re_string_peek_byte (pstr, idx); - -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1 - && ! re_string_is_single_byte_char (pstr, pstr->cur_idx + idx)) - return re_string_peek_byte (pstr, idx); -#endif - - off = pstr->cur_idx + idx; -#ifdef RE_ENABLE_I18N - if (pstr->offsets_needed) - off = pstr->offsets[off]; -#endif - - ch = pstr->raw_mbs[pstr->raw_mbs_idx + off]; - -#ifdef RE_ENABLE_I18N - /* Ensure that e.g. for tr_TR.UTF-8 BACKSLASH DOTLESS SMALL LETTER I - this function returns CAPITAL LETTER I instead of first byte of - DOTLESS SMALL LETTER I. The latter would confuse the parser, - since peek_byte_case doesn't advance cur_idx in any way. */ - if (pstr->offsets_needed && !isascii (ch)) - return re_string_peek_byte (pstr, idx); -#endif - - return ch; -} - -static unsigned char -internal_function __attribute ((pure)) -re_string_fetch_byte_case (re_string_t *pstr) -{ - if (BE (!pstr->mbs_allocated, 1)) - return re_string_fetch_byte (pstr); - -#ifdef RE_ENABLE_I18N - if (pstr->offsets_needed) - { - int off, ch; - - /* For tr_TR.UTF-8 [[:islower:]] there is - [[: CAPITAL LETTER I WITH DOT lower:]] in mbs. Skip - in that case the whole multi-byte character and return - the original letter. On the other side, with - [[: DOTLESS SMALL LETTER I return [[:I, as doing - anything else would complicate things too much. */ - - if (!re_string_first_byte (pstr, pstr->cur_idx)) - return re_string_fetch_byte (pstr); - - off = pstr->offsets[pstr->cur_idx]; - ch = pstr->raw_mbs[pstr->raw_mbs_idx + off]; - - if (! isascii (ch)) - return re_string_fetch_byte (pstr); - - re_string_skip_bytes (pstr, - re_string_char_size_at (pstr, pstr->cur_idx)); - return ch; - } -#endif - - return pstr->raw_mbs[pstr->raw_mbs_idx + pstr->cur_idx++]; -} - -static void -internal_function -re_string_destruct (re_string_t *pstr) -{ -#ifdef RE_ENABLE_I18N - re_free (pstr->wcs); - re_free (pstr->offsets); -#endif /* RE_ENABLE_I18N */ - if (pstr->mbs_allocated) - re_free (pstr->mbs); -} - -/* Return the context at IDX in INPUT. */ - -static unsigned int -internal_function -re_string_context_at (const re_string_t *input, int idx, int eflags) -{ - int c; - if (BE (idx < 0, 0)) - /* In this case, we use the value stored in input->tip_context, - since we can't know the character in input->mbs[-1] here. */ - return input->tip_context; - if (BE (idx == input->len, 0)) - return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF - : CONTEXT_NEWLINE | CONTEXT_ENDBUF); -#ifdef RE_ENABLE_I18N - if (input->mb_cur_max > 1) - { - wint_t wc; - int wc_idx = idx; - while(input->wcs[wc_idx] == WEOF) - { -#ifdef DEBUG - /* It must not happen. */ - assert (wc_idx >= 0); -#endif - --wc_idx; - if (wc_idx < 0) - return input->tip_context; - } - wc = input->wcs[wc_idx]; - if (BE (input->word_ops_used != 0, 0) && IS_WIDE_WORD_CHAR (wc)) - return CONTEXT_WORD; - return (IS_WIDE_NEWLINE (wc) && input->newline_anchor - ? CONTEXT_NEWLINE : 0); - } - else -#endif - { - c = re_string_byte_at (input, idx); - if (bitset_contain (input->word_char, c)) - return CONTEXT_WORD; - return IS_NEWLINE (c) && input->newline_anchor ? CONTEXT_NEWLINE : 0; - } -} - -/* Functions for set operation. */ - -static reg_errcode_t -internal_function -re_node_set_alloc (re_node_set *set, int size) -{ - /* - * ADR: valgrind says size can be 0, which then doesn't - * free the block of size 0. Harumph. This seems - * to work ok, though. - */ - if (size == 0) - { - memset(set, 0, sizeof(*set)); - return REG_NOERROR; - } - set->alloc = size; - set->nelem = 0; - set->elems = re_malloc (int, size); - if (BE (set->elems == NULL, 0)) - return REG_ESPACE; - return REG_NOERROR; -} - -static reg_errcode_t -internal_function -re_node_set_init_1 (re_node_set *set, int elem) -{ - set->alloc = 1; - set->nelem = 1; - set->elems = re_malloc (int, 1); - if (BE (set->elems == NULL, 0)) - { - set->alloc = set->nelem = 0; - return REG_ESPACE; - } - set->elems[0] = elem; - return REG_NOERROR; -} - -static reg_errcode_t -internal_function -re_node_set_init_2 (re_node_set *set, int elem1, int elem2) -{ - set->alloc = 2; - set->elems = re_malloc (int, 2); - if (BE (set->elems == NULL, 0)) - return REG_ESPACE; - if (elem1 == elem2) - { - set->nelem = 1; - set->elems[0] = elem1; - } - else - { - set->nelem = 2; - if (elem1 < elem2) - { - set->elems[0] = elem1; - set->elems[1] = elem2; - } - else - { - set->elems[0] = elem2; - set->elems[1] = elem1; - } - } - return REG_NOERROR; -} - -static reg_errcode_t -internal_function -re_node_set_init_copy (re_node_set *dest, const re_node_set *src) -{ - dest->nelem = src->nelem; - if (src->nelem > 0) - { - dest->alloc = dest->nelem; - dest->elems = re_malloc (int, dest->alloc); - if (BE (dest->elems == NULL, 0)) - { - dest->alloc = dest->nelem = 0; - return REG_ESPACE; - } - memcpy (dest->elems, src->elems, src->nelem * sizeof (int)); - } - else - re_node_set_init_empty (dest); - return REG_NOERROR; -} - -/* Calculate the intersection of the sets SRC1 and SRC2. And merge it to - DEST. Return value indicate the error code or REG_NOERROR if succeeded. - Note: We assume dest->elems is NULL, when dest->alloc is 0. */ - -static reg_errcode_t -internal_function -re_node_set_add_intersect (re_node_set *dest, const re_node_set *src1, - const re_node_set *src2) -{ - int i1, i2, is, id, delta, sbase; - if (src1->nelem == 0 || src2->nelem == 0) - return REG_NOERROR; - - /* We need dest->nelem + 2 * elems_in_intersection; this is a - conservative estimate. */ - if (src1->nelem + src2->nelem + dest->nelem > dest->alloc) - { - int new_alloc = src1->nelem + src2->nelem + dest->alloc; - int *new_elems = re_realloc (dest->elems, int, new_alloc); - if (BE (new_elems == NULL, 0)) - return REG_ESPACE; - dest->elems = new_elems; - dest->alloc = new_alloc; - } - - /* Find the items in the intersection of SRC1 and SRC2, and copy - into the top of DEST those that are not already in DEST itself. */ - sbase = dest->nelem + src1->nelem + src2->nelem; - i1 = src1->nelem - 1; - i2 = src2->nelem - 1; - id = dest->nelem - 1; - for (;;) - { - if (src1->elems[i1] == src2->elems[i2]) - { - /* Try to find the item in DEST. Maybe we could binary search? */ - while (id >= 0 && dest->elems[id] > src1->elems[i1]) - --id; - - if (id < 0 || dest->elems[id] != src1->elems[i1]) - dest->elems[--sbase] = src1->elems[i1]; - - if (--i1 < 0 || --i2 < 0) - break; - } - - /* Lower the highest of the two items. */ - else if (src1->elems[i1] < src2->elems[i2]) - { - if (--i2 < 0) - break; - } - else - { - if (--i1 < 0) - break; - } - } - - id = dest->nelem - 1; - is = dest->nelem + src1->nelem + src2->nelem - 1; - delta = is - sbase + 1; - - /* Now copy. When DELTA becomes zero, the remaining - DEST elements are already in place; this is more or - less the same loop that is in re_node_set_merge. */ - dest->nelem += delta; - if (delta > 0 && id >= 0) - for (;;) - { - if (dest->elems[is] > dest->elems[id]) - { - /* Copy from the top. */ - dest->elems[id + delta--] = dest->elems[is--]; - if (delta == 0) - break; - } - else - { - /* Slide from the bottom. */ - dest->elems[id + delta] = dest->elems[id]; - if (--id < 0) - break; - } - } - - /* Copy remaining SRC elements. */ - memcpy (dest->elems, dest->elems + sbase, delta * sizeof (int)); - - return REG_NOERROR; -} - -/* Calculate the union set of the sets SRC1 and SRC2. And store it to - DEST. Return value indicate the error code or REG_NOERROR if succeeded. */ - -static reg_errcode_t -internal_function -re_node_set_init_union (re_node_set *dest, const re_node_set *src1, - const re_node_set *src2) -{ - int i1, i2, id; - if (src1 != NULL && src1->nelem > 0 && src2 != NULL && src2->nelem > 0) - { - dest->alloc = src1->nelem + src2->nelem; - dest->elems = re_malloc (int, dest->alloc); - if (BE (dest->elems == NULL, 0)) - return REG_ESPACE; - } - else - { - if (src1 != NULL && src1->nelem > 0) - return re_node_set_init_copy (dest, src1); - else if (src2 != NULL && src2->nelem > 0) - return re_node_set_init_copy (dest, src2); - else - re_node_set_init_empty (dest); - return REG_NOERROR; - } - for (i1 = i2 = id = 0 ; i1 < src1->nelem && i2 < src2->nelem ;) - { - if (src1->elems[i1] > src2->elems[i2]) - { - dest->elems[id++] = src2->elems[i2++]; - continue; - } - if (src1->elems[i1] == src2->elems[i2]) - ++i2; - dest->elems[id++] = src1->elems[i1++]; - } - if (i1 < src1->nelem) - { - memcpy (dest->elems + id, src1->elems + i1, - (src1->nelem - i1) * sizeof (int)); - id += src1->nelem - i1; - } - else if (i2 < src2->nelem) - { - memcpy (dest->elems + id, src2->elems + i2, - (src2->nelem - i2) * sizeof (int)); - id += src2->nelem - i2; - } - dest->nelem = id; - return REG_NOERROR; -} - -/* Calculate the union set of the sets DEST and SRC. And store it to - DEST. Return value indicate the error code or REG_NOERROR if succeeded. */ - -static reg_errcode_t -internal_function -re_node_set_merge (re_node_set *dest, const re_node_set *src) -{ - int is, id, sbase, delta; - if (src == NULL || src->nelem == 0) - return REG_NOERROR; - if (dest->alloc < 2 * src->nelem + dest->nelem) - { - int new_alloc = 2 * (src->nelem + dest->alloc); - int *new_buffer = re_realloc (dest->elems, int, new_alloc); - if (BE (new_buffer == NULL, 0)) - return REG_ESPACE; - dest->elems = new_buffer; - dest->alloc = new_alloc; - } - - if (BE (dest->nelem == 0, 0)) - { - dest->nelem = src->nelem; - memcpy (dest->elems, src->elems, src->nelem * sizeof (int)); - return REG_NOERROR; - } - - /* Copy into the top of DEST the items of SRC that are not - found in DEST. Maybe we could binary search in DEST? */ - for (sbase = dest->nelem + 2 * src->nelem, - is = src->nelem - 1, id = dest->nelem - 1; is >= 0 && id >= 0; ) - { - if (dest->elems[id] == src->elems[is]) - is--, id--; - else if (dest->elems[id] < src->elems[is]) - dest->elems[--sbase] = src->elems[is--]; - else /* if (dest->elems[id] > src->elems[is]) */ - --id; - } - - if (is >= 0) - { - /* If DEST is exhausted, the remaining items of SRC must be unique. */ - sbase -= is + 1; - memcpy (dest->elems + sbase, src->elems, (is + 1) * sizeof (int)); - } - - id = dest->nelem - 1; - is = dest->nelem + 2 * src->nelem - 1; - delta = is - sbase + 1; - if (delta == 0) - return REG_NOERROR; - - /* Now copy. When DELTA becomes zero, the remaining - DEST elements are already in place. */ - dest->nelem += delta; - for (;;) - { - if (dest->elems[is] > dest->elems[id]) - { - /* Copy from the top. */ - dest->elems[id + delta--] = dest->elems[is--]; - if (delta == 0) - break; - } - else - { - /* Slide from the bottom. */ - dest->elems[id + delta] = dest->elems[id]; - if (--id < 0) - { - /* Copy remaining SRC elements. */ - memcpy (dest->elems, dest->elems + sbase, - delta * sizeof (int)); - break; - } - } - } - - return REG_NOERROR; -} - -/* Insert the new element ELEM to the re_node_set* SET. - SET should not already have ELEM. - return -1 if an error is occured, return 1 otherwise. */ - -static int -internal_function -re_node_set_insert (re_node_set *set, int elem) -{ - int idx; - /* In case the set is empty. */ - if (set->alloc == 0) - { - if (BE (re_node_set_init_1 (set, elem) == REG_NOERROR, 1)) - return 1; - else - return -1; - } - - if (BE (set->nelem, 0) == 0) - { - /* We already guaranteed above that set->alloc != 0. */ - set->elems[0] = elem; - ++set->nelem; - return 1; - } - - /* Realloc if we need. */ - if (set->alloc == set->nelem) - { - int *new_elems; - set->alloc = set->alloc * 2; - new_elems = re_realloc (set->elems, int, set->alloc); - if (BE (new_elems == NULL, 0)) - return -1; - set->elems = new_elems; - } - - /* Move the elements which follows the new element. Test the - first element separately to skip a check in the inner loop. */ - if (elem < set->elems[0]) - { - idx = 0; - for (idx = set->nelem; idx > 0; idx--) - set->elems[idx] = set->elems[idx - 1]; - } - else - { - for (idx = set->nelem; set->elems[idx - 1] > elem; idx--) - set->elems[idx] = set->elems[idx - 1]; - } - - /* Insert the new element. */ - set->elems[idx] = elem; - ++set->nelem; - return 1; -} - -/* Insert the new element ELEM to the re_node_set* SET. - SET should not already have any element greater than or equal to ELEM. - Return -1 if an error is occured, return 1 otherwise. */ - -static int -internal_function -re_node_set_insert_last (re_node_set *set, int elem) -{ - /* Realloc if we need. */ - if (set->alloc == set->nelem) - { - int *new_elems; - set->alloc = (set->alloc + 1) * 2; - new_elems = re_realloc (set->elems, int, set->alloc); - if (BE (new_elems == NULL, 0)) - return -1; - set->elems = new_elems; - } - - /* Insert the new element. */ - set->elems[set->nelem++] = elem; - return 1; -} - -/* Compare two node sets SET1 and SET2. - return 1 if SET1 and SET2 are equivalent, return 0 otherwise. */ - -static int -internal_function __attribute ((pure)) -re_node_set_compare (const re_node_set *set1, const re_node_set *set2) -{ - int i; - if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem) - return 0; - for (i = set1->nelem ; --i >= 0 ; ) - if (set1->elems[i] != set2->elems[i]) - return 0; - return 1; -} - -/* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise. */ - -static int -internal_function __attribute ((pure)) -re_node_set_contains (const re_node_set *set, int elem) -{ - unsigned int idx, right, mid; - if (set->nelem <= 0) - return 0; - - /* Binary search the element. */ - idx = 0; - right = set->nelem - 1; - while (idx < right) - { - mid = (idx + right) / 2; - if (set->elems[mid] < elem) - idx = mid + 1; - else - right = mid; - } - return set->elems[idx] == elem ? idx + 1 : 0; -} - -static void -internal_function -re_node_set_remove_at (re_node_set *set, int idx) -{ - if (idx < 0 || idx >= set->nelem) - return; - --set->nelem; - for (; idx < set->nelem; idx++) - set->elems[idx] = set->elems[idx + 1]; -} - - -/* Add the token TOKEN to dfa->nodes, and return the index of the token. - Or return -1, if an error will be occured. */ - -static int -internal_function -re_dfa_add_node (re_dfa_t *dfa, re_token_t token) -{ - if (BE (dfa->nodes_len >= dfa->nodes_alloc, 0)) - { - size_t new_nodes_alloc = dfa->nodes_alloc * 2; - int *new_nexts, *new_indices; - re_node_set *new_edests, *new_eclosures; - re_token_t *new_nodes; - - /* Avoid overflows in realloc. */ - const size_t max_object_size = MAX (sizeof (re_token_t), - MAX (sizeof (re_node_set), - sizeof (int))); - if (BE (SIZE_MAX / max_object_size < new_nodes_alloc, 0)) - return -1; - - new_nodes = re_realloc (dfa->nodes, re_token_t, new_nodes_alloc); - if (BE (new_nodes == NULL, 0)) - return -1; - dfa->nodes = new_nodes; - new_nexts = re_realloc (dfa->nexts, int, new_nodes_alloc); - new_indices = re_realloc (dfa->org_indices, int, new_nodes_alloc); - new_edests = re_realloc (dfa->edests, re_node_set, new_nodes_alloc); - new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc); - if (BE (new_nexts == NULL || new_indices == NULL - || new_edests == NULL || new_eclosures == NULL, 0)) - return -1; - dfa->nexts = new_nexts; - dfa->org_indices = new_indices; - dfa->edests = new_edests; - dfa->eclosures = new_eclosures; - dfa->nodes_alloc = new_nodes_alloc; - } - dfa->nodes[dfa->nodes_len] = token; - dfa->nodes[dfa->nodes_len].constraint = 0; -#ifdef RE_ENABLE_I18N - dfa->nodes[dfa->nodes_len].accept_mb = - (token.type == OP_PERIOD && dfa->mb_cur_max > 1) || token.type == COMPLEX_BRACKET; -#endif - dfa->nexts[dfa->nodes_len] = -1; - re_node_set_init_empty (dfa->edests + dfa->nodes_len); - re_node_set_init_empty (dfa->eclosures + dfa->nodes_len); - return dfa->nodes_len++; -} - -static inline unsigned int -internal_function -calc_state_hash (const re_node_set *nodes, unsigned int context) -{ - unsigned int hash = nodes->nelem + context; - int i; - for (i = 0 ; i < nodes->nelem ; i++) - hash += nodes->elems[i]; - return hash; -} - -/* Search for the state whose node_set is equivalent to NODES. - Return the pointer to the state, if we found it in the DFA. - Otherwise create the new one and return it. In case of an error - return NULL and set the error code in ERR. - Note: - We assume NULL as the invalid state, then it is possible that - return value is NULL and ERR is REG_NOERROR. - - We never return non-NULL value in case of any errors, it is for - optimization. */ - -static re_dfastate_t * -internal_function -re_acquire_state (reg_errcode_t *err, const re_dfa_t *dfa, - const re_node_set *nodes) -{ - unsigned int hash; - re_dfastate_t *new_state; - struct re_state_table_entry *spot; - int i; - if (BE (nodes->nelem == 0, 0)) - { - *err = REG_NOERROR; - return NULL; - } - hash = calc_state_hash (nodes, 0); - spot = dfa->state_table + (hash & dfa->state_hash_mask); - - for (i = 0 ; i < spot->num ; i++) - { - re_dfastate_t *state = spot->array[i]; - if (hash != state->hash) - continue; - if (re_node_set_compare (&state->nodes, nodes)) - return state; - } - - /* There are no appropriate state in the dfa, create the new one. */ - new_state = create_ci_newstate (dfa, nodes, hash); - if (BE (new_state == NULL, 0)) - *err = REG_ESPACE; - - return new_state; -} - -/* Search for the state whose node_set is equivalent to NODES and - whose context is equivalent to CONTEXT. - Return the pointer to the state, if we found it in the DFA. - Otherwise create the new one and return it. In case of an error - return NULL and set the error code in ERR. - Note: - We assume NULL as the invalid state, then it is possible that - return value is NULL and ERR is REG_NOERROR. - - We never return non-NULL value in case of any errors, it is for - optimization. */ - -static re_dfastate_t * -internal_function -re_acquire_state_context (reg_errcode_t *err, const re_dfa_t *dfa, - const re_node_set *nodes, unsigned int context) -{ - unsigned int hash; - re_dfastate_t *new_state; - struct re_state_table_entry *spot; - int i; - if (nodes->nelem == 0) - { - *err = REG_NOERROR; - return NULL; - } - hash = calc_state_hash (nodes, context); - spot = dfa->state_table + (hash & dfa->state_hash_mask); - - for (i = 0 ; i < spot->num ; i++) - { - re_dfastate_t *state = spot->array[i]; - if (state->hash == hash - && state->context == context - && re_node_set_compare (state->entrance_nodes, nodes)) - return state; - } - /* There are no appropriate state in `dfa', create the new one. */ - new_state = create_cd_newstate (dfa, nodes, context, hash); - if (BE (new_state == NULL, 0)) - *err = REG_ESPACE; - - return new_state; -} - -/* Finish initialization of the new state NEWSTATE, and using its hash value - HASH put in the appropriate bucket of DFA's state table. Return value - indicates the error code if failed. */ - -static reg_errcode_t -register_state (const re_dfa_t *dfa, re_dfastate_t *newstate, - unsigned int hash) -{ - struct re_state_table_entry *spot; - reg_errcode_t err; - int i; - - newstate->hash = hash; - err = re_node_set_alloc (&newstate->non_eps_nodes, newstate->nodes.nelem); - if (BE (err != REG_NOERROR, 0)) - return REG_ESPACE; - for (i = 0; i < newstate->nodes.nelem; i++) - { - int elem = newstate->nodes.elems[i]; - if (!IS_EPSILON_NODE (dfa->nodes[elem].type)) - if (re_node_set_insert_last (&newstate->non_eps_nodes, elem) < 0) - return REG_ESPACE; - } - - spot = dfa->state_table + (hash & dfa->state_hash_mask); - if (BE (spot->alloc <= spot->num, 0)) - { - int new_alloc = 2 * spot->num + 2; - re_dfastate_t **new_array = re_realloc (spot->array, re_dfastate_t *, - new_alloc); - if (BE (new_array == NULL, 0)) - return REG_ESPACE; - spot->array = new_array; - spot->alloc = new_alloc; - } - spot->array[spot->num++] = newstate; - return REG_NOERROR; -} - -static void -free_state (re_dfastate_t *state) -{ - re_node_set_free (&state->non_eps_nodes); - re_node_set_free (&state->inveclosure); - if (state->entrance_nodes != &state->nodes) - { - re_node_set_free (state->entrance_nodes); - re_free (state->entrance_nodes); - } - re_node_set_free (&state->nodes); - re_free (state->word_trtable); - re_free (state->trtable); - re_free (state); -} - -/* Create the new state which is independ of contexts. - Return the new state if succeeded, otherwise return NULL. */ - -static re_dfastate_t * -internal_function -create_ci_newstate (const re_dfa_t *dfa, const re_node_set *nodes, - unsigned int hash) -{ - int i; - reg_errcode_t err; - re_dfastate_t *newstate; - - newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); - if (BE (newstate == NULL, 0)) - return NULL; - err = re_node_set_init_copy (&newstate->nodes, nodes); - if (BE (err != REG_NOERROR, 0)) - { - re_free (newstate); - return NULL; - } - - newstate->entrance_nodes = &newstate->nodes; - for (i = 0 ; i < nodes->nelem ; i++) - { - re_token_t *node = dfa->nodes + nodes->elems[i]; - re_token_type_t type = node->type; - if (type == CHARACTER && !node->constraint) - continue; -#ifdef RE_ENABLE_I18N - newstate->accept_mb |= node->accept_mb; -#endif /* RE_ENABLE_I18N */ - - /* If the state has the halt node, the state is a halt state. */ - if (type == END_OF_RE) - newstate->halt = 1; - else if (type == OP_BACK_REF) - newstate->has_backref = 1; - else if (type == ANCHOR || node->constraint) - newstate->has_constraint = 1; - } - err = register_state (dfa, newstate, hash); - if (BE (err != REG_NOERROR, 0)) - { - free_state (newstate); - newstate = NULL; - } - return newstate; -} - -/* Create the new state which is depend on the context CONTEXT. - Return the new state if succeeded, otherwise return NULL. */ - -static re_dfastate_t * -internal_function -create_cd_newstate (const re_dfa_t *dfa, const re_node_set *nodes, - unsigned int context, unsigned int hash) -{ - int i, nctx_nodes = 0; - reg_errcode_t err; - re_dfastate_t *newstate; - - newstate = (re_dfastate_t *) calloc (sizeof (re_dfastate_t), 1); - if (BE (newstate == NULL, 0)) - return NULL; - err = re_node_set_init_copy (&newstate->nodes, nodes); - if (BE (err != REG_NOERROR, 0)) - { - re_free (newstate); - return NULL; - } - - newstate->context = context; - newstate->entrance_nodes = &newstate->nodes; - - for (i = 0 ; i < nodes->nelem ; i++) - { - re_token_t *node = dfa->nodes + nodes->elems[i]; - re_token_type_t type = node->type; - unsigned int constraint = node->constraint; - - if (type == CHARACTER && !constraint) - continue; -#ifdef RE_ENABLE_I18N - newstate->accept_mb |= node->accept_mb; -#endif /* RE_ENABLE_I18N */ - - /* If the state has the halt node, the state is a halt state. */ - if (type == END_OF_RE) - newstate->halt = 1; - else if (type == OP_BACK_REF) - newstate->has_backref = 1; - - if (constraint) - { - if (newstate->entrance_nodes == &newstate->nodes) - { - newstate->entrance_nodes = re_malloc (re_node_set, 1); - if (BE (newstate->entrance_nodes == NULL, 0)) - { - free_state (newstate); - return NULL; - } - if (re_node_set_init_copy (newstate->entrance_nodes, nodes) - != REG_NOERROR) - return NULL; - nctx_nodes = 0; - newstate->has_constraint = 1; - } - - if (NOT_SATISFY_PREV_CONSTRAINT (constraint,context)) - { - re_node_set_remove_at (&newstate->nodes, i - nctx_nodes); - ++nctx_nodes; - } - } - } - err = register_state (dfa, newstate, hash); - if (BE (err != REG_NOERROR, 0)) - { - free_state (newstate); - newstate = NULL; - } - return newstate; -} diff --git a/deps/regex/regex_internal.h b/deps/regex/regex_internal.h deleted file mode 100644 index 4184d7f5a62..00000000000 --- a/deps/regex/regex_internal.h +++ /dev/null @@ -1,810 +0,0 @@ -/* Extended regular expression matching and search library. - Copyright (C) 2002-2005, 2007, 2008, 2010 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Isamu Hasegawa . - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifndef _REGEX_INTERNAL_H -#define _REGEX_INTERNAL_H 1 - -#include -#include -#include -#include -#include - -#if defined HAVE_LANGINFO_H || defined HAVE_LANGINFO_CODESET || defined _LIBC -# include -#endif -#if defined HAVE_LOCALE_H || defined _LIBC -# include -#endif -#if defined HAVE_WCHAR_H || defined _LIBC -# include -#endif /* HAVE_WCHAR_H || _LIBC */ -#if defined HAVE_WCTYPE_H || defined _LIBC -# include -#endif /* HAVE_WCTYPE_H || _LIBC */ -#if defined HAVE_STDBOOL_H || defined _LIBC -# include -#endif /* HAVE_STDBOOL_H || _LIBC */ -#if !defined(ZOS_USS) -#if defined HAVE_STDINT_H || defined _LIBC -# include -#endif /* HAVE_STDINT_H || _LIBC */ -#endif /* !ZOS_USS */ -#if defined _LIBC -# include -#else -# define __libc_lock_define(CLASS,NAME) -# define __libc_lock_init(NAME) do { } while (0) -# define __libc_lock_lock(NAME) do { } while (0) -# define __libc_lock_unlock(NAME) do { } while (0) -#endif - -#ifndef GAWK -/* In case that the system doesn't have isblank(). */ -#if !defined _LIBC && !defined HAVE_ISBLANK && !defined isblank -# define isblank(ch) ((ch) == ' ' || (ch) == '\t') -#endif -#else /* GAWK */ -/* - * This is a freaking mess. On glibc systems you have to define - * a magic constant to get isblank() out of , since it's - * a C99 function. To heck with all that and borrow a page from - * dfa.c's book. - */ - -static int -is_blank (int c) -{ - return (c == ' ' || c == '\t'); -} -#endif /* GAWK */ - -#ifdef _LIBC -# ifndef _RE_DEFINE_LOCALE_FUNCTIONS -# define _RE_DEFINE_LOCALE_FUNCTIONS 1 -# include -# include -# include -# endif -#endif - -/* This is for other GNU distributions with internationalized messages. */ -#if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC -# include -# ifdef _LIBC -# undef gettext -# define gettext(msgid) \ - INTUSE(__dcgettext) (_libc_intl_domainname, msgid, LC_MESSAGES) -# endif -#else -# define gettext(msgid) (msgid) -#endif - -#ifndef gettext_noop -/* This define is so xgettext can find the internationalizable - strings. */ -# define gettext_noop(String) String -#endif - -/* For loser systems without the definition. */ -#ifndef SIZE_MAX -# define SIZE_MAX ((size_t) -1) -#endif - -#ifndef NO_MBSUPPORT -#include "mbsupport.h" /* gawk */ -#endif -#ifndef MB_CUR_MAX -#define MB_CUR_MAX 1 -#endif - -#if (defined MBS_SUPPORT) || _LIBC -# define RE_ENABLE_I18N -#endif - -#if __GNUC__ >= 3 -# define BE(expr, val) __builtin_expect (expr, val) -#else -# define BE(expr, val) (expr) -# ifdef inline -# undef inline -# endif -# define inline -#endif - -/* Number of single byte character. */ -#define SBC_MAX 256 - -#define COLL_ELEM_LEN_MAX 8 - -/* The character which represents newline. */ -#define NEWLINE_CHAR '\n' -#define WIDE_NEWLINE_CHAR L'\n' - -/* Rename to standard API for using out of glibc. */ -#ifndef _LIBC -# ifdef __wctype -# undef __wctype -# endif -# define __wctype wctype -# ifdef __iswctype -# undef __iswctype -# endif -# define __iswctype iswctype -# define __btowc btowc -# define __mbrtowc mbrtowc -#undef __mempcpy /* GAWK */ -# define __mempcpy mempcpy -# define __wcrtomb wcrtomb -# define __regfree regfree -# define attribute_hidden -#endif /* not _LIBC */ - -#ifdef __GNUC__ -# define __attribute(arg) __attribute__ (arg) -#else -# define __attribute(arg) -#endif - -extern const char __re_error_msgid[] attribute_hidden; -extern const size_t __re_error_msgid_idx[] attribute_hidden; - -/* An integer used to represent a set of bits. It must be unsigned, - and must be at least as wide as unsigned int. */ -typedef unsigned long int bitset_word_t; -/* All bits set in a bitset_word_t. */ -#define BITSET_WORD_MAX ULONG_MAX -/* Number of bits in a bitset_word_t. */ -#define BITSET_WORD_BITS (sizeof (bitset_word_t) * CHAR_BIT) -/* Number of bitset_word_t in a bit_set. */ -#define BITSET_WORDS (SBC_MAX / BITSET_WORD_BITS) -typedef bitset_word_t bitset_t[BITSET_WORDS]; -typedef bitset_word_t *re_bitset_ptr_t; -typedef const bitset_word_t *re_const_bitset_ptr_t; - -#define bitset_set(set,i) \ - (set[i / BITSET_WORD_BITS] |= (bitset_word_t) 1 << i % BITSET_WORD_BITS) -#define bitset_clear(set,i) \ - (set[i / BITSET_WORD_BITS] &= ~((bitset_word_t) 1 << i % BITSET_WORD_BITS)) -#define bitset_contain(set,i) \ - (set[i / BITSET_WORD_BITS] & ((bitset_word_t) 1 << i % BITSET_WORD_BITS)) -#define bitset_empty(set) memset (set, '\0', sizeof (bitset_t)) -#define bitset_set_all(set) memset (set, '\xff', sizeof (bitset_t)) -#define bitset_copy(dest,src) memcpy (dest, src, sizeof (bitset_t)) - -#define PREV_WORD_CONSTRAINT 0x0001 -#define PREV_NOTWORD_CONSTRAINT 0x0002 -#define NEXT_WORD_CONSTRAINT 0x0004 -#define NEXT_NOTWORD_CONSTRAINT 0x0008 -#define PREV_NEWLINE_CONSTRAINT 0x0010 -#define NEXT_NEWLINE_CONSTRAINT 0x0020 -#define PREV_BEGBUF_CONSTRAINT 0x0040 -#define NEXT_ENDBUF_CONSTRAINT 0x0080 -#define WORD_DELIM_CONSTRAINT 0x0100 -#define NOT_WORD_DELIM_CONSTRAINT 0x0200 - -typedef enum -{ - INSIDE_WORD = PREV_WORD_CONSTRAINT | NEXT_WORD_CONSTRAINT, - WORD_FIRST = PREV_NOTWORD_CONSTRAINT | NEXT_WORD_CONSTRAINT, - WORD_LAST = PREV_WORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT, - INSIDE_NOTWORD = PREV_NOTWORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT, - LINE_FIRST = PREV_NEWLINE_CONSTRAINT, - LINE_LAST = NEXT_NEWLINE_CONSTRAINT, - BUF_FIRST = PREV_BEGBUF_CONSTRAINT, - BUF_LAST = NEXT_ENDBUF_CONSTRAINT, - WORD_DELIM = WORD_DELIM_CONSTRAINT, - NOT_WORD_DELIM = NOT_WORD_DELIM_CONSTRAINT -} re_context_type; - -typedef struct -{ - int alloc; - int nelem; - int *elems; -} re_node_set; - -typedef enum -{ - NON_TYPE = 0, - - /* Node type, These are used by token, node, tree. */ - CHARACTER = 1, - END_OF_RE = 2, - SIMPLE_BRACKET = 3, - OP_BACK_REF = 4, - OP_PERIOD = 5, -#ifdef RE_ENABLE_I18N - COMPLEX_BRACKET = 6, - OP_UTF8_PERIOD = 7, -#endif /* RE_ENABLE_I18N */ - - /* We define EPSILON_BIT as a macro so that OP_OPEN_SUBEXP is used - when the debugger shows values of this enum type. */ -#define EPSILON_BIT 8 - OP_OPEN_SUBEXP = EPSILON_BIT | 0, - OP_CLOSE_SUBEXP = EPSILON_BIT | 1, - OP_ALT = EPSILON_BIT | 2, - OP_DUP_ASTERISK = EPSILON_BIT | 3, - ANCHOR = EPSILON_BIT | 4, - - /* Tree type, these are used only by tree. */ - CONCAT = 16, - SUBEXP = 17, - - /* Token type, these are used only by token. */ - OP_DUP_PLUS = 18, - OP_DUP_QUESTION, - OP_OPEN_BRACKET, - OP_CLOSE_BRACKET, - OP_CHARSET_RANGE, - OP_OPEN_DUP_NUM, - OP_CLOSE_DUP_NUM, - OP_NON_MATCH_LIST, - OP_OPEN_COLL_ELEM, - OP_CLOSE_COLL_ELEM, - OP_OPEN_EQUIV_CLASS, - OP_CLOSE_EQUIV_CLASS, - OP_OPEN_CHAR_CLASS, - OP_CLOSE_CHAR_CLASS, - OP_WORD, - OP_NOTWORD, - OP_SPACE, - OP_NOTSPACE, - BACK_SLASH - -} re_token_type_t; - -#ifdef RE_ENABLE_I18N -typedef struct -{ - /* Multibyte characters. */ - wchar_t *mbchars; - - /* Collating symbols. */ -# ifdef _LIBC - int32_t *coll_syms; -# endif - - /* Equivalence classes. */ -# ifdef _LIBC - int32_t *equiv_classes; -# endif - - /* Range expressions. */ -# ifdef _LIBC - uint32_t *range_starts; - uint32_t *range_ends; -# else /* not _LIBC */ - wchar_t *range_starts; - wchar_t *range_ends; -# endif /* not _LIBC */ - - /* Character classes. */ - wctype_t *char_classes; - - /* If this character set is the non-matching list. */ - unsigned int non_match : 1; - - /* # of multibyte characters. */ - int nmbchars; - - /* # of collating symbols. */ - int ncoll_syms; - - /* # of equivalence classes. */ - int nequiv_classes; - - /* # of range expressions. */ - int nranges; - - /* # of character classes. */ - int nchar_classes; -} re_charset_t; -#endif /* RE_ENABLE_I18N */ - -typedef struct -{ - union - { - unsigned char c; /* for CHARACTER */ - re_bitset_ptr_t sbcset; /* for SIMPLE_BRACKET */ -#ifdef RE_ENABLE_I18N - re_charset_t *mbcset; /* for COMPLEX_BRACKET */ -#endif /* RE_ENABLE_I18N */ - int idx; /* for BACK_REF */ - re_context_type ctx_type; /* for ANCHOR */ - } opr; -#if __GNUC__ >= 2 - re_token_type_t type : 8; -#else - re_token_type_t type; -#endif - unsigned int constraint : 10; /* context constraint */ - unsigned int duplicated : 1; - unsigned int opt_subexp : 1; -#ifdef RE_ENABLE_I18N - unsigned int accept_mb : 1; - /* These 2 bits can be moved into the union if needed (e.g. if running out - of bits; move opr.c to opr.c.c and move the flags to opr.c.flags). */ - unsigned int mb_partial : 1; -#endif - unsigned int word_char : 1; -} re_token_t; - -#define IS_EPSILON_NODE(type) ((type) & EPSILON_BIT) - -struct re_string_t -{ - /* Indicate the raw buffer which is the original string passed as an - argument of regexec(), re_search(), etc.. */ - const unsigned char *raw_mbs; - /* Store the multibyte string. In case of "case insensitive mode" like - REG_ICASE, upper cases of the string are stored, otherwise MBS points - the same address that RAW_MBS points. */ - unsigned char *mbs; -#ifdef RE_ENABLE_I18N - /* Store the wide character string which is corresponding to MBS. */ - wint_t *wcs; - int *offsets; - mbstate_t cur_state; -#endif - /* Index in RAW_MBS. Each character mbs[i] corresponds to - raw_mbs[raw_mbs_idx + i]. */ - int raw_mbs_idx; - /* The length of the valid characters in the buffers. */ - int valid_len; - /* The corresponding number of bytes in raw_mbs array. */ - int valid_raw_len; - /* The length of the buffers MBS and WCS. */ - int bufs_len; - /* The index in MBS, which is updated by re_string_fetch_byte. */ - int cur_idx; - /* length of RAW_MBS array. */ - int raw_len; - /* This is RAW_LEN - RAW_MBS_IDX + VALID_LEN - VALID_RAW_LEN. */ - int len; - /* End of the buffer may be shorter than its length in the cases such - as re_match_2, re_search_2. Then, we use STOP for end of the buffer - instead of LEN. */ - int raw_stop; - /* This is RAW_STOP - RAW_MBS_IDX adjusted through OFFSETS. */ - int stop; - - /* The context of mbs[0]. We store the context independently, since - the context of mbs[0] may be different from raw_mbs[0], which is - the beginning of the input string. */ - unsigned int tip_context; - /* The translation passed as a part of an argument of re_compile_pattern. */ - RE_TRANSLATE_TYPE trans; - /* Copy of re_dfa_t's word_char. */ - re_const_bitset_ptr_t word_char; - /* 1 if REG_ICASE. */ - unsigned char icase; - unsigned char is_utf8; - unsigned char map_notascii; - unsigned char mbs_allocated; - unsigned char offsets_needed; - unsigned char newline_anchor; - unsigned char word_ops_used; - int mb_cur_max; -}; -typedef struct re_string_t re_string_t; - - -struct re_dfa_t; -typedef struct re_dfa_t re_dfa_t; - -#ifndef _LIBC -# ifdef __i386__ -# define internal_function __attribute ((regparm (3), stdcall)) -# else -# define internal_function -# endif -#endif - -#ifndef NOT_IN_libc -static reg_errcode_t re_string_realloc_buffers (re_string_t *pstr, - int new_buf_len) - internal_function; -# ifdef RE_ENABLE_I18N -static void build_wcs_buffer (re_string_t *pstr) internal_function; -static reg_errcode_t build_wcs_upper_buffer (re_string_t *pstr) - internal_function; -# endif /* RE_ENABLE_I18N */ -static void build_upper_buffer (re_string_t *pstr) internal_function; -static void re_string_translate_buffer (re_string_t *pstr) internal_function; -static unsigned int re_string_context_at (const re_string_t *input, int idx, - int eflags) - internal_function __attribute ((pure)); -#endif -#define re_string_peek_byte(pstr, offset) \ - ((pstr)->mbs[(pstr)->cur_idx + offset]) -#define re_string_fetch_byte(pstr) \ - ((pstr)->mbs[(pstr)->cur_idx++]) -#define re_string_first_byte(pstr, idx) \ - ((idx) == (pstr)->valid_len || (pstr)->wcs[idx] != WEOF) -#define re_string_is_single_byte_char(pstr, idx) \ - ((pstr)->wcs[idx] != WEOF && ((pstr)->valid_len == (idx) + 1 \ - || (pstr)->wcs[(idx) + 1] != WEOF)) -#define re_string_eoi(pstr) ((pstr)->stop <= (pstr)->cur_idx) -#define re_string_cur_idx(pstr) ((pstr)->cur_idx) -#define re_string_get_buffer(pstr) ((pstr)->mbs) -#define re_string_length(pstr) ((pstr)->len) -#define re_string_byte_at(pstr,idx) ((pstr)->mbs[idx]) -#define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx)) -#define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx)) - -#ifndef _LIBC -# if HAVE_ALLOCA -# if (_MSC_VER) -# include -# define __libc_use_alloca(n) 0 -# else -# include -/* The OS usually guarantees only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - allocate anything larger than 4096 bytes. Also care for the possibility - of a few compiler-allocated temporary stack slots. */ -# define __libc_use_alloca(n) ((n) < 4032) -# endif -# else -/* alloca is implemented with malloc, so just use malloc. */ -# define __libc_use_alloca(n) 0 -# endif -#endif - -#define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t))) -/* SunOS 4.1.x realloc doesn't accept null pointers: pre-Standard C. Sigh. */ -#define re_realloc(p,t,n) ((p != NULL) ? (t *) realloc (p,(n)*sizeof(t)) : (t *) calloc(n,sizeof(t))) -#define re_free(p) free (p) - -struct bin_tree_t -{ - struct bin_tree_t *parent; - struct bin_tree_t *left; - struct bin_tree_t *right; - struct bin_tree_t *first; - struct bin_tree_t *next; - - re_token_t token; - - /* `node_idx' is the index in dfa->nodes, if `type' == 0. - Otherwise `type' indicate the type of this node. */ - int node_idx; -}; -typedef struct bin_tree_t bin_tree_t; - -#define BIN_TREE_STORAGE_SIZE \ - ((1024 - sizeof (void *)) / sizeof (bin_tree_t)) - -struct bin_tree_storage_t -{ - struct bin_tree_storage_t *next; - bin_tree_t data[BIN_TREE_STORAGE_SIZE]; -}; -typedef struct bin_tree_storage_t bin_tree_storage_t; - -#define CONTEXT_WORD 1 -#define CONTEXT_NEWLINE (CONTEXT_WORD << 1) -#define CONTEXT_BEGBUF (CONTEXT_NEWLINE << 1) -#define CONTEXT_ENDBUF (CONTEXT_BEGBUF << 1) - -#define IS_WORD_CONTEXT(c) ((c) & CONTEXT_WORD) -#define IS_NEWLINE_CONTEXT(c) ((c) & CONTEXT_NEWLINE) -#define IS_BEGBUF_CONTEXT(c) ((c) & CONTEXT_BEGBUF) -#define IS_ENDBUF_CONTEXT(c) ((c) & CONTEXT_ENDBUF) -#define IS_ORDINARY_CONTEXT(c) ((c) == 0) - -#define IS_WORD_CHAR(ch) (isalnum (ch) || (ch) == '_') -#define IS_NEWLINE(ch) ((ch) == NEWLINE_CHAR) -#define IS_WIDE_WORD_CHAR(ch) (iswalnum (ch) || (ch) == L'_') -#define IS_WIDE_NEWLINE(ch) ((ch) == WIDE_NEWLINE_CHAR) - -#define NOT_SATISFY_PREV_CONSTRAINT(constraint,context) \ - ((((constraint) & PREV_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \ - || ((constraint & PREV_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \ - || ((constraint & PREV_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context))\ - || ((constraint & PREV_BEGBUF_CONSTRAINT) && !IS_BEGBUF_CONTEXT (context))) - -#define NOT_SATISFY_NEXT_CONSTRAINT(constraint,context) \ - ((((constraint) & NEXT_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \ - || (((constraint) & NEXT_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \ - || (((constraint) & NEXT_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context)) \ - || (((constraint) & NEXT_ENDBUF_CONSTRAINT) && !IS_ENDBUF_CONTEXT (context))) - -struct re_dfastate_t -{ - unsigned int hash; - re_node_set nodes; - re_node_set non_eps_nodes; - re_node_set inveclosure; - re_node_set *entrance_nodes; - struct re_dfastate_t **trtable, **word_trtable; - unsigned int context : 4; - unsigned int halt : 1; - /* If this state can accept `multi byte'. - Note that we refer to multibyte characters, and multi character - collating elements as `multi byte'. */ - unsigned int accept_mb : 1; - /* If this state has backreference node(s). */ - unsigned int has_backref : 1; - unsigned int has_constraint : 1; -}; -typedef struct re_dfastate_t re_dfastate_t; - -struct re_state_table_entry -{ - int num; - int alloc; - re_dfastate_t **array; -}; - -/* Array type used in re_sub_match_last_t and re_sub_match_top_t. */ - -typedef struct -{ - int next_idx; - int alloc; - re_dfastate_t **array; -} state_array_t; - -/* Store information about the node NODE whose type is OP_CLOSE_SUBEXP. */ - -typedef struct -{ - int node; - int str_idx; /* The position NODE match at. */ - state_array_t path; -} re_sub_match_last_t; - -/* Store information about the node NODE whose type is OP_OPEN_SUBEXP. - And information about the node, whose type is OP_CLOSE_SUBEXP, - corresponding to NODE is stored in LASTS. */ - -typedef struct -{ - int str_idx; - int node; - state_array_t *path; - int alasts; /* Allocation size of LASTS. */ - int nlasts; /* The number of LASTS. */ - re_sub_match_last_t **lasts; -} re_sub_match_top_t; - -struct re_backref_cache_entry -{ - int node; - int str_idx; - int subexp_from; - int subexp_to; - char more; - char unused; - unsigned short int eps_reachable_subexps_map; -}; - -typedef struct -{ - /* The string object corresponding to the input string. */ - re_string_t input; -#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) - const re_dfa_t *const dfa; -#else - const re_dfa_t *dfa; -#endif - /* EFLAGS of the argument of regexec. */ - int eflags; - /* Where the matching ends. */ - int match_last; - int last_node; - /* The state log used by the matcher. */ - re_dfastate_t **state_log; - int state_log_top; - /* Back reference cache. */ - int nbkref_ents; - int abkref_ents; - struct re_backref_cache_entry *bkref_ents; - int max_mb_elem_len; - int nsub_tops; - int asub_tops; - re_sub_match_top_t **sub_tops; -} re_match_context_t; - -typedef struct -{ - re_dfastate_t **sifted_states; - re_dfastate_t **limited_states; - int last_node; - int last_str_idx; - re_node_set limits; -} re_sift_context_t; - -struct re_fail_stack_ent_t -{ - int idx; - int node; - regmatch_t *regs; - re_node_set eps_via_nodes; -}; - -struct re_fail_stack_t -{ - int num; - int alloc; - struct re_fail_stack_ent_t *stack; -}; - -struct re_dfa_t -{ - re_token_t *nodes; - size_t nodes_alloc; - size_t nodes_len; - int *nexts; - int *org_indices; - re_node_set *edests; - re_node_set *eclosures; - re_node_set *inveclosures; - struct re_state_table_entry *state_table; - re_dfastate_t *init_state; - re_dfastate_t *init_state_word; - re_dfastate_t *init_state_nl; - re_dfastate_t *init_state_begbuf; - bin_tree_t *str_tree; - bin_tree_storage_t *str_tree_storage; - re_bitset_ptr_t sb_char; - int str_tree_storage_idx; - - /* number of subexpressions `re_nsub' is in regex_t. */ - unsigned int state_hash_mask; - int init_node; - int nbackref; /* The number of backreference in this dfa. */ - - /* Bitmap expressing which backreference is used. */ - bitset_word_t used_bkref_map; - bitset_word_t completed_bkref_map; - - unsigned int has_plural_match : 1; - /* If this dfa has "multibyte node", which is a backreference or - a node which can accept multibyte character or multi character - collating element. */ - unsigned int has_mb_node : 1; - unsigned int is_utf8 : 1; - unsigned int map_notascii : 1; - unsigned int word_ops_used : 1; - int mb_cur_max; - bitset_t word_char; - reg_syntax_t syntax; - int *subexp_map; -#ifdef DEBUG - char* re_str; -#endif -#if defined _LIBC - __libc_lock_define (, lock) -#endif -}; - -#define re_node_set_init_empty(set) memset (set, '\0', sizeof (re_node_set)) -#define re_node_set_remove(set,id) \ - (re_node_set_remove_at (set, re_node_set_contains (set, id) - 1)) -#define re_node_set_empty(p) ((p)->nelem = 0) -#define re_node_set_free(set) re_free ((set)->elems) - - -typedef enum -{ - SB_CHAR, - MB_CHAR, - EQUIV_CLASS, - COLL_SYM, - CHAR_CLASS -} bracket_elem_type; - -typedef struct -{ - bracket_elem_type type; - union - { - unsigned char ch; - unsigned char *name; - wchar_t wch; - } opr; -} bracket_elem_t; - - -/* Inline functions for bitset operation. */ -static inline void -bitset_not (bitset_t set) -{ - int bitset_i; - for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i) - set[bitset_i] = ~set[bitset_i]; -} - -static inline void -bitset_merge (bitset_t dest, const bitset_t src) -{ - int bitset_i; - for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i) - dest[bitset_i] |= src[bitset_i]; -} - -static inline void -bitset_mask (bitset_t dest, const bitset_t src) -{ - int bitset_i; - for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i) - dest[bitset_i] &= src[bitset_i]; -} - -#ifdef RE_ENABLE_I18N -/* Inline functions for re_string. */ -static inline int -internal_function __attribute ((pure)) -re_string_char_size_at (const re_string_t *pstr, int idx) -{ - int byte_idx; - if (pstr->mb_cur_max == 1) - return 1; - for (byte_idx = 1; idx + byte_idx < pstr->valid_len; ++byte_idx) - if (pstr->wcs[idx + byte_idx] != WEOF) - break; - return byte_idx; -} - -static inline wint_t -internal_function __attribute ((pure)) -re_string_wchar_at (const re_string_t *pstr, int idx) -{ - if (pstr->mb_cur_max == 1) - return (wint_t) pstr->mbs[idx]; - return (wint_t) pstr->wcs[idx]; -} - -# ifndef NOT_IN_libc -static int -internal_function __attribute ((pure)) -re_string_elem_size_at (const re_string_t *pstr, int idx) -{ -# ifdef _LIBC - const unsigned char *p, *extra; - const int32_t *table, *indirect; - int32_t tmp; -# include - uint_fast32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); - - if (nrules != 0) - { - table = (const int32_t *) _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); - extra = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); - indirect = (const int32_t *) _NL_CURRENT (LC_COLLATE, - _NL_COLLATE_INDIRECTMB); - p = pstr->mbs + idx; - tmp = findidx (&p); - return p - pstr->mbs - idx; - } - else -# endif /* _LIBC */ - return 1; -} -# endif -#endif /* RE_ENABLE_I18N */ - -#endif /* _REGEX_INTERNAL_H */ diff --git a/deps/regex/regexec.c b/deps/regex/regexec.c deleted file mode 100644 index 5eb6f1fea6b..00000000000 --- a/deps/regex/regexec.c +++ /dev/null @@ -1,4369 +0,0 @@ -/* Extended regular expression matching and search library. - Copyright (C) 2002-2005, 2007, 2009, 2010 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Isamu Hasegawa . - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301 USA. */ - -static reg_errcode_t match_ctx_init (re_match_context_t *cache, int eflags, - int n) internal_function; -static void match_ctx_clean (re_match_context_t *mctx) internal_function; -static void match_ctx_free (re_match_context_t *cache) internal_function; -static reg_errcode_t match_ctx_add_entry (re_match_context_t *cache, int node, - int str_idx, int from, int to) - internal_function; -static int search_cur_bkref_entry (const re_match_context_t *mctx, int str_idx) - internal_function; -static reg_errcode_t match_ctx_add_subtop (re_match_context_t *mctx, int node, - int str_idx) internal_function; -static re_sub_match_last_t * match_ctx_add_sublast (re_sub_match_top_t *subtop, - int node, int str_idx) - internal_function; -static void sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts, - re_dfastate_t **limited_sts, int last_node, - int last_str_idx) - internal_function; -static reg_errcode_t re_search_internal (const regex_t *preg, - const char *string, int length, - int start, int range, int stop, - size_t nmatch, regmatch_t pmatch[], - int eflags); -static int re_search_2_stub (struct re_pattern_buffer *bufp, - const char *string1, int length1, - const char *string2, int length2, - int start, int range, struct re_registers *regs, - int stop, int ret_len); -static int re_search_stub (struct re_pattern_buffer *bufp, - const char *string, int length, int start, - int range, int stop, struct re_registers *regs, - int ret_len); -static unsigned re_copy_regs (struct re_registers *regs, regmatch_t *pmatch, - unsigned int nregs, int regs_allocated); -static reg_errcode_t prune_impossible_nodes (re_match_context_t *mctx); -static int check_matching (re_match_context_t *mctx, int fl_longest_match, - int *p_match_first) internal_function; -static int check_halt_state_context (const re_match_context_t *mctx, - const re_dfastate_t *state, int idx) - internal_function; -static void update_regs (const re_dfa_t *dfa, regmatch_t *pmatch, - regmatch_t *prev_idx_match, int cur_node, - int cur_idx, int nmatch) internal_function; -static reg_errcode_t push_fail_stack (struct re_fail_stack_t *fs, - int str_idx, int dest_node, int nregs, - regmatch_t *regs, - re_node_set *eps_via_nodes) - internal_function; -static reg_errcode_t set_regs (const regex_t *preg, - const re_match_context_t *mctx, - size_t nmatch, regmatch_t *pmatch, - int fl_backtrack) internal_function; -static reg_errcode_t free_fail_stack_return (struct re_fail_stack_t *fs) - internal_function; - -#ifdef RE_ENABLE_I18N -static int sift_states_iter_mb (const re_match_context_t *mctx, - re_sift_context_t *sctx, - int node_idx, int str_idx, int max_str_idx) - internal_function; -#endif /* RE_ENABLE_I18N */ -static reg_errcode_t sift_states_backward (const re_match_context_t *mctx, - re_sift_context_t *sctx) - internal_function; -static reg_errcode_t build_sifted_states (const re_match_context_t *mctx, - re_sift_context_t *sctx, int str_idx, - re_node_set *cur_dest) - internal_function; -static reg_errcode_t update_cur_sifted_state (const re_match_context_t *mctx, - re_sift_context_t *sctx, - int str_idx, - re_node_set *dest_nodes) - internal_function; -static reg_errcode_t add_epsilon_src_nodes (const re_dfa_t *dfa, - re_node_set *dest_nodes, - const re_node_set *candidates) - internal_function; -static int check_dst_limits (const re_match_context_t *mctx, - re_node_set *limits, - int dst_node, int dst_idx, int src_node, - int src_idx) internal_function; -static int check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, - int boundaries, int subexp_idx, - int from_node, int bkref_idx) - internal_function; -static int check_dst_limits_calc_pos (const re_match_context_t *mctx, - int limit, int subexp_idx, - int node, int str_idx, - int bkref_idx) internal_function; -static reg_errcode_t check_subexp_limits (const re_dfa_t *dfa, - re_node_set *dest_nodes, - const re_node_set *candidates, - re_node_set *limits, - struct re_backref_cache_entry *bkref_ents, - int str_idx) internal_function; -static reg_errcode_t sift_states_bkref (const re_match_context_t *mctx, - re_sift_context_t *sctx, - int str_idx, const re_node_set *candidates) - internal_function; -static reg_errcode_t merge_state_array (const re_dfa_t *dfa, - re_dfastate_t **dst, - re_dfastate_t **src, int num) - internal_function; -static re_dfastate_t *find_recover_state (reg_errcode_t *err, - re_match_context_t *mctx) internal_function; -static re_dfastate_t *transit_state (reg_errcode_t *err, - re_match_context_t *mctx, - re_dfastate_t *state) internal_function; -static re_dfastate_t *merge_state_with_log (reg_errcode_t *err, - re_match_context_t *mctx, - re_dfastate_t *next_state) - internal_function; -static reg_errcode_t check_subexp_matching_top (re_match_context_t *mctx, - re_node_set *cur_nodes, - int str_idx) internal_function; -#if 0 -static re_dfastate_t *transit_state_sb (reg_errcode_t *err, - re_match_context_t *mctx, - re_dfastate_t *pstate) - internal_function; -#endif -#ifdef RE_ENABLE_I18N -static reg_errcode_t transit_state_mb (re_match_context_t *mctx, - re_dfastate_t *pstate) - internal_function; -#endif /* RE_ENABLE_I18N */ -static reg_errcode_t transit_state_bkref (re_match_context_t *mctx, - const re_node_set *nodes) - internal_function; -static reg_errcode_t get_subexp (re_match_context_t *mctx, - int bkref_node, int bkref_str_idx) - internal_function; -static reg_errcode_t get_subexp_sub (re_match_context_t *mctx, - const re_sub_match_top_t *sub_top, - re_sub_match_last_t *sub_last, - int bkref_node, int bkref_str) - internal_function; -static int find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes, - int subexp_idx, int type) internal_function; -static reg_errcode_t check_arrival (re_match_context_t *mctx, - state_array_t *path, int top_node, - int top_str, int last_node, int last_str, - int type) internal_function; -static reg_errcode_t check_arrival_add_next_nodes (re_match_context_t *mctx, - int str_idx, - re_node_set *cur_nodes, - re_node_set *next_nodes) - internal_function; -static reg_errcode_t check_arrival_expand_ecl (const re_dfa_t *dfa, - re_node_set *cur_nodes, - int ex_subexp, int type) - internal_function; -static reg_errcode_t check_arrival_expand_ecl_sub (const re_dfa_t *dfa, - re_node_set *dst_nodes, - int target, int ex_subexp, - int type) internal_function; -static reg_errcode_t expand_bkref_cache (re_match_context_t *mctx, - re_node_set *cur_nodes, int cur_str, - int subexp_num, int type) - internal_function; -static int build_trtable (const re_dfa_t *dfa, - re_dfastate_t *state) internal_function; -#ifdef RE_ENABLE_I18N -static int check_node_accept_bytes (const re_dfa_t *dfa, int node_idx, - const re_string_t *input, int idx) - internal_function; -# ifdef _LIBC -static unsigned int find_collation_sequence_value (const unsigned char *mbs, - size_t name_len) - internal_function; -# endif /* _LIBC */ -#endif /* RE_ENABLE_I18N */ -static int group_nodes_into_DFAstates (const re_dfa_t *dfa, - const re_dfastate_t *state, - re_node_set *states_node, - bitset_t *states_ch) internal_function; -static int check_node_accept (const re_match_context_t *mctx, - const re_token_t *node, int idx) - internal_function; -static reg_errcode_t extend_buffers (re_match_context_t *mctx) - internal_function; - -/* Entry point for POSIX code. */ - -/* regexec searches for a given pattern, specified by PREG, in the - string STRING. - - If NMATCH is zero or REG_NOSUB was set in the cflags argument to - `regcomp', we ignore PMATCH. Otherwise, we assume PMATCH has at - least NMATCH elements, and we set them to the offsets of the - corresponding matched substrings. - - EFLAGS specifies `execution flags' which affect matching: if - REG_NOTBOL is set, then ^ does not match at the beginning of the - string; if REG_NOTEOL is set, then $ does not match at the end. - - We return 0 if we find a match and REG_NOMATCH if not. */ - -int -regexec ( - const regex_t *__restrict preg, - const char *__restrict string, - size_t nmatch, - regmatch_t pmatch[], - int eflags) -{ - reg_errcode_t err; - int start, length; - - if (eflags & ~(REG_NOTBOL | REG_NOTEOL | REG_STARTEND)) - return REG_BADPAT; - - if (eflags & REG_STARTEND) - { - start = pmatch[0].rm_so; - length = pmatch[0].rm_eo; - } - else - { - start = 0; - length = strlen (string); - } - - __libc_lock_lock (dfa->lock); - if (preg->no_sub) - err = re_search_internal (preg, string, length, start, length - start, - length, 0, NULL, eflags); - else - err = re_search_internal (preg, string, length, start, length - start, - length, nmatch, pmatch, eflags); - __libc_lock_unlock (dfa->lock); - return err != REG_NOERROR; -} - -#ifdef _LIBC -# include -versioned_symbol (libc, __regexec, regexec, GLIBC_2_3_4); - -# if SHLIB_COMPAT (libc, GLIBC_2_0, GLIBC_2_3_4) -__typeof__ (__regexec) __compat_regexec; - -int -attribute_compat_text_section -__compat_regexec (const regex_t *__restrict preg, - const char *__restrict string, size_t nmatch, - regmatch_t pmatch[], int eflags) -{ - return regexec (preg, string, nmatch, pmatch, - eflags & (REG_NOTBOL | REG_NOTEOL)); -} -compat_symbol (libc, __compat_regexec, regexec, GLIBC_2_0); -# endif -#endif - -/* Entry points for GNU code. */ - -/* re_match, re_search, re_match_2, re_search_2 - - The former two functions operate on STRING with length LENGTH, - while the later two operate on concatenation of STRING1 and STRING2 - with lengths LENGTH1 and LENGTH2, respectively. - - re_match() matches the compiled pattern in BUFP against the string, - starting at index START. - - re_search() first tries matching at index START, then it tries to match - starting from index START + 1, and so on. The last start position tried - is START + RANGE. (Thus RANGE = 0 forces re_search to operate the same - way as re_match().) - - The parameter STOP of re_{match,search}_2 specifies that no match exceeding - the first STOP characters of the concatenation of the strings should be - concerned. - - If REGS is not NULL, and BUFP->no_sub is not set, the offsets of the match - and all groups is stroed in REGS. (For the "_2" variants, the offsets are - computed relative to the concatenation, not relative to the individual - strings.) - - On success, re_match* functions return the length of the match, re_search* - return the position of the start of the match. Return value -1 means no - match was found and -2 indicates an internal error. */ - -int -re_match (struct re_pattern_buffer *bufp, - const char *string, - int length, - int start, - struct re_registers *regs) -{ - return re_search_stub (bufp, string, length, start, 0, length, regs, 1); -} -#ifdef _LIBC -weak_alias (__re_match, re_match) -#endif - -int -re_search (struct re_pattern_buffer *bufp, - const char *string, - int length, int start, int range, - struct re_registers *regs) -{ - return re_search_stub (bufp, string, length, start, range, length, regs, 0); -} -#ifdef _LIBC -weak_alias (__re_search, re_search) -#endif - -int -re_match_2 (struct re_pattern_buffer *bufp, - const char *string1, int length1, - const char *string2, int length2, int start, - struct re_registers *regs, int stop) -{ - return re_search_2_stub (bufp, string1, length1, string2, length2, - start, 0, regs, stop, 1); -} -#ifdef _LIBC -weak_alias (__re_match_2, re_match_2) -#endif - -int -re_search_2 (struct re_pattern_buffer *bufp, - const char *string1, int length1, - const char *string2, int length2, int start, - int range, struct re_registers *regs, int stop) -{ - return re_search_2_stub (bufp, string1, length1, string2, length2, - start, range, regs, stop, 0); -} -#ifdef _LIBC -weak_alias (__re_search_2, re_search_2) -#endif - -static int -re_search_2_stub (struct re_pattern_buffer *bufp, - const char *string1, int length1, - const char *string2, int length2, int start, - int range, struct re_registers *regs, - int stop, int ret_len) -{ - const char *str; - int rval; - int len = length1 + length2; - int free_str = 0; - - if (BE (length1 < 0 || length2 < 0 || stop < 0, 0)) - return -2; - - /* Concatenate the strings. */ - if (length2 > 0) - if (length1 > 0) - { - char *s = re_malloc (char, len); - - if (BE (s == NULL, 0)) - return -2; - memcpy (s, string1, length1); - memcpy (s + length1, string2, length2); - str = s; - free_str = 1; - } - else - str = string2; - else - str = string1; - - rval = re_search_stub (bufp, str, len, start, range, stop, regs, ret_len); - if (free_str) - re_free ((char *) str); - return rval; -} - -/* The parameters have the same meaning as those of re_search. - Additional parameters: - If RET_LEN is nonzero the length of the match is returned (re_match style); - otherwise the position of the match is returned. */ - -static int -re_search_stub (struct re_pattern_buffer *bufp, - const char *string, int length, int start, - int range, int stop, - struct re_registers *regs, int ret_len) -{ - reg_errcode_t result; - regmatch_t *pmatch; - int nregs, rval; - int eflags = 0; - - /* Check for out-of-range. */ - if (BE (start < 0 || start > length, 0)) - return -1; - if (BE (start + range > length, 0)) - range = length - start; - else if (BE (start + range < 0, 0)) - range = -start; - - __libc_lock_lock (dfa->lock); - - eflags |= (bufp->not_bol) ? REG_NOTBOL : 0; - eflags |= (bufp->not_eol) ? REG_NOTEOL : 0; - - /* Compile fastmap if we haven't yet. */ - if (range > 0 && bufp->fastmap != NULL && !bufp->fastmap_accurate) - re_compile_fastmap (bufp); - - if (BE (bufp->no_sub, 0)) - regs = NULL; - - /* We need at least 1 register. */ - if (regs == NULL) - nregs = 1; - else if (BE (bufp->regs_allocated == REGS_FIXED && - regs->num_regs < bufp->re_nsub + 1, 0)) - { - nregs = regs->num_regs; - if (BE (nregs < 1, 0)) - { - /* Nothing can be copied to regs. */ - regs = NULL; - nregs = 1; - } - } - else - nregs = bufp->re_nsub + 1; - pmatch = re_malloc (regmatch_t, nregs); - if (BE (pmatch == NULL, 0)) - { - rval = -2; - goto out; - } - - result = re_search_internal (bufp, string, length, start, range, stop, - nregs, pmatch, eflags); - - rval = 0; - - /* I hope we needn't fill ther regs with -1's when no match was found. */ - if (result != REG_NOERROR) - rval = -1; - else if (regs != NULL) - { - /* If caller wants register contents data back, copy them. */ - bufp->regs_allocated = re_copy_regs (regs, pmatch, nregs, - bufp->regs_allocated); - if (BE (bufp->regs_allocated == REGS_UNALLOCATED, 0)) - rval = -2; - } - - if (BE (rval == 0, 1)) - { - if (ret_len) - { - assert (pmatch[0].rm_so == start); - rval = pmatch[0].rm_eo - start; - } - else - rval = pmatch[0].rm_so; - } - re_free (pmatch); - out: - __libc_lock_unlock (dfa->lock); - return rval; -} - -static unsigned -re_copy_regs (struct re_registers *regs, - regmatch_t *pmatch, - unsigned int nregs, int regs_allocated) -{ - int rval = REGS_REALLOCATE; - unsigned int i; - unsigned int need_regs = nregs + 1; - /* We need one extra element beyond `num_regs' for the `-1' marker GNU code - uses. */ - - /* Have the register data arrays been allocated? */ - if (regs_allocated == REGS_UNALLOCATED) - { /* No. So allocate them with malloc. */ - regs->start = re_malloc (regoff_t, need_regs); - if (BE (regs->start == NULL, 0)) - return REGS_UNALLOCATED; - regs->end = re_malloc (regoff_t, need_regs); - if (BE (regs->end == NULL, 0)) - { - re_free (regs->start); - return REGS_UNALLOCATED; - } - regs->num_regs = need_regs; - } - else if (regs_allocated == REGS_REALLOCATE) - { /* Yes. If we need more elements than were already - allocated, reallocate them. If we need fewer, just - leave it alone. */ - if (BE (need_regs > regs->num_regs, 0)) - { - regoff_t *new_start = re_realloc (regs->start, regoff_t, need_regs); - regoff_t *new_end; - if (BE (new_start == NULL, 0)) - return REGS_UNALLOCATED; - new_end = re_realloc (regs->end, regoff_t, need_regs); - if (BE (new_end == NULL, 0)) - { - re_free (new_start); - return REGS_UNALLOCATED; - } - regs->start = new_start; - regs->end = new_end; - regs->num_regs = need_regs; - } - } - else - { - assert (regs_allocated == REGS_FIXED); - /* This function may not be called with REGS_FIXED and nregs too big. */ - assert (regs->num_regs >= nregs); - rval = REGS_FIXED; - } - - /* Copy the regs. */ - for (i = 0; i < nregs; ++i) - { - regs->start[i] = pmatch[i].rm_so; - regs->end[i] = pmatch[i].rm_eo; - } - for ( ; i < regs->num_regs; ++i) - regs->start[i] = regs->end[i] = -1; - - return rval; -} - -/* Set REGS to hold NUM_REGS registers, storing them in STARTS and - ENDS. Subsequent matches using PATTERN_BUFFER and REGS will use - this memory for recording register information. STARTS and ENDS - must be allocated using the malloc library routine, and must each - be at least NUM_REGS * sizeof (regoff_t) bytes long. - - If NUM_REGS == 0, then subsequent matches should allocate their own - register data. - - Unless this function is called, the first search or match using - PATTERN_BUFFER will allocate its own register data, without - freeing the old data. */ - -void -re_set_registers (struct re_pattern_buffer *bufp, - struct re_registers *regs, - unsigned num_regs, - regoff_t *starts, - regoff_t *ends) -{ - if (num_regs) - { - bufp->regs_allocated = REGS_REALLOCATE; - regs->num_regs = num_regs; - regs->start = starts; - regs->end = ends; - } - else - { - bufp->regs_allocated = REGS_UNALLOCATED; - regs->num_regs = 0; - regs->start = regs->end = (regoff_t *) 0; - } -} -#ifdef _LIBC -weak_alias (__re_set_registers, re_set_registers) -#endif - -/* Entry points compatible with 4.2 BSD regex library. We don't define - them unless specifically requested. */ - -#if defined _REGEX_RE_COMP || defined _LIBC -int -# ifdef _LIBC -weak_function -# endif -re_exec (s) - const char *s; -{ - return 0 == regexec (&re_comp_buf, s, 0, NULL, 0); -} -#endif /* _REGEX_RE_COMP */ - -/* Internal entry point. */ - -/* Searches for a compiled pattern PREG in the string STRING, whose - length is LENGTH. NMATCH, PMATCH, and EFLAGS have the same - mingings with regexec. START, and RANGE have the same meanings - with re_search. - Return REG_NOERROR if we find a match, and REG_NOMATCH if not, - otherwise return the error code. - Note: We assume front end functions already check ranges. - (START + RANGE >= 0 && START + RANGE <= LENGTH) */ - -static reg_errcode_t -re_search_internal (const regex_t *preg, - const char *string, - int length, int start, int range, int stop, - size_t nmatch, regmatch_t pmatch[], - int eflags) -{ - reg_errcode_t err; - const re_dfa_t *dfa = (const re_dfa_t *) preg->buffer; - int left_lim, right_lim, incr; - int fl_longest_match, match_first, match_kind, match_last = -1; - unsigned int extra_nmatch; - int sb, ch; -#if defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L) - re_match_context_t mctx = { .dfa = dfa }; -#else - re_match_context_t mctx; -#endif - char *fastmap = (preg->fastmap != NULL && preg->fastmap_accurate - && range && !preg->can_be_null) ? preg->fastmap : NULL; - RE_TRANSLATE_TYPE t = preg->translate; - -#if !(defined _LIBC || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)) - memset (&mctx, '\0', sizeof (re_match_context_t)); - mctx.dfa = dfa; -#endif - - extra_nmatch = (nmatch > preg->re_nsub) ? nmatch - (preg->re_nsub + 1) : 0; - nmatch -= extra_nmatch; - - /* Check if the DFA haven't been compiled. */ - if (BE (preg->used == 0 || dfa->init_state == NULL - || dfa->init_state_word == NULL || dfa->init_state_nl == NULL - || dfa->init_state_begbuf == NULL, 0)) - return REG_NOMATCH; - -#ifdef DEBUG - /* We assume front-end functions already check them. */ - assert (start + range >= 0 && start + range <= length); -#endif - - /* If initial states with non-begbuf contexts have no elements, - the regex must be anchored. If preg->newline_anchor is set, - we'll never use init_state_nl, so do not check it. */ - if (dfa->init_state->nodes.nelem == 0 - && dfa->init_state_word->nodes.nelem == 0 - && (dfa->init_state_nl->nodes.nelem == 0 - || !preg->newline_anchor)) - { - if (start != 0 && start + range != 0) - return REG_NOMATCH; - start = range = 0; - } - - /* We must check the longest matching, if nmatch > 0. */ - fl_longest_match = (nmatch != 0 || dfa->nbackref); - - err = re_string_allocate (&mctx.input, string, length, dfa->nodes_len + 1, - preg->translate, preg->syntax & RE_ICASE, dfa); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - mctx.input.stop = stop; - mctx.input.raw_stop = stop; - mctx.input.newline_anchor = preg->newline_anchor; - - err = match_ctx_init (&mctx, eflags, dfa->nbackref * 2); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - - /* We will log all the DFA states through which the dfa pass, - if nmatch > 1, or this dfa has "multibyte node", which is a - back-reference or a node which can accept multibyte character or - multi character collating element. */ - if (nmatch > 1 || dfa->has_mb_node) - { - /* Avoid overflow. */ - if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= mctx.input.bufs_len, 0)) - { - err = REG_ESPACE; - goto free_return; - } - - mctx.state_log = re_malloc (re_dfastate_t *, mctx.input.bufs_len + 1); - if (BE (mctx.state_log == NULL, 0)) - { - err = REG_ESPACE; - goto free_return; - } - } - else - mctx.state_log = NULL; - - match_first = start; - mctx.input.tip_context = (eflags & REG_NOTBOL) ? CONTEXT_BEGBUF - : CONTEXT_NEWLINE | CONTEXT_BEGBUF; - - /* Check incrementally whether of not the input string match. */ - incr = (range < 0) ? -1 : 1; - left_lim = (range < 0) ? start + range : start; - right_lim = (range < 0) ? start : start + range; - sb = dfa->mb_cur_max == 1; - match_kind = - (fastmap - ? ((sb || !(preg->syntax & RE_ICASE || t) ? 4 : 0) - | (range >= 0 ? 2 : 0) - | (t != NULL ? 1 : 0)) - : 8); - - for (;; match_first += incr) - { - err = REG_NOMATCH; - if (match_first < left_lim || right_lim < match_first) - goto free_return; - - /* Advance as rapidly as possible through the string, until we - find a plausible place to start matching. This may be done - with varying efficiency, so there are various possibilities: - only the most common of them are specialized, in order to - save on code size. We use a switch statement for speed. */ - switch (match_kind) - { - case 8: - /* No fastmap. */ - break; - - case 7: - /* Fastmap with single-byte translation, match forward. */ - while (BE (match_first < right_lim, 1) - && !fastmap[t[(unsigned char) string[match_first]]]) - ++match_first; - goto forward_match_found_start_or_reached_end; - - case 6: - /* Fastmap without translation, match forward. */ - while (BE (match_first < right_lim, 1) - && !fastmap[(unsigned char) string[match_first]]) - ++match_first; - - forward_match_found_start_or_reached_end: - if (BE (match_first == right_lim, 0)) - { - ch = match_first >= length - ? 0 : (unsigned char) string[match_first]; - if (!fastmap[t ? t[ch] : ch]) - goto free_return; - } - break; - - case 4: - case 5: - /* Fastmap without multi-byte translation, match backwards. */ - while (match_first >= left_lim) - { - ch = match_first >= length - ? 0 : (unsigned char) string[match_first]; - if (fastmap[t ? t[ch] : ch]) - break; - --match_first; - } - if (match_first < left_lim) - goto free_return; - break; - - default: - /* In this case, we can't determine easily the current byte, - since it might be a component byte of a multibyte - character. Then we use the constructed buffer instead. */ - for (;;) - { - /* If MATCH_FIRST is out of the valid range, reconstruct the - buffers. */ - unsigned int offset = match_first - mctx.input.raw_mbs_idx; - if (BE (offset >= (unsigned int) mctx.input.valid_raw_len, 0)) - { - err = re_string_reconstruct (&mctx.input, match_first, - eflags); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - - offset = match_first - mctx.input.raw_mbs_idx; - } - /* If MATCH_FIRST is out of the buffer, leave it as '\0'. - Note that MATCH_FIRST must not be smaller than 0. */ - ch = (match_first >= length - ? 0 : re_string_byte_at (&mctx.input, offset)); - if (fastmap[ch]) - break; - match_first += incr; - if (match_first < left_lim || match_first > right_lim) - { - err = REG_NOMATCH; - goto free_return; - } - } - break; - } - - /* Reconstruct the buffers so that the matcher can assume that - the matching starts from the beginning of the buffer. */ - err = re_string_reconstruct (&mctx.input, match_first, eflags); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - -#ifdef RE_ENABLE_I18N - /* Don't consider this char as a possible match start if it part, - yet isn't the head, of a multibyte character. */ - if (!sb && !re_string_first_byte (&mctx.input, 0)) - continue; -#endif - - /* It seems to be appropriate one, then use the matcher. */ - /* We assume that the matching starts from 0. */ - mctx.state_log_top = mctx.nbkref_ents = mctx.max_mb_elem_len = 0; - match_last = check_matching (&mctx, fl_longest_match, - range >= 0 ? &match_first : NULL); - if (match_last != -1) - { - if (BE (match_last == -2, 0)) - { - err = REG_ESPACE; - goto free_return; - } - else - { - mctx.match_last = match_last; - if ((!preg->no_sub && nmatch > 1) || dfa->nbackref) - { - re_dfastate_t *pstate = mctx.state_log[match_last]; - mctx.last_node = check_halt_state_context (&mctx, pstate, - match_last); - } - if ((!preg->no_sub && nmatch > 1 && dfa->has_plural_match) - || dfa->nbackref) - { - err = prune_impossible_nodes (&mctx); - if (err == REG_NOERROR) - break; - if (BE (err != REG_NOMATCH, 0)) - goto free_return; - match_last = -1; - } - else - break; /* We found a match. */ - } - } - - match_ctx_clean (&mctx); - } - -#ifdef DEBUG - assert (match_last != -1); - assert (err == REG_NOERROR); -#endif - - /* Set pmatch[] if we need. */ - if (nmatch > 0) - { - unsigned int reg_idx; - - /* Initialize registers. */ - for (reg_idx = 1; reg_idx < nmatch; ++reg_idx) - pmatch[reg_idx].rm_so = pmatch[reg_idx].rm_eo = -1; - - /* Set the points where matching start/end. */ - pmatch[0].rm_so = 0; - pmatch[0].rm_eo = mctx.match_last; - - if (!preg->no_sub && nmatch > 1) - { - err = set_regs (preg, &mctx, nmatch, pmatch, - dfa->has_plural_match && dfa->nbackref > 0); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - } - - /* At last, add the offset to the each registers, since we slided - the buffers so that we could assume that the matching starts - from 0. */ - for (reg_idx = 0; reg_idx < nmatch; ++reg_idx) - if (pmatch[reg_idx].rm_so != -1) - { -#ifdef RE_ENABLE_I18N - if (BE (mctx.input.offsets_needed != 0, 0)) - { - pmatch[reg_idx].rm_so = - (pmatch[reg_idx].rm_so == mctx.input.valid_len - ? mctx.input.valid_raw_len - : mctx.input.offsets[pmatch[reg_idx].rm_so]); - pmatch[reg_idx].rm_eo = - (pmatch[reg_idx].rm_eo == mctx.input.valid_len - ? mctx.input.valid_raw_len - : mctx.input.offsets[pmatch[reg_idx].rm_eo]); - } -#else - assert (mctx.input.offsets_needed == 0); -#endif - pmatch[reg_idx].rm_so += match_first; - pmatch[reg_idx].rm_eo += match_first; - } - for (reg_idx = 0; reg_idx < extra_nmatch; ++reg_idx) - { - pmatch[nmatch + reg_idx].rm_so = -1; - pmatch[nmatch + reg_idx].rm_eo = -1; - } - - if (dfa->subexp_map) - for (reg_idx = 0; reg_idx + 1 < nmatch; reg_idx++) - if (dfa->subexp_map[reg_idx] != reg_idx) - { - pmatch[reg_idx + 1].rm_so - = pmatch[dfa->subexp_map[reg_idx] + 1].rm_so; - pmatch[reg_idx + 1].rm_eo - = pmatch[dfa->subexp_map[reg_idx] + 1].rm_eo; - } - } - - free_return: - re_free (mctx.state_log); - if (dfa->nbackref) - match_ctx_free (&mctx); - re_string_destruct (&mctx.input); - return err; -} - -static reg_errcode_t -prune_impossible_nodes (re_match_context_t *mctx) -{ - const re_dfa_t *const dfa = mctx->dfa; - int halt_node, match_last; - reg_errcode_t ret; - re_dfastate_t **sifted_states; - re_dfastate_t **lim_states = NULL; - re_sift_context_t sctx; -#ifdef DEBUG - assert (mctx->state_log != NULL); -#endif - match_last = mctx->match_last; - halt_node = mctx->last_node; - - /* Avoid overflow. */ - if (BE (SIZE_MAX / sizeof (re_dfastate_t *) <= match_last, 0)) - return REG_ESPACE; - - sifted_states = re_malloc (re_dfastate_t *, match_last + 1); - if (BE (sifted_states == NULL, 0)) - { - ret = REG_ESPACE; - goto free_return; - } - if (dfa->nbackref) - { - lim_states = re_malloc (re_dfastate_t *, match_last + 1); - if (BE (lim_states == NULL, 0)) - { - ret = REG_ESPACE; - goto free_return; - } - while (1) - { - memset (lim_states, '\0', - sizeof (re_dfastate_t *) * (match_last + 1)); - sift_ctx_init (&sctx, sifted_states, lim_states, halt_node, - match_last); - ret = sift_states_backward (mctx, &sctx); - re_node_set_free (&sctx.limits); - if (BE (ret != REG_NOERROR, 0)) - goto free_return; - if (sifted_states[0] != NULL || lim_states[0] != NULL) - break; - do - { - --match_last; - if (match_last < 0) - { - ret = REG_NOMATCH; - goto free_return; - } - } while (mctx->state_log[match_last] == NULL - || !mctx->state_log[match_last]->halt); - halt_node = check_halt_state_context (mctx, - mctx->state_log[match_last], - match_last); - } - ret = merge_state_array (dfa, sifted_states, lim_states, - match_last + 1); - re_free (lim_states); - lim_states = NULL; - if (BE (ret != REG_NOERROR, 0)) - goto free_return; - } - else - { - sift_ctx_init (&sctx, sifted_states, lim_states, halt_node, match_last); - ret = sift_states_backward (mctx, &sctx); - re_node_set_free (&sctx.limits); - if (BE (ret != REG_NOERROR, 0)) - goto free_return; - if (sifted_states[0] == NULL) - { - ret = REG_NOMATCH; - goto free_return; - } - } - re_free (mctx->state_log); - mctx->state_log = sifted_states; - sifted_states = NULL; - mctx->last_node = halt_node; - mctx->match_last = match_last; - ret = REG_NOERROR; - free_return: - re_free (sifted_states); - re_free (lim_states); - return ret; -} - -/* Acquire an initial state and return it. - We must select appropriate initial state depending on the context, - since initial states may have constraints like "\<", "^", etc.. */ - -static inline re_dfastate_t * -__attribute ((always_inline)) internal_function -acquire_init_state_context (reg_errcode_t *err, const re_match_context_t *mctx, - int idx) -{ - const re_dfa_t *const dfa = mctx->dfa; - if (dfa->init_state->has_constraint) - { - unsigned int context; - context = re_string_context_at (&mctx->input, idx - 1, mctx->eflags); - if (IS_WORD_CONTEXT (context)) - return dfa->init_state_word; - else if (IS_ORDINARY_CONTEXT (context)) - return dfa->init_state; - else if (IS_BEGBUF_CONTEXT (context) && IS_NEWLINE_CONTEXT (context)) - return dfa->init_state_begbuf; - else if (IS_NEWLINE_CONTEXT (context)) - return dfa->init_state_nl; - else if (IS_BEGBUF_CONTEXT (context)) - { - /* It is relatively rare case, then calculate on demand. */ - return re_acquire_state_context (err, dfa, - dfa->init_state->entrance_nodes, - context); - } - else - /* Must not happen? */ - return dfa->init_state; - } - else - return dfa->init_state; -} - -/* Check whether the regular expression match input string INPUT or not, - and return the index where the matching end, return -1 if not match, - or return -2 in case of an error. - FL_LONGEST_MATCH means we want the POSIX longest matching. - If P_MATCH_FIRST is not NULL, and the match fails, it is set to the - next place where we may want to try matching. - Note that the matcher assume that the maching starts from the current - index of the buffer. */ - -static int -internal_function -check_matching (re_match_context_t *mctx, int fl_longest_match, - int *p_match_first) -{ - const re_dfa_t *const dfa = mctx->dfa; - reg_errcode_t err; - int match = 0; - int match_last = -1; - int cur_str_idx = re_string_cur_idx (&mctx->input); - re_dfastate_t *cur_state; - int at_init_state = p_match_first != NULL; - int next_start_idx = cur_str_idx; - - err = REG_NOERROR; - cur_state = acquire_init_state_context (&err, mctx, cur_str_idx); - /* An initial state must not be NULL (invalid). */ - if (BE (cur_state == NULL, 0)) - { - assert (err == REG_ESPACE); - return -2; - } - - if (mctx->state_log != NULL) - { - mctx->state_log[cur_str_idx] = cur_state; - - /* Check OP_OPEN_SUBEXP in the initial state in case that we use them - later. E.g. Processing back references. */ - if (BE (dfa->nbackref, 0)) - { - at_init_state = 0; - err = check_subexp_matching_top (mctx, &cur_state->nodes, 0); - if (BE (err != REG_NOERROR, 0)) - return err; - - if (cur_state->has_backref) - { - err = transit_state_bkref (mctx, &cur_state->nodes); - if (BE (err != REG_NOERROR, 0)) - return err; - } - } - } - - /* If the RE accepts NULL string. */ - if (BE (cur_state->halt, 0)) - { - if (!cur_state->has_constraint - || check_halt_state_context (mctx, cur_state, cur_str_idx)) - { - if (!fl_longest_match) - return cur_str_idx; - else - { - match_last = cur_str_idx; - match = 1; - } - } - } - - while (!re_string_eoi (&mctx->input)) - { - re_dfastate_t *old_state = cur_state; - int next_char_idx = re_string_cur_idx (&mctx->input) + 1; - - if (BE (next_char_idx >= mctx->input.bufs_len, 0) - || (BE (next_char_idx >= mctx->input.valid_len, 0) - && mctx->input.valid_len < mctx->input.len)) - { - err = extend_buffers (mctx); - if (BE (err != REG_NOERROR, 0)) - { - assert (err == REG_ESPACE); - return -2; - } - } - - cur_state = transit_state (&err, mctx, cur_state); - if (mctx->state_log != NULL) - cur_state = merge_state_with_log (&err, mctx, cur_state); - - if (cur_state == NULL) - { - /* Reached the invalid state or an error. Try to recover a valid - state using the state log, if available and if we have not - already found a valid (even if not the longest) match. */ - if (BE (err != REG_NOERROR, 0)) - return -2; - - if (mctx->state_log == NULL - || (match && !fl_longest_match) - || (cur_state = find_recover_state (&err, mctx)) == NULL) - break; - } - - if (BE (at_init_state, 0)) - { - if (old_state == cur_state) - next_start_idx = next_char_idx; - else - at_init_state = 0; - } - - if (cur_state->halt) - { - /* Reached a halt state. - Check the halt state can satisfy the current context. */ - if (!cur_state->has_constraint - || check_halt_state_context (mctx, cur_state, - re_string_cur_idx (&mctx->input))) - { - /* We found an appropriate halt state. */ - match_last = re_string_cur_idx (&mctx->input); - match = 1; - - /* We found a match, do not modify match_first below. */ - p_match_first = NULL; - if (!fl_longest_match) - break; - } - } - } - - if (p_match_first) - *p_match_first += next_start_idx; - - return match_last; -} - -/* Check NODE match the current context. */ - -static int -internal_function -check_halt_node_context (const re_dfa_t *dfa, int node, unsigned int context) -{ - re_token_type_t type = dfa->nodes[node].type; - unsigned int constraint = dfa->nodes[node].constraint; - if (type != END_OF_RE) - return 0; - if (!constraint) - return 1; - if (NOT_SATISFY_NEXT_CONSTRAINT (constraint, context)) - return 0; - return 1; -} - -/* Check the halt state STATE match the current context. - Return 0 if not match, if the node, STATE has, is a halt node and - match the context, return the node. */ - -static int -internal_function -check_halt_state_context (const re_match_context_t *mctx, - const re_dfastate_t *state, int idx) -{ - int i; - unsigned int context; -#ifdef DEBUG - assert (state->halt); -#endif - context = re_string_context_at (&mctx->input, idx, mctx->eflags); - for (i = 0; i < state->nodes.nelem; ++i) - if (check_halt_node_context (mctx->dfa, state->nodes.elems[i], context)) - return state->nodes.elems[i]; - return 0; -} - -/* Compute the next node to which "NFA" transit from NODE("NFA" is a NFA - corresponding to the DFA). - Return the destination node, and update EPS_VIA_NODES, return -1 in case - of errors. */ - -static int -internal_function -proceed_next_node (const re_match_context_t *mctx, int nregs, regmatch_t *regs, - int *pidx, int node, re_node_set *eps_via_nodes, - struct re_fail_stack_t *fs) -{ - const re_dfa_t *const dfa = mctx->dfa; - int i, err; - if (IS_EPSILON_NODE (dfa->nodes[node].type)) - { - re_node_set *cur_nodes = &mctx->state_log[*pidx]->nodes; - re_node_set *edests = &dfa->edests[node]; - int dest_node; - err = re_node_set_insert (eps_via_nodes, node); - if (BE (err < 0, 0)) - return -2; - /* Pick up a valid destination, or return -1 if none is found. */ - for (dest_node = -1, i = 0; i < edests->nelem; ++i) - { - int candidate = edests->elems[i]; - if (!re_node_set_contains (cur_nodes, candidate)) - continue; - if (dest_node == -1) - dest_node = candidate; - - else - { - /* In order to avoid infinite loop like "(a*)*", return the second - epsilon-transition if the first was already considered. */ - if (re_node_set_contains (eps_via_nodes, dest_node)) - return candidate; - - /* Otherwise, push the second epsilon-transition on the fail stack. */ - else if (fs != NULL - && push_fail_stack (fs, *pidx, candidate, nregs, regs, - eps_via_nodes)) - return -2; - - /* We know we are going to exit. */ - break; - } - } - return dest_node; - } - else - { - int naccepted = 0; - re_token_type_t type = dfa->nodes[node].type; - -#ifdef RE_ENABLE_I18N - if (dfa->nodes[node].accept_mb) - naccepted = check_node_accept_bytes (dfa, node, &mctx->input, *pidx); - else -#endif /* RE_ENABLE_I18N */ - if (type == OP_BACK_REF) - { - int subexp_idx = dfa->nodes[node].opr.idx + 1; - naccepted = regs[subexp_idx].rm_eo - regs[subexp_idx].rm_so; - if (fs != NULL) - { - if (regs[subexp_idx].rm_so == -1 || regs[subexp_idx].rm_eo == -1) - return -1; - else if (naccepted) - { - char *buf = (char *) re_string_get_buffer (&mctx->input); - if (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx, - naccepted) != 0) - return -1; - } - } - - if (naccepted == 0) - { - int dest_node; - err = re_node_set_insert (eps_via_nodes, node); - if (BE (err < 0, 0)) - return -2; - dest_node = dfa->edests[node].elems[0]; - if (re_node_set_contains (&mctx->state_log[*pidx]->nodes, - dest_node)) - return dest_node; - } - } - - if (naccepted != 0 - || check_node_accept (mctx, dfa->nodes + node, *pidx)) - { - int dest_node = dfa->nexts[node]; - *pidx = (naccepted == 0) ? *pidx + 1 : *pidx + naccepted; - if (fs && (*pidx > mctx->match_last || mctx->state_log[*pidx] == NULL - || !re_node_set_contains (&mctx->state_log[*pidx]->nodes, - dest_node))) - return -1; - re_node_set_empty (eps_via_nodes); - return dest_node; - } - } - return -1; -} - -static reg_errcode_t -internal_function -push_fail_stack (struct re_fail_stack_t *fs, int str_idx, int dest_node, - int nregs, regmatch_t *regs, re_node_set *eps_via_nodes) -{ - reg_errcode_t err; - int num = fs->num++; - if (fs->num == fs->alloc) - { - struct re_fail_stack_ent_t *new_array; - new_array = realloc (fs->stack, (sizeof (struct re_fail_stack_ent_t) - * fs->alloc * 2)); - if (new_array == NULL) - return REG_ESPACE; - fs->alloc *= 2; - fs->stack = new_array; - } - fs->stack[num].idx = str_idx; - fs->stack[num].node = dest_node; - fs->stack[num].regs = re_malloc (regmatch_t, nregs); - if (fs->stack[num].regs == NULL) - return REG_ESPACE; - memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs); - err = re_node_set_init_copy (&fs->stack[num].eps_via_nodes, eps_via_nodes); - return err; -} - -static int -internal_function -pop_fail_stack (struct re_fail_stack_t *fs, int *pidx, int nregs, - regmatch_t *regs, re_node_set *eps_via_nodes) -{ - int num = --fs->num; - assert (num >= 0); - *pidx = fs->stack[num].idx; - memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs); - re_node_set_free (eps_via_nodes); - re_free (fs->stack[num].regs); - *eps_via_nodes = fs->stack[num].eps_via_nodes; - return fs->stack[num].node; -} - -/* Set the positions where the subexpressions are starts/ends to registers - PMATCH. - Note: We assume that pmatch[0] is already set, and - pmatch[i].rm_so == pmatch[i].rm_eo == -1 for 0 < i < nmatch. */ - -static reg_errcode_t -internal_function -set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch, - regmatch_t *pmatch, int fl_backtrack) -{ - const re_dfa_t *dfa = (const re_dfa_t *) preg->buffer; - int idx, cur_node; - re_node_set eps_via_nodes; - struct re_fail_stack_t *fs; - struct re_fail_stack_t fs_body = { 0, 2, NULL }; - regmatch_t *prev_idx_match; - int prev_idx_match_malloced = 0; - -#ifdef DEBUG - assert (nmatch > 1); - assert (mctx->state_log != NULL); -#endif - if (fl_backtrack) - { - fs = &fs_body; - fs->stack = re_malloc (struct re_fail_stack_ent_t, fs->alloc); - if (fs->stack == NULL) - return REG_ESPACE; - } - else - fs = NULL; - - cur_node = dfa->init_node; - re_node_set_init_empty (&eps_via_nodes); - -#ifdef HAVE_ALLOCA - if (__libc_use_alloca (nmatch * sizeof (regmatch_t))) - prev_idx_match = (regmatch_t *) alloca (nmatch * sizeof (regmatch_t)); - else -#endif - { - prev_idx_match = re_malloc (regmatch_t, nmatch); - if (prev_idx_match == NULL) - { - free_fail_stack_return (fs); - return REG_ESPACE; - } - prev_idx_match_malloced = 1; - } - memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch); - - for (idx = pmatch[0].rm_so; idx <= pmatch[0].rm_eo ;) - { - update_regs (dfa, pmatch, prev_idx_match, cur_node, idx, nmatch); - - if (idx == pmatch[0].rm_eo && cur_node == mctx->last_node) - { - unsigned int reg_idx; - if (fs) - { - for (reg_idx = 0; reg_idx < nmatch; ++reg_idx) - if (pmatch[reg_idx].rm_so > -1 && pmatch[reg_idx].rm_eo == -1) - break; - if (reg_idx == nmatch) - { - re_node_set_free (&eps_via_nodes); - if (prev_idx_match_malloced) - re_free (prev_idx_match); - return free_fail_stack_return (fs); - } - cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, - &eps_via_nodes); - } - else - { - re_node_set_free (&eps_via_nodes); - if (prev_idx_match_malloced) - re_free (prev_idx_match); - return REG_NOERROR; - } - } - - /* Proceed to next node. */ - cur_node = proceed_next_node (mctx, nmatch, pmatch, &idx, cur_node, - &eps_via_nodes, fs); - - if (BE (cur_node < 0, 0)) - { - if (BE (cur_node == -2, 0)) - { - re_node_set_free (&eps_via_nodes); - if (prev_idx_match_malloced) - re_free (prev_idx_match); - free_fail_stack_return (fs); - return REG_ESPACE; - } - if (fs) - cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch, - &eps_via_nodes); - else - { - re_node_set_free (&eps_via_nodes); - if (prev_idx_match_malloced) - re_free (prev_idx_match); - return REG_NOMATCH; - } - } - } - re_node_set_free (&eps_via_nodes); - if (prev_idx_match_malloced) - re_free (prev_idx_match); - return free_fail_stack_return (fs); -} - -static reg_errcode_t -internal_function -free_fail_stack_return (struct re_fail_stack_t *fs) -{ - if (fs) - { - int fs_idx; - for (fs_idx = 0; fs_idx < fs->num; ++fs_idx) - { - re_node_set_free (&fs->stack[fs_idx].eps_via_nodes); - re_free (fs->stack[fs_idx].regs); - } - re_free (fs->stack); - } - return REG_NOERROR; -} - -static void -internal_function -update_regs (const re_dfa_t *dfa, regmatch_t *pmatch, - regmatch_t *prev_idx_match, int cur_node, int cur_idx, int nmatch) -{ - int type = dfa->nodes[cur_node].type; - if (type == OP_OPEN_SUBEXP) - { - int reg_num = dfa->nodes[cur_node].opr.idx + 1; - - /* We are at the first node of this sub expression. */ - if (reg_num < nmatch) - { - pmatch[reg_num].rm_so = cur_idx; - pmatch[reg_num].rm_eo = -1; - } - } - else if (type == OP_CLOSE_SUBEXP) - { - int reg_num = dfa->nodes[cur_node].opr.idx + 1; - if (reg_num < nmatch) - { - /* We are at the last node of this sub expression. */ - if (pmatch[reg_num].rm_so < cur_idx) - { - pmatch[reg_num].rm_eo = cur_idx; - /* This is a non-empty match or we are not inside an optional - subexpression. Accept this right away. */ - memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch); - } - else - { - if (dfa->nodes[cur_node].opt_subexp - && prev_idx_match[reg_num].rm_so != -1) - /* We transited through an empty match for an optional - subexpression, like (a?)*, and this is not the subexp's - first match. Copy back the old content of the registers - so that matches of an inner subexpression are undone as - well, like in ((a?))*. */ - memcpy (pmatch, prev_idx_match, sizeof (regmatch_t) * nmatch); - else - /* We completed a subexpression, but it may be part of - an optional one, so do not update PREV_IDX_MATCH. */ - pmatch[reg_num].rm_eo = cur_idx; - } - } - } -} - -/* This function checks the STATE_LOG from the SCTX->last_str_idx to 0 - and sift the nodes in each states according to the following rules. - Updated state_log will be wrote to STATE_LOG. - - Rules: We throw away the Node `a' in the STATE_LOG[STR_IDX] if... - 1. When STR_IDX == MATCH_LAST(the last index in the state_log): - If `a' isn't the LAST_NODE and `a' can't epsilon transit to - the LAST_NODE, we throw away the node `a'. - 2. When 0 <= STR_IDX < MATCH_LAST and `a' accepts - string `s' and transit to `b': - i. If 'b' isn't in the STATE_LOG[STR_IDX+strlen('s')], we throw - away the node `a'. - ii. If 'b' is in the STATE_LOG[STR_IDX+strlen('s')] but 'b' is - thrown away, we throw away the node `a'. - 3. When 0 <= STR_IDX < MATCH_LAST and 'a' epsilon transit to 'b': - i. If 'b' isn't in the STATE_LOG[STR_IDX], we throw away the - node `a'. - ii. If 'b' is in the STATE_LOG[STR_IDX] but 'b' is thrown away, - we throw away the node `a'. */ - -#define STATE_NODE_CONTAINS(state,node) \ - ((state) != NULL && re_node_set_contains (&(state)->nodes, node)) - -static reg_errcode_t -internal_function -sift_states_backward (const re_match_context_t *mctx, re_sift_context_t *sctx) -{ - reg_errcode_t err; - int null_cnt = 0; - int str_idx = sctx->last_str_idx; - re_node_set cur_dest; - -#ifdef DEBUG - assert (mctx->state_log != NULL && mctx->state_log[str_idx] != NULL); -#endif - - /* Build sifted state_log[str_idx]. It has the nodes which can epsilon - transit to the last_node and the last_node itself. */ - err = re_node_set_init_1 (&cur_dest, sctx->last_node); - if (BE (err != REG_NOERROR, 0)) - return err; - err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - - /* Then check each states in the state_log. */ - while (str_idx > 0) - { - /* Update counters. */ - null_cnt = (sctx->sifted_states[str_idx] == NULL) ? null_cnt + 1 : 0; - if (null_cnt > mctx->max_mb_elem_len) - { - memset (sctx->sifted_states, '\0', - sizeof (re_dfastate_t *) * str_idx); - re_node_set_free (&cur_dest); - return REG_NOERROR; - } - re_node_set_empty (&cur_dest); - --str_idx; - - if (mctx->state_log[str_idx]) - { - err = build_sifted_states (mctx, sctx, str_idx, &cur_dest); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - } - - /* Add all the nodes which satisfy the following conditions: - - It can epsilon transit to a node in CUR_DEST. - - It is in CUR_SRC. - And update state_log. */ - err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - } - err = REG_NOERROR; - free_return: - re_node_set_free (&cur_dest); - return err; -} - -static reg_errcode_t -internal_function -build_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx, - int str_idx, re_node_set *cur_dest) -{ - const re_dfa_t *const dfa = mctx->dfa; - const re_node_set *cur_src = &mctx->state_log[str_idx]->non_eps_nodes; - int i; - - /* Then build the next sifted state. - We build the next sifted state on `cur_dest', and update - `sifted_states[str_idx]' with `cur_dest'. - Note: - `cur_dest' is the sifted state from `state_log[str_idx + 1]'. - `cur_src' points the node_set of the old `state_log[str_idx]' - (with the epsilon nodes pre-filtered out). */ - for (i = 0; i < cur_src->nelem; i++) - { - int prev_node = cur_src->elems[i]; - int naccepted = 0; - int ret; - -#ifdef DEBUG - re_token_type_t type = dfa->nodes[prev_node].type; - assert (!IS_EPSILON_NODE (type)); -#endif -#ifdef RE_ENABLE_I18N - /* If the node may accept `multi byte'. */ - if (dfa->nodes[prev_node].accept_mb) - naccepted = sift_states_iter_mb (mctx, sctx, prev_node, - str_idx, sctx->last_str_idx); -#endif /* RE_ENABLE_I18N */ - - /* We don't check backreferences here. - See update_cur_sifted_state(). */ - if (!naccepted - && check_node_accept (mctx, dfa->nodes + prev_node, str_idx) - && STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + 1], - dfa->nexts[prev_node])) - naccepted = 1; - - if (naccepted == 0) - continue; - - if (sctx->limits.nelem) - { - int to_idx = str_idx + naccepted; - if (check_dst_limits (mctx, &sctx->limits, - dfa->nexts[prev_node], to_idx, - prev_node, str_idx)) - continue; - } - ret = re_node_set_insert (cur_dest, prev_node); - if (BE (ret == -1, 0)) - return REG_ESPACE; - } - - return REG_NOERROR; -} - -/* Helper functions. */ - -static reg_errcode_t -internal_function -clean_state_log_if_needed (re_match_context_t *mctx, int next_state_log_idx) -{ - int top = mctx->state_log_top; - - if (next_state_log_idx >= mctx->input.bufs_len - || (next_state_log_idx >= mctx->input.valid_len - && mctx->input.valid_len < mctx->input.len)) - { - reg_errcode_t err; - err = extend_buffers (mctx); - if (BE (err != REG_NOERROR, 0)) - return err; - } - - if (top < next_state_log_idx) - { - memset (mctx->state_log + top + 1, '\0', - sizeof (re_dfastate_t *) * (next_state_log_idx - top)); - mctx->state_log_top = next_state_log_idx; - } - return REG_NOERROR; -} - -static reg_errcode_t -internal_function -merge_state_array (const re_dfa_t *dfa, re_dfastate_t **dst, - re_dfastate_t **src, int num) -{ - int st_idx; - reg_errcode_t err; - for (st_idx = 0; st_idx < num; ++st_idx) - { - if (dst[st_idx] == NULL) - dst[st_idx] = src[st_idx]; - else if (src[st_idx] != NULL) - { - re_node_set merged_set; - err = re_node_set_init_union (&merged_set, &dst[st_idx]->nodes, - &src[st_idx]->nodes); - if (BE (err != REG_NOERROR, 0)) - return err; - dst[st_idx] = re_acquire_state (&err, dfa, &merged_set); - re_node_set_free (&merged_set); - if (BE (err != REG_NOERROR, 0)) - return err; - } - } - return REG_NOERROR; -} - -static reg_errcode_t -internal_function -update_cur_sifted_state (const re_match_context_t *mctx, - re_sift_context_t *sctx, int str_idx, - re_node_set *dest_nodes) -{ - const re_dfa_t *const dfa = mctx->dfa; - reg_errcode_t err = REG_NOERROR; - const re_node_set *candidates; - candidates = ((mctx->state_log[str_idx] == NULL) ? NULL - : &mctx->state_log[str_idx]->nodes); - - if (dest_nodes->nelem == 0) - sctx->sifted_states[str_idx] = NULL; - else - { - if (candidates) - { - /* At first, add the nodes which can epsilon transit to a node in - DEST_NODE. */ - err = add_epsilon_src_nodes (dfa, dest_nodes, candidates); - if (BE (err != REG_NOERROR, 0)) - return err; - - /* Then, check the limitations in the current sift_context. */ - if (sctx->limits.nelem) - { - err = check_subexp_limits (dfa, dest_nodes, candidates, &sctx->limits, - mctx->bkref_ents, str_idx); - if (BE (err != REG_NOERROR, 0)) - return err; - } - } - - sctx->sifted_states[str_idx] = re_acquire_state (&err, dfa, dest_nodes); - if (BE (err != REG_NOERROR, 0)) - return err; - } - - if (candidates && mctx->state_log[str_idx]->has_backref) - { - err = sift_states_bkref (mctx, sctx, str_idx, candidates); - if (BE (err != REG_NOERROR, 0)) - return err; - } - return REG_NOERROR; -} - -static reg_errcode_t -internal_function -add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes, - const re_node_set *candidates) -{ - reg_errcode_t err = REG_NOERROR; - int i; - - re_dfastate_t *state = re_acquire_state (&err, dfa, dest_nodes); - if (BE (err != REG_NOERROR, 0)) - return err; - - if (!state->inveclosure.alloc) - { - err = re_node_set_alloc (&state->inveclosure, dest_nodes->nelem); - if (BE (err != REG_NOERROR, 0)) - return REG_ESPACE; - for (i = 0; i < dest_nodes->nelem; i++) - { - err = re_node_set_merge (&state->inveclosure, - dfa->inveclosures + dest_nodes->elems[i]); - if (BE (err != REG_NOERROR, 0)) - return REG_ESPACE; - } - } - return re_node_set_add_intersect (dest_nodes, candidates, - &state->inveclosure); -} - -static reg_errcode_t -internal_function -sub_epsilon_src_nodes (const re_dfa_t *dfa, int node, re_node_set *dest_nodes, - const re_node_set *candidates) -{ - int ecl_idx; - reg_errcode_t err; - re_node_set *inv_eclosure = dfa->inveclosures + node; - re_node_set except_nodes; - re_node_set_init_empty (&except_nodes); - for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx) - { - int cur_node = inv_eclosure->elems[ecl_idx]; - if (cur_node == node) - continue; - if (IS_EPSILON_NODE (dfa->nodes[cur_node].type)) - { - int edst1 = dfa->edests[cur_node].elems[0]; - int edst2 = ((dfa->edests[cur_node].nelem > 1) - ? dfa->edests[cur_node].elems[1] : -1); - if ((!re_node_set_contains (inv_eclosure, edst1) - && re_node_set_contains (dest_nodes, edst1)) - || (edst2 > 0 - && !re_node_set_contains (inv_eclosure, edst2) - && re_node_set_contains (dest_nodes, edst2))) - { - err = re_node_set_add_intersect (&except_nodes, candidates, - dfa->inveclosures + cur_node); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&except_nodes); - return err; - } - } - } - } - for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx) - { - int cur_node = inv_eclosure->elems[ecl_idx]; - if (!re_node_set_contains (&except_nodes, cur_node)) - { - int idx = re_node_set_contains (dest_nodes, cur_node) - 1; - re_node_set_remove_at (dest_nodes, idx); - } - } - re_node_set_free (&except_nodes); - return REG_NOERROR; -} - -static int -internal_function -check_dst_limits (const re_match_context_t *mctx, re_node_set *limits, - int dst_node, int dst_idx, int src_node, int src_idx) -{ - const re_dfa_t *const dfa = mctx->dfa; - int lim_idx, src_pos, dst_pos; - - int dst_bkref_idx = search_cur_bkref_entry (mctx, dst_idx); - int src_bkref_idx = search_cur_bkref_entry (mctx, src_idx); - for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx) - { - int subexp_idx; - struct re_backref_cache_entry *ent; - ent = mctx->bkref_ents + limits->elems[lim_idx]; - subexp_idx = dfa->nodes[ent->node].opr.idx; - - dst_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx], - subexp_idx, dst_node, dst_idx, - dst_bkref_idx); - src_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx], - subexp_idx, src_node, src_idx, - src_bkref_idx); - - /* In case of: - ( ) - ( ) - ( ) */ - if (src_pos == dst_pos) - continue; /* This is unrelated limitation. */ - else - return 1; - } - return 0; -} - -static int -internal_function -check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, int boundaries, - int subexp_idx, int from_node, int bkref_idx) -{ - const re_dfa_t *const dfa = mctx->dfa; - const re_node_set *eclosures = dfa->eclosures + from_node; - int node_idx; - - /* Else, we are on the boundary: examine the nodes on the epsilon - closure. */ - for (node_idx = 0; node_idx < eclosures->nelem; ++node_idx) - { - int node = eclosures->elems[node_idx]; - switch (dfa->nodes[node].type) - { - case OP_BACK_REF: - if (bkref_idx != -1) - { - struct re_backref_cache_entry *ent = mctx->bkref_ents + bkref_idx; - do - { - int dst, cpos; - - if (ent->node != node) - continue; - - if (subexp_idx < BITSET_WORD_BITS - && !(ent->eps_reachable_subexps_map - & ((bitset_word_t) 1 << subexp_idx))) - continue; - - /* Recurse trying to reach the OP_OPEN_SUBEXP and - OP_CLOSE_SUBEXP cases below. But, if the - destination node is the same node as the source - node, don't recurse because it would cause an - infinite loop: a regex that exhibits this behavior - is ()\1*\1* */ - dst = dfa->edests[node].elems[0]; - if (dst == from_node) - { - if (boundaries & 1) - return -1; - else /* if (boundaries & 2) */ - return 0; - } - - cpos = - check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx, - dst, bkref_idx); - if (cpos == -1 /* && (boundaries & 1) */) - return -1; - if (cpos == 0 && (boundaries & 2)) - return 0; - - if (subexp_idx < BITSET_WORD_BITS) - ent->eps_reachable_subexps_map - &= ~((bitset_word_t) 1 << subexp_idx); - } - while (ent++->more); - } - break; - - case OP_OPEN_SUBEXP: - if ((boundaries & 1) && subexp_idx == dfa->nodes[node].opr.idx) - return -1; - break; - - case OP_CLOSE_SUBEXP: - if ((boundaries & 2) && subexp_idx == dfa->nodes[node].opr.idx) - return 0; - break; - - default: - break; - } - } - - return (boundaries & 2) ? 1 : 0; -} - -static int -internal_function -check_dst_limits_calc_pos (const re_match_context_t *mctx, int limit, - int subexp_idx, int from_node, int str_idx, - int bkref_idx) -{ - struct re_backref_cache_entry *lim = mctx->bkref_ents + limit; - int boundaries; - - /* If we are outside the range of the subexpression, return -1 or 1. */ - if (str_idx < lim->subexp_from) - return -1; - - if (lim->subexp_to < str_idx) - return 1; - - /* If we are within the subexpression, return 0. */ - boundaries = (str_idx == lim->subexp_from); - boundaries |= (str_idx == lim->subexp_to) << 1; - if (boundaries == 0) - return 0; - - /* Else, examine epsilon closure. */ - return check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx, - from_node, bkref_idx); -} - -/* Check the limitations of sub expressions LIMITS, and remove the nodes - which are against limitations from DEST_NODES. */ - -static reg_errcode_t -internal_function -check_subexp_limits (const re_dfa_t *dfa, re_node_set *dest_nodes, - const re_node_set *candidates, re_node_set *limits, - struct re_backref_cache_entry *bkref_ents, int str_idx) -{ - reg_errcode_t err; - int node_idx, lim_idx; - - for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx) - { - int subexp_idx; - struct re_backref_cache_entry *ent; - ent = bkref_ents + limits->elems[lim_idx]; - - if (str_idx <= ent->subexp_from || ent->str_idx < str_idx) - continue; /* This is unrelated limitation. */ - - subexp_idx = dfa->nodes[ent->node].opr.idx; - if (ent->subexp_to == str_idx) - { - int ops_node = -1; - int cls_node = -1; - for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx) - { - int node = dest_nodes->elems[node_idx]; - re_token_type_t type = dfa->nodes[node].type; - if (type == OP_OPEN_SUBEXP - && subexp_idx == dfa->nodes[node].opr.idx) - ops_node = node; - else if (type == OP_CLOSE_SUBEXP - && subexp_idx == dfa->nodes[node].opr.idx) - cls_node = node; - } - - /* Check the limitation of the open subexpression. */ - /* Note that (ent->subexp_to = str_idx != ent->subexp_from). */ - if (ops_node >= 0) - { - err = sub_epsilon_src_nodes (dfa, ops_node, dest_nodes, - candidates); - if (BE (err != REG_NOERROR, 0)) - return err; - } - - /* Check the limitation of the close subexpression. */ - if (cls_node >= 0) - for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx) - { - int node = dest_nodes->elems[node_idx]; - if (!re_node_set_contains (dfa->inveclosures + node, - cls_node) - && !re_node_set_contains (dfa->eclosures + node, - cls_node)) - { - /* It is against this limitation. - Remove it form the current sifted state. */ - err = sub_epsilon_src_nodes (dfa, node, dest_nodes, - candidates); - if (BE (err != REG_NOERROR, 0)) - return err; - --node_idx; - } - } - } - else /* (ent->subexp_to != str_idx) */ - { - for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx) - { - int node = dest_nodes->elems[node_idx]; - re_token_type_t type = dfa->nodes[node].type; - if (type == OP_CLOSE_SUBEXP || type == OP_OPEN_SUBEXP) - { - if (subexp_idx != dfa->nodes[node].opr.idx) - continue; - /* It is against this limitation. - Remove it form the current sifted state. */ - err = sub_epsilon_src_nodes (dfa, node, dest_nodes, - candidates); - if (BE (err != REG_NOERROR, 0)) - return err; - } - } - } - } - return REG_NOERROR; -} - -static reg_errcode_t -internal_function -sift_states_bkref (const re_match_context_t *mctx, re_sift_context_t *sctx, - int str_idx, const re_node_set *candidates) -{ - const re_dfa_t *const dfa = mctx->dfa; - reg_errcode_t err; - int node_idx, node; - re_sift_context_t local_sctx; - int first_idx = search_cur_bkref_entry (mctx, str_idx); - - if (first_idx == -1) - return REG_NOERROR; - - local_sctx.sifted_states = NULL; /* Mark that it hasn't been initialized. */ - - for (node_idx = 0; node_idx < candidates->nelem; ++node_idx) - { - int enabled_idx; - re_token_type_t type; - struct re_backref_cache_entry *entry; - node = candidates->elems[node_idx]; - type = dfa->nodes[node].type; - /* Avoid infinite loop for the REs like "()\1+". */ - if (node == sctx->last_node && str_idx == sctx->last_str_idx) - continue; - if (type != OP_BACK_REF) - continue; - - entry = mctx->bkref_ents + first_idx; - enabled_idx = first_idx; - do - { - int subexp_len; - int to_idx; - int dst_node; - int ret; - re_dfastate_t *cur_state; - - if (entry->node != node) - continue; - subexp_len = entry->subexp_to - entry->subexp_from; - to_idx = str_idx + subexp_len; - dst_node = (subexp_len ? dfa->nexts[node] - : dfa->edests[node].elems[0]); - - if (to_idx > sctx->last_str_idx - || sctx->sifted_states[to_idx] == NULL - || !STATE_NODE_CONTAINS (sctx->sifted_states[to_idx], dst_node) - || check_dst_limits (mctx, &sctx->limits, node, - str_idx, dst_node, to_idx)) - continue; - - if (local_sctx.sifted_states == NULL) - { - local_sctx = *sctx; - err = re_node_set_init_copy (&local_sctx.limits, &sctx->limits); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - } - local_sctx.last_node = node; - local_sctx.last_str_idx = str_idx; - ret = re_node_set_insert (&local_sctx.limits, enabled_idx); - if (BE (ret < 0, 0)) - { - err = REG_ESPACE; - goto free_return; - } - cur_state = local_sctx.sifted_states[str_idx]; - err = sift_states_backward (mctx, &local_sctx); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - if (sctx->limited_states != NULL) - { - err = merge_state_array (dfa, sctx->limited_states, - local_sctx.sifted_states, - str_idx + 1); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - } - local_sctx.sifted_states[str_idx] = cur_state; - re_node_set_remove (&local_sctx.limits, enabled_idx); - - /* mctx->bkref_ents may have changed, reload the pointer. */ - entry = mctx->bkref_ents + enabled_idx; - } - while (enabled_idx++, entry++->more); - } - err = REG_NOERROR; - free_return: - if (local_sctx.sifted_states != NULL) - { - re_node_set_free (&local_sctx.limits); - } - - return err; -} - - -#ifdef RE_ENABLE_I18N -static int -internal_function -sift_states_iter_mb (const re_match_context_t *mctx, re_sift_context_t *sctx, - int node_idx, int str_idx, int max_str_idx) -{ - const re_dfa_t *const dfa = mctx->dfa; - int naccepted; - /* Check the node can accept `multi byte'. */ - naccepted = check_node_accept_bytes (dfa, node_idx, &mctx->input, str_idx); - if (naccepted > 0 && str_idx + naccepted <= max_str_idx && - !STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + naccepted], - dfa->nexts[node_idx])) - /* The node can't accept the `multi byte', or the - destination was already thrown away, then the node - could't accept the current input `multi byte'. */ - naccepted = 0; - /* Otherwise, it is sure that the node could accept - `naccepted' bytes input. */ - return naccepted; -} -#endif /* RE_ENABLE_I18N */ - - -/* Functions for state transition. */ - -/* Return the next state to which the current state STATE will transit by - accepting the current input byte, and update STATE_LOG if necessary. - If STATE can accept a multibyte char/collating element/back reference - update the destination of STATE_LOG. */ - -static re_dfastate_t * -internal_function -transit_state (reg_errcode_t *err, re_match_context_t *mctx, - re_dfastate_t *state) -{ - re_dfastate_t **trtable; - unsigned char ch; - -#ifdef RE_ENABLE_I18N - /* If the current state can accept multibyte. */ - if (BE (state->accept_mb, 0)) - { - *err = transit_state_mb (mctx, state); - if (BE (*err != REG_NOERROR, 0)) - return NULL; - } -#endif /* RE_ENABLE_I18N */ - - /* Then decide the next state with the single byte. */ -#if 0 - if (0) - /* don't use transition table */ - return transit_state_sb (err, mctx, state); -#endif - - /* Use transition table */ - ch = re_string_fetch_byte (&mctx->input); - for (;;) - { - trtable = state->trtable; - if (BE (trtable != NULL, 1)) - return trtable[ch]; - - trtable = state->word_trtable; - if (BE (trtable != NULL, 1)) - { - unsigned int context; - context - = re_string_context_at (&mctx->input, - re_string_cur_idx (&mctx->input) - 1, - mctx->eflags); - if (IS_WORD_CONTEXT (context)) - return trtable[ch + SBC_MAX]; - else - return trtable[ch]; - } - - if (!build_trtable (mctx->dfa, state)) - { - *err = REG_ESPACE; - return NULL; - } - - /* Retry, we now have a transition table. */ - } -} - -/* Update the state_log if we need */ -re_dfastate_t * -internal_function -merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx, - re_dfastate_t *next_state) -{ - const re_dfa_t *const dfa = mctx->dfa; - int cur_idx = re_string_cur_idx (&mctx->input); - - if (cur_idx > mctx->state_log_top) - { - mctx->state_log[cur_idx] = next_state; - mctx->state_log_top = cur_idx; - } - else if (mctx->state_log[cur_idx] == 0) - { - mctx->state_log[cur_idx] = next_state; - } - else - { - re_dfastate_t *pstate; - unsigned int context; - re_node_set next_nodes, *log_nodes, *table_nodes = NULL; - /* If (state_log[cur_idx] != 0), it implies that cur_idx is - the destination of a multibyte char/collating element/ - back reference. Then the next state is the union set of - these destinations and the results of the transition table. */ - pstate = mctx->state_log[cur_idx]; - log_nodes = pstate->entrance_nodes; - if (next_state != NULL) - { - table_nodes = next_state->entrance_nodes; - *err = re_node_set_init_union (&next_nodes, table_nodes, - log_nodes); - if (BE (*err != REG_NOERROR, 0)) - return NULL; - } - else - next_nodes = *log_nodes; - /* Note: We already add the nodes of the initial state, - then we don't need to add them here. */ - - context = re_string_context_at (&mctx->input, - re_string_cur_idx (&mctx->input) - 1, - mctx->eflags); - next_state = mctx->state_log[cur_idx] - = re_acquire_state_context (err, dfa, &next_nodes, context); - /* We don't need to check errors here, since the return value of - this function is next_state and ERR is already set. */ - - if (table_nodes != NULL) - re_node_set_free (&next_nodes); - } - - if (BE (dfa->nbackref, 0) && next_state != NULL) - { - /* Check OP_OPEN_SUBEXP in the current state in case that we use them - later. We must check them here, since the back references in the - next state might use them. */ - *err = check_subexp_matching_top (mctx, &next_state->nodes, - cur_idx); - if (BE (*err != REG_NOERROR, 0)) - return NULL; - - /* If the next state has back references. */ - if (next_state->has_backref) - { - *err = transit_state_bkref (mctx, &next_state->nodes); - if (BE (*err != REG_NOERROR, 0)) - return NULL; - next_state = mctx->state_log[cur_idx]; - } - } - - return next_state; -} - -/* Skip bytes in the input that correspond to part of a - multi-byte match, then look in the log for a state - from which to restart matching. */ -re_dfastate_t * -internal_function -find_recover_state (reg_errcode_t *err, re_match_context_t *mctx) -{ - re_dfastate_t *cur_state; - do - { - int max = mctx->state_log_top; - int cur_str_idx = re_string_cur_idx (&mctx->input); - - do - { - if (++cur_str_idx > max) - return NULL; - re_string_skip_bytes (&mctx->input, 1); - } - while (mctx->state_log[cur_str_idx] == NULL); - - cur_state = merge_state_with_log (err, mctx, NULL); - } - while (*err == REG_NOERROR && cur_state == NULL); - return cur_state; -} - -/* Helper functions for transit_state. */ - -/* From the node set CUR_NODES, pick up the nodes whose types are - OP_OPEN_SUBEXP and which have corresponding back references in the regular - expression. And register them to use them later for evaluating the - correspoding back references. */ - -static reg_errcode_t -internal_function -check_subexp_matching_top (re_match_context_t *mctx, re_node_set *cur_nodes, - int str_idx) -{ - const re_dfa_t *const dfa = mctx->dfa; - int node_idx; - reg_errcode_t err; - - /* TODO: This isn't efficient. - Because there might be more than one nodes whose types are - OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all - nodes. - E.g. RE: (a){2} */ - for (node_idx = 0; node_idx < cur_nodes->nelem; ++node_idx) - { - int node = cur_nodes->elems[node_idx]; - if (dfa->nodes[node].type == OP_OPEN_SUBEXP - && dfa->nodes[node].opr.idx < BITSET_WORD_BITS - && (dfa->used_bkref_map - & ((bitset_word_t) 1 << dfa->nodes[node].opr.idx))) - { - err = match_ctx_add_subtop (mctx, node, str_idx); - if (BE (err != REG_NOERROR, 0)) - return err; - } - } - return REG_NOERROR; -} - -#if 0 -/* Return the next state to which the current state STATE will transit by - accepting the current input byte. */ - -static re_dfastate_t * -transit_state_sb (reg_errcode_t *err, re_match_context_t *mctx, - re_dfastate_t *state) -{ - const re_dfa_t *const dfa = mctx->dfa; - re_node_set next_nodes; - re_dfastate_t *next_state; - int node_cnt, cur_str_idx = re_string_cur_idx (&mctx->input); - unsigned int context; - - *err = re_node_set_alloc (&next_nodes, state->nodes.nelem + 1); - if (BE (*err != REG_NOERROR, 0)) - return NULL; - for (node_cnt = 0; node_cnt < state->nodes.nelem; ++node_cnt) - { - int cur_node = state->nodes.elems[node_cnt]; - if (check_node_accept (mctx, dfa->nodes + cur_node, cur_str_idx)) - { - *err = re_node_set_merge (&next_nodes, - dfa->eclosures + dfa->nexts[cur_node]); - if (BE (*err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return NULL; - } - } - } - context = re_string_context_at (&mctx->input, cur_str_idx, mctx->eflags); - next_state = re_acquire_state_context (err, dfa, &next_nodes, context); - /* We don't need to check errors here, since the return value of - this function is next_state and ERR is already set. */ - - re_node_set_free (&next_nodes); - re_string_skip_bytes (&mctx->input, 1); - return next_state; -} -#endif - -#ifdef RE_ENABLE_I18N -static reg_errcode_t -internal_function -transit_state_mb (re_match_context_t *mctx, re_dfastate_t *pstate) -{ - const re_dfa_t *const dfa = mctx->dfa; - reg_errcode_t err; - int i; - - for (i = 0; i < pstate->nodes.nelem; ++i) - { - re_node_set dest_nodes, *new_nodes; - int cur_node_idx = pstate->nodes.elems[i]; - int naccepted, dest_idx; - unsigned int context; - re_dfastate_t *dest_state; - - if (!dfa->nodes[cur_node_idx].accept_mb) - continue; - - if (dfa->nodes[cur_node_idx].constraint) - { - context = re_string_context_at (&mctx->input, - re_string_cur_idx (&mctx->input), - mctx->eflags); - if (NOT_SATISFY_NEXT_CONSTRAINT (dfa->nodes[cur_node_idx].constraint, - context)) - continue; - } - - /* How many bytes the node can accept? */ - naccepted = check_node_accept_bytes (dfa, cur_node_idx, &mctx->input, - re_string_cur_idx (&mctx->input)); - if (naccepted == 0) - continue; - - /* The node can accepts `naccepted' bytes. */ - dest_idx = re_string_cur_idx (&mctx->input) + naccepted; - mctx->max_mb_elem_len = ((mctx->max_mb_elem_len < naccepted) ? naccepted - : mctx->max_mb_elem_len); - err = clean_state_log_if_needed (mctx, dest_idx); - if (BE (err != REG_NOERROR, 0)) - return err; -#ifdef DEBUG - assert (dfa->nexts[cur_node_idx] != -1); -#endif - new_nodes = dfa->eclosures + dfa->nexts[cur_node_idx]; - - dest_state = mctx->state_log[dest_idx]; - if (dest_state == NULL) - dest_nodes = *new_nodes; - else - { - err = re_node_set_init_union (&dest_nodes, - dest_state->entrance_nodes, new_nodes); - if (BE (err != REG_NOERROR, 0)) - return err; - } - context = re_string_context_at (&mctx->input, dest_idx - 1, - mctx->eflags); - mctx->state_log[dest_idx] - = re_acquire_state_context (&err, dfa, &dest_nodes, context); - if (dest_state != NULL) - re_node_set_free (&dest_nodes); - if (BE (mctx->state_log[dest_idx] == NULL && err != REG_NOERROR, 0)) - return err; - } - return REG_NOERROR; -} -#endif /* RE_ENABLE_I18N */ - -static reg_errcode_t -internal_function -transit_state_bkref (re_match_context_t *mctx, const re_node_set *nodes) -{ - const re_dfa_t *const dfa = mctx->dfa; - reg_errcode_t err; - int i; - int cur_str_idx = re_string_cur_idx (&mctx->input); - - for (i = 0; i < nodes->nelem; ++i) - { - int dest_str_idx, prev_nelem, bkc_idx; - int node_idx = nodes->elems[i]; - unsigned int context; - const re_token_t *node = dfa->nodes + node_idx; - re_node_set *new_dest_nodes; - - /* Check whether `node' is a backreference or not. */ - if (node->type != OP_BACK_REF) - continue; - - if (node->constraint) - { - context = re_string_context_at (&mctx->input, cur_str_idx, - mctx->eflags); - if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context)) - continue; - } - - /* `node' is a backreference. - Check the substring which the substring matched. */ - bkc_idx = mctx->nbkref_ents; - err = get_subexp (mctx, node_idx, cur_str_idx); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - - /* And add the epsilon closures (which is `new_dest_nodes') of - the backreference to appropriate state_log. */ -#ifdef DEBUG - assert (dfa->nexts[node_idx] != -1); -#endif - for (; bkc_idx < mctx->nbkref_ents; ++bkc_idx) - { - int subexp_len; - re_dfastate_t *dest_state; - struct re_backref_cache_entry *bkref_ent; - bkref_ent = mctx->bkref_ents + bkc_idx; - if (bkref_ent->node != node_idx || bkref_ent->str_idx != cur_str_idx) - continue; - subexp_len = bkref_ent->subexp_to - bkref_ent->subexp_from; - new_dest_nodes = (subexp_len == 0 - ? dfa->eclosures + dfa->edests[node_idx].elems[0] - : dfa->eclosures + dfa->nexts[node_idx]); - dest_str_idx = (cur_str_idx + bkref_ent->subexp_to - - bkref_ent->subexp_from); - context = re_string_context_at (&mctx->input, dest_str_idx - 1, - mctx->eflags); - dest_state = mctx->state_log[dest_str_idx]; - prev_nelem = ((mctx->state_log[cur_str_idx] == NULL) ? 0 - : mctx->state_log[cur_str_idx]->nodes.nelem); - /* Add `new_dest_node' to state_log. */ - if (dest_state == NULL) - { - mctx->state_log[dest_str_idx] - = re_acquire_state_context (&err, dfa, new_dest_nodes, - context); - if (BE (mctx->state_log[dest_str_idx] == NULL - && err != REG_NOERROR, 0)) - goto free_return; - } - else - { - re_node_set dest_nodes; - err = re_node_set_init_union (&dest_nodes, - dest_state->entrance_nodes, - new_dest_nodes); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&dest_nodes); - goto free_return; - } - mctx->state_log[dest_str_idx] - = re_acquire_state_context (&err, dfa, &dest_nodes, context); - re_node_set_free (&dest_nodes); - if (BE (mctx->state_log[dest_str_idx] == NULL - && err != REG_NOERROR, 0)) - goto free_return; - } - /* We need to check recursively if the backreference can epsilon - transit. */ - if (subexp_len == 0 - && mctx->state_log[cur_str_idx]->nodes.nelem > prev_nelem) - { - err = check_subexp_matching_top (mctx, new_dest_nodes, - cur_str_idx); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - err = transit_state_bkref (mctx, new_dest_nodes); - if (BE (err != REG_NOERROR, 0)) - goto free_return; - } - } - } - err = REG_NOERROR; - free_return: - return err; -} - -/* Enumerate all the candidates which the backreference BKREF_NODE can match - at BKREF_STR_IDX, and register them by match_ctx_add_entry(). - Note that we might collect inappropriate candidates here. - However, the cost of checking them strictly here is too high, then we - delay these checking for prune_impossible_nodes(). */ - -static reg_errcode_t -internal_function -get_subexp (re_match_context_t *mctx, int bkref_node, int bkref_str_idx) -{ - const re_dfa_t *const dfa = mctx->dfa; - int subexp_num, sub_top_idx; - const char *buf = (const char *) re_string_get_buffer (&mctx->input); - /* Return if we have already checked BKREF_NODE at BKREF_STR_IDX. */ - int cache_idx = search_cur_bkref_entry (mctx, bkref_str_idx); - if (cache_idx != -1) - { - const struct re_backref_cache_entry *entry - = mctx->bkref_ents + cache_idx; - do - if (entry->node == bkref_node) - return REG_NOERROR; /* We already checked it. */ - while (entry++->more); - } - - subexp_num = dfa->nodes[bkref_node].opr.idx; - - /* For each sub expression */ - for (sub_top_idx = 0; sub_top_idx < mctx->nsub_tops; ++sub_top_idx) - { - reg_errcode_t err; - re_sub_match_top_t *sub_top = mctx->sub_tops[sub_top_idx]; - re_sub_match_last_t *sub_last; - int sub_last_idx, sl_str, bkref_str_off; - - if (dfa->nodes[sub_top->node].opr.idx != subexp_num) - continue; /* It isn't related. */ - - sl_str = sub_top->str_idx; - bkref_str_off = bkref_str_idx; - /* At first, check the last node of sub expressions we already - evaluated. */ - for (sub_last_idx = 0; sub_last_idx < sub_top->nlasts; ++sub_last_idx) - { - int sl_str_diff; - sub_last = sub_top->lasts[sub_last_idx]; - sl_str_diff = sub_last->str_idx - sl_str; - /* The matched string by the sub expression match with the substring - at the back reference? */ - if (sl_str_diff > 0) - { - if (BE (bkref_str_off + sl_str_diff > mctx->input.valid_len, 0)) - { - /* Not enough chars for a successful match. */ - if (bkref_str_off + sl_str_diff > mctx->input.len) - break; - - err = clean_state_log_if_needed (mctx, - bkref_str_off - + sl_str_diff); - if (BE (err != REG_NOERROR, 0)) - return err; - buf = (const char *) re_string_get_buffer (&mctx->input); - } - if (memcmp (buf + bkref_str_off, buf + sl_str, sl_str_diff) != 0) - /* We don't need to search this sub expression any more. */ - break; - } - bkref_str_off += sl_str_diff; - sl_str += sl_str_diff; - err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node, - bkref_str_idx); - - /* Reload buf, since the preceding call might have reallocated - the buffer. */ - buf = (const char *) re_string_get_buffer (&mctx->input); - - if (err == REG_NOMATCH) - continue; - if (BE (err != REG_NOERROR, 0)) - return err; - } - - if (sub_last_idx < sub_top->nlasts) - continue; - if (sub_last_idx > 0) - ++sl_str; - /* Then, search for the other last nodes of the sub expression. */ - for (; sl_str <= bkref_str_idx; ++sl_str) - { - int cls_node, sl_str_off; - const re_node_set *nodes; - sl_str_off = sl_str - sub_top->str_idx; - /* The matched string by the sub expression match with the substring - at the back reference? */ - if (sl_str_off > 0) - { - if (BE (bkref_str_off >= mctx->input.valid_len, 0)) - { - /* If we are at the end of the input, we cannot match. */ - if (bkref_str_off >= mctx->input.len) - break; - - err = extend_buffers (mctx); - if (BE (err != REG_NOERROR, 0)) - return err; - - buf = (const char *) re_string_get_buffer (&mctx->input); - } - if (buf [bkref_str_off++] != buf[sl_str - 1]) - break; /* We don't need to search this sub expression - any more. */ - } - if (mctx->state_log[sl_str] == NULL) - continue; - /* Does this state have a ')' of the sub expression? */ - nodes = &mctx->state_log[sl_str]->nodes; - cls_node = find_subexp_node (dfa, nodes, subexp_num, - OP_CLOSE_SUBEXP); - if (cls_node == -1) - continue; /* No. */ - if (sub_top->path == NULL) - { - sub_top->path = calloc (sizeof (state_array_t), - sl_str - sub_top->str_idx + 1); - if (sub_top->path == NULL) - return REG_ESPACE; - } - /* Can the OP_OPEN_SUBEXP node arrive the OP_CLOSE_SUBEXP node - in the current context? */ - err = check_arrival (mctx, sub_top->path, sub_top->node, - sub_top->str_idx, cls_node, sl_str, - OP_CLOSE_SUBEXP); - if (err == REG_NOMATCH) - continue; - if (BE (err != REG_NOERROR, 0)) - return err; - sub_last = match_ctx_add_sublast (sub_top, cls_node, sl_str); - if (BE (sub_last == NULL, 0)) - return REG_ESPACE; - err = get_subexp_sub (mctx, sub_top, sub_last, bkref_node, - bkref_str_idx); - if (err == REG_NOMATCH) - continue; - } - } - return REG_NOERROR; -} - -/* Helper functions for get_subexp(). */ - -/* Check SUB_LAST can arrive to the back reference BKREF_NODE at BKREF_STR. - If it can arrive, register the sub expression expressed with SUB_TOP - and SUB_LAST. */ - -static reg_errcode_t -internal_function -get_subexp_sub (re_match_context_t *mctx, const re_sub_match_top_t *sub_top, - re_sub_match_last_t *sub_last, int bkref_node, int bkref_str) -{ - reg_errcode_t err; - int to_idx; - /* Can the subexpression arrive the back reference? */ - err = check_arrival (mctx, &sub_last->path, sub_last->node, - sub_last->str_idx, bkref_node, bkref_str, - OP_OPEN_SUBEXP); - if (err != REG_NOERROR) - return err; - err = match_ctx_add_entry (mctx, bkref_node, bkref_str, sub_top->str_idx, - sub_last->str_idx); - if (BE (err != REG_NOERROR, 0)) - return err; - to_idx = bkref_str + sub_last->str_idx - sub_top->str_idx; - return clean_state_log_if_needed (mctx, to_idx); -} - -/* Find the first node which is '(' or ')' and whose index is SUBEXP_IDX. - Search '(' if FL_OPEN, or search ')' otherwise. - TODO: This function isn't efficient... - Because there might be more than one nodes whose types are - OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all - nodes. - E.g. RE: (a){2} */ - -static int -internal_function -find_subexp_node (const re_dfa_t *dfa, const re_node_set *nodes, - int subexp_idx, int type) -{ - int cls_idx; - for (cls_idx = 0; cls_idx < nodes->nelem; ++cls_idx) - { - int cls_node = nodes->elems[cls_idx]; - const re_token_t *node = dfa->nodes + cls_node; - if (node->type == type - && node->opr.idx == subexp_idx) - return cls_node; - } - return -1; -} - -/* Check whether the node TOP_NODE at TOP_STR can arrive to the node - LAST_NODE at LAST_STR. We record the path onto PATH since it will be - heavily reused. - Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise. */ - -static reg_errcode_t -internal_function -check_arrival (re_match_context_t *mctx, state_array_t *path, int top_node, - int top_str, int last_node, int last_str, int type) -{ - const re_dfa_t *const dfa = mctx->dfa; - reg_errcode_t err = REG_NOERROR; - int subexp_num, backup_cur_idx, str_idx, null_cnt; - re_dfastate_t *cur_state = NULL; - re_node_set *cur_nodes, next_nodes; - re_dfastate_t **backup_state_log; - unsigned int context; - - subexp_num = dfa->nodes[top_node].opr.idx; - /* Extend the buffer if we need. */ - if (BE (path->alloc < last_str + mctx->max_mb_elem_len + 1, 0)) - { - re_dfastate_t **new_array; - int old_alloc = path->alloc; - path->alloc += last_str + mctx->max_mb_elem_len + 1; - new_array = re_realloc (path->array, re_dfastate_t *, path->alloc); - if (BE (new_array == NULL, 0)) - { - path->alloc = old_alloc; - return REG_ESPACE; - } - path->array = new_array; - memset (new_array + old_alloc, '\0', - sizeof (re_dfastate_t *) * (path->alloc - old_alloc)); - } - - str_idx = path->next_idx ? path->next_idx : top_str; - - /* Temporary modify MCTX. */ - backup_state_log = mctx->state_log; - backup_cur_idx = mctx->input.cur_idx; - mctx->state_log = path->array; - mctx->input.cur_idx = str_idx; - - /* Setup initial node set. */ - context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags); - if (str_idx == top_str) - { - err = re_node_set_init_1 (&next_nodes, top_node); - if (BE (err != REG_NOERROR, 0)) - return err; - err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - } - else - { - cur_state = mctx->state_log[str_idx]; - if (cur_state && cur_state->has_backref) - { - err = re_node_set_init_copy (&next_nodes, &cur_state->nodes); - if (BE (err != REG_NOERROR, 0)) - return err; - } - else - re_node_set_init_empty (&next_nodes); - } - if (str_idx == top_str || (cur_state && cur_state->has_backref)) - { - if (next_nodes.nelem) - { - err = expand_bkref_cache (mctx, &next_nodes, str_idx, - subexp_num, type); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - } - cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context); - if (BE (cur_state == NULL && err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - mctx->state_log[str_idx] = cur_state; - } - - for (null_cnt = 0; str_idx < last_str && null_cnt <= mctx->max_mb_elem_len;) - { - re_node_set_empty (&next_nodes); - if (mctx->state_log[str_idx + 1]) - { - err = re_node_set_merge (&next_nodes, - &mctx->state_log[str_idx + 1]->nodes); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - } - if (cur_state) - { - err = check_arrival_add_next_nodes (mctx, str_idx, - &cur_state->non_eps_nodes, - &next_nodes); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - } - ++str_idx; - if (next_nodes.nelem) - { - err = check_arrival_expand_ecl (dfa, &next_nodes, subexp_num, type); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - err = expand_bkref_cache (mctx, &next_nodes, str_idx, - subexp_num, type); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - } - context = re_string_context_at (&mctx->input, str_idx - 1, mctx->eflags); - cur_state = re_acquire_state_context (&err, dfa, &next_nodes, context); - if (BE (cur_state == NULL && err != REG_NOERROR, 0)) - { - re_node_set_free (&next_nodes); - return err; - } - mctx->state_log[str_idx] = cur_state; - null_cnt = cur_state == NULL ? null_cnt + 1 : 0; - } - re_node_set_free (&next_nodes); - cur_nodes = (mctx->state_log[last_str] == NULL ? NULL - : &mctx->state_log[last_str]->nodes); - path->next_idx = str_idx; - - /* Fix MCTX. */ - mctx->state_log = backup_state_log; - mctx->input.cur_idx = backup_cur_idx; - - /* Then check the current node set has the node LAST_NODE. */ - if (cur_nodes != NULL && re_node_set_contains (cur_nodes, last_node)) - return REG_NOERROR; - - return REG_NOMATCH; -} - -/* Helper functions for check_arrival. */ - -/* Calculate the destination nodes of CUR_NODES at STR_IDX, and append them - to NEXT_NODES. - TODO: This function is similar to the functions transit_state*(), - however this function has many additional works. - Can't we unify them? */ - -static reg_errcode_t -internal_function -check_arrival_add_next_nodes (re_match_context_t *mctx, int str_idx, - re_node_set *cur_nodes, re_node_set *next_nodes) -{ - const re_dfa_t *const dfa = mctx->dfa; - int result; - int cur_idx; -#ifdef RE_ENABLE_I18N - reg_errcode_t err = REG_NOERROR; -#endif - re_node_set union_set; - re_node_set_init_empty (&union_set); - for (cur_idx = 0; cur_idx < cur_nodes->nelem; ++cur_idx) - { - int naccepted = 0; - int cur_node = cur_nodes->elems[cur_idx]; -#ifdef DEBUG - re_token_type_t type = dfa->nodes[cur_node].type; - assert (!IS_EPSILON_NODE (type)); -#endif -#ifdef RE_ENABLE_I18N - /* If the node may accept `multi byte'. */ - if (dfa->nodes[cur_node].accept_mb) - { - naccepted = check_node_accept_bytes (dfa, cur_node, &mctx->input, - str_idx); - if (naccepted > 1) - { - re_dfastate_t *dest_state; - int next_node = dfa->nexts[cur_node]; - int next_idx = str_idx + naccepted; - dest_state = mctx->state_log[next_idx]; - re_node_set_empty (&union_set); - if (dest_state) - { - err = re_node_set_merge (&union_set, &dest_state->nodes); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&union_set); - return err; - } - } - result = re_node_set_insert (&union_set, next_node); - if (BE (result < 0, 0)) - { - re_node_set_free (&union_set); - return REG_ESPACE; - } - mctx->state_log[next_idx] = re_acquire_state (&err, dfa, - &union_set); - if (BE (mctx->state_log[next_idx] == NULL - && err != REG_NOERROR, 0)) - { - re_node_set_free (&union_set); - return err; - } - } - } -#endif /* RE_ENABLE_I18N */ - if (naccepted - || check_node_accept (mctx, dfa->nodes + cur_node, str_idx)) - { - result = re_node_set_insert (next_nodes, dfa->nexts[cur_node]); - if (BE (result < 0, 0)) - { - re_node_set_free (&union_set); - return REG_ESPACE; - } - } - } - re_node_set_free (&union_set); - return REG_NOERROR; -} - -/* For all the nodes in CUR_NODES, add the epsilon closures of them to - CUR_NODES, however exclude the nodes which are: - - inside the sub expression whose number is EX_SUBEXP, if FL_OPEN. - - out of the sub expression whose number is EX_SUBEXP, if !FL_OPEN. -*/ - -static reg_errcode_t -internal_function -check_arrival_expand_ecl (const re_dfa_t *dfa, re_node_set *cur_nodes, - int ex_subexp, int type) -{ - reg_errcode_t err; - int idx, outside_node; - re_node_set new_nodes; -#ifdef DEBUG - assert (cur_nodes->nelem); -#endif - err = re_node_set_alloc (&new_nodes, cur_nodes->nelem); - if (BE (err != REG_NOERROR, 0)) - return err; - /* Create a new node set NEW_NODES with the nodes which are epsilon - closures of the node in CUR_NODES. */ - - for (idx = 0; idx < cur_nodes->nelem; ++idx) - { - int cur_node = cur_nodes->elems[idx]; - const re_node_set *eclosure = dfa->eclosures + cur_node; - outside_node = find_subexp_node (dfa, eclosure, ex_subexp, type); - if (outside_node == -1) - { - /* There are no problematic nodes, just merge them. */ - err = re_node_set_merge (&new_nodes, eclosure); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&new_nodes); - return err; - } - } - else - { - /* There are problematic nodes, re-calculate incrementally. */ - err = check_arrival_expand_ecl_sub (dfa, &new_nodes, cur_node, - ex_subexp, type); - if (BE (err != REG_NOERROR, 0)) - { - re_node_set_free (&new_nodes); - return err; - } - } - } - re_node_set_free (cur_nodes); - *cur_nodes = new_nodes; - return REG_NOERROR; -} - -/* Helper function for check_arrival_expand_ecl. - Check incrementally the epsilon closure of TARGET, and if it isn't - problematic append it to DST_NODES. */ - -static reg_errcode_t -internal_function -check_arrival_expand_ecl_sub (const re_dfa_t *dfa, re_node_set *dst_nodes, - int target, int ex_subexp, int type) -{ - int cur_node; - for (cur_node = target; !re_node_set_contains (dst_nodes, cur_node);) - { - int err; - - if (dfa->nodes[cur_node].type == type - && dfa->nodes[cur_node].opr.idx == ex_subexp) - { - if (type == OP_CLOSE_SUBEXP) - { - err = re_node_set_insert (dst_nodes, cur_node); - if (BE (err == -1, 0)) - return REG_ESPACE; - } - break; - } - err = re_node_set_insert (dst_nodes, cur_node); - if (BE (err == -1, 0)) - return REG_ESPACE; - if (dfa->edests[cur_node].nelem == 0) - break; - if (dfa->edests[cur_node].nelem == 2) - { - err = check_arrival_expand_ecl_sub (dfa, dst_nodes, - dfa->edests[cur_node].elems[1], - ex_subexp, type); - if (BE (err != REG_NOERROR, 0)) - return err; - } - cur_node = dfa->edests[cur_node].elems[0]; - } - return REG_NOERROR; -} - - -/* For all the back references in the current state, calculate the - destination of the back references by the appropriate entry - in MCTX->BKREF_ENTS. */ - -static reg_errcode_t -internal_function -expand_bkref_cache (re_match_context_t *mctx, re_node_set *cur_nodes, - int cur_str, int subexp_num, int type) -{ - const re_dfa_t *const dfa = mctx->dfa; - reg_errcode_t err; - int cache_idx_start = search_cur_bkref_entry (mctx, cur_str); - struct re_backref_cache_entry *ent; - - if (cache_idx_start == -1) - return REG_NOERROR; - - restart: - ent = mctx->bkref_ents + cache_idx_start; - do - { - int to_idx, next_node; - - /* Is this entry ENT is appropriate? */ - if (!re_node_set_contains (cur_nodes, ent->node)) - continue; /* No. */ - - to_idx = cur_str + ent->subexp_to - ent->subexp_from; - /* Calculate the destination of the back reference, and append it - to MCTX->STATE_LOG. */ - if (to_idx == cur_str) - { - /* The backreference did epsilon transit, we must re-check all the - node in the current state. */ - re_node_set new_dests; - reg_errcode_t err2, err3; - next_node = dfa->edests[ent->node].elems[0]; - if (re_node_set_contains (cur_nodes, next_node)) - continue; - err = re_node_set_init_1 (&new_dests, next_node); - err2 = check_arrival_expand_ecl (dfa, &new_dests, subexp_num, type); - err3 = re_node_set_merge (cur_nodes, &new_dests); - re_node_set_free (&new_dests); - if (BE (err != REG_NOERROR || err2 != REG_NOERROR - || err3 != REG_NOERROR, 0)) - { - err = (err != REG_NOERROR ? err - : (err2 != REG_NOERROR ? err2 : err3)); - return err; - } - /* TODO: It is still inefficient... */ - goto restart; - } - else - { - re_node_set union_set; - next_node = dfa->nexts[ent->node]; - if (mctx->state_log[to_idx]) - { - int ret; - if (re_node_set_contains (&mctx->state_log[to_idx]->nodes, - next_node)) - continue; - err = re_node_set_init_copy (&union_set, - &mctx->state_log[to_idx]->nodes); - ret = re_node_set_insert (&union_set, next_node); - if (BE (err != REG_NOERROR || ret < 0, 0)) - { - re_node_set_free (&union_set); - err = err != REG_NOERROR ? err : REG_ESPACE; - return err; - } - } - else - { - err = re_node_set_init_1 (&union_set, next_node); - if (BE (err != REG_NOERROR, 0)) - return err; - } - mctx->state_log[to_idx] = re_acquire_state (&err, dfa, &union_set); - re_node_set_free (&union_set); - if (BE (mctx->state_log[to_idx] == NULL - && err != REG_NOERROR, 0)) - return err; - } - } - while (ent++->more); - return REG_NOERROR; -} - -/* Build transition table for the state. - Return 1 if succeeded, otherwise return NULL. */ - -static int -internal_function -build_trtable (const re_dfa_t *dfa, re_dfastate_t *state) -{ - reg_errcode_t err; - int i, j, ch, need_word_trtable = 0; - bitset_word_t elem, mask; - bool dests_node_malloced = false; - bool dest_states_malloced = false; - int ndests; /* Number of the destination states from `state'. */ - re_dfastate_t **trtable; - re_dfastate_t **dest_states = NULL, **dest_states_word, **dest_states_nl; - re_node_set follows, *dests_node; - bitset_t *dests_ch; - bitset_t acceptable; - - struct dests_alloc - { - re_node_set dests_node[SBC_MAX]; - bitset_t dests_ch[SBC_MAX]; - } *dests_alloc; - - /* We build DFA states which corresponds to the destination nodes - from `state'. `dests_node[i]' represents the nodes which i-th - destination state contains, and `dests_ch[i]' represents the - characters which i-th destination state accepts. */ -#ifdef HAVE_ALLOCA - if (__libc_use_alloca (sizeof (struct dests_alloc))) - dests_alloc = (struct dests_alloc *) alloca (sizeof (struct dests_alloc)); - else -#endif - { - dests_alloc = re_malloc (struct dests_alloc, 1); - if (BE (dests_alloc == NULL, 0)) - return 0; - dests_node_malloced = true; - } - dests_node = dests_alloc->dests_node; - dests_ch = dests_alloc->dests_ch; - - /* Initialize transiton table. */ - state->word_trtable = state->trtable = NULL; - - /* At first, group all nodes belonging to `state' into several - destinations. */ - ndests = group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch); - if (BE (ndests <= 0, 0)) - { - if (dests_node_malloced) - free (dests_alloc); - /* Return 0 in case of an error, 1 otherwise. */ - if (ndests == 0) - { - state->trtable = (re_dfastate_t **) - calloc (sizeof (re_dfastate_t *), SBC_MAX); - return 1; - } - return 0; - } - - err = re_node_set_alloc (&follows, ndests + 1); - if (BE (err != REG_NOERROR, 0)) - goto out_free; - - /* Avoid arithmetic overflow in size calculation. */ - if (BE ((((SIZE_MAX - (sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX) - / (3 * sizeof (re_dfastate_t *))) - < ndests), - 0)) - goto out_free; - -#ifdef HAVE_ALLOCA - if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX - + ndests * 3 * sizeof (re_dfastate_t *))) - dest_states = (re_dfastate_t **) - alloca (ndests * 3 * sizeof (re_dfastate_t *)); - else -#endif - { - dest_states = (re_dfastate_t **) - malloc (ndests * 3 * sizeof (re_dfastate_t *)); - if (BE (dest_states == NULL, 0)) - { -out_free: - if (dest_states_malloced) - free (dest_states); - re_node_set_free (&follows); - for (i = 0; i < ndests; ++i) - re_node_set_free (dests_node + i); - if (dests_node_malloced) - free (dests_alloc); - return 0; - } - dest_states_malloced = true; - } - dest_states_word = dest_states + ndests; - dest_states_nl = dest_states_word + ndests; - bitset_empty (acceptable); - - /* Then build the states for all destinations. */ - for (i = 0; i < ndests; ++i) - { - int next_node; - re_node_set_empty (&follows); - /* Merge the follows of this destination states. */ - for (j = 0; j < dests_node[i].nelem; ++j) - { - next_node = dfa->nexts[dests_node[i].elems[j]]; - if (next_node != -1) - { - err = re_node_set_merge (&follows, dfa->eclosures + next_node); - if (BE (err != REG_NOERROR, 0)) - goto out_free; - } - } - dest_states[i] = re_acquire_state_context (&err, dfa, &follows, 0); - if (BE (dest_states[i] == NULL && err != REG_NOERROR, 0)) - goto out_free; - /* If the new state has context constraint, - build appropriate states for these contexts. */ - if (dest_states[i]->has_constraint) - { - dest_states_word[i] = re_acquire_state_context (&err, dfa, &follows, - CONTEXT_WORD); - if (BE (dest_states_word[i] == NULL && err != REG_NOERROR, 0)) - goto out_free; - - if (dest_states[i] != dest_states_word[i] && dfa->mb_cur_max > 1) - need_word_trtable = 1; - - dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows, - CONTEXT_NEWLINE); - if (BE (dest_states_nl[i] == NULL && err != REG_NOERROR, 0)) - goto out_free; - } - else - { - dest_states_word[i] = dest_states[i]; - dest_states_nl[i] = dest_states[i]; - } - bitset_merge (acceptable, dests_ch[i]); - } - - if (!BE (need_word_trtable, 0)) - { - /* We don't care about whether the following character is a word - character, or we are in a single-byte character set so we can - discern by looking at the character code: allocate a - 256-entry transition table. */ - trtable = state->trtable = - (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX); - if (BE (trtable == NULL, 0)) - goto out_free; - - /* For all characters ch...: */ - for (i = 0; i < BITSET_WORDS; ++i) - for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1; - elem; - mask <<= 1, elem >>= 1, ++ch) - if (BE (elem & 1, 0)) - { - /* There must be exactly one destination which accepts - character ch. See group_nodes_into_DFAstates. */ - for (j = 0; (dests_ch[j][i] & mask) == 0; ++j) - ; - - /* j-th destination accepts the word character ch. */ - if (dfa->word_char[i] & mask) - trtable[ch] = dest_states_word[j]; - else - trtable[ch] = dest_states[j]; - } - } - else - { - /* We care about whether the following character is a word - character, and we are in a multi-byte character set: discern - by looking at the character code: build two 256-entry - transition tables, one starting at trtable[0] and one - starting at trtable[SBC_MAX]. */ - trtable = state->word_trtable = - (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), 2 * SBC_MAX); - if (BE (trtable == NULL, 0)) - goto out_free; - - /* For all characters ch...: */ - for (i = 0; i < BITSET_WORDS; ++i) - for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1; - elem; - mask <<= 1, elem >>= 1, ++ch) - if (BE (elem & 1, 0)) - { - /* There must be exactly one destination which accepts - character ch. See group_nodes_into_DFAstates. */ - for (j = 0; (dests_ch[j][i] & mask) == 0; ++j) - ; - - /* j-th destination accepts the word character ch. */ - trtable[ch] = dest_states[j]; - trtable[ch + SBC_MAX] = dest_states_word[j]; - } - } - - /* new line */ - if (bitset_contain (acceptable, NEWLINE_CHAR)) - { - /* The current state accepts newline character. */ - for (j = 0; j < ndests; ++j) - if (bitset_contain (dests_ch[j], NEWLINE_CHAR)) - { - /* k-th destination accepts newline character. */ - trtable[NEWLINE_CHAR] = dest_states_nl[j]; - if (need_word_trtable) - trtable[NEWLINE_CHAR + SBC_MAX] = dest_states_nl[j]; - /* There must be only one destination which accepts - newline. See group_nodes_into_DFAstates. */ - break; - } - } - - if (dest_states_malloced) - free (dest_states); - - re_node_set_free (&follows); - for (i = 0; i < ndests; ++i) - re_node_set_free (dests_node + i); - - if (dests_node_malloced) - free (dests_alloc); - - return 1; -} - -/* Group all nodes belonging to STATE into several destinations. - Then for all destinations, set the nodes belonging to the destination - to DESTS_NODE[i] and set the characters accepted by the destination - to DEST_CH[i]. This function return the number of destinations. */ - -static int -internal_function -group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state, - re_node_set *dests_node, bitset_t *dests_ch) -{ - reg_errcode_t err; - int result; - int i, j, k; - int ndests; /* Number of the destinations from `state'. */ - bitset_t accepts; /* Characters a node can accept. */ - const re_node_set *cur_nodes = &state->nodes; - bitset_empty (accepts); - ndests = 0; - - /* For all the nodes belonging to `state', */ - for (i = 0; i < cur_nodes->nelem; ++i) - { - re_token_t *node = &dfa->nodes[cur_nodes->elems[i]]; - re_token_type_t type = node->type; - unsigned int constraint = node->constraint; - - /* Enumerate all single byte character this node can accept. */ - if (type == CHARACTER) - bitset_set (accepts, node->opr.c); - else if (type == SIMPLE_BRACKET) - { - bitset_merge (accepts, node->opr.sbcset); - } - else if (type == OP_PERIOD) - { -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - bitset_merge (accepts, dfa->sb_char); - else -#endif - bitset_set_all (accepts); - if (!(dfa->syntax & RE_DOT_NEWLINE)) - bitset_clear (accepts, '\n'); - if (dfa->syntax & RE_DOT_NOT_NULL) - bitset_clear (accepts, '\0'); - } -#ifdef RE_ENABLE_I18N - else if (type == OP_UTF8_PERIOD) - { - memset (accepts, '\xff', sizeof (bitset_t) / 2); - if (!(dfa->syntax & RE_DOT_NEWLINE)) - bitset_clear (accepts, '\n'); - if (dfa->syntax & RE_DOT_NOT_NULL) - bitset_clear (accepts, '\0'); - } -#endif - else - continue; - - /* Check the `accepts' and sift the characters which are not - match it the context. */ - if (constraint) - { - if (constraint & NEXT_NEWLINE_CONSTRAINT) - { - bool accepts_newline = bitset_contain (accepts, NEWLINE_CHAR); - bitset_empty (accepts); - if (accepts_newline) - bitset_set (accepts, NEWLINE_CHAR); - else - continue; - } - if (constraint & NEXT_ENDBUF_CONSTRAINT) - { - bitset_empty (accepts); - continue; - } - - if (constraint & NEXT_WORD_CONSTRAINT) - { - bitset_word_t any_set = 0; - if (type == CHARACTER && !node->word_char) - { - bitset_empty (accepts); - continue; - } -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - for (j = 0; j < BITSET_WORDS; ++j) - any_set |= (accepts[j] &= (dfa->word_char[j] | ~dfa->sb_char[j])); - else -#endif - for (j = 0; j < BITSET_WORDS; ++j) - any_set |= (accepts[j] &= dfa->word_char[j]); - if (!any_set) - continue; - } - if (constraint & NEXT_NOTWORD_CONSTRAINT) - { - bitset_word_t any_set = 0; - if (type == CHARACTER && node->word_char) - { - bitset_empty (accepts); - continue; - } -#ifdef RE_ENABLE_I18N - if (dfa->mb_cur_max > 1) - for (j = 0; j < BITSET_WORDS; ++j) - any_set |= (accepts[j] &= ~(dfa->word_char[j] & dfa->sb_char[j])); - else -#endif - for (j = 0; j < BITSET_WORDS; ++j) - any_set |= (accepts[j] &= ~dfa->word_char[j]); - if (!any_set) - continue; - } - } - - /* Then divide `accepts' into DFA states, or create a new - state. Above, we make sure that accepts is not empty. */ - for (j = 0; j < ndests; ++j) - { - bitset_t intersec; /* Intersection sets, see below. */ - bitset_t remains; - /* Flags, see below. */ - bitset_word_t has_intersec, not_subset, not_consumed; - - /* Optimization, skip if this state doesn't accept the character. */ - if (type == CHARACTER && !bitset_contain (dests_ch[j], node->opr.c)) - continue; - - /* Enumerate the intersection set of this state and `accepts'. */ - has_intersec = 0; - for (k = 0; k < BITSET_WORDS; ++k) - has_intersec |= intersec[k] = accepts[k] & dests_ch[j][k]; - /* And skip if the intersection set is empty. */ - if (!has_intersec) - continue; - - /* Then check if this state is a subset of `accepts'. */ - not_subset = not_consumed = 0; - for (k = 0; k < BITSET_WORDS; ++k) - { - not_subset |= remains[k] = ~accepts[k] & dests_ch[j][k]; - not_consumed |= accepts[k] = accepts[k] & ~dests_ch[j][k]; - } - - /* If this state isn't a subset of `accepts', create a - new group state, which has the `remains'. */ - if (not_subset) - { - bitset_copy (dests_ch[ndests], remains); - bitset_copy (dests_ch[j], intersec); - err = re_node_set_init_copy (dests_node + ndests, &dests_node[j]); - if (BE (err != REG_NOERROR, 0)) - goto error_return; - ++ndests; - } - - /* Put the position in the current group. */ - result = re_node_set_insert (&dests_node[j], cur_nodes->elems[i]); - if (BE (result < 0, 0)) - goto error_return; - - /* If all characters are consumed, go to next node. */ - if (!not_consumed) - break; - } - /* Some characters remain, create a new group. */ - if (j == ndests) - { - bitset_copy (dests_ch[ndests], accepts); - err = re_node_set_init_1 (dests_node + ndests, cur_nodes->elems[i]); - if (BE (err != REG_NOERROR, 0)) - goto error_return; - ++ndests; - bitset_empty (accepts); - } - } - return ndests; - error_return: - for (j = 0; j < ndests; ++j) - re_node_set_free (dests_node + j); - return -1; -} - -#ifdef RE_ENABLE_I18N -/* Check how many bytes the node `dfa->nodes[node_idx]' accepts. - Return the number of the bytes the node accepts. - STR_IDX is the current index of the input string. - - This function handles the nodes which can accept one character, or - one collating element like '.', '[a-z]', opposite to the other nodes - can only accept one byte. */ - -static int -internal_function -check_node_accept_bytes (const re_dfa_t *dfa, int node_idx, - const re_string_t *input, int str_idx) -{ - const re_token_t *node = dfa->nodes + node_idx; - int char_len, elem_len; - int i; - wint_t wc; - - if (BE (node->type == OP_UTF8_PERIOD, 0)) - { - unsigned char c = re_string_byte_at (input, str_idx), d; - if (BE (c < 0xc2, 1)) - return 0; - - if (str_idx + 2 > input->len) - return 0; - - d = re_string_byte_at (input, str_idx + 1); - if (c < 0xe0) - return (d < 0x80 || d > 0xbf) ? 0 : 2; - else if (c < 0xf0) - { - char_len = 3; - if (c == 0xe0 && d < 0xa0) - return 0; - } - else if (c < 0xf8) - { - char_len = 4; - if (c == 0xf0 && d < 0x90) - return 0; - } - else if (c < 0xfc) - { - char_len = 5; - if (c == 0xf8 && d < 0x88) - return 0; - } - else if (c < 0xfe) - { - char_len = 6; - if (c == 0xfc && d < 0x84) - return 0; - } - else - return 0; - - if (str_idx + char_len > input->len) - return 0; - - for (i = 1; i < char_len; ++i) - { - d = re_string_byte_at (input, str_idx + i); - if (d < 0x80 || d > 0xbf) - return 0; - } - return char_len; - } - - char_len = re_string_char_size_at (input, str_idx); - if (node->type == OP_PERIOD) - { - if (char_len <= 1) - return 0; - /* FIXME: I don't think this if is needed, as both '\n' - and '\0' are char_len == 1. */ - /* '.' accepts any one character except the following two cases. */ - if ((!(dfa->syntax & RE_DOT_NEWLINE) && - re_string_byte_at (input, str_idx) == '\n') || - ((dfa->syntax & RE_DOT_NOT_NULL) && - re_string_byte_at (input, str_idx) == '\0')) - return 0; - return char_len; - } - - elem_len = re_string_elem_size_at (input, str_idx); - wc = __btowc(*(input->mbs+str_idx)); - if (((elem_len <= 1 && char_len <= 1) || char_len == 0) && (wc != WEOF && wc < SBC_MAX)) - return 0; - - if (node->type == COMPLEX_BRACKET) - { - const re_charset_t *cset = node->opr.mbcset; -# ifdef _LIBC - const unsigned char *pin - = ((const unsigned char *) re_string_get_buffer (input) + str_idx); - int j; - uint32_t nrules; -# endif /* _LIBC */ - int match_len = 0; - wchar_t wc = ((cset->nranges || cset->nchar_classes || cset->nmbchars) - ? re_string_wchar_at (input, str_idx) : 0); - - /* match with multibyte character? */ - for (i = 0; i < cset->nmbchars; ++i) - if (wc == cset->mbchars[i]) - { - match_len = char_len; - goto check_node_accept_bytes_match; - } - /* match with character_class? */ - for (i = 0; i < cset->nchar_classes; ++i) - { - wctype_t wt = cset->char_classes[i]; - if (__iswctype (wc, wt)) - { - match_len = char_len; - goto check_node_accept_bytes_match; - } - } - -# ifdef _LIBC - nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); - if (nrules != 0) - { - unsigned int in_collseq = 0; - const int32_t *table, *indirect; - const unsigned char *weights, *extra; - const char *collseqwc; - /* This #include defines a local function! */ -# include - - /* match with collating_symbol? */ - if (cset->ncoll_syms) - extra = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB); - for (i = 0; i < cset->ncoll_syms; ++i) - { - const unsigned char *coll_sym = extra + cset->coll_syms[i]; - /* Compare the length of input collating element and - the length of current collating element. */ - if (*coll_sym != elem_len) - continue; - /* Compare each bytes. */ - for (j = 0; j < *coll_sym; j++) - if (pin[j] != coll_sym[1 + j]) - break; - if (j == *coll_sym) - { - /* Match if every bytes is equal. */ - match_len = j; - goto check_node_accept_bytes_match; - } - } - - if (cset->nranges) - { - if (elem_len <= char_len) - { - collseqwc = _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQWC); - in_collseq = __collseq_table_lookup (collseqwc, wc); - } - else - in_collseq = find_collation_sequence_value (pin, elem_len); - } - /* match with range expression? */ - for (i = 0; i < cset->nranges; ++i) - if (cset->range_starts[i] <= in_collseq - && in_collseq <= cset->range_ends[i]) - { - match_len = elem_len; - goto check_node_accept_bytes_match; - } - - /* match with equivalence_class? */ - if (cset->nequiv_classes) - { - const unsigned char *cp = pin; - table = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_TABLEMB); - weights = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_WEIGHTMB); - extra = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_EXTRAMB); - indirect = (const int32_t *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_INDIRECTMB); - int32_t idx = findidx (&cp); - if (idx > 0) - for (i = 0; i < cset->nequiv_classes; ++i) - { - int32_t equiv_class_idx = cset->equiv_classes[i]; - size_t weight_len = weights[idx & 0xffffff]; - if (weight_len == weights[equiv_class_idx & 0xffffff] - && (idx >> 24) == (equiv_class_idx >> 24)) - { - int cnt = 0; - - idx &= 0xffffff; - equiv_class_idx &= 0xffffff; - - while (cnt <= weight_len - && (weights[equiv_class_idx + 1 + cnt] - == weights[idx + 1 + cnt])) - ++cnt; - if (cnt > weight_len) - { - match_len = elem_len; - goto check_node_accept_bytes_match; - } - } - } - } - } - else -# endif /* _LIBC */ - { - /* match with range expression? */ -#if __GNUC__ >= 2 - wchar_t cmp_buf[] = {L'\0', L'\0', wc, L'\0', L'\0', L'\0'}; -#else - wchar_t cmp_buf[] = {L'\0', L'\0', L'\0', L'\0', L'\0', L'\0'}; - cmp_buf[2] = wc; -#endif - for (i = 0; i < cset->nranges; ++i) - { - cmp_buf[0] = cset->range_starts[i]; - cmp_buf[4] = cset->range_ends[i]; - if (wcscoll (cmp_buf, cmp_buf + 2) <= 0 - && wcscoll (cmp_buf + 2, cmp_buf + 4) <= 0) - { - match_len = char_len; - goto check_node_accept_bytes_match; - } - } - } - check_node_accept_bytes_match: - if (!cset->non_match) - return match_len; - else - { - if (match_len > 0) - return 0; - else - return (elem_len > char_len) ? elem_len : char_len; - } - } - return 0; -} - -# ifdef _LIBC -static unsigned int -internal_function -find_collation_sequence_value (const unsigned char *mbs, size_t mbs_len) -{ - uint32_t nrules = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_NRULES); - if (nrules == 0) - { - if (mbs_len == 1) - { - /* No valid character. Match it as a single byte character. */ - const unsigned char *collseq = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_COLLSEQMB); - return collseq[mbs[0]]; - } - return UINT_MAX; - } - else - { - int32_t idx; - const unsigned char *extra = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB); - int32_t extrasize = (const unsigned char *) - _NL_CURRENT (LC_COLLATE, _NL_COLLATE_SYMB_EXTRAMB + 1) - extra; - - for (idx = 0; idx < extrasize;) - { - int mbs_cnt, found = 0; - int32_t elem_mbs_len; - /* Skip the name of collating element name. */ - idx = idx + extra[idx] + 1; - elem_mbs_len = extra[idx++]; - if (mbs_len == elem_mbs_len) - { - for (mbs_cnt = 0; mbs_cnt < elem_mbs_len; ++mbs_cnt) - if (extra[idx + mbs_cnt] != mbs[mbs_cnt]) - break; - if (mbs_cnt == elem_mbs_len) - /* Found the entry. */ - found = 1; - } - /* Skip the byte sequence of the collating element. */ - idx += elem_mbs_len; - /* Adjust for the alignment. */ - idx = (idx + 3) & ~3; - /* Skip the collation sequence value. */ - idx += sizeof (uint32_t); - /* Skip the wide char sequence of the collating element. */ - idx = idx + sizeof (uint32_t) * (extra[idx] + 1); - /* If we found the entry, return the sequence value. */ - if (found) - return *(uint32_t *) (extra + idx); - /* Skip the collation sequence value. */ - idx += sizeof (uint32_t); - } - return UINT_MAX; - } -} -# endif /* _LIBC */ -#endif /* RE_ENABLE_I18N */ - -/* Check whether the node accepts the byte which is IDX-th - byte of the INPUT. */ - -static int -internal_function -check_node_accept (const re_match_context_t *mctx, const re_token_t *node, - int idx) -{ - unsigned char ch; - ch = re_string_byte_at (&mctx->input, idx); - switch (node->type) - { - case CHARACTER: - if (node->opr.c != ch) - return 0; - break; - - case SIMPLE_BRACKET: - if (!bitset_contain (node->opr.sbcset, ch)) - return 0; - break; - -#ifdef RE_ENABLE_I18N - case OP_UTF8_PERIOD: - if (ch >= 0x80) - return 0; - /* FALLTHROUGH */ -#endif - case OP_PERIOD: - if ((ch == '\n' && !(mctx->dfa->syntax & RE_DOT_NEWLINE)) - || (ch == '\0' && (mctx->dfa->syntax & RE_DOT_NOT_NULL))) - return 0; - break; - - default: - return 0; - } - - if (node->constraint) - { - /* The node has constraints. Check whether the current context - satisfies the constraints. */ - unsigned int context = re_string_context_at (&mctx->input, idx, - mctx->eflags); - if (NOT_SATISFY_NEXT_CONSTRAINT (node->constraint, context)) - return 0; - } - - return 1; -} - -/* Extend the buffers, if the buffers have run out. */ - -static reg_errcode_t -internal_function -extend_buffers (re_match_context_t *mctx) -{ - reg_errcode_t ret; - re_string_t *pstr = &mctx->input; - - /* Avoid overflow. */ - if (BE (INT_MAX / 2 / sizeof (re_dfastate_t *) <= pstr->bufs_len, 0)) - return REG_ESPACE; - - /* Double the lengthes of the buffers. */ - ret = re_string_realloc_buffers (pstr, pstr->bufs_len * 2); - if (BE (ret != REG_NOERROR, 0)) - return ret; - - if (mctx->state_log != NULL) - { - /* And double the length of state_log. */ - /* XXX We have no indication of the size of this buffer. If this - allocation fail we have no indication that the state_log array - does not have the right size. */ - re_dfastate_t **new_array = re_realloc (mctx->state_log, re_dfastate_t *, - pstr->bufs_len + 1); - if (BE (new_array == NULL, 0)) - return REG_ESPACE; - mctx->state_log = new_array; - } - - /* Then reconstruct the buffers. */ - if (pstr->icase) - { -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1) - { - ret = build_wcs_upper_buffer (pstr); - if (BE (ret != REG_NOERROR, 0)) - return ret; - } - else -#endif /* RE_ENABLE_I18N */ - build_upper_buffer (pstr); - } - else - { -#ifdef RE_ENABLE_I18N - if (pstr->mb_cur_max > 1) - build_wcs_buffer (pstr); - else -#endif /* RE_ENABLE_I18N */ - { - if (pstr->trans != NULL) - re_string_translate_buffer (pstr); - } - } - return REG_NOERROR; -} - - -/* Functions for matching context. */ - -/* Initialize MCTX. */ - -static reg_errcode_t -internal_function -match_ctx_init (re_match_context_t *mctx, int eflags, int n) -{ - mctx->eflags = eflags; - mctx->match_last = -1; - if (n > 0) - { - mctx->bkref_ents = re_malloc (struct re_backref_cache_entry, n); - mctx->sub_tops = re_malloc (re_sub_match_top_t *, n); - if (BE (mctx->bkref_ents == NULL || mctx->sub_tops == NULL, 0)) - return REG_ESPACE; - } - /* Already zero-ed by the caller. - else - mctx->bkref_ents = NULL; - mctx->nbkref_ents = 0; - mctx->nsub_tops = 0; */ - mctx->abkref_ents = n; - mctx->max_mb_elem_len = 1; - mctx->asub_tops = n; - return REG_NOERROR; -} - -/* Clean the entries which depend on the current input in MCTX. - This function must be invoked when the matcher changes the start index - of the input, or changes the input string. */ - -static void -internal_function -match_ctx_clean (re_match_context_t *mctx) -{ - int st_idx; - for (st_idx = 0; st_idx < mctx->nsub_tops; ++st_idx) - { - int sl_idx; - re_sub_match_top_t *top = mctx->sub_tops[st_idx]; - for (sl_idx = 0; sl_idx < top->nlasts; ++sl_idx) - { - re_sub_match_last_t *last = top->lasts[sl_idx]; - re_free (last->path.array); - re_free (last); - } - re_free (top->lasts); - if (top->path) - { - re_free (top->path->array); - re_free (top->path); - } - free (top); - } - - mctx->nsub_tops = 0; - mctx->nbkref_ents = 0; -} - -/* Free all the memory associated with MCTX. */ - -static void -internal_function -match_ctx_free (re_match_context_t *mctx) -{ - /* First, free all the memory associated with MCTX->SUB_TOPS. */ - match_ctx_clean (mctx); - re_free (mctx->sub_tops); - re_free (mctx->bkref_ents); -} - -/* Add a new backreference entry to MCTX. - Note that we assume that caller never call this function with duplicate - entry, and call with STR_IDX which isn't smaller than any existing entry. -*/ - -static reg_errcode_t -internal_function -match_ctx_add_entry (re_match_context_t *mctx, int node, int str_idx, int from, - int to) -{ - if (mctx->nbkref_ents >= mctx->abkref_ents) - { - struct re_backref_cache_entry* new_entry; - new_entry = re_realloc (mctx->bkref_ents, struct re_backref_cache_entry, - mctx->abkref_ents * 2); - if (BE (new_entry == NULL, 0)) - { - re_free (mctx->bkref_ents); - return REG_ESPACE; - } - mctx->bkref_ents = new_entry; - memset (mctx->bkref_ents + mctx->nbkref_ents, '\0', - sizeof (struct re_backref_cache_entry) * mctx->abkref_ents); - mctx->abkref_ents *= 2; - } - if (mctx->nbkref_ents > 0 - && mctx->bkref_ents[mctx->nbkref_ents - 1].str_idx == str_idx) - mctx->bkref_ents[mctx->nbkref_ents - 1].more = 1; - - mctx->bkref_ents[mctx->nbkref_ents].node = node; - mctx->bkref_ents[mctx->nbkref_ents].str_idx = str_idx; - mctx->bkref_ents[mctx->nbkref_ents].subexp_from = from; - mctx->bkref_ents[mctx->nbkref_ents].subexp_to = to; - - /* This is a cache that saves negative results of check_dst_limits_calc_pos. - If bit N is clear, means that this entry won't epsilon-transition to - an OP_OPEN_SUBEXP or OP_CLOSE_SUBEXP for the N+1-th subexpression. If - it is set, check_dst_limits_calc_pos_1 will recurse and try to find one - such node. - - A backreference does not epsilon-transition unless it is empty, so set - to all zeros if FROM != TO. */ - mctx->bkref_ents[mctx->nbkref_ents].eps_reachable_subexps_map - = (from == to ? ~0 : 0); - - mctx->bkref_ents[mctx->nbkref_ents++].more = 0; - if (mctx->max_mb_elem_len < to - from) - mctx->max_mb_elem_len = to - from; - return REG_NOERROR; -} - -/* Search for the first entry which has the same str_idx, or -1 if none is - found. Note that MCTX->BKREF_ENTS is already sorted by MCTX->STR_IDX. */ - -static int -internal_function -search_cur_bkref_entry (const re_match_context_t *mctx, int str_idx) -{ - int left, right, mid, last; - last = right = mctx->nbkref_ents; - for (left = 0; left < right;) - { - mid = (left + right) / 2; - if (mctx->bkref_ents[mid].str_idx < str_idx) - left = mid + 1; - else - right = mid; - } - if (left < last && mctx->bkref_ents[left].str_idx == str_idx) - return left; - else - return -1; -} - -/* Register the node NODE, whose type is OP_OPEN_SUBEXP, and which matches - at STR_IDX. */ - -static reg_errcode_t -internal_function -match_ctx_add_subtop (re_match_context_t *mctx, int node, int str_idx) -{ -#ifdef DEBUG - assert (mctx->sub_tops != NULL); - assert (mctx->asub_tops > 0); -#endif - if (BE (mctx->nsub_tops == mctx->asub_tops, 0)) - { - int new_asub_tops = mctx->asub_tops * 2; - re_sub_match_top_t **new_array = re_realloc (mctx->sub_tops, - re_sub_match_top_t *, - new_asub_tops); - if (BE (new_array == NULL, 0)) - return REG_ESPACE; - mctx->sub_tops = new_array; - mctx->asub_tops = new_asub_tops; - } - mctx->sub_tops[mctx->nsub_tops] = calloc (1, sizeof (re_sub_match_top_t)); - if (BE (mctx->sub_tops[mctx->nsub_tops] == NULL, 0)) - return REG_ESPACE; - mctx->sub_tops[mctx->nsub_tops]->node = node; - mctx->sub_tops[mctx->nsub_tops++]->str_idx = str_idx; - return REG_NOERROR; -} - -/* Register the node NODE, whose type is OP_CLOSE_SUBEXP, and which matches - at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP. */ - -static re_sub_match_last_t * -internal_function -match_ctx_add_sublast (re_sub_match_top_t *subtop, int node, int str_idx) -{ - re_sub_match_last_t *new_entry; - if (BE (subtop->nlasts == subtop->alasts, 0)) - { - int new_alasts = 2 * subtop->alasts + 1; - re_sub_match_last_t **new_array = re_realloc (subtop->lasts, - re_sub_match_last_t *, - new_alasts); - if (BE (new_array == NULL, 0)) - return NULL; - subtop->lasts = new_array; - subtop->alasts = new_alasts; - } - new_entry = calloc (1, sizeof (re_sub_match_last_t)); - if (BE (new_entry != NULL, 1)) - { - subtop->lasts[subtop->nlasts] = new_entry; - new_entry->node = node; - new_entry->str_idx = str_idx; - ++subtop->nlasts; - } - return new_entry; -} - -static void -internal_function -sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts, - re_dfastate_t **limited_sts, int last_node, int last_str_idx) -{ - sctx->sifted_states = sifted_sts; - sctx->limited_states = limited_sts; - sctx->last_node = last_node; - sctx->last_str_idx = last_str_idx; - re_node_set_init_empty (&sctx->limits); -} diff --git a/deps/zlib/adler32.c b/deps/zlib/adler32.c deleted file mode 100644 index 65ad6a5adc4..00000000000 --- a/deps/zlib/adler32.c +++ /dev/null @@ -1,169 +0,0 @@ -/* adler32.c -- compute the Adler-32 checksum of a data stream - * Copyright (C) 1995-2007 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" - -#define local static - -local uLong adler32_combine_(uLong adler1, uLong adler2, z_off64_t len2); - -#define BASE 65521UL /* largest prime smaller than 65536 */ -#define NMAX 5552 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ - -#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;} -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1); -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2); -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4); -#define DO16(buf) DO8(buf,0); DO8(buf,8); - -/* use NO_DIVIDE if your processor does not do division in hardware */ -#ifdef NO_DIVIDE -# define MOD(a) \ - do { \ - if (a >= (BASE << 16)) a -= (BASE << 16); \ - if (a >= (BASE << 15)) a -= (BASE << 15); \ - if (a >= (BASE << 14)) a -= (BASE << 14); \ - if (a >= (BASE << 13)) a -= (BASE << 13); \ - if (a >= (BASE << 12)) a -= (BASE << 12); \ - if (a >= (BASE << 11)) a -= (BASE << 11); \ - if (a >= (BASE << 10)) a -= (BASE << 10); \ - if (a >= (BASE << 9)) a -= (BASE << 9); \ - if (a >= (BASE << 8)) a -= (BASE << 8); \ - if (a >= (BASE << 7)) a -= (BASE << 7); \ - if (a >= (BASE << 6)) a -= (BASE << 6); \ - if (a >= (BASE << 5)) a -= (BASE << 5); \ - if (a >= (BASE << 4)) a -= (BASE << 4); \ - if (a >= (BASE << 3)) a -= (BASE << 3); \ - if (a >= (BASE << 2)) a -= (BASE << 2); \ - if (a >= (BASE << 1)) a -= (BASE << 1); \ - if (a >= BASE) a -= BASE; \ - } while (0) -# define MOD4(a) \ - do { \ - if (a >= (BASE << 4)) a -= (BASE << 4); \ - if (a >= (BASE << 3)) a -= (BASE << 3); \ - if (a >= (BASE << 2)) a -= (BASE << 2); \ - if (a >= (BASE << 1)) a -= (BASE << 1); \ - if (a >= BASE) a -= BASE; \ - } while (0) -#else -# define MOD(a) a %= BASE -# define MOD4(a) a %= BASE -#endif - -/* ========================================================================= */ -uLong ZEXPORT adler32(adler, buf, len) - uLong adler; - const Bytef *buf; - uInt len; -{ - unsigned long sum2; - unsigned n; - - /* split Adler-32 into component sums */ - sum2 = (adler >> 16) & 0xffff; - adler &= 0xffff; - - /* in case user likes doing a byte at a time, keep it fast */ - if (len == 1) { - adler += buf[0]; - if (adler >= BASE) - adler -= BASE; - sum2 += adler; - if (sum2 >= BASE) - sum2 -= BASE; - return adler | (sum2 << 16); - } - - /* initial Adler-32 value (deferred check for len == 1 speed) */ - if (buf == Z_NULL) - return 1L; - - /* in case short lengths are provided, keep it somewhat fast */ - if (len < 16) { - while (len--) { - adler += *buf++; - sum2 += adler; - } - if (adler >= BASE) - adler -= BASE; - MOD4(sum2); /* only added so many BASE's */ - return adler | (sum2 << 16); - } - - /* do length NMAX blocks -- requires just one modulo operation */ - while (len >= NMAX) { - len -= NMAX; - n = NMAX / 16; /* NMAX is divisible by 16 */ - do { - DO16(buf); /* 16 sums unrolled */ - buf += 16; - } while (--n); - MOD(adler); - MOD(sum2); - } - - /* do remaining bytes (less than NMAX, still just one modulo) */ - if (len) { /* avoid modulos if none remaining */ - while (len >= 16) { - len -= 16; - DO16(buf); - buf += 16; - } - while (len--) { - adler += *buf++; - sum2 += adler; - } - MOD(adler); - MOD(sum2); - } - - /* return recombined sums */ - return adler | (sum2 << 16); -} - -/* ========================================================================= */ -local uLong adler32_combine_(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ - unsigned long sum1; - unsigned long sum2; - unsigned rem; - - /* the derivation of this formula is left as an exercise for the reader */ - rem = (unsigned)(len2 % BASE); - sum1 = adler1 & 0xffff; - sum2 = rem * sum1; - MOD(sum2); - sum1 += (adler2 & 0xffff) + BASE - 1; - sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem; - if (sum1 >= BASE) sum1 -= BASE; - if (sum1 >= BASE) sum1 -= BASE; - if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1); - if (sum2 >= BASE) sum2 -= BASE; - return sum1 | (sum2 << 16); -} - -/* ========================================================================= */ -uLong ZEXPORT adler32_combine(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off_t len2; -{ - return adler32_combine_(adler1, adler2, len2); -} - -uLong ZEXPORT adler32_combine64(adler1, adler2, len2) - uLong adler1; - uLong adler2; - z_off64_t len2; -{ - return adler32_combine_(adler1, adler2, len2); -} diff --git a/deps/zlib/crc32.c b/deps/zlib/crc32.c deleted file mode 100644 index 91be372d224..00000000000 --- a/deps/zlib/crc32.c +++ /dev/null @@ -1,442 +0,0 @@ -/* crc32.c -- compute the CRC-32 of a data stream - * Copyright (C) 1995-2006, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - * - * Thanks to Rodney Brown for his contribution of faster - * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing - * tables for updating the shift register in one step with three exclusive-ors - * instead of four steps with four exclusive-ors. This results in about a - * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3. - */ - -/* @(#) $Id$ */ - -/* - Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore - protection on the static variables used to control the first-use generation - of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should - first call get_crc_table() to initialize the tables before allowing more than - one thread to use crc32(). - */ - -#ifdef MAKECRCH -# include -# ifndef DYNAMIC_CRC_TABLE -# define DYNAMIC_CRC_TABLE -# endif /* !DYNAMIC_CRC_TABLE */ -#endif /* MAKECRCH */ - -#include "zutil.h" /* for STDC and FAR definitions */ - -#define local static - -/* Find a four-byte integer type for crc32_little() and crc32_big(). */ -#ifndef NOBYFOUR -# ifdef STDC /* need ANSI C limits.h to determine sizes */ -# include -# define BYFOUR -# if (UINT_MAX == 0xffffffffUL) - typedef unsigned int u4; -# else -# if (ULONG_MAX == 0xffffffffUL) - typedef unsigned long u4; -# else -# if (USHRT_MAX == 0xffffffffUL) - typedef unsigned short u4; -# else -# undef BYFOUR /* can't find a four-byte integer type! */ -# endif -# endif -# endif -# endif /* STDC */ -#endif /* !NOBYFOUR */ - -/* Definitions for doing the crc four data bytes at a time. */ -#ifdef BYFOUR -# define REV(w) ((((w)>>24)&0xff)+(((w)>>8)&0xff00)+ \ - (((w)&0xff00)<<8)+(((w)&0xff)<<24)) - local unsigned long crc32_little OF((unsigned long, - const unsigned char FAR *, unsigned)); - local unsigned long crc32_big OF((unsigned long, - const unsigned char FAR *, unsigned)); -# define TBLS 8 -#else -# define TBLS 1 -#endif /* BYFOUR */ - -/* Local functions for crc concatenation */ -local unsigned long gf2_matrix_times OF((unsigned long *mat, - unsigned long vec)); -local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat)); -local uLong crc32_combine_(uLong crc1, uLong crc2, z_off64_t len2); - - -#ifdef DYNAMIC_CRC_TABLE - -local volatile int crc_table_empty = 1; -local unsigned long FAR crc_table[TBLS][256]; -local void make_crc_table OF((void)); -#ifdef MAKECRCH - local void write_table OF((FILE *, const unsigned long FAR *)); -#endif /* MAKECRCH */ -/* - Generate tables for a byte-wise 32-bit CRC calculation on the polynomial: - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1. - - Polynomials over GF(2) are represented in binary, one bit per coefficient, - with the lowest powers in the most significant bit. Then adding polynomials - is just exclusive-or, and multiplying a polynomial by x is a right shift by - one. If we call the above polynomial p, and represent a byte as the - polynomial q, also with the lowest power in the most significant bit (so the - byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p, - where a mod b means the remainder after dividing a by b. - - This calculation is done using the shift-register method of multiplying and - taking the remainder. The register is initialized to zero, and for each - incoming bit, x^32 is added mod p to the register if the bit is a one (where - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by - x (which is shifting right by one and adding x^32 mod p if the bit shifted - out is a one). We start with the highest power (least significant bit) of - q and repeat for all eight bits of q. - - The first table is simply the CRC of all possible eight bit values. This is - all the information needed to generate CRCs on data a byte at a time for all - combinations of CRC register values and incoming bytes. The remaining tables - allow for word-at-a-time CRC calculation for both big-endian and little- - endian machines, where a word is four bytes. -*/ -local void make_crc_table() -{ - unsigned long c; - int n, k; - unsigned long poly; /* polynomial exclusive-or pattern */ - /* terms of polynomial defining this crc (except x^32): */ - static volatile int first = 1; /* flag to limit concurrent making */ - static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26}; - - /* See if another task is already doing this (not thread-safe, but better - than nothing -- significantly reduces duration of vulnerability in - case the advice about DYNAMIC_CRC_TABLE is ignored) */ - if (first) { - first = 0; - - /* make exclusive-or pattern from polynomial (0xedb88320UL) */ - poly = 0UL; - for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++) - poly |= 1UL << (31 - p[n]); - - /* generate a crc for every 8-bit value */ - for (n = 0; n < 256; n++) { - c = (unsigned long)n; - for (k = 0; k < 8; k++) - c = c & 1 ? poly ^ (c >> 1) : c >> 1; - crc_table[0][n] = c; - } - -#ifdef BYFOUR - /* generate crc for each value followed by one, two, and three zeros, - and then the byte reversal of those as well as the first table */ - for (n = 0; n < 256; n++) { - c = crc_table[0][n]; - crc_table[4][n] = REV(c); - for (k = 1; k < 4; k++) { - c = crc_table[0][c & 0xff] ^ (c >> 8); - crc_table[k][n] = c; - crc_table[k + 4][n] = REV(c); - } - } -#endif /* BYFOUR */ - - crc_table_empty = 0; - } - else { /* not first */ - /* wait for the other guy to finish (not efficient, but rare) */ - while (crc_table_empty) - ; - } - -#ifdef MAKECRCH - /* write out CRC tables to crc32.h */ - { - FILE *out; - - out = fopen("crc32.h", "w"); - if (out == NULL) return; - fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n"); - fprintf(out, " * Generated automatically by crc32.c\n */\n\n"); - fprintf(out, "local const unsigned long FAR "); - fprintf(out, "crc_table[TBLS][256] =\n{\n {\n"); - write_table(out, crc_table[0]); -# ifdef BYFOUR - fprintf(out, "#ifdef BYFOUR\n"); - for (k = 1; k < 8; k++) { - fprintf(out, " },\n {\n"); - write_table(out, crc_table[k]); - } - fprintf(out, "#endif\n"); -# endif /* BYFOUR */ - fprintf(out, " }\n};\n"); - fclose(out); - } -#endif /* MAKECRCH */ -} - -#ifdef MAKECRCH -local void write_table(out, table) - FILE *out; - const unsigned long FAR *table; -{ - int n; - - for (n = 0; n < 256; n++) - fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n], - n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", ")); -} -#endif /* MAKECRCH */ - -#else /* !DYNAMIC_CRC_TABLE */ -/* ======================================================================== - * Tables of CRC-32s of all single-byte values, made by make_crc_table(). - */ -#include "crc32.h" -#endif /* DYNAMIC_CRC_TABLE */ - -/* ========================================================================= - * This function can be used by asm versions of crc32() - */ -const unsigned long FAR * ZEXPORT get_crc_table() -{ -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - return (const unsigned long FAR *)crc_table; -} - -/* ========================================================================= */ -#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8) -#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1 - -/* ========================================================================= */ -unsigned long ZEXPORT crc32(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - uInt len; -{ - if (buf == Z_NULL) return 0UL; - -#ifdef DYNAMIC_CRC_TABLE - if (crc_table_empty) - make_crc_table(); -#endif /* DYNAMIC_CRC_TABLE */ - -#ifdef BYFOUR - if (sizeof(void *) == sizeof(ptrdiff_t)) { - u4 endian; - - endian = 1; - if (*((unsigned char *)(&endian))) - return crc32_little(crc, buf, len); - else - return crc32_big(crc, buf, len); - } -#endif /* BYFOUR */ - crc = crc ^ 0xffffffffUL; - while (len >= 8) { - DO8; - len -= 8; - } - if (len) do { - DO1; - } while (--len); - return crc ^ 0xffffffffUL; -} - -#ifdef BYFOUR - -/* ========================================================================= */ -#define DOLIT4 c ^= *buf4++; \ - c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \ - crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24] -#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4 - -/* ========================================================================= */ -local unsigned long crc32_little(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - unsigned len; -{ - register u4 c; - register const u4 FAR *buf4; - - c = (u4)crc; - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - len--; - } - - buf4 = (const u4 FAR *)(const void FAR *)buf; - while (len >= 32) { - DOLIT32; - len -= 32; - } - while (len >= 4) { - DOLIT4; - len -= 4; - } - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8); - } while (--len); - c = ~c; - return (unsigned long)c; -} - -/* ========================================================================= */ -#define DOBIG4 c ^= *++buf4; \ - c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \ - crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24] -#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4 - -/* ========================================================================= */ -local unsigned long crc32_big(crc, buf, len) - unsigned long crc; - const unsigned char FAR *buf; - unsigned len; -{ - register u4 c; - register const u4 FAR *buf4; - - c = REV((u4)crc); - c = ~c; - while (len && ((ptrdiff_t)buf & 3)) { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - len--; - } - - buf4 = (const u4 FAR *)(const void FAR *)buf; - buf4--; - while (len >= 32) { - DOBIG32; - len -= 32; - } - while (len >= 4) { - DOBIG4; - len -= 4; - } - buf4++; - buf = (const unsigned char FAR *)buf4; - - if (len) do { - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8); - } while (--len); - c = ~c; - return (unsigned long)(REV(c)); -} - -#endif /* BYFOUR */ - -#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */ - -/* ========================================================================= */ -local unsigned long gf2_matrix_times(mat, vec) - unsigned long *mat; - unsigned long vec; -{ - unsigned long sum; - - sum = 0; - while (vec) { - if (vec & 1) - sum ^= *mat; - vec >>= 1; - mat++; - } - return sum; -} - -/* ========================================================================= */ -local void gf2_matrix_square(square, mat) - unsigned long *square; - unsigned long *mat; -{ - int n; - - for (n = 0; n < GF2_DIM; n++) - square[n] = gf2_matrix_times(mat, mat[n]); -} - -/* ========================================================================= */ -local uLong crc32_combine_(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; -{ - int n; - unsigned long row; - unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */ - unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */ - - /* degenerate case (also disallow negative lengths) */ - if (len2 <= 0) - return crc1; - - /* put operator for one zero bit in odd */ - odd[0] = 0xedb88320UL; /* CRC-32 polynomial */ - row = 1; - for (n = 1; n < GF2_DIM; n++) { - odd[n] = row; - row <<= 1; - } - - /* put operator for two zero bits in even */ - gf2_matrix_square(even, odd); - - /* put operator for four zero bits in odd */ - gf2_matrix_square(odd, even); - - /* apply len2 zeros to crc1 (first square will put the operator for one - zero byte, eight zero bits, in even) */ - do { - /* apply zeros operator for this bit of len2 */ - gf2_matrix_square(even, odd); - if (len2 & 1) - crc1 = gf2_matrix_times(even, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - if (len2 == 0) - break; - - /* another iteration of the loop with odd and even swapped */ - gf2_matrix_square(odd, even); - if (len2 & 1) - crc1 = gf2_matrix_times(odd, crc1); - len2 >>= 1; - - /* if no more bits set, then done */ - } while (len2 != 0); - - /* return combined crc */ - crc1 ^= crc2; - return crc1; -} - -/* ========================================================================= */ -uLong ZEXPORT crc32_combine(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off_t len2; -{ - return crc32_combine_(crc1, crc2, len2); -} - -uLong ZEXPORT crc32_combine64(crc1, crc2, len2) - uLong crc1; - uLong crc2; - z_off64_t len2; -{ - return crc32_combine_(crc1, crc2, len2); -} diff --git a/deps/zlib/crc32.h b/deps/zlib/crc32.h deleted file mode 100644 index 8053b6117c0..00000000000 --- a/deps/zlib/crc32.h +++ /dev/null @@ -1,441 +0,0 @@ -/* crc32.h -- tables for rapid CRC calculation - * Generated automatically by crc32.c - */ - -local const unsigned long FAR crc_table[TBLS][256] = -{ - { - 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL, - 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL, - 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL, - 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL, - 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL, - 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL, - 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL, - 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL, - 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL, - 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL, - 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL, - 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL, - 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL, - 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL, - 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL, - 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL, - 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL, - 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL, - 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL, - 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL, - 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL, - 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL, - 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL, - 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL, - 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL, - 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL, - 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL, - 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL, - 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL, - 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL, - 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL, - 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL, - 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL, - 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL, - 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL, - 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL, - 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL, - 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL, - 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL, - 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL, - 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL, - 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL, - 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL, - 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL, - 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL, - 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL, - 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL, - 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL, - 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL, - 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL, - 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL, - 0x2d02ef8dUL -#ifdef BYFOUR - }, - { - 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL, - 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL, - 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL, - 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL, - 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL, - 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL, - 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL, - 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL, - 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL, - 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL, - 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL, - 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL, - 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL, - 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL, - 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL, - 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL, - 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL, - 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL, - 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL, - 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL, - 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL, - 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL, - 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL, - 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL, - 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL, - 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL, - 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL, - 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL, - 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL, - 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL, - 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL, - 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL, - 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL, - 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL, - 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL, - 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL, - 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL, - 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL, - 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL, - 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL, - 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL, - 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL, - 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL, - 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL, - 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL, - 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL, - 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL, - 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL, - 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL, - 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL, - 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL, - 0x9324fd72UL - }, - { - 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL, - 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL, - 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL, - 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL, - 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL, - 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL, - 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL, - 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL, - 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL, - 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL, - 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL, - 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL, - 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL, - 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL, - 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL, - 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL, - 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL, - 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL, - 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL, - 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL, - 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL, - 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL, - 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL, - 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL, - 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL, - 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL, - 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL, - 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL, - 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL, - 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL, - 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL, - 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL, - 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL, - 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL, - 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL, - 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL, - 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL, - 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL, - 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL, - 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL, - 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL, - 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL, - 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL, - 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL, - 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL, - 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL, - 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL, - 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL, - 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL, - 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL, - 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL, - 0xbe9834edUL - }, - { - 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL, - 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL, - 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL, - 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL, - 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL, - 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL, - 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL, - 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL, - 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL, - 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL, - 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL, - 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL, - 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL, - 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL, - 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL, - 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL, - 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL, - 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL, - 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL, - 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL, - 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL, - 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL, - 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL, - 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL, - 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL, - 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL, - 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL, - 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL, - 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL, - 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL, - 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL, - 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL, - 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL, - 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL, - 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL, - 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL, - 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL, - 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL, - 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL, - 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL, - 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL, - 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL, - 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL, - 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL, - 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL, - 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL, - 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL, - 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL, - 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL, - 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL, - 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL, - 0xde0506f1UL - }, - { - 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL, - 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL, - 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL, - 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL, - 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL, - 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL, - 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL, - 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL, - 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL, - 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL, - 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL, - 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL, - 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL, - 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL, - 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL, - 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL, - 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL, - 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL, - 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL, - 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL, - 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL, - 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL, - 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL, - 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL, - 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL, - 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL, - 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL, - 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL, - 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL, - 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL, - 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL, - 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL, - 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL, - 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL, - 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL, - 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL, - 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL, - 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL, - 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL, - 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL, - 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL, - 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL, - 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL, - 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL, - 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL, - 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL, - 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL, - 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL, - 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL, - 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL, - 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL, - 0x8def022dUL - }, - { - 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL, - 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL, - 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL, - 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL, - 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL, - 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL, - 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL, - 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL, - 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL, - 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL, - 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL, - 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL, - 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL, - 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL, - 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL, - 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL, - 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL, - 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL, - 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL, - 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL, - 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL, - 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL, - 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL, - 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL, - 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL, - 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL, - 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL, - 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL, - 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL, - 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL, - 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL, - 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL, - 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL, - 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL, - 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL, - 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL, - 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL, - 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL, - 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL, - 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL, - 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL, - 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL, - 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL, - 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL, - 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL, - 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL, - 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL, - 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL, - 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL, - 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL, - 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL, - 0x72fd2493UL - }, - { - 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL, - 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL, - 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL, - 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL, - 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL, - 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL, - 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL, - 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL, - 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL, - 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL, - 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL, - 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL, - 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL, - 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL, - 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL, - 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL, - 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL, - 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL, - 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL, - 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL, - 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL, - 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL, - 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL, - 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL, - 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL, - 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL, - 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL, - 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL, - 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL, - 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL, - 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL, - 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL, - 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL, - 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL, - 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL, - 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL, - 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL, - 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL, - 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL, - 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL, - 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL, - 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL, - 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL, - 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL, - 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL, - 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL, - 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL, - 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL, - 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL, - 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL, - 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL, - 0xed3498beUL - }, - { - 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL, - 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL, - 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL, - 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL, - 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL, - 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL, - 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL, - 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL, - 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL, - 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL, - 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL, - 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL, - 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL, - 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL, - 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL, - 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL, - 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL, - 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL, - 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL, - 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL, - 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL, - 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL, - 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL, - 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL, - 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL, - 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL, - 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL, - 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL, - 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL, - 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL, - 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL, - 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL, - 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL, - 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL, - 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL, - 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL, - 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL, - 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL, - 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL, - 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL, - 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL, - 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL, - 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL, - 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL, - 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL, - 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL, - 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL, - 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL, - 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL, - 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL, - 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL, - 0xf10605deUL -#endif - } -}; diff --git a/deps/zlib/deflate.c b/deps/zlib/deflate.c deleted file mode 100644 index 5c4022f3d47..00000000000 --- a/deps/zlib/deflate.c +++ /dev/null @@ -1,1834 +0,0 @@ -/* deflate.c -- compress data using the deflation algorithm - * Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process depends on being able to identify portions - * of the input text which are identical to earlier input (within a - * sliding window trailing behind the input currently being processed). - * - * The most straightforward technique turns out to be the fastest for - * most input files: try all possible matches and select the longest. - * The key feature of this algorithm is that insertions into the string - * dictionary are very simple and thus fast, and deletions are avoided - * completely. Insertions are performed at each input character, whereas - * string matches are performed only when the previous match ends. So it - * is preferable to spend more time in matches to allow very fast string - * insertions and avoid deletions. The matching algorithm for small - * strings is inspired from that of Rabin & Karp. A brute force approach - * is used to find longer strings when a small match has been found. - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze - * (by Leonid Broukhis). - * A previous version of this file used a more sophisticated algorithm - * (by Fiala and Greene) which is guaranteed to run in linear amortized - * time, but has a larger average cost, uses more memory and is patented. - * However the F&G algorithm may be faster for some highly redundant - * files if the parameter max_chain_length (described below) is too large. - * - * ACKNOWLEDGEMENTS - * - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and - * I found it in 'freeze' written by Leonid Broukhis. - * Thanks to many people for bug reports and testing. - * - * REFERENCES - * - * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification". - * Available in http://www.ietf.org/rfc/rfc1951.txt - * - * A description of the Rabin and Karp algorithm is given in the book - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252. - * - * Fiala,E.R., and Greene,D.H. - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595 - * - */ - -/* @(#) $Id$ */ - -#include "deflate.h" - -const char deflate_copyright[] = - " deflate 1.2.5 Copyright 1995-2010 Jean-loup Gailly and Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* =========================================================================== - * Function prototypes. - */ -typedef enum { - need_more, /* block not completed, need more input or more output */ - block_done, /* block flush performed */ - finish_started, /* finish started, need only more output at next deflate */ - finish_done /* finish done, accept no more input or output */ -} block_state; - -typedef block_state (*compress_func) OF((deflate_state *s, int flush)); -/* Compression function. Returns the block state after the call. */ - -local void fill_window OF((deflate_state *s)); -local block_state deflate_stored OF((deflate_state *s, int flush)); -local block_state deflate_fast OF((deflate_state *s, int flush)); -#ifndef FASTEST -local block_state deflate_slow OF((deflate_state *s, int flush)); -#endif -local block_state deflate_rle OF((deflate_state *s, int flush)); -local block_state deflate_huff OF((deflate_state *s, int flush)); -local void lm_init OF((deflate_state *s)); -local void putShortMSB OF((deflate_state *s, uInt b)); -local void flush_pending OF((z_streamp strm)); -local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size)); -#ifdef ASMV - void match_init OF((void)); /* asm code initialization */ - uInt longest_match OF((deflate_state *s, IPos cur_match)); -#else -local uInt longest_match OF((deflate_state *s, IPos cur_match)); -#endif - -#ifdef DEBUG -local void check_match OF((deflate_state *s, IPos start, IPos match, - int length)); -#endif - -/* =========================================================================== - * Local data - */ - -#define NIL 0 -/* Tail of hash chains */ - -#ifndef TOO_FAR -# define TOO_FAR 4096 -#endif -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */ - -/* Values for max_lazy_match, good_match and max_chain_length, depending on - * the desired pack level (0..9). The values given below have been tuned to - * exclude worst case performance for pathological files. Better values may be - * found for specific files. - */ -typedef struct config_s { - ush good_length; /* reduce lazy search above this match length */ - ush max_lazy; /* do not perform lazy search above this match length */ - ush nice_length; /* quit search above this match length */ - ush max_chain; - compress_func func; -} config; - -#ifdef FASTEST -local const config configuration_table[2] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */ -#else -local const config configuration_table[10] = { -/* good lazy nice chain */ -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */ -/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */ -/* 2 */ {4, 5, 16, 8, deflate_fast}, -/* 3 */ {4, 6, 32, 32, deflate_fast}, - -/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */ -/* 5 */ {8, 16, 32, 32, deflate_slow}, -/* 6 */ {8, 16, 128, 128, deflate_slow}, -/* 7 */ {8, 32, 128, 256, deflate_slow}, -/* 8 */ {32, 128, 258, 1024, deflate_slow}, -/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */ -#endif - -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different - * meaning. - */ - -#define EQUAL 0 -/* result of memcmp for equal strings */ - -#ifndef NO_DUMMY_DECL -struct static_tree_desc_s {int dummy;}; /* for buggy compilers */ -#endif - -/* =========================================================================== - * Update a hash value with the given input byte - * IN assertion: all calls to to UPDATE_HASH are made with consecutive - * input characters, so that a running hash key can be computed from the - * previous key instead of complete recalculation each time. - */ -#define UPDATE_HASH(s,h,c) (h = (((h)<hash_shift) ^ (c)) & s->hash_mask) - - -/* =========================================================================== - * Insert string str in the dictionary and set match_head to the previous head - * of the hash chain (the most recent string with same hash key). Return - * the previous length of the hash chain. - * If this file is compiled with -DFASTEST, the compression level is forced - * to 1, and no hash chains are maintained. - * IN assertion: all calls to to INSERT_STRING are made with consecutive - * input characters and the first MIN_MATCH bytes of str are valid - * (except for the last MIN_MATCH-1 bytes of the input file). - */ -#ifdef FASTEST -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#else -#define INSERT_STRING(s, str, match_head) \ - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \ - match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \ - s->head[s->ins_h] = (Pos)(str)) -#endif - -/* =========================================================================== - * Initialize the hash table (avoiding 64K overflow for 16 bit systems). - * prev[] will be initialized on the fly. - */ -#define CLEAR_HASH(s) \ - s->head[s->hash_size-1] = NIL; \ - zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head)); - -/* ========================================================================= */ -int ZEXPORT deflateInit_(strm, level, version, stream_size) - z_streamp strm; - int level; - const char *version; - int stream_size; -{ - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL, - Z_DEFAULT_STRATEGY, version, stream_size); - /* To do: ignore strm->next_in if we use it as window */ -} - -/* ========================================================================= */ -int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy, - version, stream_size) - z_streamp strm; - int level; - int method; - int windowBits; - int memLevel; - int strategy; - const char *version; - int stream_size; -{ - deflate_state *s; - int wrap = 1; - static const char my_version[] = ZLIB_VERSION; - - ushf *overlay; - /* We overlay pending_buf and d_buf+l_buf. This works since the average - * output size for (length,distance) codes is <= 24 bits. - */ - - if (version == Z_NULL || version[0] != my_version[0] || - stream_size != sizeof(z_stream)) { - return Z_VERSION_ERROR; - } - if (strm == Z_NULL) return Z_STREAM_ERROR; - - strm->msg = Z_NULL; - if (strm->zalloc == (alloc_func)0) { - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; - } - if (strm->zfree == (free_func)0) strm->zfree = zcfree; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - - if (windowBits < 0) { /* suppress zlib wrapper */ - wrap = 0; - windowBits = -windowBits; - } -#ifdef GZIP - else if (windowBits > 15) { - wrap = 2; /* write gzip wrapper instead */ - windowBits -= 16; - } -#endif - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED || - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 || - strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */ - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state)); - if (s == Z_NULL) return Z_MEM_ERROR; - strm->state = (struct internal_state FAR *)s; - s->strm = strm; - - s->wrap = wrap; - s->gzhead = Z_NULL; - s->w_bits = windowBits; - s->w_size = 1 << s->w_bits; - s->w_mask = s->w_size - 1; - - s->hash_bits = memLevel + 7; - s->hash_size = 1 << s->hash_bits; - s->hash_mask = s->hash_size - 1; - s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH); - - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte)); - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos)); - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos)); - - s->high_water = 0; /* nothing written to s->window yet */ - - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */ - - overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2); - s->pending_buf = (uchf *) overlay; - s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L); - - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL || - s->pending_buf == Z_NULL) { - s->status = FINISH_STATE; - strm->msg = (char*)ERR_MSG(Z_MEM_ERROR); - deflateEnd (strm); - return Z_MEM_ERROR; - } - s->d_buf = overlay + s->lit_bufsize/sizeof(ush); - s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize; - - s->level = level; - s->strategy = strategy; - s->method = (Byte)method; - - return deflateReset(strm); -} - -/* ========================================================================= */ -int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength) - z_streamp strm; - const Bytef *dictionary; - uInt dictLength; -{ - deflate_state *s; - uInt length = dictLength; - uInt n; - IPos hash_head = 0; - - if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL || - strm->state->wrap == 2 || - (strm->state->wrap == 1 && strm->state->status != INIT_STATE)) - return Z_STREAM_ERROR; - - s = strm->state; - if (s->wrap) - strm->adler = adler32(strm->adler, dictionary, dictLength); - - if (length < MIN_MATCH) return Z_OK; - if (length > s->w_size) { - length = s->w_size; - dictionary += dictLength - length; /* use the tail of the dictionary */ - } - zmemcpy(s->window, dictionary, length); - s->strstart = length; - s->block_start = (long)length; - - /* Insert all strings in the hash table (except for the last two bytes). - * s->lookahead stays null, so s->ins_h will be recomputed at the next - * call of fill_window. - */ - s->ins_h = s->window[0]; - UPDATE_HASH(s, s->ins_h, s->window[1]); - for (n = 0; n <= length - MIN_MATCH; n++) { - INSERT_STRING(s, n, hash_head); - } - if (hash_head) hash_head = 0; /* to make compiler happy */ - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateReset (strm) - z_streamp strm; -{ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) { - return Z_STREAM_ERROR; - } - - strm->total_in = strm->total_out = 0; - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */ - strm->data_type = Z_UNKNOWN; - - s = (deflate_state *)strm->state; - s->pending = 0; - s->pending_out = s->pending_buf; - - if (s->wrap < 0) { - s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */ - } - s->status = s->wrap ? INIT_STATE : BUSY_STATE; - strm->adler = -#ifdef GZIP - s->wrap == 2 ? crc32(0L, Z_NULL, 0) : -#endif - adler32(0L, Z_NULL, 0); - s->last_flush = Z_NO_FLUSH; - - _tr_init(s); - lm_init(s); - - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateSetHeader (strm, head) - z_streamp strm; - gz_headerp head; -{ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - if (strm->state->wrap != 2) return Z_STREAM_ERROR; - strm->state->gzhead = head; - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflatePrime (strm, bits, value) - z_streamp strm; - int bits; - int value; -{ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - strm->state->bi_valid = bits; - strm->state->bi_buf = (ush)(value & ((1 << bits) - 1)); - return Z_OK; -} - -/* ========================================================================= */ -int ZEXPORT deflateParams(strm, level, strategy) - z_streamp strm; - int level; - int strategy; -{ - deflate_state *s; - compress_func func; - int err = Z_OK; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; - -#ifdef FASTEST - if (level != 0) level = 1; -#else - if (level == Z_DEFAULT_COMPRESSION) level = 6; -#endif - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) { - return Z_STREAM_ERROR; - } - func = configuration_table[s->level].func; - - if ((strategy != s->strategy || func != configuration_table[level].func) && - strm->total_in != 0) { - /* Flush the last buffer: */ - err = deflate(strm, Z_BLOCK); - } - if (s->level != level) { - s->level = level; - s->max_lazy_match = configuration_table[level].max_lazy; - s->good_match = configuration_table[level].good_length; - s->nice_match = configuration_table[level].nice_length; - s->max_chain_length = configuration_table[level].max_chain; - } - s->strategy = strategy; - return err; -} - -/* ========================================================================= */ -int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain) - z_streamp strm; - int good_length; - int max_lazy; - int nice_length; - int max_chain; -{ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - s = strm->state; - s->good_match = good_length; - s->max_lazy_match = max_lazy; - s->nice_match = nice_length; - s->max_chain_length = max_chain; - return Z_OK; -} - -/* ========================================================================= - * For the default windowBits of 15 and memLevel of 8, this function returns - * a close to exact, as well as small, upper bound on the compressed size. - * They are coded as constants here for a reason--if the #define's are - * changed, then this function needs to be changed as well. The return - * value for 15 and 8 only works for those exact settings. - * - * For any setting other than those defaults for windowBits and memLevel, - * the value returned is a conservative worst case for the maximum expansion - * resulting from using fixed blocks instead of stored blocks, which deflate - * can emit on compressed data for some combinations of the parameters. - * - * This function could be more sophisticated to provide closer upper bounds for - * every combination of windowBits and memLevel. But even the conservative - * upper bound of about 14% expansion does not seem onerous for output buffer - * allocation. - */ -uLong ZEXPORT deflateBound(strm, sourceLen) - z_streamp strm; - uLong sourceLen; -{ - deflate_state *s; - uLong complen, wraplen; - Bytef *str; - - /* conservative upper bound for compressed data */ - complen = sourceLen + - ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5; - - /* if can't get parameters, return conservative bound plus zlib wrapper */ - if (strm == Z_NULL || strm->state == Z_NULL) - return complen + 6; - - /* compute wrapper length */ - s = strm->state; - switch (s->wrap) { - case 0: /* raw deflate */ - wraplen = 0; - break; - case 1: /* zlib wrapper */ - wraplen = 6 + (s->strstart ? 4 : 0); - break; - case 2: /* gzip wrapper */ - wraplen = 18; - if (s->gzhead != Z_NULL) { /* user-supplied gzip header */ - if (s->gzhead->extra != Z_NULL) - wraplen += 2 + s->gzhead->extra_len; - str = s->gzhead->name; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - str = s->gzhead->comment; - if (str != Z_NULL) - do { - wraplen++; - } while (*str++); - if (s->gzhead->hcrc) - wraplen += 2; - } - break; - default: /* for compiler happiness */ - wraplen = 6; - } - - /* if not default parameters, return conservative bound */ - if (s->w_bits != 15 || s->hash_bits != 8 + 7) - return complen + wraplen; - - /* default settings: return tight bound for that case */ - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + - (sourceLen >> 25) + 13 - 6 + wraplen; -} - -/* ========================================================================= - * Put a short in the pending buffer. The 16-bit value is put in MSB order. - * IN assertion: the stream state is correct and there is enough room in - * pending_buf. - */ -local void putShortMSB (s, b) - deflate_state *s; - uInt b; -{ - put_byte(s, (Byte)(b >> 8)); - put_byte(s, (Byte)(b & 0xff)); -} - -/* ========================================================================= - * Flush as much pending output as possible. All deflate() output goes - * through this function so some applications may wish to modify it - * to avoid allocating a large strm->next_out buffer and copying into it. - * (See also read_buf()). - */ -local void flush_pending(strm) - z_streamp strm; -{ - unsigned len = strm->state->pending; - - if (len > strm->avail_out) len = strm->avail_out; - if (len == 0) return; - - zmemcpy(strm->next_out, strm->state->pending_out, len); - strm->next_out += len; - strm->state->pending_out += len; - strm->total_out += len; - strm->avail_out -= len; - strm->state->pending -= len; - if (strm->state->pending == 0) { - strm->state->pending_out = strm->state->pending_buf; - } -} - -/* ========================================================================= */ -int ZEXPORT deflate (strm, flush) - z_streamp strm; - int flush; -{ - int old_flush; /* value of flush param for previous deflate call */ - deflate_state *s; - - if (strm == Z_NULL || strm->state == Z_NULL || - flush > Z_BLOCK || flush < 0) { - return Z_STREAM_ERROR; - } - s = strm->state; - - if (strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0) || - (s->status == FINISH_STATE && flush != Z_FINISH)) { - ERR_RETURN(strm, Z_STREAM_ERROR); - } - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR); - - s->strm = strm; /* just in case */ - old_flush = s->last_flush; - s->last_flush = flush; - - /* Write the header */ - if (s->status == INIT_STATE) { -#ifdef GZIP - if (s->wrap == 2) { - strm->adler = crc32(0L, Z_NULL, 0); - put_byte(s, 31); - put_byte(s, 139); - put_byte(s, 8); - if (s->gzhead == Z_NULL) { - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, 0); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, OS_CODE); - s->status = BUSY_STATE; - } - else { - put_byte(s, (s->gzhead->text ? 1 : 0) + - (s->gzhead->hcrc ? 2 : 0) + - (s->gzhead->extra == Z_NULL ? 0 : 4) + - (s->gzhead->name == Z_NULL ? 0 : 8) + - (s->gzhead->comment == Z_NULL ? 0 : 16) - ); - put_byte(s, (Byte)(s->gzhead->time & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff)); - put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff)); - put_byte(s, s->level == 9 ? 2 : - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ? - 4 : 0)); - put_byte(s, s->gzhead->os & 0xff); - if (s->gzhead->extra != Z_NULL) { - put_byte(s, s->gzhead->extra_len & 0xff); - put_byte(s, (s->gzhead->extra_len >> 8) & 0xff); - } - if (s->gzhead->hcrc) - strm->adler = crc32(strm->adler, s->pending_buf, - s->pending); - s->gzindex = 0; - s->status = EXTRA_STATE; - } - } - else -#endif - { - uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8; - uInt level_flags; - - if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2) - level_flags = 0; - else if (s->level < 6) - level_flags = 1; - else if (s->level == 6) - level_flags = 2; - else - level_flags = 3; - header |= (level_flags << 6); - if (s->strstart != 0) header |= PRESET_DICT; - header += 31 - (header % 31); - - s->status = BUSY_STATE; - putShortMSB(s, header); - - /* Save the adler32 of the preset dictionary: */ - if (s->strstart != 0) { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - strm->adler = adler32(0L, Z_NULL, 0); - } - } -#ifdef GZIP - if (s->status == EXTRA_STATE) { - if (s->gzhead->extra != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - - while (s->gzindex < (s->gzhead->extra_len & 0xffff)) { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) - break; - } - put_byte(s, s->gzhead->extra[s->gzindex]); - s->gzindex++; - } - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (s->gzindex == s->gzhead->extra_len) { - s->gzindex = 0; - s->status = NAME_STATE; - } - } - else - s->status = NAME_STATE; - } - if (s->status == NAME_STATE) { - if (s->gzhead->name != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - int val; - - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->name[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) { - s->gzindex = 0; - s->status = COMMENT_STATE; - } - } - else - s->status = COMMENT_STATE; - } - if (s->status == COMMENT_STATE) { - if (s->gzhead->comment != Z_NULL) { - uInt beg = s->pending; /* start of bytes to update crc */ - int val; - - do { - if (s->pending == s->pending_buf_size) { - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - flush_pending(strm); - beg = s->pending; - if (s->pending == s->pending_buf_size) { - val = 1; - break; - } - } - val = s->gzhead->comment[s->gzindex++]; - put_byte(s, val); - } while (val != 0); - if (s->gzhead->hcrc && s->pending > beg) - strm->adler = crc32(strm->adler, s->pending_buf + beg, - s->pending - beg); - if (val == 0) - s->status = HCRC_STATE; - } - else - s->status = HCRC_STATE; - } - if (s->status == HCRC_STATE) { - if (s->gzhead->hcrc) { - if (s->pending + 2 > s->pending_buf_size) - flush_pending(strm); - if (s->pending + 2 <= s->pending_buf_size) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - strm->adler = crc32(0L, Z_NULL, 0); - s->status = BUSY_STATE; - } - } - else - s->status = BUSY_STATE; - } -#endif - - /* Flush as much pending output as possible */ - if (s->pending != 0) { - flush_pending(strm); - if (strm->avail_out == 0) { - /* Since avail_out is 0, deflate will be called again with - * more output space, but possibly with both pending and - * avail_in equal to zero. There won't be anything to do, - * but this is not an error situation so make sure we - * return OK instead of BUF_ERROR at next call of deflate: - */ - s->last_flush = -1; - return Z_OK; - } - - /* Make sure there is something to do and avoid duplicate consecutive - * flushes. For repeated and useless calls with Z_FINISH, we keep - * returning Z_STREAM_END instead of Z_BUF_ERROR. - */ - } else if (strm->avail_in == 0 && flush <= old_flush && - flush != Z_FINISH) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* User must not provide more input after the first FINISH: */ - if (s->status == FINISH_STATE && strm->avail_in != 0) { - ERR_RETURN(strm, Z_BUF_ERROR); - } - - /* Start a new block or continue the current one. - */ - if (strm->avail_in != 0 || s->lookahead != 0 || - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) { - block_state bstate; - - bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) : - (s->strategy == Z_RLE ? deflate_rle(s, flush) : - (*(configuration_table[s->level].func))(s, flush)); - - if (bstate == finish_started || bstate == finish_done) { - s->status = FINISH_STATE; - } - if (bstate == need_more || bstate == finish_started) { - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */ - } - return Z_OK; - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call - * of deflate should use the same flush parameter to make sure - * that the flush is complete. So we don't have to output an - * empty block here, this will be done at next call. This also - * ensures that for a very small output buffer, we emit at most - * one empty block. - */ - } - if (bstate == block_done) { - if (flush == Z_PARTIAL_FLUSH) { - _tr_align(s); - } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */ - _tr_stored_block(s, (char*)0, 0L, 0); - /* For a full flush, this empty block will be recognized - * as a special marker by inflate_sync(). - */ - if (flush == Z_FULL_FLUSH) { - CLEAR_HASH(s); /* forget history */ - if (s->lookahead == 0) { - s->strstart = 0; - s->block_start = 0L; - } - } - } - flush_pending(strm); - if (strm->avail_out == 0) { - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */ - return Z_OK; - } - } - } - Assert(strm->avail_out > 0, "bug2"); - - if (flush != Z_FINISH) return Z_OK; - if (s->wrap <= 0) return Z_STREAM_END; - - /* Write the trailer */ -#ifdef GZIP - if (s->wrap == 2) { - put_byte(s, (Byte)(strm->adler & 0xff)); - put_byte(s, (Byte)((strm->adler >> 8) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 16) & 0xff)); - put_byte(s, (Byte)((strm->adler >> 24) & 0xff)); - put_byte(s, (Byte)(strm->total_in & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 8) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 16) & 0xff)); - put_byte(s, (Byte)((strm->total_in >> 24) & 0xff)); - } - else -#endif - { - putShortMSB(s, (uInt)(strm->adler >> 16)); - putShortMSB(s, (uInt)(strm->adler & 0xffff)); - } - flush_pending(strm); - /* If avail_out is zero, the application will call deflate again - * to flush the rest. - */ - if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */ - return s->pending != 0 ? Z_OK : Z_STREAM_END; -} - -/* ========================================================================= */ -int ZEXPORT deflateEnd (strm) - z_streamp strm; -{ - int status; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - - status = strm->state->status; - if (status != INIT_STATE && - status != EXTRA_STATE && - status != NAME_STATE && - status != COMMENT_STATE && - status != HCRC_STATE && - status != BUSY_STATE && - status != FINISH_STATE) { - return Z_STREAM_ERROR; - } - - /* Deallocate in reverse order of allocations: */ - TRY_FREE(strm, strm->state->pending_buf); - TRY_FREE(strm, strm->state->head); - TRY_FREE(strm, strm->state->prev); - TRY_FREE(strm, strm->state->window); - - ZFREE(strm, strm->state); - strm->state = Z_NULL; - - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK; -} - -/* ========================================================================= - * Copy the source state to the destination state. - * To simplify the source, this is not supported for 16-bit MSDOS (which - * doesn't have enough memory anyway to duplicate compression states). - */ -int ZEXPORT deflateCopy (dest, source) - z_streamp dest; - z_streamp source; -{ -#ifdef MAXSEG_64K - return Z_STREAM_ERROR; -#else - deflate_state *ds; - deflate_state *ss; - ushf *overlay; - - - if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) { - return Z_STREAM_ERROR; - } - - ss = source->state; - - zmemcpy(dest, source, sizeof(z_stream)); - - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state)); - if (ds == Z_NULL) return Z_MEM_ERROR; - dest->state = (struct internal_state FAR *) ds; - zmemcpy(ds, ss, sizeof(deflate_state)); - ds->strm = dest; - - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte)); - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos)); - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos)); - overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2); - ds->pending_buf = (uchf *) overlay; - - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL || - ds->pending_buf == Z_NULL) { - deflateEnd (dest); - return Z_MEM_ERROR; - } - /* following zmemcpy do not work for 16-bit MSDOS */ - zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte)); - zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos)); - zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos)); - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size); - - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf); - ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush); - ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize; - - ds->l_desc.dyn_tree = ds->dyn_ltree; - ds->d_desc.dyn_tree = ds->dyn_dtree; - ds->bl_desc.dyn_tree = ds->bl_tree; - - return Z_OK; -#endif /* MAXSEG_64K */ -} - -/* =========================================================================== - * Read a new buffer from the current input stream, update the adler32 - * and total number of bytes read. All deflate() input goes through - * this function so some applications may wish to modify it to avoid - * allocating a large strm->next_in buffer and copying from it. - * (See also flush_pending()). - */ -local int read_buf(strm, buf, size) - z_streamp strm; - Bytef *buf; - unsigned size; -{ - unsigned len = strm->avail_in; - - if (len > size) len = size; - if (len == 0) return 0; - - strm->avail_in -= len; - - if (strm->state->wrap == 1) { - strm->adler = adler32(strm->adler, strm->next_in, len); - } -#ifdef GZIP - else if (strm->state->wrap == 2) { - strm->adler = crc32(strm->adler, strm->next_in, len); - } -#endif - zmemcpy(buf, strm->next_in, len); - strm->next_in += len; - strm->total_in += len; - - return (int)len; -} - -/* =========================================================================== - * Initialize the "longest match" routines for a new zlib stream - */ -local void lm_init (s) - deflate_state *s; -{ - s->window_size = (ulg)2L*s->w_size; - - CLEAR_HASH(s); - - /* Set the default configuration parameters: - */ - s->max_lazy_match = configuration_table[s->level].max_lazy; - s->good_match = configuration_table[s->level].good_length; - s->nice_match = configuration_table[s->level].nice_length; - s->max_chain_length = configuration_table[s->level].max_chain; - - s->strstart = 0; - s->block_start = 0L; - s->lookahead = 0; - s->match_length = s->prev_length = MIN_MATCH-1; - s->match_available = 0; - s->ins_h = 0; -#ifndef FASTEST -#ifdef ASMV - match_init(); /* initialize the asm code */ -#endif -#endif -} - -#ifndef FASTEST -/* =========================================================================== - * Set match_start to the longest match starting at the given string and - * return its length. Matches shorter or equal to prev_length are discarded, - * in which case the result is equal to prev_length and match_start is - * garbage. - * IN assertions: cur_match is the head of the hash chain for the current - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1 - * OUT assertion: the match length is not greater than s->lookahead. - */ -#ifndef ASMV -/* For 80x86 and 680x0, an optimized version will be provided in match.asm or - * match.S. The code will be functionally equivalent. - */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - unsigned chain_length = s->max_chain_length;/* max hash chain length */ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - int best_len = s->prev_length; /* best match length so far */ - int nice_match = s->nice_match; /* stop if match long enough */ - IPos limit = s->strstart > (IPos)MAX_DIST(s) ? - s->strstart - (IPos)MAX_DIST(s) : NIL; - /* Stop when cur_match becomes <= limit. To simplify the code, - * we prevent matches with the string of window index 0. - */ - Posf *prev = s->prev; - uInt wmask = s->w_mask; - -#ifdef UNALIGNED_OK - /* Compare two bytes at a time. Note: this is not always beneficial. - * Try with and without -DUNALIGNED_OK to check. - */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1; - register ush scan_start = *(ushf*)scan; - register ush scan_end = *(ushf*)(scan+best_len-1); -#else - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - register Byte scan_end1 = scan[best_len-1]; - register Byte scan_end = scan[best_len]; -#endif - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - /* Do not waste too much time if we already have a good match: */ - if (s->prev_length >= s->good_match) { - chain_length >>= 2; - } - /* Do not look for matches beyond the end of the input. This is necessary - * to make deflate deterministic. - */ - if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead; - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - do { - Assert(cur_match < s->strstart, "no future"); - match = s->window + cur_match; - - /* Skip to next match if the match length cannot increase - * or if the match length is less than 2. Note that the checks below - * for insufficient lookahead only occur occasionally for performance - * reasons. Therefore uninitialized memory will be accessed, and - * conditional jumps will be made that depend on those values. - * However the length of the match is limited to the lookahead, so - * the output of deflate is not affected by the uninitialized values. - */ -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258) - /* This code assumes sizeof(unsigned short) == 2. Do not use - * UNALIGNED_OK if your compiler uses a different size. - */ - if (*(ushf*)(match+best_len-1) != scan_end || - *(ushf*)match != scan_start) continue; - - /* It is not necessary to compare scan[2] and match[2] since they are - * always equal when the other bytes match, given that the hash keys - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at - * strstart+3, +5, ... up to strstart+257. We check for insufficient - * lookahead only every 4th comparison; the 128th check will be made - * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is - * necessary to put more guard bytes at the end of the window, or - * to check more often for insufficient lookahead. - */ - Assert(scan[2] == match[2], "scan[2]?"); - scan++, match++; - do { - } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - *(ushf*)(scan+=2) == *(ushf*)(match+=2) && - scan < strend); - /* The funny "do {}" generates better code on most compilers */ - - /* Here, scan <= window+strstart+257 */ - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - if (*scan == *match) scan++; - - len = (MAX_MATCH - 1) - (int)(strend-scan); - scan = strend - (MAX_MATCH-1); - -#else /* UNALIGNED_OK */ - - if (match[best_len] != scan_end || - match[best_len-1] != scan_end1 || - *match != *scan || - *++match != scan[1]) continue; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match++; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - scan = strend - MAX_MATCH; - -#endif /* UNALIGNED_OK */ - - if (len > best_len) { - s->match_start = cur_match; - best_len = len; - if (len >= nice_match) break; -#ifdef UNALIGNED_OK - scan_end = *(ushf*)(scan+best_len-1); -#else - scan_end1 = scan[best_len-1]; - scan_end = scan[best_len]; -#endif - } - } while ((cur_match = prev[cur_match & wmask]) > limit - && --chain_length != 0); - - if ((uInt)best_len <= s->lookahead) return (uInt)best_len; - return s->lookahead; -} -#endif /* ASMV */ - -#else /* FASTEST */ - -/* --------------------------------------------------------------------------- - * Optimized version for FASTEST only - */ -local uInt longest_match(s, cur_match) - deflate_state *s; - IPos cur_match; /* current match */ -{ - register Bytef *scan = s->window + s->strstart; /* current string */ - register Bytef *match; /* matched string */ - register int len; /* length of current match */ - register Bytef *strend = s->window + s->strstart + MAX_MATCH; - - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16. - * It is easy to get rid of this optimization if necessary. - */ - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever"); - - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead"); - - Assert(cur_match < s->strstart, "no future"); - - match = s->window + cur_match; - - /* Return failure if the match length is less than 2: - */ - if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1; - - /* The check at best_len-1 can be removed because it will be made - * again later. (This heuristic is not always a win.) - * It is not necessary to compare scan[2] and match[2] since they - * are always equal when the other bytes match, given that - * the hash keys are equal and that HASH_BITS >= 8. - */ - scan += 2, match += 2; - Assert(*scan == *match, "match[2]?"); - - /* We check for insufficient lookahead only every 8th comparison; - * the 256th check will be made at strstart+258. - */ - do { - } while (*++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - *++scan == *++match && *++scan == *++match && - scan < strend); - - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan"); - - len = MAX_MATCH - (int)(strend - scan); - - if (len < MIN_MATCH) return MIN_MATCH - 1; - - s->match_start = cur_match; - return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead; -} - -#endif /* FASTEST */ - -#ifdef DEBUG -/* =========================================================================== - * Check that the match at match_start is indeed a match. - */ -local void check_match(s, start, match, length) - deflate_state *s; - IPos start, match; - int length; -{ - /* check that the match is indeed a match */ - if (zmemcmp(s->window + match, - s->window + start, length) != EQUAL) { - fprintf(stderr, " start %u, match %u, length %d\n", - start, match, length); - do { - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]); - } while (--length != 0); - z_error("invalid match"); - } - if (z_verbose > 1) { - fprintf(stderr,"\\[%d,%d]", start-match, length); - do { putc(s->window[start++], stderr); } while (--length != 0); - } -} -#else -# define check_match(s, start, match, length) -#endif /* DEBUG */ - -/* =========================================================================== - * Fill the window when the lookahead becomes insufficient. - * Updates strstart and lookahead. - * - * IN assertion: lookahead < MIN_LOOKAHEAD - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD - * At least one byte has been read, or avail_in == 0; reads are - * performed for at least two bytes (required for the zip translate_eol - * option -- not supported here). - */ -local void fill_window(s) - deflate_state *s; -{ - register unsigned n, m; - register Posf *p; - unsigned more; /* Amount of free space at the end of the window. */ - uInt wsize = s->w_size; - - do { - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart); - - /* Deal with !@#$% 64K limit: */ - if (sizeof(int) <= 2) { - if (more == 0 && s->strstart == 0 && s->lookahead == 0) { - more = wsize; - - } else if (more == (unsigned)(-1)) { - /* Very unlikely, but possible on 16 bit machine if - * strstart == 0 && lookahead == 1 (input done a byte at time) - */ - more--; - } - } - - /* If the window is almost full and there is insufficient lookahead, - * move the upper half to the lower one to make room in the upper half. - */ - if (s->strstart >= wsize+MAX_DIST(s)) { - - zmemcpy(s->window, s->window+wsize, (unsigned)wsize); - s->match_start -= wsize; - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */ - s->block_start -= (long) wsize; - - /* Slide the hash table (could be avoided with 32 bit values - at the expense of memory usage). We slide even when level == 0 - to keep the hash table consistent if we switch back to level > 0 - later. (Using level 0 permanently is not an optimal usage of - zlib, so we don't care about this pathological case.) - */ - n = s->hash_size; - p = &s->head[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - } while (--n); - - n = wsize; -#ifndef FASTEST - p = &s->prev[n]; - do { - m = *--p; - *p = (Pos)(m >= wsize ? m-wsize : NIL); - /* If n is not on any hash chain, prev[n] is garbage but - * its value will never be used. - */ - } while (--n); -#endif - more += wsize; - } - if (s->strm->avail_in == 0) return; - - /* If there was no sliding: - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 && - * more == window_size - lookahead - strstart - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1) - * => more >= window_size - 2*WSIZE + 2 - * In the BIG_MEM or MMAP case (not yet supported), - * window_size == input_size + MIN_LOOKAHEAD && - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD. - * Otherwise, window_size == 2*WSIZE so more >= 2. - * If there was sliding, more >= WSIZE. So in all cases, more >= 2. - */ - Assert(more >= 2, "more < 2"); - - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more); - s->lookahead += n; - - /* Initialize the hash value now that we have some input: */ - if (s->lookahead >= MIN_MATCH) { - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - } - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage, - * but this is not important since only literal bytes will be emitted. - */ - - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0); - - /* If the WIN_INIT bytes after the end of the current data have never been - * written, then zero those bytes in order to avoid memory check reports of - * the use of uninitialized (or uninitialised as Julian writes) bytes by - * the longest match routines. Update the high water mark for the next - * time through here. WIN_INIT is set to MAX_MATCH since the longest match - * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead. - */ - if (s->high_water < s->window_size) { - ulg curr = s->strstart + (ulg)(s->lookahead); - ulg init; - - if (s->high_water < curr) { - /* Previous high water mark below current data -- zero WIN_INIT - * bytes or up to end of window, whichever is less. - */ - init = s->window_size - curr; - if (init > WIN_INIT) - init = WIN_INIT; - zmemzero(s->window + curr, (unsigned)init); - s->high_water = curr + init; - } - else if (s->high_water < (ulg)curr + WIN_INIT) { - /* High water mark at or above current data, but below current data - * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up - * to end of window, whichever is less. - */ - init = (ulg)curr + WIN_INIT - s->high_water; - if (init > s->window_size - s->high_water) - init = s->window_size - s->high_water; - zmemzero(s->window + s->high_water, (unsigned)init); - s->high_water += init; - } - } -} - -/* =========================================================================== - * Flush the current block, with given end-of-file flag. - * IN assertion: strstart is set to the end of the current match. - */ -#define FLUSH_BLOCK_ONLY(s, last) { \ - _tr_flush_block(s, (s->block_start >= 0L ? \ - (charf *)&s->window[(unsigned)s->block_start] : \ - (charf *)Z_NULL), \ - (ulg)((long)s->strstart - s->block_start), \ - (last)); \ - s->block_start = s->strstart; \ - flush_pending(s->strm); \ - Tracev((stderr,"[FLUSH]")); \ -} - -/* Same but force premature exit if necessary. */ -#define FLUSH_BLOCK(s, last) { \ - FLUSH_BLOCK_ONLY(s, last); \ - if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \ -} - -/* =========================================================================== - * Copy without compression as much as possible from the input stream, return - * the current block state. - * This function does not insert new strings in the dictionary since - * uncompressible data is probably not useful. This function is used - * only for the level=0 compression option. - * NOTE: this function should be optimized to avoid extra copying from - * window to pending_buf. - */ -local block_state deflate_stored(s, flush) - deflate_state *s; - int flush; -{ - /* Stored blocks are limited to 0xffff bytes, pending_buf is limited - * to pending_buf_size, and each stored block has a 5 byte header: - */ - ulg max_block_size = 0xffff; - ulg max_start; - - if (max_block_size > s->pending_buf_size - 5) { - max_block_size = s->pending_buf_size - 5; - } - - /* Copy as much as possible from input to output: */ - for (;;) { - /* Fill the window as much as possible: */ - if (s->lookahead <= 1) { - - Assert(s->strstart < s->w_size+MAX_DIST(s) || - s->block_start >= (long)s->w_size, "slide too late"); - - fill_window(s); - if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more; - - if (s->lookahead == 0) break; /* flush the current block */ - } - Assert(s->block_start >= 0L, "block gone"); - - s->strstart += s->lookahead; - s->lookahead = 0; - - /* Emit a stored block if pending_buf will be full: */ - max_start = s->block_start + max_block_size; - if (s->strstart == 0 || (ulg)s->strstart >= max_start) { - /* strstart == 0 is possible when wraparound on 16-bit machine */ - s->lookahead = (uInt)(s->strstart - max_start); - s->strstart = (uInt)max_start; - FLUSH_BLOCK(s, 0); - } - /* Flush if we may have to slide, otherwise block_start may become - * negative and the data will be gone: - */ - if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) { - FLUSH_BLOCK(s, 0); - } - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -/* =========================================================================== - * Compress as much as possible from the input stream, return the current - * block state. - * This function does not perform lazy evaluation of matches and inserts - * new strings in the dictionary only for unmatched strings or for short - * matches. It is used only for the fast compression options. - */ -local block_state deflate_fast(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head; /* head of the hash chain */ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - * At this point we have always match_length < MIN_MATCH - */ - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ - } - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->match_start, s->match_length); - - _tr_tally_dist(s, s->strstart - s->match_start, - s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - - /* Insert new strings in the hash table only if the match length - * is not too large. This saves time but degrades compression. - */ -#ifndef FASTEST - if (s->match_length <= s->max_insert_length && - s->lookahead >= MIN_MATCH) { - s->match_length--; /* string at strstart already in table */ - do { - s->strstart++; - INSERT_STRING(s, s->strstart, hash_head); - /* strstart never exceeds WSIZE-MAX_MATCH, so there are - * always MIN_MATCH bytes ahead. - */ - } while (--s->match_length != 0); - s->strstart++; - } else -#endif - { - s->strstart += s->match_length; - s->match_length = 0; - s->ins_h = s->window[s->strstart]; - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]); -#if MIN_MATCH != 3 - Call UPDATE_HASH() MIN_MATCH-3 more times -#endif - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not - * matter since it will be recomputed at next deflate call. - */ - } - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -#ifndef FASTEST -/* =========================================================================== - * Same as above, but achieves better compression. We use a lazy - * evaluation for matches: a match is finally adopted only if there is - * no better match at the next window position. - */ -local block_state deflate_slow(s, flush) - deflate_state *s; - int flush; -{ - IPos hash_head; /* head of hash chain */ - int bflush; /* set if current block must be flushed */ - - /* Process the input block. */ - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the next match, plus MIN_MATCH bytes to insert the - * string following the next match. - */ - if (s->lookahead < MIN_LOOKAHEAD) { - fill_window(s); - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* Insert the string window[strstart .. strstart+2] in the - * dictionary, and set hash_head to the head of the hash chain: - */ - hash_head = NIL; - if (s->lookahead >= MIN_MATCH) { - INSERT_STRING(s, s->strstart, hash_head); - } - - /* Find the longest match, discarding those <= prev_length. - */ - s->prev_length = s->match_length, s->prev_match = s->match_start; - s->match_length = MIN_MATCH-1; - - if (hash_head != NIL && s->prev_length < s->max_lazy_match && - s->strstart - hash_head <= MAX_DIST(s)) { - /* To simplify the code, we prevent matches with the string - * of window index 0 (in particular we have to avoid a match - * of the string with itself at the start of the input file). - */ - s->match_length = longest_match (s, hash_head); - /* longest_match() sets match_start */ - - if (s->match_length <= 5 && (s->strategy == Z_FILTERED -#if TOO_FAR <= 32767 - || (s->match_length == MIN_MATCH && - s->strstart - s->match_start > TOO_FAR) -#endif - )) { - - /* If prev_match is also MIN_MATCH, match_start is garbage - * but we will ignore the current match anyway. - */ - s->match_length = MIN_MATCH-1; - } - } - /* If there was a match at the previous step and the current - * match is not better, output the previous match: - */ - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) { - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH; - /* Do not insert strings in hash table beyond this. */ - - check_match(s, s->strstart-1, s->prev_match, s->prev_length); - - _tr_tally_dist(s, s->strstart -1 - s->prev_match, - s->prev_length - MIN_MATCH, bflush); - - /* Insert in hash table all strings up to the end of the match. - * strstart-1 and strstart are already inserted. If there is not - * enough lookahead, the last two strings are not inserted in - * the hash table. - */ - s->lookahead -= s->prev_length-1; - s->prev_length -= 2; - do { - if (++s->strstart <= max_insert) { - INSERT_STRING(s, s->strstart, hash_head); - } - } while (--s->prev_length != 0); - s->match_available = 0; - s->match_length = MIN_MATCH-1; - s->strstart++; - - if (bflush) FLUSH_BLOCK(s, 0); - - } else if (s->match_available) { - /* If there was no match at the previous position, output a - * single literal. If there was a match but the current match - * is longer, truncate the previous match to a single literal. - */ - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - if (bflush) { - FLUSH_BLOCK_ONLY(s, 0); - } - s->strstart++; - s->lookahead--; - if (s->strm->avail_out == 0) return need_more; - } else { - /* There is no previous match to compare with, wait for - * the next step to decide. - */ - s->match_available = 1; - s->strstart++; - s->lookahead--; - } - } - Assert (flush != Z_NO_FLUSH, "no flush?"); - if (s->match_available) { - Tracevv((stderr,"%c", s->window[s->strstart-1])); - _tr_tally_lit(s, s->window[s->strstart-1], bflush); - s->match_available = 0; - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} -#endif /* FASTEST */ - -/* =========================================================================== - * For Z_RLE, simply look for runs of bytes, generate matches only of distance - * one. Do not maintain a hash table. (It will be regenerated if this run of - * deflate switches away from Z_RLE.) - */ -local block_state deflate_rle(s, flush) - deflate_state *s; - int flush; -{ - int bflush; /* set if current block must be flushed */ - uInt prev; /* byte at distance one to match */ - Bytef *scan, *strend; /* scan goes up to strend for length of run */ - - for (;;) { - /* Make sure that we always have enough lookahead, except - * at the end of the input file. We need MAX_MATCH bytes - * for the longest encodable run. - */ - if (s->lookahead < MAX_MATCH) { - fill_window(s); - if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) { - return need_more; - } - if (s->lookahead == 0) break; /* flush the current block */ - } - - /* See how many times the previous byte repeats */ - s->match_length = 0; - if (s->lookahead >= MIN_MATCH && s->strstart > 0) { - scan = s->window + s->strstart - 1; - prev = *scan; - if (prev == *++scan && prev == *++scan && prev == *++scan) { - strend = s->window + s->strstart + MAX_MATCH; - do { - } while (prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - prev == *++scan && prev == *++scan && - scan < strend); - s->match_length = MAX_MATCH - (int)(strend - scan); - if (s->match_length > s->lookahead) - s->match_length = s->lookahead; - } - } - - /* Emit match if have run of MIN_MATCH or longer, else emit literal */ - if (s->match_length >= MIN_MATCH) { - check_match(s, s->strstart, s->strstart - 1, s->match_length); - - _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush); - - s->lookahead -= s->match_length; - s->strstart += s->match_length; - s->match_length = 0; - } else { - /* No match, output a literal byte */ - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - } - if (bflush) FLUSH_BLOCK(s, 0); - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} - -/* =========================================================================== - * For Z_HUFFMAN_ONLY, do not look for matches. Do not maintain a hash table. - * (It will be regenerated if this run of deflate switches away from Huffman.) - */ -local block_state deflate_huff(s, flush) - deflate_state *s; - int flush; -{ - int bflush; /* set if current block must be flushed */ - - for (;;) { - /* Make sure that we have a literal to write. */ - if (s->lookahead == 0) { - fill_window(s); - if (s->lookahead == 0) { - if (flush == Z_NO_FLUSH) - return need_more; - break; /* flush the current block */ - } - } - - /* Output a literal byte */ - s->match_length = 0; - Tracevv((stderr,"%c", s->window[s->strstart])); - _tr_tally_lit (s, s->window[s->strstart], bflush); - s->lookahead--; - s->strstart++; - if (bflush) FLUSH_BLOCK(s, 0); - } - FLUSH_BLOCK(s, flush == Z_FINISH); - return flush == Z_FINISH ? finish_done : block_done; -} diff --git a/deps/zlib/deflate.h b/deps/zlib/deflate.h deleted file mode 100644 index d7d26f8a96c..00000000000 --- a/deps/zlib/deflate.h +++ /dev/null @@ -1,342 +0,0 @@ -/* deflate.h -- internal compression state - * Copyright (C) 1995-2010 Jean-loup Gailly - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef DEFLATE_H -#define DEFLATE_H - -#include "zutil.h" - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer creation by deflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip encoding - should be left enabled. */ -#ifndef NO_GZIP -# define GZIP -#endif - -/* =========================================================================== - * Internal compression state. - */ - -#define LENGTH_CODES 29 -/* number of length codes, not counting the special END_BLOCK code */ - -#define LITERALS 256 -/* number of literal bytes 0..255 */ - -#define L_CODES (LITERALS+1+LENGTH_CODES) -/* number of Literal or Length codes, including the END_BLOCK code */ - -#define D_CODES 30 -/* number of distance codes */ - -#define BL_CODES 19 -/* number of codes used to transfer the bit lengths */ - -#define HEAP_SIZE (2*L_CODES+1) -/* maximum heap size */ - -#define MAX_BITS 15 -/* All codes must not exceed MAX_BITS bits */ - -#define INIT_STATE 42 -#define EXTRA_STATE 69 -#define NAME_STATE 73 -#define COMMENT_STATE 91 -#define HCRC_STATE 103 -#define BUSY_STATE 113 -#define FINISH_STATE 666 -/* Stream status */ - - -/* Data structure describing a single value and its code string. */ -typedef struct ct_data_s { - union { - ush freq; /* frequency count */ - ush code; /* bit string */ - } fc; - union { - ush dad; /* father node in Huffman tree */ - ush len; /* length of bit string */ - } dl; -} FAR ct_data; - -#define Freq fc.freq -#define Code fc.code -#define Dad dl.dad -#define Len dl.len - -typedef struct static_tree_desc_s static_tree_desc; - -typedef struct tree_desc_s { - ct_data *dyn_tree; /* the dynamic tree */ - int max_code; /* largest code with non zero frequency */ - static_tree_desc *stat_desc; /* the corresponding static tree */ -} FAR tree_desc; - -typedef ush Pos; -typedef Pos FAR Posf; -typedef unsigned IPos; - -/* A Pos is an index in the character window. We use short instead of int to - * save space in the various tables. IPos is used only for parameter passing. - */ - -typedef struct internal_state { - z_streamp strm; /* pointer back to this zlib stream */ - int status; /* as the name implies */ - Bytef *pending_buf; /* output still pending */ - ulg pending_buf_size; /* size of pending_buf */ - Bytef *pending_out; /* next pending byte to output to the stream */ - uInt pending; /* nb of bytes in the pending buffer */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - gz_headerp gzhead; /* gzip header information to write */ - uInt gzindex; /* where in extra, name, or comment */ - Byte method; /* STORED (for zip only) or DEFLATED */ - int last_flush; /* value of flush param for previous deflate call */ - - /* used by deflate.c: */ - - uInt w_size; /* LZ77 window size (32K by default) */ - uInt w_bits; /* log2(w_size) (8..16) */ - uInt w_mask; /* w_size - 1 */ - - Bytef *window; - /* Sliding window. Input bytes are read into the second half of the window, - * and move to the first half later to keep a dictionary of at least wSize - * bytes. With this organization, matches are limited to a distance of - * wSize-MAX_MATCH bytes, but this ensures that IO is always - * performed with a length multiple of the block size. Also, it limits - * the window size to 64K, which is quite useful on MSDOS. - * To do: use the user input buffer as sliding window. - */ - - ulg window_size; - /* Actual size of window: 2*wSize, except when the user input buffer - * is directly used as sliding window. - */ - - Posf *prev; - /* Link to older string with same hash index. To limit the size of this - * array to 64K, this link is maintained only for the last 32K strings. - * An index in this array is thus a window index modulo 32K. - */ - - Posf *head; /* Heads of the hash chains or NIL. */ - - uInt ins_h; /* hash index of string to be inserted */ - uInt hash_size; /* number of elements in hash table */ - uInt hash_bits; /* log2(hash_size) */ - uInt hash_mask; /* hash_size-1 */ - - uInt hash_shift; - /* Number of bits by which ins_h must be shifted at each input - * step. It must be such that after MIN_MATCH steps, the oldest - * byte no longer takes part in the hash key, that is: - * hash_shift * MIN_MATCH >= hash_bits - */ - - long block_start; - /* Window position at the beginning of the current output block. Gets - * negative when the window is moved backwards. - */ - - uInt match_length; /* length of best match */ - IPos prev_match; /* previous match */ - int match_available; /* set if previous match exists */ - uInt strstart; /* start of string to insert */ - uInt match_start; /* start of matching string */ - uInt lookahead; /* number of valid bytes ahead in window */ - - uInt prev_length; - /* Length of the best match at previous step. Matches not greater than this - * are discarded. This is used in the lazy match evaluation. - */ - - uInt max_chain_length; - /* To speed up deflation, hash chains are never searched beyond this - * length. A higher limit improves compression ratio but degrades the - * speed. - */ - - uInt max_lazy_match; - /* Attempt to find a better match only when the current match is strictly - * smaller than this value. This mechanism is used only for compression - * levels >= 4. - */ -# define max_insert_length max_lazy_match - /* Insert new strings in the hash table only if the match length is not - * greater than this length. This saves time but degrades compression. - * max_insert_length is used only for compression levels <= 3. - */ - - int level; /* compression level (1..9) */ - int strategy; /* favor or force Huffman coding*/ - - uInt good_match; - /* Use a faster search when the previous match is longer than this */ - - int nice_match; /* Stop searching when current match exceeds this */ - - /* used by trees.c: */ - /* Didn't use ct_data typedef below to supress compiler warning */ - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */ - struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */ - struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */ - - struct tree_desc_s l_desc; /* desc. for literal tree */ - struct tree_desc_s d_desc; /* desc. for distance tree */ - struct tree_desc_s bl_desc; /* desc. for bit length tree */ - - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */ - int heap_len; /* number of elements in the heap */ - int heap_max; /* element of largest frequency */ - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used. - * The same heap array is used to build all trees. - */ - - uch depth[2*L_CODES+1]; - /* Depth of each subtree used as tie breaker for trees of equal frequency - */ - - uchf *l_buf; /* buffer for literals or lengths */ - - uInt lit_bufsize; - /* Size of match buffer for literals/lengths. There are 4 reasons for - * limiting lit_bufsize to 64K: - * - frequencies can be kept in 16 bit counters - * - if compression is not successful for the first block, all input - * data is still in the window so we can still emit a stored block even - * when input comes from standard input. (This can also be done for - * all blocks if lit_bufsize is not greater than 32K.) - * - if compression is not successful for a file smaller than 64K, we can - * even emit a stored file instead of a stored block (saving 5 bytes). - * This is applicable only for zip (not gzip or zlib). - * - creating new Huffman trees less frequently may not provide fast - * adaptation to changes in the input data statistics. (Take for - * example a binary file with poorly compressible code followed by - * a highly compressible string table.) Smaller buffer sizes give - * fast adaptation but have of course the overhead of transmitting - * trees more frequently. - * - I can't count above 4 - */ - - uInt last_lit; /* running index in l_buf */ - - ushf *d_buf; - /* Buffer for distances. To simplify the code, d_buf and l_buf have - * the same number of elements. To use different lengths, an extra flag - * array would be necessary. - */ - - ulg opt_len; /* bit length of current block with optimal trees */ - ulg static_len; /* bit length of current block with static trees */ - uInt matches; /* number of string matches in current block */ - int last_eob_len; /* bit length of EOB code for last block */ - -#ifdef DEBUG - ulg compressed_len; /* total bit length of compressed file mod 2^32 */ - ulg bits_sent; /* bit length of compressed data sent mod 2^32 */ -#endif - - ush bi_buf; - /* Output buffer. bits are inserted starting at the bottom (least - * significant bits). - */ - int bi_valid; - /* Number of valid bits in bi_buf. All bits above the last valid bit - * are always zero. - */ - - ulg high_water; - /* High water mark offset in window for initialized bytes -- bytes above - * this are set to zero in order to avoid memory check warnings when - * longest match routines access bytes past the input. This is then - * updated to the new high water mark. - */ - -} FAR deflate_state; - -/* Output a byte on the stream. - * IN assertion: there is enough room in pending_buf. - */ -#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);} - - -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1) -/* Minimum amount of lookahead, except at the end of the input file. - * See deflate.c for comments about the MIN_MATCH+1. - */ - -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD) -/* In order to simplify the code, particularly on 16 bit machines, match - * distances are limited to MAX_DIST instead of WSIZE. - */ - -#define WIN_INIT MAX_MATCH -/* Number of bytes after end of data in window to initialize in order to avoid - memory checker errors from longest match routines */ - - /* in trees.c */ -void ZLIB_INTERNAL _tr_init OF((deflate_state *s)); -int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc)); -void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); -void ZLIB_INTERNAL _tr_align OF((deflate_state *s)); -void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf, - ulg stored_len, int last)); - -#define d_code(dist) \ - ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)]) -/* Mapping from a distance to a distance code. dist is the distance - 1 and - * must not have side effects. _dist_code[256] and _dist_code[257] are never - * used. - */ - -#ifndef DEBUG -/* Inline versions of _tr_tally for speed: */ - -#if defined(GEN_TREES_H) || !defined(STDC) - extern uch ZLIB_INTERNAL _length_code[]; - extern uch ZLIB_INTERNAL _dist_code[]; -#else - extern const uch ZLIB_INTERNAL _length_code[]; - extern const uch ZLIB_INTERNAL _dist_code[]; -#endif - -# define _tr_tally_lit(s, c, flush) \ - { uch cc = (uch)(c); \ - s->d_buf[s->last_lit] = 0; \ - s->l_buf[s->last_lit++] = cc; \ - s->dyn_ltree[cc].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -# define _tr_tally_dist(s, distance, length, flush) \ - { uch len = (uch)(length); \ - ush dist = (ush)(distance); \ - s->d_buf[s->last_lit] = dist; \ - s->l_buf[s->last_lit++] = len; \ - dist--; \ - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \ - s->dyn_dtree[d_code(dist)].Freq++; \ - flush = (s->last_lit == s->lit_bufsize-1); \ - } -#else -# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c) -# define _tr_tally_dist(s, distance, length, flush) \ - flush = _tr_tally(s, distance, length) -#endif - -#endif /* DEFLATE_H */ diff --git a/deps/zlib/inffast.c b/deps/zlib/inffast.c deleted file mode 100644 index 2f1d60b43b8..00000000000 --- a/deps/zlib/inffast.c +++ /dev/null @@ -1,340 +0,0 @@ -/* inffast.c -- fast decoding - * Copyright (C) 1995-2008, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifndef ASMINF - -/* Allow machine dependent optimization for post-increment or pre-increment. - Based on testing to date, - Pre-increment preferred for: - - PowerPC G3 (Adler) - - MIPS R5000 (Randers-Pehrson) - Post-increment preferred for: - - none - No measurable difference: - - Pentium III (Anderson) - - M68060 (Nikl) - */ -#ifdef POSTINC -# define OFF 0 -# define PUP(a) *(a)++ -#else -# define OFF 1 -# define PUP(a) *++(a) -#endif - -/* - Decode literal, length, and distance codes and write out the resulting - literal and match bytes until either not enough input or output is - available, an end-of-block is encountered, or a data error is encountered. - When large enough input and output buffers are supplied to inflate(), for - example, a 16K input buffer and a 64K output buffer, more than 95% of the - inflate execution time is spent in this routine. - - Entry assumptions: - - state->mode == LEN - strm->avail_in >= 6 - strm->avail_out >= 258 - start >= strm->avail_out - state->bits < 8 - - On return, state->mode is one of: - - LEN -- ran out of enough output space or enough available input - TYPE -- reached end of block code, inflate() to interpret next block - BAD -- error in block data - - Notes: - - - The maximum input bits used by a length/distance pair is 15 bits for the - length code, 5 bits for the length extra, 15 bits for the distance code, - and 13 bits for the distance extra. This totals 48 bits, or six bytes. - Therefore if strm->avail_in >= 6, then there is enough input to avoid - checking for available input while decoding. - - - The maximum bytes that a single length/distance pair can output is 258 - bytes, which is the maximum length that can be coded. inflate_fast() - requires strm->avail_out >= 258 for each loop to avoid checking for - output space. - */ -void ZLIB_INTERNAL inflate_fast(strm, start) -z_streamp strm; -unsigned start; /* inflate()'s starting value for strm->avail_out */ -{ - struct inflate_state FAR *state; - unsigned char FAR *in; /* local strm->next_in */ - unsigned char FAR *last; /* while in < last, enough input available */ - unsigned char FAR *out; /* local strm->next_out */ - unsigned char FAR *beg; /* inflate()'s initial strm->next_out */ - unsigned char FAR *end; /* while out < end, enough space available */ -#ifdef INFLATE_STRICT - unsigned dmax; /* maximum distance from zlib header */ -#endif - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */ - unsigned long hold; /* local strm->hold */ - unsigned bits; /* local strm->bits */ - code const FAR *lcode; /* local strm->lencode */ - code const FAR *dcode; /* local strm->distcode */ - unsigned lmask; /* mask for first level of length codes */ - unsigned dmask; /* mask for first level of distance codes */ - code here; /* retrieved table entry */ - unsigned op; /* code bits, operation, extra bits, or */ - /* window position, window bytes to copy */ - unsigned len; /* match length, unused bytes */ - unsigned dist; /* match distance */ - unsigned char FAR *from; /* where to copy match from */ - - /* copy state to local variables */ - state = (struct inflate_state FAR *)strm->state; - in = strm->next_in - OFF; - last = in + (strm->avail_in - 5); - out = strm->next_out - OFF; - beg = out - (start - strm->avail_out); - end = out + (strm->avail_out - 257); -#ifdef INFLATE_STRICT - dmax = state->dmax; -#endif - wsize = state->wsize; - whave = state->whave; - wnext = state->wnext; - window = state->window; - hold = state->hold; - bits = state->bits; - lcode = state->lencode; - dcode = state->distcode; - lmask = (1U << state->lenbits) - 1; - dmask = (1U << state->distbits) - 1; - - /* decode literals and length/distances until end-of-block or not enough - input data or output space */ - do { - if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - here = lcode[hold & lmask]; - dolen: - op = (unsigned)(here.bits); - hold >>= op; - bits -= op; - op = (unsigned)(here.op); - if (op == 0) { /* literal */ - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - PUP(out) = (unsigned char)(here.val); - } - else if (op & 16) { /* length base */ - len = (unsigned)(here.val); - op &= 15; /* number of extra bits */ - if (op) { - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - len += (unsigned)hold & ((1U << op) - 1); - hold >>= op; - bits -= op; - } - Tracevv((stderr, "inflate: length %u\n", len)); - if (bits < 15) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - here = dcode[hold & dmask]; - dodist: - op = (unsigned)(here.bits); - hold >>= op; - bits -= op; - op = (unsigned)(here.op); - if (op & 16) { /* distance base */ - dist = (unsigned)(here.val); - op &= 15; /* number of extra bits */ - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - if (bits < op) { - hold += (unsigned long)(PUP(in)) << bits; - bits += 8; - } - } - dist += (unsigned)hold & ((1U << op) - 1); -#ifdef INFLATE_STRICT - if (dist > dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - hold >>= op; - bits -= op; - Tracevv((stderr, "inflate: distance %u\n", dist)); - op = (unsigned)(out - beg); /* max distance in output */ - if (dist > op) { /* see if copy from window */ - op = dist - op; /* distance back in window */ - if (op > whave) { - if (state->sane) { - strm->msg = - (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - if (len <= op - whave) { - do { - PUP(out) = 0; - } while (--len); - continue; - } - len -= op - whave; - do { - PUP(out) = 0; - } while (--op > whave); - if (op == 0) { - from = out - dist; - do { - PUP(out) = PUP(from); - } while (--len); - continue; - } -#endif - } - from = window - OFF; - if (wnext == 0) { /* very common case */ - from += wsize - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - else if (wnext < op) { /* wrap around window */ - from += wsize + wnext - op; - op -= wnext; - if (op < len) { /* some from end of window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = window - OFF; - if (wnext < len) { /* some from start of window */ - op = wnext; - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - } - else { /* contiguous in window */ - from += wnext - op; - if (op < len) { /* some from window */ - len -= op; - do { - PUP(out) = PUP(from); - } while (--op); - from = out - dist; /* rest from output */ - } - } - while (len > 2) { - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } - else { - from = out - dist; /* copy direct from output */ - do { /* minimum length is three */ - PUP(out) = PUP(from); - PUP(out) = PUP(from); - PUP(out) = PUP(from); - len -= 3; - } while (len > 2); - if (len) { - PUP(out) = PUP(from); - if (len > 1) - PUP(out) = PUP(from); - } - } - } - else if ((op & 64) == 0) { /* 2nd level distance code */ - here = dcode[here.val + (hold & ((1U << op) - 1))]; - goto dodist; - } - else { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - } - else if ((op & 64) == 0) { /* 2nd level length code */ - here = lcode[here.val + (hold & ((1U << op) - 1))]; - goto dolen; - } - else if (op & 32) { /* end-of-block */ - Tracevv((stderr, "inflate: end of block\n")); - state->mode = TYPE; - break; - } - else { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - } while (in < last && out < end); - - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */ - len = bits >> 3; - in -= len; - bits -= len << 3; - hold &= (1U << bits) - 1; - - /* update state and return */ - strm->next_in = in + OFF; - strm->next_out = out + OFF; - strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last)); - strm->avail_out = (unsigned)(out < end ? - 257 + (end - out) : 257 - (out - end)); - state->hold = hold; - state->bits = bits; - return; -} - -/* - inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe): - - Using bit fields for code structure - - Different op definition to avoid & for extra bits (do & for table bits) - - Three separate decoding do-loops for direct, window, and wnext == 0 - - Special case for distance > 1 copies to do overlapped load and store copy - - Explicit branch predictions (based on measured branch probabilities) - - Deferring match copy and interspersed it with decoding subsequent codes - - Swapping literal/length else - - Swapping window/direct else - - Larger unrolled copy loops (three is about right) - - Moving len -= 3 statement into middle of loop - */ - -#endif /* !ASMINF */ diff --git a/deps/zlib/inffast.h b/deps/zlib/inffast.h deleted file mode 100644 index e5c1aa4ca8c..00000000000 --- a/deps/zlib/inffast.h +++ /dev/null @@ -1,11 +0,0 @@ -/* inffast.h -- header to use inffast.c - * Copyright (C) 1995-2003, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start)); diff --git a/deps/zlib/inffixed.h b/deps/zlib/inffixed.h deleted file mode 100644 index 75ed4b5978d..00000000000 --- a/deps/zlib/inffixed.h +++ /dev/null @@ -1,94 +0,0 @@ - /* inffixed.h -- table for decoding fixed codes - * Generated automatically by makefixed(). - */ - - /* WARNING: this file should *not* be used by applications. It - is part of the implementation of the compression library and - is subject to change. Applications should only use zlib.h. - */ - - static const code lenfix[512] = { - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48}, - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128}, - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59}, - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176}, - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20}, - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100}, - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8}, - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216}, - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76}, - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114}, - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2}, - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148}, - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42}, - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86}, - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15}, - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236}, - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62}, - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142}, - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31}, - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162}, - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25}, - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105}, - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4}, - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202}, - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69}, - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125}, - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13}, - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195}, - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35}, - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91}, - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19}, - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246}, - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55}, - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135}, - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99}, - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190}, - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16}, - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96}, - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6}, - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209}, - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72}, - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116}, - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4}, - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153}, - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44}, - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82}, - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11}, - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229}, - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58}, - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138}, - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51}, - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173}, - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30}, - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110}, - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0}, - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195}, - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65}, - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121}, - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9}, - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258}, - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37}, - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93}, - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23}, - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251}, - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51}, - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131}, - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67}, - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183}, - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23}, - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103}, - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9}, - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223}, - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79}, - {0,9,255} - }; - - static const code distfix[32] = { - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025}, - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193}, - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385}, - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577}, - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073}, - {22,5,193},{64,5,0} - }; diff --git a/deps/zlib/inflate.c b/deps/zlib/inflate.c deleted file mode 100644 index a8431abeacf..00000000000 --- a/deps/zlib/inflate.c +++ /dev/null @@ -1,1480 +0,0 @@ -/* inflate.c -- zlib decompression - * Copyright (C) 1995-2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * Change history: - * - * 1.2.beta0 24 Nov 2002 - * - First version -- complete rewrite of inflate to simplify code, avoid - * creation of window when not needed, minimize use of window when it is - * needed, make inffast.c even faster, implement gzip decoding, and to - * improve code readability and style over the previous zlib inflate code - * - * 1.2.beta1 25 Nov 2002 - * - Use pointers for available input and output checking in inffast.c - * - Remove input and output counters in inffast.c - * - Change inffast.c entry and loop from avail_in >= 7 to >= 6 - * - Remove unnecessary second byte pull from length extra in inffast.c - * - Unroll direct copy to three copies per loop in inffast.c - * - * 1.2.beta2 4 Dec 2002 - * - Change external routine names to reduce potential conflicts - * - Correct filename to inffixed.h for fixed tables in inflate.c - * - Make hbuf[] unsigned char to match parameter type in inflate.c - * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset) - * to avoid negation problem on Alphas (64 bit) in inflate.c - * - * 1.2.beta3 22 Dec 2002 - * - Add comments on state->bits assertion in inffast.c - * - Add comments on op field in inftrees.h - * - Fix bug in reuse of allocated window after inflateReset() - * - Remove bit fields--back to byte structure for speed - * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths - * - Change post-increments to pre-increments in inflate_fast(), PPC biased? - * - Add compile time option, POSTINC, to use post-increments instead (Intel?) - * - Make MATCH copy in inflate() much faster for when inflate_fast() not used - * - Use local copies of stream next and avail values, as well as local bit - * buffer and bit count in inflate()--for speed when inflate_fast() not used - * - * 1.2.beta4 1 Jan 2003 - * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings - * - Move a comment on output buffer sizes from inffast.c to inflate.c - * - Add comments in inffast.c to introduce the inflate_fast() routine - * - Rearrange window copies in inflate_fast() for speed and simplification - * - Unroll last copy for window match in inflate_fast() - * - Use local copies of window variables in inflate_fast() for speed - * - Pull out common wnext == 0 case for speed in inflate_fast() - * - Make op and len in inflate_fast() unsigned for consistency - * - Add FAR to lcode and dcode declarations in inflate_fast() - * - Simplified bad distance check in inflate_fast() - * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new - * source file infback.c to provide a call-back interface to inflate for - * programs like gzip and unzip -- uses window as output buffer to avoid - * window copying - * - * 1.2.beta5 1 Jan 2003 - * - Improved inflateBack() interface to allow the caller to provide initial - * input in strm. - * - Fixed stored blocks bug in inflateBack() - * - * 1.2.beta6 4 Jan 2003 - * - Added comments in inffast.c on effectiveness of POSTINC - * - Typecasting all around to reduce compiler warnings - * - Changed loops from while (1) or do {} while (1) to for (;;), again to - * make compilers happy - * - Changed type of window in inflateBackInit() to unsigned char * - * - * 1.2.beta7 27 Jan 2003 - * - Changed many types to unsigned or unsigned short to avoid warnings - * - Added inflateCopy() function - * - * 1.2.0 9 Mar 2003 - * - Changed inflateBack() interface to provide separate opaque descriptors - * for the in() and out() functions - * - Changed inflateBack() argument and in_func typedef to swap the length - * and buffer address return values for the input function - * - Check next_in and next_out for Z_NULL on entry to inflate() - * - * The history for versions after 1.2.0 are in ChangeLog in zlib distribution. - */ - -#include "zutil.h" -#include "inftrees.h" -#include "inflate.h" -#include "inffast.h" - -#ifdef MAKEFIXED -# ifndef BUILDFIXED -# define BUILDFIXED -# endif -#endif - -/* function prototypes */ -local void fixedtables OF((struct inflate_state FAR *state)); -local int updatewindow OF((z_streamp strm, unsigned out)); -#ifdef BUILDFIXED - void makefixed OF((void)); -#endif -local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf, - unsigned len)); - -int ZEXPORT inflateReset(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - strm->total_in = strm->total_out = state->total = 0; - strm->msg = Z_NULL; - strm->adler = 1; /* to support ill-conceived Java test suite */ - state->mode = HEAD; - state->last = 0; - state->havedict = 0; - state->dmax = 32768U; - state->head = Z_NULL; - state->wsize = 0; - state->whave = 0; - state->wnext = 0; - state->hold = 0; - state->bits = 0; - state->lencode = state->distcode = state->next = state->codes; - state->sane = 1; - state->back = -1; - Tracev((stderr, "inflate: reset\n")); - return Z_OK; -} - -int ZEXPORT inflateReset2(strm, windowBits) -z_streamp strm; -int windowBits; -{ - int wrap; - struct inflate_state FAR *state; - - /* get the state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - - /* extract wrap request from windowBits parameter */ - if (windowBits < 0) { - wrap = 0; - windowBits = -windowBits; - } - else { - wrap = (windowBits >> 4) + 1; -#ifdef GUNZIP - if (windowBits < 48) - windowBits &= 15; -#endif - } - - /* set number of window bits, free window if different */ - if (windowBits && (windowBits < 8 || windowBits > 15)) - return Z_STREAM_ERROR; - if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) { - ZFREE(strm, state->window); - state->window = Z_NULL; - } - - /* update state and reset the rest of it */ - state->wrap = wrap; - state->wbits = (unsigned)windowBits; - return inflateReset(strm); -} - -int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size) -z_streamp strm; -int windowBits; -const char *version; -int stream_size; -{ - int ret; - struct inflate_state FAR *state; - - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] || - stream_size != (int)(sizeof(z_stream))) - return Z_VERSION_ERROR; - if (strm == Z_NULL) return Z_STREAM_ERROR; - strm->msg = Z_NULL; /* in case we return an error */ - if (strm->zalloc == (alloc_func)0) { - strm->zalloc = zcalloc; - strm->opaque = (voidpf)0; - } - if (strm->zfree == (free_func)0) strm->zfree = zcfree; - state = (struct inflate_state FAR *) - ZALLOC(strm, 1, sizeof(struct inflate_state)); - if (state == Z_NULL) return Z_MEM_ERROR; - Tracev((stderr, "inflate: allocated\n")); - strm->state = (struct internal_state FAR *)state; - state->window = Z_NULL; - ret = inflateReset2(strm, windowBits); - if (ret != Z_OK) { - ZFREE(strm, state); - strm->state = Z_NULL; - } - return ret; -} - -int ZEXPORT inflateInit_(strm, version, stream_size) -z_streamp strm; -const char *version; -int stream_size; -{ - return inflateInit2_(strm, DEF_WBITS, version, stream_size); -} - -int ZEXPORT inflatePrime(strm, bits, value) -z_streamp strm; -int bits; -int value; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (bits < 0) { - state->hold = 0; - state->bits = 0; - return Z_OK; - } - if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR; - value &= (1L << bits) - 1; - state->hold += value << state->bits; - state->bits += bits; - return Z_OK; -} - -/* - Return state with length and distance decoding tables and index sizes set to - fixed code decoding. Normally this returns fixed tables from inffixed.h. - If BUILDFIXED is defined, then instead this routine builds the tables the - first time it's called, and returns those tables the first time and - thereafter. This reduces the size of the code by about 2K bytes, in - exchange for a little execution time. However, BUILDFIXED should not be - used for threaded applications, since the rewriting of the tables and virgin - may not be thread-safe. - */ -local void fixedtables(state) -struct inflate_state FAR *state; -{ -#ifdef BUILDFIXED - static int virgin = 1; - static code *lenfix, *distfix; - static code fixed[544]; - - /* build fixed huffman tables if first call (may not be thread safe) */ - if (virgin) { - unsigned sym, bits; - static code *next; - - /* literal/length table */ - sym = 0; - while (sym < 144) state->lens[sym++] = 8; - while (sym < 256) state->lens[sym++] = 9; - while (sym < 280) state->lens[sym++] = 7; - while (sym < 288) state->lens[sym++] = 8; - next = fixed; - lenfix = next; - bits = 9; - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work); - - /* distance table */ - sym = 0; - while (sym < 32) state->lens[sym++] = 5; - distfix = next; - bits = 5; - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work); - - /* do this just once */ - virgin = 0; - } -#else /* !BUILDFIXED */ -# include "inffixed.h" -#endif /* BUILDFIXED */ - state->lencode = lenfix; - state->lenbits = 9; - state->distcode = distfix; - state->distbits = 5; -} - -#ifdef MAKEFIXED -#include - -/* - Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also - defines BUILDFIXED, so the tables are built on the fly. makefixed() writes - those tables to stdout, which would be piped to inffixed.h. A small program - can simply call makefixed to do this: - - void makefixed(void); - - int main(void) - { - makefixed(); - return 0; - } - - Then that can be linked with zlib built with MAKEFIXED defined and run: - - a.out > inffixed.h - */ -void makefixed() -{ - unsigned low, size; - struct inflate_state state; - - fixedtables(&state); - puts(" /* inffixed.h -- table for decoding fixed codes"); - puts(" * Generated automatically by makefixed()."); - puts(" */"); - puts(""); - puts(" /* WARNING: this file should *not* be used by applications."); - puts(" It is part of the implementation of this library and is"); - puts(" subject to change. Applications should only use zlib.h."); - puts(" */"); - puts(""); - size = 1U << 9; - printf(" static const code lenfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 7) == 0) printf("\n "); - printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits, - state.lencode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); - size = 1U << 5; - printf("\n static const code distfix[%u] = {", size); - low = 0; - for (;;) { - if ((low % 6) == 0) printf("\n "); - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits, - state.distcode[low].val); - if (++low == size) break; - putchar(','); - } - puts("\n };"); -} -#endif /* MAKEFIXED */ - -/* - Update the window with the last wsize (normally 32K) bytes written before - returning. If window does not exist yet, create it. This is only called - when a window is already in use, or when output has been written during this - inflate call, but the end of the deflate stream has not been reached yet. - It is also called to create a window for dictionary data when a dictionary - is loaded. - - Providing output buffers larger than 32K to inflate() should provide a speed - advantage, since only the last 32K of output is copied to the sliding window - upon return from inflate(), and since all distances after the first 32K of - output will fall in the output data, making match copies simpler and faster. - The advantage may be dependent on the size of the processor's data caches. - */ -local int updatewindow(strm, out) -z_streamp strm; -unsigned out; -{ - struct inflate_state FAR *state; - unsigned copy, dist; - - state = (struct inflate_state FAR *)strm->state; - - /* if it hasn't been done already, allocate space for the window */ - if (state->window == Z_NULL) { - state->window = (unsigned char FAR *) - ZALLOC(strm, 1U << state->wbits, - sizeof(unsigned char)); - if (state->window == Z_NULL) return 1; - } - - /* if window not in use yet, initialize */ - if (state->wsize == 0) { - state->wsize = 1U << state->wbits; - state->wnext = 0; - state->whave = 0; - } - - /* copy state->wsize or less output bytes into the circular window */ - copy = out - strm->avail_out; - if (copy >= state->wsize) { - zmemcpy(state->window, strm->next_out - state->wsize, state->wsize); - state->wnext = 0; - state->whave = state->wsize; - } - else { - dist = state->wsize - state->wnext; - if (dist > copy) dist = copy; - zmemcpy(state->window + state->wnext, strm->next_out - copy, dist); - copy -= dist; - if (copy) { - zmemcpy(state->window, strm->next_out - copy, copy); - state->wnext = copy; - state->whave = state->wsize; - } - else { - state->wnext += dist; - if (state->wnext == state->wsize) state->wnext = 0; - if (state->whave < state->wsize) state->whave += dist; - } - } - return 0; -} - -/* Macros for inflate(): */ - -/* check function to use adler32() for zlib or crc32() for gzip */ -#ifdef GUNZIP -# define UPDATE(check, buf, len) \ - (state->flags ? crc32(check, buf, len) : adler32(check, buf, len)) -#else -# define UPDATE(check, buf, len) adler32(check, buf, len) -#endif - -/* check macros for header crc */ -#ifdef GUNZIP -# define CRC2(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - check = crc32(check, hbuf, 2); \ - } while (0) - -# define CRC4(check, word) \ - do { \ - hbuf[0] = (unsigned char)(word); \ - hbuf[1] = (unsigned char)((word) >> 8); \ - hbuf[2] = (unsigned char)((word) >> 16); \ - hbuf[3] = (unsigned char)((word) >> 24); \ - check = crc32(check, hbuf, 4); \ - } while (0) -#endif - -/* Load registers with state in inflate() for speed */ -#define LOAD() \ - do { \ - put = strm->next_out; \ - left = strm->avail_out; \ - next = strm->next_in; \ - have = strm->avail_in; \ - hold = state->hold; \ - bits = state->bits; \ - } while (0) - -/* Restore state from registers in inflate() */ -#define RESTORE() \ - do { \ - strm->next_out = put; \ - strm->avail_out = left; \ - strm->next_in = next; \ - strm->avail_in = have; \ - state->hold = hold; \ - state->bits = bits; \ - } while (0) - -/* Clear the input bit accumulator */ -#define INITBITS() \ - do { \ - hold = 0; \ - bits = 0; \ - } while (0) - -/* Get a byte of input into the bit accumulator, or return from inflate() - if there is no input available. */ -#define PULLBYTE() \ - do { \ - if (have == 0) goto inf_leave; \ - have--; \ - hold += (unsigned long)(*next++) << bits; \ - bits += 8; \ - } while (0) - -/* Assure that there are at least n bits in the bit accumulator. If there is - not enough available input to do that, then return from inflate(). */ -#define NEEDBITS(n) \ - do { \ - while (bits < (unsigned)(n)) \ - PULLBYTE(); \ - } while (0) - -/* Return the low n bits of the bit accumulator (n < 16) */ -#define BITS(n) \ - ((unsigned)hold & ((1U << (n)) - 1)) - -/* Remove n bits from the bit accumulator */ -#define DROPBITS(n) \ - do { \ - hold >>= (n); \ - bits -= (unsigned)(n); \ - } while (0) - -/* Remove zero to seven bits as needed to go to a byte boundary */ -#define BYTEBITS() \ - do { \ - hold >>= bits & 7; \ - bits -= bits & 7; \ - } while (0) - -/* Reverse the bytes in a 32-bit value */ -#define REVERSE(q) \ - ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \ - (((q) & 0xff00) << 8) + (((q) & 0xff) << 24)) - -/* - inflate() uses a state machine to process as much input data and generate as - much output data as possible before returning. The state machine is - structured roughly as follows: - - for (;;) switch (state) { - ... - case STATEn: - if (not enough input data or output space to make progress) - return; - ... make progress ... - state = STATEm; - break; - ... - } - - so when inflate() is called again, the same case is attempted again, and - if the appropriate resources are provided, the machine proceeds to the - next state. The NEEDBITS() macro is usually the way the state evaluates - whether it can proceed or should return. NEEDBITS() does the return if - the requested bits are not available. The typical use of the BITS macros - is: - - NEEDBITS(n); - ... do something with BITS(n) ... - DROPBITS(n); - - where NEEDBITS(n) either returns from inflate() if there isn't enough - input left to load n bits into the accumulator, or it continues. BITS(n) - gives the low n bits in the accumulator. When done, DROPBITS(n) drops - the low n bits off the accumulator. INITBITS() clears the accumulator - and sets the number of available bits to zero. BYTEBITS() discards just - enough bits to put the accumulator on a byte boundary. After BYTEBITS() - and a NEEDBITS(8), then BITS(8) would return the next byte in the stream. - - NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return - if there is no input available. The decoding of variable length codes uses - PULLBYTE() directly in order to pull just enough bytes to decode the next - code, and no more. - - Some states loop until they get enough input, making sure that enough - state information is maintained to continue the loop where it left off - if NEEDBITS() returns in the loop. For example, want, need, and keep - would all have to actually be part of the saved state in case NEEDBITS() - returns: - - case STATEw: - while (want < need) { - NEEDBITS(n); - keep[want++] = BITS(n); - DROPBITS(n); - } - state = STATEx; - case STATEx: - - As shown above, if the next state is also the next case, then the break - is omitted. - - A state may also return if there is not enough output space available to - complete that state. Those states are copying stored data, writing a - literal byte, and copying a matching string. - - When returning, a "goto inf_leave" is used to update the total counters, - update the check value, and determine whether any progress has been made - during that inflate() call in order to return the proper return code. - Progress is defined as a change in either strm->avail_in or strm->avail_out. - When there is a window, goto inf_leave will update the window with the last - output written. If a goto inf_leave occurs in the middle of decompression - and there is no window currently, goto inf_leave will create one and copy - output to the window for the next call of inflate(). - - In this implementation, the flush parameter of inflate() only affects the - return code (per zlib.h). inflate() always writes as much as possible to - strm->next_out, given the space available and the provided input--the effect - documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers - the allocation of and copying into a sliding window until necessary, which - provides the effect documented in zlib.h for Z_FINISH when the entire input - stream available. So the only thing the flush parameter actually does is: - when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it - will return Z_BUF_ERROR if it has not reached the end of the stream. - */ - -int ZEXPORT inflate(strm, flush) -z_streamp strm; -int flush; -{ - struct inflate_state FAR *state; - unsigned char FAR *next; /* next input */ - unsigned char FAR *put; /* next output */ - unsigned have, left; /* available input and output */ - unsigned long hold; /* bit buffer */ - unsigned bits; /* bits in bit buffer */ - unsigned in, out; /* save starting available input and output */ - unsigned copy; /* number of stored or match bytes to copy */ - unsigned char FAR *from; /* where to copy match bytes from */ - code here; /* current decoding table entry */ - code last; /* parent table entry */ - unsigned len; /* length to copy for repeats, bits to drop */ - int ret; /* return code */ -#ifdef GUNZIP - unsigned char hbuf[4]; /* buffer for gzip header crc calculation */ -#endif - static const unsigned short order[19] = /* permutation of code lengths */ - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; - - if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL || - (strm->next_in == Z_NULL && strm->avail_in != 0)) - return Z_STREAM_ERROR; - - state = (struct inflate_state FAR *)strm->state; - if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */ - LOAD(); - in = have; - out = left; - ret = Z_OK; - for (;;) - switch (state->mode) { - case HEAD: - if (state->wrap == 0) { - state->mode = TYPEDO; - break; - } - NEEDBITS(16); -#ifdef GUNZIP - if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */ - state->check = crc32(0L, Z_NULL, 0); - CRC2(state->check, hold); - INITBITS(); - state->mode = FLAGS; - break; - } - state->flags = 0; /* expect zlib header */ - if (state->head != Z_NULL) - state->head->done = -1; - if (!(state->wrap & 1) || /* check if zlib header allowed */ -#else - if ( -#endif - ((BITS(8) << 8) + (hold >> 8)) % 31) { - strm->msg = (char *)"incorrect header check"; - state->mode = BAD; - break; - } - if (BITS(4) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - DROPBITS(4); - len = BITS(4) + 8; - if (state->wbits == 0) - state->wbits = len; - else if (len > state->wbits) { - strm->msg = (char *)"invalid window size"; - state->mode = BAD; - break; - } - state->dmax = 1U << len; - Tracev((stderr, "inflate: zlib header ok\n")); - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = hold & 0x200 ? DICTID : TYPE; - INITBITS(); - break; -#ifdef GUNZIP - case FLAGS: - NEEDBITS(16); - state->flags = (int)(hold); - if ((state->flags & 0xff) != Z_DEFLATED) { - strm->msg = (char *)"unknown compression method"; - state->mode = BAD; - break; - } - if (state->flags & 0xe000) { - strm->msg = (char *)"unknown header flags set"; - state->mode = BAD; - break; - } - if (state->head != Z_NULL) - state->head->text = (int)((hold >> 8) & 1); - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - state->mode = TIME; - case TIME: - NEEDBITS(32); - if (state->head != Z_NULL) - state->head->time = hold; - if (state->flags & 0x0200) CRC4(state->check, hold); - INITBITS(); - state->mode = OS; - case OS: - NEEDBITS(16); - if (state->head != Z_NULL) { - state->head->xflags = (int)(hold & 0xff); - state->head->os = (int)(hold >> 8); - } - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - state->mode = EXLEN; - case EXLEN: - if (state->flags & 0x0400) { - NEEDBITS(16); - state->length = (unsigned)(hold); - if (state->head != Z_NULL) - state->head->extra_len = (unsigned)hold; - if (state->flags & 0x0200) CRC2(state->check, hold); - INITBITS(); - } - else if (state->head != Z_NULL) - state->head->extra = Z_NULL; - state->mode = EXTRA; - case EXTRA: - if (state->flags & 0x0400) { - copy = state->length; - if (copy > have) copy = have; - if (copy) { - if (state->head != Z_NULL && - state->head->extra != Z_NULL) { - len = state->head->extra_len - state->length; - zmemcpy(state->head->extra + len, next, - len + copy > state->head->extra_max ? - state->head->extra_max - len : copy); - } - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - state->length -= copy; - } - if (state->length) goto inf_leave; - } - state->length = 0; - state->mode = NAME; - case NAME: - if (state->flags & 0x0800) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->name != Z_NULL && - state->length < state->head->name_max) - state->head->name[state->length++] = len; - } while (len && copy < have); - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->name = Z_NULL; - state->length = 0; - state->mode = COMMENT; - case COMMENT: - if (state->flags & 0x1000) { - if (have == 0) goto inf_leave; - copy = 0; - do { - len = (unsigned)(next[copy++]); - if (state->head != Z_NULL && - state->head->comment != Z_NULL && - state->length < state->head->comm_max) - state->head->comment[state->length++] = len; - } while (len && copy < have); - if (state->flags & 0x0200) - state->check = crc32(state->check, next, copy); - have -= copy; - next += copy; - if (len) goto inf_leave; - } - else if (state->head != Z_NULL) - state->head->comment = Z_NULL; - state->mode = HCRC; - case HCRC: - if (state->flags & 0x0200) { - NEEDBITS(16); - if (hold != (state->check & 0xffff)) { - strm->msg = (char *)"header crc mismatch"; - state->mode = BAD; - break; - } - INITBITS(); - } - if (state->head != Z_NULL) { - state->head->hcrc = (int)((state->flags >> 9) & 1); - state->head->done = 1; - } - strm->adler = state->check = crc32(0L, Z_NULL, 0); - state->mode = TYPE; - break; -#endif - case DICTID: - NEEDBITS(32); - strm->adler = state->check = REVERSE(hold); - INITBITS(); - state->mode = DICT; - case DICT: - if (state->havedict == 0) { - RESTORE(); - return Z_NEED_DICT; - } - strm->adler = state->check = adler32(0L, Z_NULL, 0); - state->mode = TYPE; - case TYPE: - if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave; - case TYPEDO: - if (state->last) { - BYTEBITS(); - state->mode = CHECK; - break; - } - NEEDBITS(3); - state->last = BITS(1); - DROPBITS(1); - switch (BITS(2)) { - case 0: /* stored block */ - Tracev((stderr, "inflate: stored block%s\n", - state->last ? " (last)" : "")); - state->mode = STORED; - break; - case 1: /* fixed block */ - fixedtables(state); - Tracev((stderr, "inflate: fixed codes block%s\n", - state->last ? " (last)" : "")); - state->mode = LEN_; /* decode codes */ - if (flush == Z_TREES) { - DROPBITS(2); - goto inf_leave; - } - break; - case 2: /* dynamic block */ - Tracev((stderr, "inflate: dynamic codes block%s\n", - state->last ? " (last)" : "")); - state->mode = TABLE; - break; - case 3: - strm->msg = (char *)"invalid block type"; - state->mode = BAD; - } - DROPBITS(2); - break; - case STORED: - BYTEBITS(); /* go to byte boundary */ - NEEDBITS(32); - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) { - strm->msg = (char *)"invalid stored block lengths"; - state->mode = BAD; - break; - } - state->length = (unsigned)hold & 0xffff; - Tracev((stderr, "inflate: stored length %u\n", - state->length)); - INITBITS(); - state->mode = COPY_; - if (flush == Z_TREES) goto inf_leave; - case COPY_: - state->mode = COPY; - case COPY: - copy = state->length; - if (copy) { - if (copy > have) copy = have; - if (copy > left) copy = left; - if (copy == 0) goto inf_leave; - zmemcpy(put, next, copy); - have -= copy; - next += copy; - left -= copy; - put += copy; - state->length -= copy; - break; - } - Tracev((stderr, "inflate: stored end\n")); - state->mode = TYPE; - break; - case TABLE: - NEEDBITS(14); - state->nlen = BITS(5) + 257; - DROPBITS(5); - state->ndist = BITS(5) + 1; - DROPBITS(5); - state->ncode = BITS(4) + 4; - DROPBITS(4); -#ifndef PKZIP_BUG_WORKAROUND - if (state->nlen > 286 || state->ndist > 30) { - strm->msg = (char *)"too many length or distance symbols"; - state->mode = BAD; - break; - } -#endif - Tracev((stderr, "inflate: table sizes ok\n")); - state->have = 0; - state->mode = LENLENS; - case LENLENS: - while (state->have < state->ncode) { - NEEDBITS(3); - state->lens[order[state->have++]] = (unsigned short)BITS(3); - DROPBITS(3); - } - while (state->have < 19) - state->lens[order[state->have++]] = 0; - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 7; - ret = inflate_table(CODES, state->lens, 19, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid code lengths set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: code lengths ok\n")); - state->have = 0; - state->mode = CODELENS; - case CODELENS: - while (state->have < state->nlen + state->ndist) { - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.val < 16) { - NEEDBITS(here.bits); - DROPBITS(here.bits); - state->lens[state->have++] = here.val; - } - else { - if (here.val == 16) { - NEEDBITS(here.bits + 2); - DROPBITS(here.bits); - if (state->have == 0) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - len = state->lens[state->have - 1]; - copy = 3 + BITS(2); - DROPBITS(2); - } - else if (here.val == 17) { - NEEDBITS(here.bits + 3); - DROPBITS(here.bits); - len = 0; - copy = 3 + BITS(3); - DROPBITS(3); - } - else { - NEEDBITS(here.bits + 7); - DROPBITS(here.bits); - len = 0; - copy = 11 + BITS(7); - DROPBITS(7); - } - if (state->have + copy > state->nlen + state->ndist) { - strm->msg = (char *)"invalid bit length repeat"; - state->mode = BAD; - break; - } - while (copy--) - state->lens[state->have++] = (unsigned short)len; - } - } - - /* handle error breaks in while */ - if (state->mode == BAD) break; - - /* check for end-of-block code (better have one) */ - if (state->lens[256] == 0) { - strm->msg = (char *)"invalid code -- missing end-of-block"; - state->mode = BAD; - break; - } - - /* build code tables -- note: do not change the lenbits or distbits - values here (9 and 6) without reading the comments in inftrees.h - concerning the ENOUGH constants, which depend on those values */ - state->next = state->codes; - state->lencode = (code const FAR *)(state->next); - state->lenbits = 9; - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next), - &(state->lenbits), state->work); - if (ret) { - strm->msg = (char *)"invalid literal/lengths set"; - state->mode = BAD; - break; - } - state->distcode = (code const FAR *)(state->next); - state->distbits = 6; - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist, - &(state->next), &(state->distbits), state->work); - if (ret) { - strm->msg = (char *)"invalid distances set"; - state->mode = BAD; - break; - } - Tracev((stderr, "inflate: codes ok\n")); - state->mode = LEN_; - if (flush == Z_TREES) goto inf_leave; - case LEN_: - state->mode = LEN; - case LEN: - if (have >= 6 && left >= 258) { - RESTORE(); - inflate_fast(strm, out); - LOAD(); - if (state->mode == TYPE) - state->back = -1; - break; - } - state->back = 0; - for (;;) { - here = state->lencode[BITS(state->lenbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if (here.op && (here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->lencode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - state->length = (unsigned)here.val; - if ((int)(here.op) == 0) { - Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ? - "inflate: literal '%c'\n" : - "inflate: literal 0x%02x\n", here.val)); - state->mode = LIT; - break; - } - if (here.op & 32) { - Tracevv((stderr, "inflate: end of block\n")); - state->back = -1; - state->mode = TYPE; - break; - } - if (here.op & 64) { - strm->msg = (char *)"invalid literal/length code"; - state->mode = BAD; - break; - } - state->extra = (unsigned)(here.op) & 15; - state->mode = LENEXT; - case LENEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->length += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } - Tracevv((stderr, "inflate: length %u\n", state->length)); - state->was = state->length; - state->mode = DIST; - case DIST: - for (;;) { - here = state->distcode[BITS(state->distbits)]; - if ((unsigned)(here.bits) <= bits) break; - PULLBYTE(); - } - if ((here.op & 0xf0) == 0) { - last = here; - for (;;) { - here = state->distcode[last.val + - (BITS(last.bits + last.op) >> last.bits)]; - if ((unsigned)(last.bits + here.bits) <= bits) break; - PULLBYTE(); - } - DROPBITS(last.bits); - state->back += last.bits; - } - DROPBITS(here.bits); - state->back += here.bits; - if (here.op & 64) { - strm->msg = (char *)"invalid distance code"; - state->mode = BAD; - break; - } - state->offset = (unsigned)here.val; - state->extra = (unsigned)(here.op) & 15; - state->mode = DISTEXT; - case DISTEXT: - if (state->extra) { - NEEDBITS(state->extra); - state->offset += BITS(state->extra); - DROPBITS(state->extra); - state->back += state->extra; - } -#ifdef INFLATE_STRICT - if (state->offset > state->dmax) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#endif - Tracevv((stderr, "inflate: distance %u\n", state->offset)); - state->mode = MATCH; - case MATCH: - if (left == 0) goto inf_leave; - copy = out - left; - if (state->offset > copy) { /* copy from window */ - copy = state->offset - copy; - if (copy > state->whave) { - if (state->sane) { - strm->msg = (char *)"invalid distance too far back"; - state->mode = BAD; - break; - } -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - Trace((stderr, "inflate.c too far\n")); - copy -= state->whave; - if (copy > state->length) copy = state->length; - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = 0; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; -#endif - } - if (copy > state->wnext) { - copy -= state->wnext; - from = state->window + (state->wsize - copy); - } - else - from = state->window + (state->wnext - copy); - if (copy > state->length) copy = state->length; - } - else { /* copy from output */ - from = put - state->offset; - copy = state->length; - } - if (copy > left) copy = left; - left -= copy; - state->length -= copy; - do { - *put++ = *from++; - } while (--copy); - if (state->length == 0) state->mode = LEN; - break; - case LIT: - if (left == 0) goto inf_leave; - *put++ = (unsigned char)(state->length); - left--; - state->mode = LEN; - break; - case CHECK: - if (state->wrap) { - NEEDBITS(32); - out -= left; - strm->total_out += out; - state->total += out; - if (out) - strm->adler = state->check = - UPDATE(state->check, put - out, out); - out = left; - if (( -#ifdef GUNZIP - state->flags ? hold : -#endif - REVERSE(hold)) != state->check) { - strm->msg = (char *)"incorrect data check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: check matches trailer\n")); - } -#ifdef GUNZIP - state->mode = LENGTH; - case LENGTH: - if (state->wrap && state->flags) { - NEEDBITS(32); - if (hold != (state->total & 0xffffffffUL)) { - strm->msg = (char *)"incorrect length check"; - state->mode = BAD; - break; - } - INITBITS(); - Tracev((stderr, "inflate: length matches trailer\n")); - } -#endif - state->mode = DONE; - case DONE: - ret = Z_STREAM_END; - goto inf_leave; - case BAD: - ret = Z_DATA_ERROR; - goto inf_leave; - case MEM: - return Z_MEM_ERROR; - case SYNC: - default: - return Z_STREAM_ERROR; - } - - /* - Return from inflate(), updating the total counts and the check value. - If there was no progress during the inflate() call, return a buffer - error. Call updatewindow() to create and/or update the window state. - Note: a memory error from inflate() is non-recoverable. - */ - inf_leave: - RESTORE(); - if (state->wsize || (state->mode < CHECK && out != strm->avail_out)) - if (updatewindow(strm, out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - in -= strm->avail_in; - out -= strm->avail_out; - strm->total_in += in; - strm->total_out += out; - state->total += out; - if (state->wrap && out) - strm->adler = state->check = - UPDATE(state->check, strm->next_out - out, out); - strm->data_type = state->bits + (state->last ? 64 : 0) + - (state->mode == TYPE ? 128 : 0) + - (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0); - if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK) - ret = Z_BUF_ERROR; - return ret; -} - -int ZEXPORT inflateEnd(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->window != Z_NULL) ZFREE(strm, state->window); - ZFREE(strm, strm->state); - strm->state = Z_NULL; - Tracev((stderr, "inflate: end\n")); - return Z_OK; -} - -int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength) -z_streamp strm; -const Bytef *dictionary; -uInt dictLength; -{ - struct inflate_state FAR *state; - unsigned long id; - - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (state->wrap != 0 && state->mode != DICT) - return Z_STREAM_ERROR; - - /* check for correct dictionary id */ - if (state->mode == DICT) { - id = adler32(0L, Z_NULL, 0); - id = adler32(id, dictionary, dictLength); - if (id != state->check) - return Z_DATA_ERROR; - } - - /* copy dictionary to window */ - if (updatewindow(strm, strm->avail_out)) { - state->mode = MEM; - return Z_MEM_ERROR; - } - if (dictLength > state->wsize) { - zmemcpy(state->window, dictionary + dictLength - state->wsize, - state->wsize); - state->whave = state->wsize; - } - else { - zmemcpy(state->window + state->wsize - dictLength, dictionary, - dictLength); - state->whave = dictLength; - } - state->havedict = 1; - Tracev((stderr, "inflate: dictionary set\n")); - return Z_OK; -} - -int ZEXPORT inflateGetHeader(strm, head) -z_streamp strm; -gz_headerp head; -{ - struct inflate_state FAR *state; - - /* check state */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if ((state->wrap & 2) == 0) return Z_STREAM_ERROR; - - /* save header structure */ - state->head = head; - head->done = 0; - return Z_OK; -} - -/* - Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found - or when out of input. When called, *have is the number of pattern bytes - found in order so far, in 0..3. On return *have is updated to the new - state. If on return *have equals four, then the pattern was found and the - return value is how many bytes were read including the last byte of the - pattern. If *have is less than four, then the pattern has not been found - yet and the return value is len. In the latter case, syncsearch() can be - called again with more data and the *have state. *have is initialized to - zero for the first call. - */ -local unsigned syncsearch(have, buf, len) -unsigned FAR *have; -unsigned char FAR *buf; -unsigned len; -{ - unsigned got; - unsigned next; - - got = *have; - next = 0; - while (next < len && got < 4) { - if ((int)(buf[next]) == (got < 2 ? 0 : 0xff)) - got++; - else if (buf[next]) - got = 0; - else - got = 4 - got; - next++; - } - *have = got; - return next; -} - -int ZEXPORT inflateSync(strm) -z_streamp strm; -{ - unsigned len; /* number of bytes to look at or looked at */ - unsigned long in, out; /* temporary to save total_in and total_out */ - unsigned char buf[4]; /* to restore bit buffer to byte string */ - struct inflate_state FAR *state; - - /* check parameters */ - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR; - - /* if first time, start search in bit buffer */ - if (state->mode != SYNC) { - state->mode = SYNC; - state->hold <<= state->bits & 7; - state->bits -= state->bits & 7; - len = 0; - while (state->bits >= 8) { - buf[len++] = (unsigned char)(state->hold); - state->hold >>= 8; - state->bits -= 8; - } - state->have = 0; - syncsearch(&(state->have), buf, len); - } - - /* search available input */ - len = syncsearch(&(state->have), strm->next_in, strm->avail_in); - strm->avail_in -= len; - strm->next_in += len; - strm->total_in += len; - - /* return no joy or set up to restart inflate() on a new block */ - if (state->have != 4) return Z_DATA_ERROR; - in = strm->total_in; out = strm->total_out; - inflateReset(strm); - strm->total_in = in; strm->total_out = out; - state->mode = TYPE; - return Z_OK; -} - -/* - Returns true if inflate is currently at the end of a block generated by - Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP - implementation to provide an additional safety check. PPP uses - Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored - block. When decompressing, PPP checks that at the end of input packet, - inflate is waiting for these length bytes. - */ -int ZEXPORT inflateSyncPoint(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - return state->mode == STORED && state->bits == 0; -} - -int ZEXPORT inflateCopy(dest, source) -z_streamp dest; -z_streamp source; -{ - struct inflate_state FAR *state; - struct inflate_state FAR *copy; - unsigned char FAR *window; - unsigned wsize; - - /* check input */ - if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL || - source->zalloc == (alloc_func)0 || source->zfree == (free_func)0) - return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)source->state; - - /* allocate space */ - copy = (struct inflate_state FAR *) - ZALLOC(source, 1, sizeof(struct inflate_state)); - if (copy == Z_NULL) return Z_MEM_ERROR; - window = Z_NULL; - if (state->window != Z_NULL) { - window = (unsigned char FAR *) - ZALLOC(source, 1U << state->wbits, sizeof(unsigned char)); - if (window == Z_NULL) { - ZFREE(source, copy); - return Z_MEM_ERROR; - } - } - - /* copy state */ - zmemcpy(dest, source, sizeof(z_stream)); - zmemcpy(copy, state, sizeof(struct inflate_state)); - if (state->lencode >= state->codes && - state->lencode <= state->codes + ENOUGH - 1) { - copy->lencode = copy->codes + (state->lencode - state->codes); - copy->distcode = copy->codes + (state->distcode - state->codes); - } - copy->next = copy->codes + (state->next - state->codes); - if (window != Z_NULL) { - wsize = 1U << state->wbits; - zmemcpy(window, state->window, wsize); - } - copy->window = window; - dest->state = (struct internal_state FAR *)copy; - return Z_OK; -} - -int ZEXPORT inflateUndermine(strm, subvert) -z_streamp strm; -int subvert; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR; - state = (struct inflate_state FAR *)strm->state; - state->sane = !subvert; -#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR - return Z_OK; -#else - state->sane = 1; - return Z_DATA_ERROR; -#endif -} - -long ZEXPORT inflateMark(strm) -z_streamp strm; -{ - struct inflate_state FAR *state; - - if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16; - state = (struct inflate_state FAR *)strm->state; - return ((long)(state->back) << 16) + - (state->mode == COPY ? state->length : - (state->mode == MATCH ? state->was - state->length : 0)); -} diff --git a/deps/zlib/inflate.h b/deps/zlib/inflate.h deleted file mode 100644 index 95f4986d400..00000000000 --- a/deps/zlib/inflate.h +++ /dev/null @@ -1,122 +0,0 @@ -/* inflate.h -- internal inflate state definition - * Copyright (C) 1995-2009 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* define NO_GZIP when compiling if you want to disable gzip header and - trailer decoding by inflate(). NO_GZIP would be used to avoid linking in - the crc code when it is not needed. For shared libraries, gzip decoding - should be left enabled. */ -#ifndef NO_GZIP -# define GUNZIP -#endif - -/* Possible inflate modes between inflate() calls */ -typedef enum { - HEAD, /* i: waiting for magic header */ - FLAGS, /* i: waiting for method and flags (gzip) */ - TIME, /* i: waiting for modification time (gzip) */ - OS, /* i: waiting for extra flags and operating system (gzip) */ - EXLEN, /* i: waiting for extra length (gzip) */ - EXTRA, /* i: waiting for extra bytes (gzip) */ - NAME, /* i: waiting for end of file name (gzip) */ - COMMENT, /* i: waiting for end of comment (gzip) */ - HCRC, /* i: waiting for header crc (gzip) */ - DICTID, /* i: waiting for dictionary check value */ - DICT, /* waiting for inflateSetDictionary() call */ - TYPE, /* i: waiting for type bits, including last-flag bit */ - TYPEDO, /* i: same, but skip check to exit inflate on new block */ - STORED, /* i: waiting for stored size (length and complement) */ - COPY_, /* i/o: same as COPY below, but only first time in */ - COPY, /* i/o: waiting for input or output to copy stored block */ - TABLE, /* i: waiting for dynamic block table lengths */ - LENLENS, /* i: waiting for code length code lengths */ - CODELENS, /* i: waiting for length/lit and distance code lengths */ - LEN_, /* i: same as LEN below, but only first time in */ - LEN, /* i: waiting for length/lit/eob code */ - LENEXT, /* i: waiting for length extra bits */ - DIST, /* i: waiting for distance code */ - DISTEXT, /* i: waiting for distance extra bits */ - MATCH, /* o: waiting for output space to copy string */ - LIT, /* o: waiting for output space to write literal */ - CHECK, /* i: waiting for 32-bit check value */ - LENGTH, /* i: waiting for 32-bit length (gzip) */ - DONE, /* finished check, done -- remain here until reset */ - BAD, /* got a data error -- remain here until reset */ - MEM, /* got an inflate() memory error -- remain here until reset */ - SYNC /* looking for synchronization bytes to restart inflate() */ -} inflate_mode; - -/* - State transitions between above modes - - - (most modes can go to BAD or MEM on error -- not shown for clarity) - - Process header: - HEAD -> (gzip) or (zlib) or (raw) - (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT -> - HCRC -> TYPE - (zlib) -> DICTID or TYPE - DICTID -> DICT -> TYPE - (raw) -> TYPEDO - Read deflate blocks: - TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK - STORED -> COPY_ -> COPY -> TYPE - TABLE -> LENLENS -> CODELENS -> LEN_ - LEN_ -> LEN - Read deflate codes in fixed or dynamic block: - LEN -> LENEXT or LIT or TYPE - LENEXT -> DIST -> DISTEXT -> MATCH -> LEN - LIT -> LEN - Process trailer: - CHECK -> LENGTH -> DONE - */ - -/* state maintained between inflate() calls. Approximately 10K bytes. */ -struct inflate_state { - inflate_mode mode; /* current inflate mode */ - int last; /* true if processing last block */ - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */ - int havedict; /* true if dictionary provided */ - int flags; /* gzip header method and flags (0 if zlib) */ - unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */ - unsigned long check; /* protected copy of check value */ - unsigned long total; /* protected copy of output count */ - gz_headerp head; /* where to save gzip header information */ - /* sliding window */ - unsigned wbits; /* log base 2 of requested window size */ - unsigned wsize; /* window size or zero if not using window */ - unsigned whave; /* valid bytes in the window */ - unsigned wnext; /* window write index */ - unsigned char FAR *window; /* allocated sliding window, if needed */ - /* bit accumulator */ - unsigned long hold; /* input bit accumulator */ - unsigned bits; /* number of bits in "in" */ - /* for string and stored block copying */ - unsigned length; /* literal or length of data to copy */ - unsigned offset; /* distance back to copy string from */ - /* for table and code decoding */ - unsigned extra; /* extra bits needed */ - /* fixed and dynamic code tables */ - code const FAR *lencode; /* starting table for length/literal codes */ - code const FAR *distcode; /* starting table for distance codes */ - unsigned lenbits; /* index bits for lencode */ - unsigned distbits; /* index bits for distcode */ - /* dynamic table building */ - unsigned ncode; /* number of code length code lengths */ - unsigned nlen; /* number of length code lengths */ - unsigned ndist; /* number of distance code lengths */ - unsigned have; /* number of code lengths in lens[] */ - code FAR *next; /* next available space in codes[] */ - unsigned short lens[320]; /* temporary storage for code lengths */ - unsigned short work[288]; /* work area for code table building */ - code codes[ENOUGH]; /* space for code tables */ - int sane; /* if false, allow invalid distance too far */ - int back; /* bits back of last unprocessed length/lit */ - unsigned was; /* initial length of match */ -}; diff --git a/deps/zlib/inftrees.c b/deps/zlib/inftrees.c deleted file mode 100644 index 11e9c52accb..00000000000 --- a/deps/zlib/inftrees.c +++ /dev/null @@ -1,330 +0,0 @@ -/* inftrees.c -- generate Huffman trees for efficient decoding - * Copyright (C) 1995-2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -#include "zutil.h" -#include "inftrees.h" - -#define MAXBITS 15 - -const char inflate_copyright[] = - " inflate 1.2.5 Copyright 1995-2010 Mark Adler "; -/* - If you use the zlib library in a product, an acknowledgment is welcome - in the documentation of your product. If for some reason you cannot - include such an acknowledgment, I would appreciate that you keep this - copyright string in the executable of your product. - */ - -/* - Build a set of tables to decode the provided canonical Huffman code. - The code lengths are lens[0..codes-1]. The result starts at *table, - whose indices are 0..2^bits-1. work is a writable array of at least - lens shorts, which is used as a work area. type is the type of code - to be generated, CODES, LENS, or DISTS. On return, zero is success, - -1 is an invalid code, and +1 means that ENOUGH isn't enough. table - on return points to the next available entry's address. bits is the - requested root table index bits, and on return it is the actual root - table index bits. It will differ if the request is greater than the - longest code or if it is less than the shortest code. - */ -int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work) -codetype type; -unsigned short FAR *lens; -unsigned codes; -code FAR * FAR *table; -unsigned FAR *bits; -unsigned short FAR *work; -{ - unsigned len; /* a code's length in bits */ - unsigned sym; /* index of code symbols */ - unsigned min, max; /* minimum and maximum code lengths */ - unsigned root; /* number of index bits for root table */ - unsigned curr; /* number of index bits for current table */ - unsigned drop; /* code bits to drop for sub-table */ - int left; /* number of prefix codes available */ - unsigned used; /* code entries in table used */ - unsigned huff; /* Huffman code */ - unsigned incr; /* for incrementing code, index */ - unsigned fill; /* index for replicating entries */ - unsigned low; /* low bits for current root entry */ - unsigned mask; /* mask for low root bits */ - code here; /* table entry for duplication */ - code FAR *next; /* next available space in table */ - const unsigned short FAR *base; /* base value table to use */ - const unsigned short FAR *extra; /* extra bits table to use */ - int end; /* use base and extra for symbol > end */ - unsigned short count[MAXBITS+1]; /* number of codes of each length */ - unsigned short offs[MAXBITS+1]; /* offsets in table for each length */ - static const unsigned short lbase[31] = { /* Length codes 257..285 base */ - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; - static const unsigned short lext[31] = { /* Length codes 257..285 extra */ - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 73, 195}; - static const unsigned short dbase[32] = { /* Distance codes 0..29 base */ - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, - 8193, 12289, 16385, 24577, 0, 0}; - static const unsigned short dext[32] = { /* Distance codes 0..29 extra */ - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27, - 28, 28, 29, 29, 64, 64}; - - /* - Process a set of code lengths to create a canonical Huffman code. The - code lengths are lens[0..codes-1]. Each length corresponds to the - symbols 0..codes-1. The Huffman code is generated by first sorting the - symbols by length from short to long, and retaining the symbol order - for codes with equal lengths. Then the code starts with all zero bits - for the first code of the shortest length, and the codes are integer - increments for the same length, and zeros are appended as the length - increases. For the deflate format, these bits are stored backwards - from their more natural integer increment ordering, and so when the - decoding tables are built in the large loop below, the integer codes - are incremented backwards. - - This routine assumes, but does not check, that all of the entries in - lens[] are in the range 0..MAXBITS. The caller must assure this. - 1..MAXBITS is interpreted as that code length. zero means that that - symbol does not occur in this code. - - The codes are sorted by computing a count of codes for each length, - creating from that a table of starting indices for each length in the - sorted table, and then entering the symbols in order in the sorted - table. The sorted table is work[], with that space being provided by - the caller. - - The length counts are used for other purposes as well, i.e. finding - the minimum and maximum length codes, determining if there are any - codes at all, checking for a valid set of lengths, and looking ahead - at length counts to determine sub-table sizes when building the - decoding tables. - */ - - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */ - for (len = 0; len <= MAXBITS; len++) - count[len] = 0; - for (sym = 0; sym < codes; sym++) - count[lens[sym]]++; - - /* bound code lengths, force root to be within code lengths */ - root = *bits; - for (max = MAXBITS; max >= 1; max--) - if (count[max] != 0) break; - if (root > max) root = max; - if (max == 0) { /* no symbols to code at all */ - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)1; - here.val = (unsigned short)0; - *(*table)++ = here; /* make a table to force an error */ - *(*table)++ = here; - *bits = 1; - return 0; /* no symbols, but wait for decoding to report error */ - } - for (min = 1; min < max; min++) - if (count[min] != 0) break; - if (root < min) root = min; - - /* check for an over-subscribed or incomplete set of lengths */ - left = 1; - for (len = 1; len <= MAXBITS; len++) { - left <<= 1; - left -= count[len]; - if (left < 0) return -1; /* over-subscribed */ - } - if (left > 0 && (type == CODES || max != 1)) - return -1; /* incomplete set */ - - /* generate offsets into symbol table for each length for sorting */ - offs[1] = 0; - for (len = 1; len < MAXBITS; len++) - offs[len + 1] = offs[len] + count[len]; - - /* sort symbols by length, by symbol order within each length */ - for (sym = 0; sym < codes; sym++) - if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym; - - /* - Create and fill in decoding tables. In this loop, the table being - filled is at next and has curr index bits. The code being used is huff - with length len. That code is converted to an index by dropping drop - bits off of the bottom. For codes where len is less than drop + curr, - those top drop + curr - len bits are incremented through all values to - fill the table with replicated entries. - - root is the number of index bits for the root table. When len exceeds - root, sub-tables are created pointed to by the root entry with an index - of the low root bits of huff. This is saved in low to check for when a - new sub-table should be started. drop is zero when the root table is - being filled, and drop is root when sub-tables are being filled. - - When a new sub-table is needed, it is necessary to look ahead in the - code lengths to determine what size sub-table is needed. The length - counts are used for this, and so count[] is decremented as codes are - entered in the tables. - - used keeps track of how many table entries have been allocated from the - provided *table space. It is checked for LENS and DIST tables against - the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in - the initial root table size constants. See the comments in inftrees.h - for more information. - - sym increments through all symbols, and the loop terminates when - all codes of length max, i.e. all codes, have been processed. This - routine permits incomplete codes, so another loop after this one fills - in the rest of the decoding tables with invalid code markers. - */ - - /* set up for code type */ - switch (type) { - case CODES: - base = extra = work; /* dummy value--not used */ - end = 19; - break; - case LENS: - base = lbase; - base -= 257; - extra = lext; - extra -= 257; - end = 256; - break; - default: /* DISTS */ - base = dbase; - extra = dext; - end = -1; - } - - /* initialize state for loop */ - huff = 0; /* starting code */ - sym = 0; /* starting code symbol */ - len = min; /* starting code length */ - next = *table; /* current table to fill in */ - curr = root; /* current table index bits */ - drop = 0; /* current bits to drop from code for index */ - low = (unsigned)(-1); /* trigger new sub-table when len > root */ - used = 1U << root; /* use root table entries */ - mask = used - 1; /* mask for comparing low */ - - /* check available table space */ - if ((type == LENS && used >= ENOUGH_LENS) || - (type == DISTS && used >= ENOUGH_DISTS)) - return 1; - - /* process all codes and make table entries */ - for (;;) { - /* create table entry */ - here.bits = (unsigned char)(len - drop); - if ((int)(work[sym]) < end) { - here.op = (unsigned char)0; - here.val = work[sym]; - } - else if ((int)(work[sym]) > end) { - here.op = (unsigned char)(extra[work[sym]]); - here.val = base[work[sym]]; - } - else { - here.op = (unsigned char)(32 + 64); /* end of block */ - here.val = 0; - } - - /* replicate for those indices with low len bits equal to huff */ - incr = 1U << (len - drop); - fill = 1U << curr; - min = fill; /* save offset to next table */ - do { - fill -= incr; - next[(huff >> drop) + fill] = here; - } while (fill != 0); - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - - /* go to next symbol, update count, len */ - sym++; - if (--(count[len]) == 0) { - if (len == max) break; - len = lens[work[sym]]; - } - - /* create new sub-table if needed */ - if (len > root && (huff & mask) != low) { - /* if first time, transition to sub-tables */ - if (drop == 0) - drop = root; - - /* increment past last table */ - next += min; /* here min is 1 << curr */ - - /* determine length of next table */ - curr = len - drop; - left = (int)(1 << curr); - while (curr + drop < max) { - left -= count[curr + drop]; - if (left <= 0) break; - curr++; - left <<= 1; - } - - /* check for enough space */ - used += 1U << curr; - if ((type == LENS && used >= ENOUGH_LENS) || - (type == DISTS && used >= ENOUGH_DISTS)) - return 1; - - /* point entry in root table to sub-table */ - low = huff & mask; - (*table)[low].op = (unsigned char)curr; - (*table)[low].bits = (unsigned char)root; - (*table)[low].val = (unsigned short)(next - *table); - } - } - - /* - Fill in rest of table for incomplete codes. This loop is similar to the - loop above in incrementing huff for table indices. It is assumed that - len is equal to curr + drop, so there is no loop needed to increment - through high index bits. When the current sub-table is filled, the loop - drops back to the root table to fill in any remaining entries there. - */ - here.op = (unsigned char)64; /* invalid code marker */ - here.bits = (unsigned char)(len - drop); - here.val = (unsigned short)0; - while (huff != 0) { - /* when done with sub-table, drop back to root table */ - if (drop != 0 && (huff & mask) != low) { - drop = 0; - len = root; - next = *table; - here.bits = (unsigned char)len; - } - - /* put invalid code marker in table */ - next[huff >> drop] = here; - - /* backwards increment the len-bit code huff */ - incr = 1U << (len - 1); - while (huff & incr) - incr >>= 1; - if (incr != 0) { - huff &= incr - 1; - huff += incr; - } - else - huff = 0; - } - - /* set return parameters */ - *table += used; - *bits = root; - return 0; -} diff --git a/deps/zlib/inftrees.h b/deps/zlib/inftrees.h deleted file mode 100644 index baa53a0b1a1..00000000000 --- a/deps/zlib/inftrees.h +++ /dev/null @@ -1,62 +0,0 @@ -/* inftrees.h -- header to use inftrees.c - * Copyright (C) 1995-2005, 2010 Mark Adler - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* Structure for decoding tables. Each entry provides either the - information needed to do the operation requested by the code that - indexed that table entry, or it provides a pointer to another - table that indexes more bits of the code. op indicates whether - the entry is a pointer to another table, a literal, a length or - distance, an end-of-block, or an invalid code. For a table - pointer, the low four bits of op is the number of index bits of - that table. For a length or distance, the low four bits of op - is the number of extra bits to get after the code. bits is - the number of bits in this code or part of the code to drop off - of the bit buffer. val is the actual byte to output in the case - of a literal, the base length or distance, or the offset from - the current table to the next table. Each entry is four bytes. */ -typedef struct { - unsigned char op; /* operation, extra bits, table bits */ - unsigned char bits; /* bits in this part of the code */ - unsigned short val; /* offset in table or code value */ -} code; - -/* op values as set by inflate_table(): - 00000000 - literal - 0000tttt - table link, tttt != 0 is the number of table index bits - 0001eeee - length or distance, eeee is the number of extra bits - 01100000 - end of block - 01000000 - invalid code - */ - -/* Maximum size of the dynamic table. The maximum number of code structures is - 1444, which is the sum of 852 for literal/length codes and 592 for distance - codes. These values were found by exhaustive searches using the program - examples/enough.c found in the zlib distribtution. The arguments to that - program are the number of symbols, the initial root table size, and the - maximum bit length of a code. "enough 286 9 15" for literal/length codes - returns returns 852, and "enough 30 6 15" for distance codes returns 592. - The initial root table size (9 or 6) is found in the fifth argument of the - inflate_table() calls in inflate.c and infback.c. If the root table size is - changed, then these maximum sizes would be need to be recalculated and - updated. */ -#define ENOUGH_LENS 852 -#define ENOUGH_DISTS 592 -#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS) - -/* Type of code to build for inflate_table() */ -typedef enum { - CODES, - LENS, - DISTS -} codetype; - -int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens, - unsigned codes, code FAR * FAR *table, - unsigned FAR *bits, unsigned short FAR *work)); diff --git a/deps/zlib/trees.c b/deps/zlib/trees.c deleted file mode 100644 index 3e9a138c7ef..00000000000 --- a/deps/zlib/trees.c +++ /dev/null @@ -1,1244 +0,0 @@ -/* trees.c -- output deflated data using Huffman coding - * Copyright (C) 1995-2010 Jean-loup Gailly - * detect_data_type() function provided freely by Cosmin Truta, 2006 - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* - * ALGORITHM - * - * The "deflation" process uses several Huffman trees. The more - * common source values are represented by shorter bit sequences. - * - * Each code tree is stored in a compressed form which is itself - * a Huffman encoding of the lengths of all the code strings (in - * ascending order by source values). The actual code strings are - * reconstructed from the lengths in the inflate process, as described - * in the deflate specification. - * - * REFERENCES - * - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification". - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc - * - * Storer, James A. - * Data Compression: Methods and Theory, pp. 49-50. - * Computer Science Press, 1988. ISBN 0-7167-8156-5. - * - * Sedgewick, R. - * Algorithms, p290. - * Addison-Wesley, 1983. ISBN 0-201-06672-6. - */ - -/* @(#) $Id$ */ - -/* #define GEN_TREES_H */ - -#include "deflate.h" - -#ifdef DEBUG -# include -#endif - -/* =========================================================================== - * Constants - */ - -#define MAX_BL_BITS 7 -/* Bit length codes must not exceed MAX_BL_BITS bits */ - -#define END_BLOCK 256 -/* end of block literal code */ - -#define REP_3_6 16 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */ - -#define REPZ_3_10 17 -/* repeat a zero length 3-10 times (3 bits of repeat count) */ - -#define REPZ_11_138 18 -/* repeat a zero length 11-138 times (7 bits of repeat count) */ - -local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */ - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0}; - -local const int extra_dbits[D_CODES] /* extra bits for each distance code */ - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13}; - -local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */ - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7}; - -local const uch bl_order[BL_CODES] - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15}; -/* The lengths of the bit length codes are sent in order of decreasing - * probability, to avoid transmitting the lengths for unused bit length codes. - */ - -#define Buf_size (8 * 2*sizeof(char)) -/* Number of bits used within bi_buf. (bi_buf might be implemented on - * more than 16 bits on some systems.) - */ - -/* =========================================================================== - * Local data. These are initialized only once. - */ - -#define DIST_CODE_LEN 512 /* see definition of array dist_code below */ - -#if defined(GEN_TREES_H) || !defined(STDC) -/* non ANSI compilers may not accept trees.h */ - -local ct_data static_ltree[L_CODES+2]; -/* The static literal tree. Since the bit lengths are imposed, there is no - * need for the L_CODES extra codes used during heap construction. However - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init - * below). - */ - -local ct_data static_dtree[D_CODES]; -/* The static distance tree. (Actually a trivial tree since all codes use - * 5 bits.) - */ - -uch _dist_code[DIST_CODE_LEN]; -/* Distance codes. The first 256 values correspond to the distances - * 3 .. 258, the last 256 values correspond to the top 8 bits of - * the 15 bit distances. - */ - -uch _length_code[MAX_MATCH-MIN_MATCH+1]; -/* length code for each normalized match length (0 == MIN_MATCH) */ - -local int base_length[LENGTH_CODES]; -/* First normalized length for each code (0 = MIN_MATCH) */ - -local int base_dist[D_CODES]; -/* First normalized distance for each code (0 = distance of 1) */ - -#else -# include "trees.h" -#endif /* GEN_TREES_H */ - -struct static_tree_desc_s { - const ct_data *static_tree; /* static tree or NULL */ - const intf *extra_bits; /* extra bits for each code or NULL */ - int extra_base; /* base index for extra_bits */ - int elems; /* max number of elements in the tree */ - int max_length; /* max bit length for the codes */ -}; - -local static_tree_desc static_l_desc = -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS}; - -local static_tree_desc static_d_desc = -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS}; - -local static_tree_desc static_bl_desc = -{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS}; - -/* =========================================================================== - * Local (static) routines in this file. - */ - -local void tr_static_init OF((void)); -local void init_block OF((deflate_state *s)); -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k)); -local void gen_bitlen OF((deflate_state *s, tree_desc *desc)); -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count)); -local void build_tree OF((deflate_state *s, tree_desc *desc)); -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code)); -local int build_bl_tree OF((deflate_state *s)); -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes, - int blcodes)); -local void compress_block OF((deflate_state *s, ct_data *ltree, - ct_data *dtree)); -local int detect_data_type OF((deflate_state *s)); -local unsigned bi_reverse OF((unsigned value, int length)); -local void bi_windup OF((deflate_state *s)); -local void bi_flush OF((deflate_state *s)); -local void copy_block OF((deflate_state *s, charf *buf, unsigned len, - int header)); - -#ifdef GEN_TREES_H -local void gen_trees_header OF((void)); -#endif - -#ifndef DEBUG -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len) - /* Send a code of the given tree. c and tree must not have side effects */ - -#else /* DEBUG */ -# define send_code(s, c, tree) \ - { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \ - send_bits(s, tree[c].Code, tree[c].Len); } -#endif - -/* =========================================================================== - * Output a short LSB first on the stream. - * IN assertion: there is enough room in pendingBuf. - */ -#define put_short(s, w) { \ - put_byte(s, (uch)((w) & 0xff)); \ - put_byte(s, (uch)((ush)(w) >> 8)); \ -} - -/* =========================================================================== - * Send a value on a given number of bits. - * IN assertion: length <= 16 and value fits in length bits. - */ -#ifdef DEBUG -local void send_bits OF((deflate_state *s, int value, int length)); - -local void send_bits(s, value, length) - deflate_state *s; - int value; /* value to send */ - int length; /* number of bits */ -{ - Tracevv((stderr," l %2d v %4x ", length, value)); - Assert(length > 0 && length <= 15, "invalid length"); - s->bits_sent += (ulg)length; - - /* If not enough room in bi_buf, use (valid) bits from bi_buf and - * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid)) - * unused bits in value. - */ - if (s->bi_valid > (int)Buf_size - length) { - s->bi_buf |= (ush)value << s->bi_valid; - put_short(s, s->bi_buf); - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid); - s->bi_valid += length - Buf_size; - } else { - s->bi_buf |= (ush)value << s->bi_valid; - s->bi_valid += length; - } -} -#else /* !DEBUG */ - -#define send_bits(s, value, length) \ -{ int len = length;\ - if (s->bi_valid > (int)Buf_size - len) {\ - int val = value;\ - s->bi_buf |= (ush)val << s->bi_valid;\ - put_short(s, s->bi_buf);\ - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\ - s->bi_valid += len - Buf_size;\ - } else {\ - s->bi_buf |= (ush)(value) << s->bi_valid;\ - s->bi_valid += len;\ - }\ -} -#endif /* DEBUG */ - - -/* the arguments must not have side effects */ - -/* =========================================================================== - * Initialize the various 'constant' tables. - */ -local void tr_static_init() -{ -#if defined(GEN_TREES_H) || !defined(STDC) - static int static_init_done = 0; - int n; /* iterates over tree elements */ - int bits; /* bit counter */ - int length; /* length value */ - int code; /* code value */ - int dist; /* distance index */ - ush bl_count[MAX_BITS+1]; - /* number of codes at each bit length for an optimal tree */ - - if (static_init_done) return; - - /* For some embedded targets, global variables are not initialized: */ -#ifdef NO_INIT_GLOBAL_POINTERS - static_l_desc.static_tree = static_ltree; - static_l_desc.extra_bits = extra_lbits; - static_d_desc.static_tree = static_dtree; - static_d_desc.extra_bits = extra_dbits; - static_bl_desc.extra_bits = extra_blbits; -#endif - - /* Initialize the mapping length (0..255) -> length code (0..28) */ - length = 0; - for (code = 0; code < LENGTH_CODES-1; code++) { - base_length[code] = length; - for (n = 0; n < (1< dist code (0..29) */ - dist = 0; - for (code = 0 ; code < 16; code++) { - base_dist[code] = dist; - for (n = 0; n < (1<>= 7; /* from now on, all distances are divided by 128 */ - for ( ; code < D_CODES; code++) { - base_dist[code] = dist << 7; - for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) { - _dist_code[256 + dist++] = (uch)code; - } - } - Assert (dist == 256, "tr_static_init: 256+dist != 512"); - - /* Construct the codes of the static literal tree */ - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0; - n = 0; - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++; - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++; - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++; - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++; - /* Codes 286 and 287 do not exist, but we must include them in the - * tree construction to get a canonical Huffman tree (longest code - * all ones) - */ - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count); - - /* The static distance tree is trivial: */ - for (n = 0; n < D_CODES; n++) { - static_dtree[n].Len = 5; - static_dtree[n].Code = bi_reverse((unsigned)n, 5); - } - static_init_done = 1; - -# ifdef GEN_TREES_H - gen_trees_header(); -# endif -#endif /* defined(GEN_TREES_H) || !defined(STDC) */ -} - -/* =========================================================================== - * Genererate the file trees.h describing the static trees. - */ -#ifdef GEN_TREES_H -# ifndef DEBUG -# include -# endif - -# define SEPARATOR(i, last, width) \ - ((i) == (last)? "\n};\n\n" : \ - ((i) % (width) == (width)-1 ? ",\n" : ", ")) - -void gen_trees_header() -{ - FILE *header = fopen("trees.h", "w"); - int i; - - Assert (header != NULL, "Can't open trees.h"); - fprintf(header, - "/* header created automatically with -DGEN_TREES_H */\n\n"); - - fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n"); - for (i = 0; i < L_CODES+2; i++) { - fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code, - static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5)); - } - - fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code, - static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5)); - } - - fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n"); - for (i = 0; i < DIST_CODE_LEN; i++) { - fprintf(header, "%2u%s", _dist_code[i], - SEPARATOR(i, DIST_CODE_LEN-1, 20)); - } - - fprintf(header, - "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n"); - for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) { - fprintf(header, "%2u%s", _length_code[i], - SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20)); - } - - fprintf(header, "local const int base_length[LENGTH_CODES] = {\n"); - for (i = 0; i < LENGTH_CODES; i++) { - fprintf(header, "%1u%s", base_length[i], - SEPARATOR(i, LENGTH_CODES-1, 20)); - } - - fprintf(header, "local const int base_dist[D_CODES] = {\n"); - for (i = 0; i < D_CODES; i++) { - fprintf(header, "%5u%s", base_dist[i], - SEPARATOR(i, D_CODES-1, 10)); - } - - fclose(header); -} -#endif /* GEN_TREES_H */ - -/* =========================================================================== - * Initialize the tree data structures for a new zlib stream. - */ -void ZLIB_INTERNAL _tr_init(s) - deflate_state *s; -{ - tr_static_init(); - - s->l_desc.dyn_tree = s->dyn_ltree; - s->l_desc.stat_desc = &static_l_desc; - - s->d_desc.dyn_tree = s->dyn_dtree; - s->d_desc.stat_desc = &static_d_desc; - - s->bl_desc.dyn_tree = s->bl_tree; - s->bl_desc.stat_desc = &static_bl_desc; - - s->bi_buf = 0; - s->bi_valid = 0; - s->last_eob_len = 8; /* enough lookahead for inflate */ -#ifdef DEBUG - s->compressed_len = 0L; - s->bits_sent = 0L; -#endif - - /* Initialize the first block of the first file: */ - init_block(s); -} - -/* =========================================================================== - * Initialize a new block. - */ -local void init_block(s) - deflate_state *s; -{ - int n; /* iterates over tree elements */ - - /* Initialize the trees. */ - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0; - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0; - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0; - - s->dyn_ltree[END_BLOCK].Freq = 1; - s->opt_len = s->static_len = 0L; - s->last_lit = s->matches = 0; -} - -#define SMALLEST 1 -/* Index within the heap array of least frequent node in the Huffman tree */ - - -/* =========================================================================== - * Remove the smallest element from the heap and recreate the heap with - * one less element. Updates heap and heap_len. - */ -#define pqremove(s, tree, top) \ -{\ - top = s->heap[SMALLEST]; \ - s->heap[SMALLEST] = s->heap[s->heap_len--]; \ - pqdownheap(s, tree, SMALLEST); \ -} - -/* =========================================================================== - * Compares to subtrees, using the tree depth as tie breaker when - * the subtrees have equal frequency. This minimizes the worst case length. - */ -#define smaller(tree, n, m, depth) \ - (tree[n].Freq < tree[m].Freq || \ - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m])) - -/* =========================================================================== - * Restore the heap property by moving down the tree starting at node k, - * exchanging a node with the smallest of its two sons if necessary, stopping - * when the heap property is re-established (each father smaller than its - * two sons). - */ -local void pqdownheap(s, tree, k) - deflate_state *s; - ct_data *tree; /* the tree to restore */ - int k; /* node to move down */ -{ - int v = s->heap[k]; - int j = k << 1; /* left son of k */ - while (j <= s->heap_len) { - /* Set j to the smallest of the two sons: */ - if (j < s->heap_len && - smaller(tree, s->heap[j+1], s->heap[j], s->depth)) { - j++; - } - /* Exit if v is smaller than both sons */ - if (smaller(tree, v, s->heap[j], s->depth)) break; - - /* Exchange v with the smallest son */ - s->heap[k] = s->heap[j]; k = j; - - /* And continue down the tree, setting j to the left son of k */ - j <<= 1; - } - s->heap[k] = v; -} - -/* =========================================================================== - * Compute the optimal bit lengths for a tree and update the total bit length - * for the current block. - * IN assertion: the fields freq and dad are set, heap[heap_max] and - * above are the tree nodes sorted by increasing frequency. - * OUT assertions: the field len is set to the optimal bit length, the - * array bl_count contains the frequencies for each bit length. - * The length opt_len is updated; static_len is also updated if stree is - * not null. - */ -local void gen_bitlen(s, desc) - deflate_state *s; - tree_desc *desc; /* the tree descriptor */ -{ - ct_data *tree = desc->dyn_tree; - int max_code = desc->max_code; - const ct_data *stree = desc->stat_desc->static_tree; - const intf *extra = desc->stat_desc->extra_bits; - int base = desc->stat_desc->extra_base; - int max_length = desc->stat_desc->max_length; - int h; /* heap index */ - int n, m; /* iterate over the tree elements */ - int bits; /* bit length */ - int xbits; /* extra bits */ - ush f; /* frequency */ - int overflow = 0; /* number of elements with bit length too large */ - - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0; - - /* In a first pass, compute the optimal bit lengths (which may - * overflow in the case of the bit length tree). - */ - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */ - - for (h = s->heap_max+1; h < HEAP_SIZE; h++) { - n = s->heap[h]; - bits = tree[tree[n].Dad].Len + 1; - if (bits > max_length) bits = max_length, overflow++; - tree[n].Len = (ush)bits; - /* We overwrite tree[n].Dad which is no longer needed */ - - if (n > max_code) continue; /* not a leaf node */ - - s->bl_count[bits]++; - xbits = 0; - if (n >= base) xbits = extra[n-base]; - f = tree[n].Freq; - s->opt_len += (ulg)f * (bits + xbits); - if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits); - } - if (overflow == 0) return; - - Trace((stderr,"\nbit length overflow\n")); - /* This happens for example on obj2 and pic of the Calgary corpus */ - - /* Find the first bit length which could increase: */ - do { - bits = max_length-1; - while (s->bl_count[bits] == 0) bits--; - s->bl_count[bits]--; /* move one leaf down the tree */ - s->bl_count[bits+1] += 2; /* move one overflow item as its brother */ - s->bl_count[max_length]--; - /* The brother of the overflow item also moves one step up, - * but this does not affect bl_count[max_length] - */ - overflow -= 2; - } while (overflow > 0); - - /* Now recompute all bit lengths, scanning in increasing frequency. - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all - * lengths instead of fixing only the wrong ones. This idea is taken - * from 'ar' written by Haruhiko Okumura.) - */ - for (bits = max_length; bits != 0; bits--) { - n = s->bl_count[bits]; - while (n != 0) { - m = s->heap[--h]; - if (m > max_code) continue; - if ((unsigned) tree[m].Len != (unsigned) bits) { - Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits)); - s->opt_len += ((long)bits - (long)tree[m].Len) - *(long)tree[m].Freq; - tree[m].Len = (ush)bits; - } - n--; - } - } -} - -/* =========================================================================== - * Generate the codes for a given tree and bit counts (which need not be - * optimal). - * IN assertion: the array bl_count contains the bit length statistics for - * the given tree and the field len is set for all tree elements. - * OUT assertion: the field code is set for all tree elements of non - * zero code length. - */ -local void gen_codes (tree, max_code, bl_count) - ct_data *tree; /* the tree to decorate */ - int max_code; /* largest code with non zero frequency */ - ushf *bl_count; /* number of codes at each bit length */ -{ - ush next_code[MAX_BITS+1]; /* next code value for each bit length */ - ush code = 0; /* running code value */ - int bits; /* bit index */ - int n; /* code index */ - - /* The distribution counts are first used to generate the code values - * without bit reversal. - */ - for (bits = 1; bits <= MAX_BITS; bits++) { - next_code[bits] = code = (code + bl_count[bits-1]) << 1; - } - /* Check that the bit counts in bl_count are consistent. The last code - * must be all ones. - */ - Assert (code + bl_count[MAX_BITS]-1 == (1<dyn_tree; - const ct_data *stree = desc->stat_desc->static_tree; - int elems = desc->stat_desc->elems; - int n, m; /* iterate over heap elements */ - int max_code = -1; /* largest code with non zero frequency */ - int node; /* new node being created */ - - /* Construct the initial heap, with least frequent element in - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. - * heap[0] is not used. - */ - s->heap_len = 0, s->heap_max = HEAP_SIZE; - - for (n = 0; n < elems; n++) { - if (tree[n].Freq != 0) { - s->heap[++(s->heap_len)] = max_code = n; - s->depth[n] = 0; - } else { - tree[n].Len = 0; - } - } - - /* The pkzip format requires that at least one distance code exists, - * and that at least one bit should be sent even if there is only one - * possible code. So to avoid special checks later on we force at least - * two codes of non zero frequency. - */ - while (s->heap_len < 2) { - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0); - tree[node].Freq = 1; - s->depth[node] = 0; - s->opt_len--; if (stree) s->static_len -= stree[node].Len; - /* node is 0 or 1 so it does not have extra bits */ - } - desc->max_code = max_code; - - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, - * establish sub-heaps of increasing lengths: - */ - for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n); - - /* Construct the Huffman tree by repeatedly combining the least two - * frequent nodes. - */ - node = elems; /* next internal node of the tree */ - do { - pqremove(s, tree, n); /* n = node of least frequency */ - m = s->heap[SMALLEST]; /* m = node of next least frequency */ - - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */ - s->heap[--(s->heap_max)] = m; - - /* Create a new node father of n and m */ - tree[node].Freq = tree[n].Freq + tree[m].Freq; - s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ? - s->depth[n] : s->depth[m]) + 1); - tree[n].Dad = tree[m].Dad = (ush)node; -#ifdef DUMP_BL_TREE - if (tree == s->bl_tree) { - fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)", - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq); - } -#endif - /* and insert the new node in the heap */ - s->heap[SMALLEST] = node++; - pqdownheap(s, tree, SMALLEST); - - } while (s->heap_len >= 2); - - s->heap[--(s->heap_max)] = s->heap[SMALLEST]; - - /* At this point, the fields freq and dad are set. We can now - * generate the bit lengths. - */ - gen_bitlen(s, (tree_desc *)desc); - - /* The field len is now set, we can generate the bit codes */ - gen_codes ((ct_data *)tree, max_code, s->bl_count); -} - -/* =========================================================================== - * Scan a literal or distance tree to determine the frequencies of the codes - * in the bit length tree. - */ -local void scan_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - if (nextlen == 0) max_count = 138, min_count = 3; - tree[max_code+1].Len = (ush)0xffff; /* guard */ - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - s->bl_tree[curlen].Freq += (ush)count; - } else if (curlen != 0) { - if (curlen != prevlen) s->bl_tree[curlen].Freq++; - s->bl_tree[REP_3_6].Freq++; - } else if (count <= 10) { - s->bl_tree[REPZ_3_10].Freq++; - } else { - s->bl_tree[REPZ_11_138].Freq++; - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Send a literal or distance tree in compressed form, using the codes in - * bl_tree. - */ -local void send_tree (s, tree, max_code) - deflate_state *s; - ct_data *tree; /* the tree to be scanned */ - int max_code; /* and its largest code of non zero frequency */ -{ - int n; /* iterates over all tree elements */ - int prevlen = -1; /* last emitted length */ - int curlen; /* length of current code */ - int nextlen = tree[0].Len; /* length of next code */ - int count = 0; /* repeat count of the current code */ - int max_count = 7; /* max repeat count */ - int min_count = 4; /* min repeat count */ - - /* tree[max_code+1].Len = -1; */ /* guard already set */ - if (nextlen == 0) max_count = 138, min_count = 3; - - for (n = 0; n <= max_code; n++) { - curlen = nextlen; nextlen = tree[n+1].Len; - if (++count < max_count && curlen == nextlen) { - continue; - } else if (count < min_count) { - do { send_code(s, curlen, s->bl_tree); } while (--count != 0); - - } else if (curlen != 0) { - if (curlen != prevlen) { - send_code(s, curlen, s->bl_tree); count--; - } - Assert(count >= 3 && count <= 6, " 3_6?"); - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2); - - } else if (count <= 10) { - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3); - - } else { - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7); - } - count = 0; prevlen = curlen; - if (nextlen == 0) { - max_count = 138, min_count = 3; - } else if (curlen == nextlen) { - max_count = 6, min_count = 3; - } else { - max_count = 7, min_count = 4; - } - } -} - -/* =========================================================================== - * Construct the Huffman tree for the bit lengths and return the index in - * bl_order of the last bit length code to send. - */ -local int build_bl_tree(s) - deflate_state *s; -{ - int max_blindex; /* index of last bit length code of non zero freq */ - - /* Determine the bit length frequencies for literal and distance trees */ - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code); - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code); - - /* Build the bit length tree: */ - build_tree(s, (tree_desc *)(&(s->bl_desc))); - /* opt_len now includes the length of the tree representations, except - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts. - */ - - /* Determine the number of bit length codes to send. The pkzip format - * requires that at least 4 bit length codes be sent. (appnote.txt says - * 3 but the actual value used is 4.) - */ - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) { - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break; - } - /* Update opt_len to include the bit length tree and counts */ - s->opt_len += 3*(max_blindex+1) + 5+5+4; - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld", - s->opt_len, s->static_len)); - - return max_blindex; -} - -/* =========================================================================== - * Send the header for a block using dynamic Huffman trees: the counts, the - * lengths of the bit length codes, the literal tree and the distance tree. - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4. - */ -local void send_all_trees(s, lcodes, dcodes, blcodes) - deflate_state *s; - int lcodes, dcodes, blcodes; /* number of codes for each tree */ -{ - int rank; /* index in bl_order */ - - Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes"); - Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES, - "too many codes"); - Tracev((stderr, "\nbl counts: ")); - send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */ - send_bits(s, dcodes-1, 5); - send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */ - for (rank = 0; rank < blcodes; rank++) { - Tracev((stderr, "\nbl code %2d ", bl_order[rank])); - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3); - } - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */ - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent)); - - send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */ - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent)); -} - -/* =========================================================================== - * Send a stored block - */ -void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ -{ - send_bits(s, (STORED_BLOCK<<1)+last, 3); /* send block type */ -#ifdef DEBUG - s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L; - s->compressed_len += (stored_len + 4) << 3; -#endif - copy_block(s, buf, (unsigned)stored_len, 1); /* with header */ -} - -/* =========================================================================== - * Send one empty static block to give enough lookahead for inflate. - * This takes 10 bits, of which 7 may remain in the bit buffer. - * The current inflate code requires 9 bits of lookahead. If the - * last two codes for the previous block (real code plus EOB) were coded - * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode - * the last real code. In this case we send two empty static blocks instead - * of one. (There are no problems if the previous block is stored or fixed.) - * To simplify the code, we assume the worst case of last real code encoded - * on one bit only. - */ -void ZLIB_INTERNAL _tr_align(s) - deflate_state *s; -{ - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */ -#endif - bi_flush(s); - /* Of the 10 bits for the empty block, we have already sent - * (10 - bi_valid) bits. The lookahead for the last real code (before - * the EOB of the previous block) was thus at least one plus the length - * of the EOB plus what we have just sent of the empty static block. - */ - if (1 + s->last_eob_len + 10 - s->bi_valid < 9) { - send_bits(s, STATIC_TREES<<1, 3); - send_code(s, END_BLOCK, static_ltree); -#ifdef DEBUG - s->compressed_len += 10L; -#endif - bi_flush(s); - } - s->last_eob_len = 7; -} - -/* =========================================================================== - * Determine the best encoding for the current block: dynamic trees, static - * trees or store, and output the encoded block to the zip file. - */ -void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last) - deflate_state *s; - charf *buf; /* input block, or NULL if too old */ - ulg stored_len; /* length of input block */ - int last; /* one if this is the last block for a file */ -{ - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */ - int max_blindex = 0; /* index of last bit length code of non zero freq */ - - /* Build the Huffman trees unless a stored block is forced */ - if (s->level > 0) { - - /* Check if the file is binary or text */ - if (s->strm->data_type == Z_UNKNOWN) - s->strm->data_type = detect_data_type(s); - - /* Construct the literal and distance trees */ - build_tree(s, (tree_desc *)(&(s->l_desc))); - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - - build_tree(s, (tree_desc *)(&(s->d_desc))); - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len, - s->static_len)); - /* At this point, opt_len and static_len are the total bit lengths of - * the compressed block data, excluding the tree representations. - */ - - /* Build the bit length tree for the above two trees, and get the index - * in bl_order of the last bit length code to send. - */ - max_blindex = build_bl_tree(s); - - /* Determine the best encoding. Compute the block lengths in bytes. */ - opt_lenb = (s->opt_len+3+7)>>3; - static_lenb = (s->static_len+3+7)>>3; - - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ", - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len, - s->last_lit)); - - if (static_lenb <= opt_lenb) opt_lenb = static_lenb; - - } else { - Assert(buf != (char*)0, "lost buf"); - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */ - } - -#ifdef FORCE_STORED - if (buf != (char*)0) { /* force stored block */ -#else - if (stored_len+4 <= opt_lenb && buf != (char*)0) { - /* 4: two words for the lengths */ -#endif - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE. - * Otherwise we can't have processed more than WSIZE input bytes since - * the last block flush, because compression would have been - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to - * transform a block into a stored block. - */ - _tr_stored_block(s, buf, stored_len, last); - -#ifdef FORCE_STATIC - } else if (static_lenb >= 0) { /* force static trees */ -#else - } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) { -#endif - send_bits(s, (STATIC_TREES<<1)+last, 3); - compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree); -#ifdef DEBUG - s->compressed_len += 3 + s->static_len; -#endif - } else { - send_bits(s, (DYN_TREES<<1)+last, 3); - send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1, - max_blindex+1); - compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree); -#ifdef DEBUG - s->compressed_len += 3 + s->opt_len; -#endif - } - Assert (s->compressed_len == s->bits_sent, "bad compressed size"); - /* The above check is made mod 2^32, for files larger than 512 MB - * and uLong implemented on 32 bits. - */ - init_block(s); - - if (last) { - bi_windup(s); -#ifdef DEBUG - s->compressed_len += 7; /* align on byte boundary */ -#endif - } - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3, - s->compressed_len-7*last)); -} - -/* =========================================================================== - * Save the match info and tally the frequency counts. Return true if - * the current block must be flushed. - */ -int ZLIB_INTERNAL _tr_tally (s, dist, lc) - deflate_state *s; - unsigned dist; /* distance of matched string */ - unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */ -{ - s->d_buf[s->last_lit] = (ush)dist; - s->l_buf[s->last_lit++] = (uch)lc; - if (dist == 0) { - /* lc is the unmatched char */ - s->dyn_ltree[lc].Freq++; - } else { - s->matches++; - /* Here, lc is the match length - MIN_MATCH */ - dist--; /* dist = match distance - 1 */ - Assert((ush)dist < (ush)MAX_DIST(s) && - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) && - (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match"); - - s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++; - s->dyn_dtree[d_code(dist)].Freq++; - } - -#ifdef TRUNCATE_BLOCK - /* Try to guess if it is profitable to stop the current block here */ - if ((s->last_lit & 0x1fff) == 0 && s->level > 2) { - /* Compute an upper bound for the compressed length */ - ulg out_length = (ulg)s->last_lit*8L; - ulg in_length = (ulg)((long)s->strstart - s->block_start); - int dcode; - for (dcode = 0; dcode < D_CODES; dcode++) { - out_length += (ulg)s->dyn_dtree[dcode].Freq * - (5L+extra_dbits[dcode]); - } - out_length >>= 3; - Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ", - s->last_lit, in_length, out_length, - 100L - out_length*100L/in_length)); - if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1; - } -#endif - return (s->last_lit == s->lit_bufsize-1); - /* We avoid equality with lit_bufsize because of wraparound at 64K - * on 16 bit machines and because stored blocks are restricted to - * 64K-1 bytes. - */ -} - -/* =========================================================================== - * Send the block data compressed using the given Huffman trees - */ -local void compress_block(s, ltree, dtree) - deflate_state *s; - ct_data *ltree; /* literal tree */ - ct_data *dtree; /* distance tree */ -{ - unsigned dist; /* distance of matched string */ - int lc; /* match length or unmatched char (if dist == 0) */ - unsigned lx = 0; /* running index in l_buf */ - unsigned code; /* the code to send */ - int extra; /* number of extra bits to send */ - - if (s->last_lit != 0) do { - dist = s->d_buf[lx]; - lc = s->l_buf[lx++]; - if (dist == 0) { - send_code(s, lc, ltree); /* send a literal byte */ - Tracecv(isgraph(lc), (stderr," '%c' ", lc)); - } else { - /* Here, lc is the match length - MIN_MATCH */ - code = _length_code[lc]; - send_code(s, code+LITERALS+1, ltree); /* send the length code */ - extra = extra_lbits[code]; - if (extra != 0) { - lc -= base_length[code]; - send_bits(s, lc, extra); /* send the extra length bits */ - } - dist--; /* dist is now the match distance - 1 */ - code = d_code(dist); - Assert (code < D_CODES, "bad d_code"); - - send_code(s, code, dtree); /* send the distance code */ - extra = extra_dbits[code]; - if (extra != 0) { - dist -= base_dist[code]; - send_bits(s, dist, extra); /* send the extra distance bits */ - } - } /* literal or match pair ? */ - - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */ - Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx, - "pendingBuf overflow"); - - } while (lx < s->last_lit); - - send_code(s, END_BLOCK, ltree); - s->last_eob_len = ltree[END_BLOCK].Len; -} - -/* =========================================================================== - * Check if the data type is TEXT or BINARY, using the following algorithm: - * - TEXT if the two conditions below are satisfied: - * a) There are no non-portable control characters belonging to the - * "black list" (0..6, 14..25, 28..31). - * b) There is at least one printable character belonging to the - * "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255). - * - BINARY otherwise. - * - The following partially-portable control characters form a - * "gray list" that is ignored in this detection algorithm: - * (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}). - * IN assertion: the fields Freq of dyn_ltree are set. - */ -local int detect_data_type(s) - deflate_state *s; -{ - /* black_mask is the bit mask of black-listed bytes - * set bits 0..6, 14..25, and 28..31 - * 0xf3ffc07f = binary 11110011111111111100000001111111 - */ - unsigned long black_mask = 0xf3ffc07fUL; - int n; - - /* Check for non-textual ("black-listed") bytes. */ - for (n = 0; n <= 31; n++, black_mask >>= 1) - if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0)) - return Z_BINARY; - - /* Check for textual ("white-listed") bytes. */ - if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0 - || s->dyn_ltree[13].Freq != 0) - return Z_TEXT; - for (n = 32; n < LITERALS; n++) - if (s->dyn_ltree[n].Freq != 0) - return Z_TEXT; - - /* There are no "black-listed" or "white-listed" bytes: - * this stream either is empty or has tolerated ("gray-listed") bytes only. - */ - return Z_BINARY; -} - -/* =========================================================================== - * Reverse the first len bits of a code, using straightforward code (a faster - * method would use a table) - * IN assertion: 1 <= len <= 15 - */ -local unsigned bi_reverse(code, len) - unsigned code; /* the value to invert */ - int len; /* its bit length */ -{ - register unsigned res = 0; - do { - res |= code & 1; - code >>= 1, res <<= 1; - } while (--len > 0); - return res >> 1; -} - -/* =========================================================================== - * Flush the bit buffer, keeping at most 7 bits in it. - */ -local void bi_flush(s) - deflate_state *s; -{ - if (s->bi_valid == 16) { - put_short(s, s->bi_buf); - s->bi_buf = 0; - s->bi_valid = 0; - } else if (s->bi_valid >= 8) { - put_byte(s, (Byte)s->bi_buf); - s->bi_buf >>= 8; - s->bi_valid -= 8; - } -} - -/* =========================================================================== - * Flush the bit buffer and align the output on a byte boundary - */ -local void bi_windup(s) - deflate_state *s; -{ - if (s->bi_valid > 8) { - put_short(s, s->bi_buf); - } else if (s->bi_valid > 0) { - put_byte(s, (Byte)s->bi_buf); - } - s->bi_buf = 0; - s->bi_valid = 0; -#ifdef DEBUG - s->bits_sent = (s->bits_sent+7) & ~7; -#endif -} - -/* =========================================================================== - * Copy a stored block, storing first the length and its - * one's complement if requested. - */ -local void copy_block(s, buf, len, header) - deflate_state *s; - charf *buf; /* the input data */ - unsigned len; /* its length */ - int header; /* true if block header must be written */ -{ - bi_windup(s); /* align on byte boundary */ - s->last_eob_len = 8; /* enough lookahead for inflate */ - - if (header) { - put_short(s, (ush)len); - put_short(s, (ush)~len); -#ifdef DEBUG - s->bits_sent += 2*16; -#endif - } -#ifdef DEBUG - s->bits_sent += (ulg)len<<3; -#endif - while (len--) { - put_byte(s, *buf++); - } -} diff --git a/deps/zlib/trees.h b/deps/zlib/trees.h deleted file mode 100644 index d35639d82a2..00000000000 --- a/deps/zlib/trees.h +++ /dev/null @@ -1,128 +0,0 @@ -/* header created automatically with -DGEN_TREES_H */ - -local const ct_data static_ltree[L_CODES+2] = { -{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}}, -{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}}, -{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}}, -{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}}, -{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}}, -{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}}, -{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}}, -{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}}, -{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}}, -{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}}, -{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}}, -{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}}, -{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}}, -{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}}, -{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}}, -{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}}, -{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}}, -{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}}, -{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}}, -{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}}, -{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}}, -{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}}, -{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}}, -{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}}, -{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}}, -{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}}, -{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}}, -{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}}, -{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}}, -{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}}, -{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}}, -{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}}, -{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}}, -{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}}, -{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}}, -{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}}, -{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}}, -{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}}, -{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}}, -{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}}, -{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}}, -{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}}, -{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}}, -{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}}, -{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}}, -{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}}, -{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}}, -{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}}, -{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}}, -{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}}, -{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}}, -{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}}, -{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}}, -{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}}, -{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}}, -{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}}, -{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}}, -{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}} -}; - -local const ct_data static_dtree[D_CODES] = { -{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}}, -{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}}, -{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}}, -{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}}, -{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}}, -{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}} -}; - -const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8, - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, -10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, -11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, -13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17, -18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, -28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 -}; - -const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, -13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16, -17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, -19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, -21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, -22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23, -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, -26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 -}; - -local const int base_length[LENGTH_CODES] = { -0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56, -64, 80, 96, 112, 128, 160, 192, 224, 0 -}; - -local const int base_dist[D_CODES] = { - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24, - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768, - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 -}; - diff --git a/deps/zlib/zconf.h b/deps/zlib/zconf.h deleted file mode 100644 index 15081436128..00000000000 --- a/deps/zlib/zconf.h +++ /dev/null @@ -1,54 +0,0 @@ -/* zconf.h -- configuration of the zlib compression library - * Copyright (C) 1995-2010 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#ifndef ZCONF_H -#define ZCONF_H - -#include "../../src/common.h" - -/* Jeez, don't complain about non-prototype - * forms, we didn't write zlib */ -#if defined(_MSC_VER) -# pragma warning( disable : 4131 ) -#endif - -/* Maximum value for memLevel in deflateInit2 */ -#define MAX_MEM_LEVEL 9 - -/* Maximum value for windowBits in deflateInit2 and inflateInit2. - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files - * created by gzip. (Files created by minigzip can still be extracted by - * gzip.) - */ -#define MAX_WBITS 15 /* 32K LZ77 window */ - -#define ZEXTERN extern -#define ZEXPORT -#define ZEXPORTVA -#ifndef FAR -# define FAR -#endif -#define OF(args) args - -typedef unsigned char Byte; /* 8 bits */ -typedef unsigned int uInt; /* 16 bits or more */ -typedef unsigned long uLong; /* 32 bits or more */ - -typedef Byte FAR Bytef; -typedef char FAR charf; -typedef int FAR intf; -typedef uInt FAR uIntf; -typedef uLong FAR uLongf; - -typedef void const *voidpc; -typedef void FAR *voidpf; -typedef void *voidp; - -#define z_off_t git_off_t -#define z_off64_t z_off_t - -#endif /* ZCONF_H */ diff --git a/deps/zlib/zlib.h b/deps/zlib/zlib.h deleted file mode 100644 index bfbba83e8ee..00000000000 --- a/deps/zlib/zlib.h +++ /dev/null @@ -1,1613 +0,0 @@ -/* zlib.h -- interface of the 'zlib' general purpose compression library - version 1.2.5, April 19th, 2010 - - Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler - - This software is provided 'as-is', without any express or implied - warranty. In no event will the authors be held liable for any damages - arising from the use of this software. - - Permission is granted to anyone to use this software for any purpose, - including commercial applications, and to alter it and redistribute it - freely, subject to the following restrictions: - - 1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgment in the product documentation would be - appreciated but is not required. - 2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. - 3. This notice may not be removed or altered from any source distribution. - - Jean-loup Gailly Mark Adler - jloup@gzip.org madler@alumni.caltech.edu - - - The data format used by the zlib library is described by RFCs (Request for - Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt - (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). -*/ - -#ifndef ZLIB_H -#define ZLIB_H - -#include "zconf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ZLIB_VERSION "1.2.5" -#define ZLIB_VERNUM 0x1250 -#define ZLIB_VER_MAJOR 1 -#define ZLIB_VER_MINOR 2 -#define ZLIB_VER_REVISION 5 -#define ZLIB_VER_SUBREVISION 0 - -/* - The 'zlib' compression library provides in-memory compression and - decompression functions, including integrity checks of the uncompressed data. - This version of the library supports only one compression method (deflation) - but other algorithms will be added later and will have the same stream - interface. - - Compression can be done in a single step if the buffers are large enough, - or can be done by repeated calls of the compression function. In the latter - case, the application must provide more input and/or consume the output - (providing more output space) before each call. - - The compressed data format used by default by the in-memory functions is - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped - around a deflate stream, which is itself documented in RFC 1951. - - The library also supports reading and writing files in gzip (.gz) format - with an interface similar to that of stdio using the functions that start - with "gz". The gzip format is different from the zlib format. gzip is a - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream. - - This library can optionally read and write gzip streams in memory as well. - - The zlib format was designed to be compact and fast for use in memory - and on communications channels. The gzip format was designed for single- - file compression on file systems, has a larger header than zlib to maintain - directory information, and uses a different, slower check method than zlib. - - The library does not install any signal handler. The decoder checks - the consistency of the compressed data, so the library should never crash - even in case of corrupted input. -*/ - -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size)); -typedef void (*free_func) OF((voidpf opaque, voidpf address)); - -struct internal_state; - -typedef struct z_stream_s { - Bytef *next_in; /* next input byte */ - uInt avail_in; /* number of bytes available at next_in */ - uLong total_in; /* total nb of input bytes read so far */ - - Bytef *next_out; /* next output byte should be put there */ - uInt avail_out; /* remaining free space at next_out */ - uLong total_out; /* total nb of bytes output so far */ - - char *msg; /* last error message, NULL if no error */ - struct internal_state FAR *state; /* not visible by applications */ - - alloc_func zalloc; /* used to allocate the internal state */ - free_func zfree; /* used to free the internal state */ - voidpf opaque; /* private data object passed to zalloc and zfree */ - - int data_type; /* best guess about the data type: binary or text */ - uLong adler; /* adler32 value of the uncompressed data */ - uLong reserved; /* reserved for future use */ -} z_stream; - -typedef z_stream FAR *z_streamp; - -/* - gzip header information passed to and from zlib routines. See RFC 1952 - for more details on the meanings of these fields. -*/ -typedef struct gz_header_s { - int text; /* true if compressed data believed to be text */ - uLong time; /* modification time */ - int xflags; /* extra flags (not used when writing a gzip file) */ - int os; /* operating system */ - Bytef *extra; /* pointer to extra field or Z_NULL if none */ - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */ - uInt extra_max; /* space at extra (only when reading header) */ - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */ - uInt name_max; /* space at name (only when reading header) */ - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */ - uInt comm_max; /* space at comment (only when reading header) */ - int hcrc; /* true if there was or will be a header crc */ - int done; /* true when done reading gzip header (not used - when writing a gzip file) */ -} gz_header; - -typedef gz_header FAR *gz_headerp; - -/* - The application must update next_in and avail_in when avail_in has dropped - to zero. It must update next_out and avail_out when avail_out has dropped - to zero. The application must initialize zalloc, zfree and opaque before - calling the init function. All other fields are set by the compression - library and must not be updated by the application. - - The opaque value provided by the application will be passed as the first - parameter for calls of zalloc and zfree. This can be useful for custom - memory management. The compression library attaches no meaning to the - opaque value. - - zalloc must return Z_NULL if there is not enough memory for the object. - If zlib is used in a multi-threaded application, zalloc and zfree must be - thread safe. - - On 16-bit systems, the functions zalloc and zfree must be able to allocate - exactly 65536 bytes, but will not be required to allocate more than this if - the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS, pointers - returned by zalloc for objects of exactly 65536 bytes *must* have their - offset normalized to zero. The default allocation function provided by this - library ensures this (see zutil.c). To reduce memory requirements and avoid - any allocation of 64K objects, at the expense of compression ratio, compile - the library with -DMAX_WBITS=14 (see zconf.h). - - The fields total_in and total_out can be used for statistics or progress - reports. After compression, total_in holds the total size of the - uncompressed data and may be saved for use in the decompressor (particularly - if the decompressor wants to decompress everything in a single step). -*/ - - /* constants */ - -#define Z_NO_FLUSH 0 -#define Z_PARTIAL_FLUSH 1 -#define Z_SYNC_FLUSH 2 -#define Z_FULL_FLUSH 3 -#define Z_FINISH 4 -#define Z_BLOCK 5 -#define Z_TREES 6 -/* Allowed flush values; see deflate() and inflate() below for details */ - -#define Z_OK 0 -#define Z_STREAM_END 1 -#define Z_NEED_DICT 2 -#define Z_ERRNO (-1) -#define Z_STREAM_ERROR (-2) -#define Z_DATA_ERROR (-3) -#define Z_MEM_ERROR (-4) -#define Z_BUF_ERROR (-5) -#define Z_VERSION_ERROR (-6) -/* Return codes for the compression/decompression functions. Negative values - * are errors, positive values are used for special but normal events. - */ - -#define Z_NO_COMPRESSION 0 -#define Z_BEST_SPEED 1 -#define Z_BEST_COMPRESSION 9 -#define Z_DEFAULT_COMPRESSION (-1) -/* compression levels */ - -#define Z_FILTERED 1 -#define Z_HUFFMAN_ONLY 2 -#define Z_RLE 3 -#define Z_FIXED 4 -#define Z_DEFAULT_STRATEGY 0 -/* compression strategy; see deflateInit2() below for details */ - -#define Z_BINARY 0 -#define Z_TEXT 1 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */ -#define Z_UNKNOWN 2 -/* Possible values of the data_type field (though see inflate()) */ - -#define Z_DEFLATED 8 -/* The deflate compression method (the only one supported in this version) */ - -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */ - -#define zlib_version zlibVersion() -/* for compatibility with versions < 1.0.2 */ - - - /* basic functions */ - -ZEXTERN const char * ZEXPORT zlibVersion OF((void)); -/* The application can compare zlibVersion and ZLIB_VERSION for consistency. - If the first character differs, the library code actually used is not - compatible with the zlib.h header file used by the application. This check - is automatically made by deflateInit and inflateInit. - */ - -/* -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level)); - - Initializes the internal stream state for compression. The fields - zalloc, zfree and opaque must be initialized before by the caller. If - zalloc and zfree are set to Z_NULL, deflateInit updates them to use default - allocation functions. - - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9: - 1 gives best speed, 9 gives best compression, 0 gives no compression at all - (the input data is simply copied a block at a time). Z_DEFAULT_COMPRESSION - requests a default compromise between speed and compression (currently - equivalent to level 6). - - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if level is not a valid compression level, or - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible - with the version assumed by the caller (ZLIB_VERSION). msg is set to null - if there is no error message. deflateInit does not perform any compression: - this will be done by deflate(). -*/ - - -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush)); -/* - deflate compresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. deflate performs one or both of the - following actions: - - - Compress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in and avail_in are updated and - processing will resume at this point for the next call of deflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. This action is forced if the parameter flush is non zero. - Forcing flush frequently degrades the compression ratio, so this parameter - should be set only when necessary (in interactive applications). Some - output may be provided even if flush is not set. - - Before the call of deflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating avail_in or avail_out accordingly; avail_out should - never be zero before the call. The application can consume the compressed - output when it wants, for example when the output buffer is full (avail_out - == 0), or after each call of deflate(). If deflate returns Z_OK and with - zero avail_out, it must be called again after making room in the output - buffer because there might be more output pending. - - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to - decide how much data to accumulate before producing output, in order to - maximize compression. - - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is - flushed to the output buffer and the output is aligned on a byte boundary, so - that the decompressor can get all input data available so far. (In - particular avail_in is zero after the call if enough output space has been - provided before the call.) Flushing may degrade compression for some - compression algorithms and so it should be used only when necessary. This - completes the current deflate block and follows it with an empty stored block - that is three bits plus filler bits to the next byte, followed by four bytes - (00 00 ff ff). - - If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the - output buffer, but the output is not aligned to a byte boundary. All of the - input data so far will be available to the decompressor, as for Z_SYNC_FLUSH. - This completes the current deflate block and follows it with an empty fixed - codes block that is 10 bits long. This assures that enough bytes are output - in order for the decompressor to finish the block before the empty fixed code - block. - - If flush is set to Z_BLOCK, a deflate block is completed and emitted, as - for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to - seven bits of the current block are held to be written as the next byte after - the next deflate block is completed. In this case, the decompressor may not - be provided enough bits at this point in order to complete decompression of - the data provided so far to the compressor. It may need to wait for the next - block to be emitted. This is for advanced applications that need to control - the emission of deflate blocks. - - If flush is set to Z_FULL_FLUSH, all output is flushed as with - Z_SYNC_FLUSH, and the compression state is reset so that decompression can - restart from this point if previous compressed data has been damaged or if - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade - compression. - - If deflate returns with avail_out == 0, this function must be called again - with the same value of the flush parameter and more output space (updated - avail_out), until the flush is complete (deflate returns with non-zero - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that - avail_out is greater than six to avoid repeated flush markers due to - avail_out == 0 on return. - - If the parameter flush is set to Z_FINISH, pending input is processed, - pending output is flushed and deflate returns with Z_STREAM_END if there was - enough output space; if deflate returns with Z_OK, this function must be - called again with Z_FINISH and more output space (updated avail_out) but no - more input data, until it returns with Z_STREAM_END or an error. After - deflate has returned Z_STREAM_END, the only possible operations on the stream - are deflateReset or deflateEnd. - - Z_FINISH can be used immediately after deflateInit if all the compression - is to be done in a single step. In this case, avail_out must be at least the - value returned by deflateBound (see below). If deflate does not return - Z_STREAM_END, then it must be called again as described above. - - deflate() sets strm->adler to the adler32 checksum of all input read - so far (that is, total_in bytes). - - deflate() may update strm->data_type if it can make a good guess about - the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered - binary. This field is only for information purposes and does not affect the - compression algorithm in any manner. - - deflate() returns Z_OK if some progress has been made (more input - processed or more output produced), Z_STREAM_END if all input has been - consumed and all output has been produced (only when flush is set to - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example - if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible - (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not - fatal, and deflate() can be called again with more input and more output - space to continue compressing. -*/ - - -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the - stream state was inconsistent, Z_DATA_ERROR if the stream was freed - prematurely (some input or output was discarded). In the error case, msg - may be set but then points to a static string (which must not be - deallocated). -*/ - - -/* -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm)); - - Initializes the internal stream state for decompression. The fields - next_in, avail_in, zalloc, zfree and opaque must be initialized before by - the caller. If next_in is not Z_NULL and avail_in is large enough (the - exact value depends on the compression method), inflateInit determines the - compression method from the zlib header and allocates all data structures - accordingly; otherwise the allocation will be deferred to the first call of - inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to - use default allocation functions. - - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit() does not process any header information -- that is deferred - until inflate() is called. -*/ - - -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush)); -/* - inflate decompresses as much data as possible, and stops when the input - buffer becomes empty or the output buffer becomes full. It may introduce - some output latency (reading input without producing any output) except when - forced to flush. - - The detailed semantics are as follows. inflate performs one or both of the - following actions: - - - Decompress more input starting at next_in and update next_in and avail_in - accordingly. If not all input can be processed (because there is not - enough room in the output buffer), next_in is updated and processing will - resume at this point for the next call of inflate(). - - - Provide more output starting at next_out and update next_out and avail_out - accordingly. inflate() provides as much output as possible, until there is - no more input data or no more space in the output buffer (see below about - the flush parameter). - - Before the call of inflate(), the application should ensure that at least - one of the actions is possible, by providing more input and/or consuming more - output, and updating the next_* and avail_* values accordingly. The - application can consume the uncompressed output when it wants, for example - when the output buffer is full (avail_out == 0), or after each call of - inflate(). If inflate returns Z_OK and with zero avail_out, it must be - called again after making room in the output buffer because there might be - more output pending. - - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH, - Z_BLOCK, or Z_TREES. Z_SYNC_FLUSH requests that inflate() flush as much - output as possible to the output buffer. Z_BLOCK requests that inflate() - stop if and when it gets to the next deflate block boundary. When decoding - the zlib or gzip format, this will cause inflate() to return immediately - after the header and before the first block. When doing a raw inflate, - inflate() will go ahead and process the first block, and will return when it - gets to the end of that block, or when it runs out of data. - - The Z_BLOCK option assists in appending to or combining deflate streams. - Also to assist in this, on return inflate() will set strm->data_type to the - number of unused bits in the last byte taken from strm->next_in, plus 64 if - inflate() is currently decoding the last block in the deflate stream, plus - 128 if inflate() returned immediately after decoding an end-of-block code or - decoding the complete header up to just before the first byte of the deflate - stream. The end-of-block will not be indicated until all of the uncompressed - data from that block has been written to strm->next_out. The number of - unused bits may in general be greater than seven, except when bit 7 of - data_type is set, in which case the number of unused bits will be less than - eight. data_type is set as noted here every time inflate() returns for all - flush options, and so can be used to determine the amount of currently - consumed input in bits. - - The Z_TREES option behaves as Z_BLOCK does, but it also returns when the - end of each deflate block header is reached, before any actual data in that - block is decoded. This allows the caller to determine the length of the - deflate block header for later use in random access within a deflate block. - 256 is added to the value of strm->data_type when inflate() returns - immediately after reaching the end of the deflate block header. - - inflate() should normally be called until it returns Z_STREAM_END or an - error. However if all decompression is to be performed in a single step (a - single call of inflate), the parameter flush should be set to Z_FINISH. In - this case all pending input is processed and all pending output is flushed; - avail_out must be large enough to hold all the uncompressed data. (The size - of the uncompressed data may have been saved by the compressor for this - purpose.) The next operation on this stream must be inflateEnd to deallocate - the decompression state. The use of Z_FINISH is never required, but can be - used to inform inflate that a faster approach may be used for the single - inflate() call. - - In this implementation, inflate() always flushes as much output as - possible to the output buffer, and always uses the faster approach on the - first call. So the only effect of the flush parameter in this implementation - is on the return value of inflate(), as noted below, or when it returns early - because Z_BLOCK or Z_TREES is used. - - If a preset dictionary is needed after this call (see inflateSetDictionary - below), inflate sets strm->adler to the adler32 checksum of the dictionary - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets - strm->adler to the adler32 checksum of all output produced so far (that is, - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described - below. At the end of the stream, inflate() checks that its computed adler32 - checksum is equal to that saved by the compressor and returns Z_STREAM_END - only if the checksum is correct. - - inflate() can decompress and check either zlib-wrapped or gzip-wrapped - deflate data. The header type is detected automatically, if requested when - initializing with inflateInit2(). Any information contained in the gzip - header is not retained, so applications that need that information should - instead use raw inflate, see inflateInit2() below, or inflateBack() and - perform their own processing of the gzip header and trailer. - - inflate() returns Z_OK if some progress has been made (more input processed - or more output produced), Z_STREAM_END if the end of the compressed data has - been reached and all uncompressed output has been produced, Z_NEED_DICT if a - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was - corrupted (input stream not conforming to the zlib format or incorrect check - value), Z_STREAM_ERROR if the stream structure was inconsistent (for example - next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory, - Z_BUF_ERROR if no progress is possible or if there was not enough room in the - output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and - inflate() can be called again with more input and more output space to - continue decompressing. If Z_DATA_ERROR is returned, the application may - then call inflateSync() to look for a good compression block if a partial - recovery of the data is desired. -*/ - - -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm)); -/* - All dynamically allocated data structures for this stream are freed. - This function discards any unprocessed input and does not flush any pending - output. - - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state - was inconsistent. In the error case, msg may be set but then points to a - static string (which must not be deallocated). -*/ - - - /* Advanced functions */ - -/* - The following functions are needed only in some special applications. -*/ - -/* -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm, - int level, - int method, - int windowBits, - int memLevel, - int strategy)); - - This is another version of deflateInit with more compression options. The - fields next_in, zalloc, zfree and opaque must be initialized before by the - caller. - - The method parameter is the compression method. It must be Z_DEFLATED in - this version of the library. - - The windowBits parameter is the base two logarithm of the window size - (the size of the history buffer). It should be in the range 8..15 for this - version of the library. Larger values of this parameter result in better - compression at the expense of memory usage. The default value is 15 if - deflateInit is used instead. - - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits - determines the window size. deflate() will then generate raw deflate data - with no zlib header or trailer, and will not compute an adler32 check value. - - windowBits can also be greater than 15 for optional gzip encoding. Add - 16 to windowBits to write a simple gzip header and trailer around the - compressed data instead of a zlib wrapper. The gzip header will have no - file name, no extra data, no comment, no modification time (set to zero), no - header crc, and the operating system will be set to 255 (unknown). If a - gzip stream is being written, strm->adler is a crc32 instead of an adler32. - - The memLevel parameter specifies how much memory should be allocated - for the internal compression state. memLevel=1 uses minimum memory but is - slow and reduces compression ratio; memLevel=9 uses maximum memory for - optimal speed. The default value is 8. See zconf.h for total memory usage - as a function of windowBits and memLevel. - - The strategy parameter is used to tune the compression algorithm. Use the - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no - string match), or Z_RLE to limit match distances to one (run-length - encoding). Filtered data consists mostly of small values with a somewhat - random distribution. In this case, the compression algorithm is tuned to - compress them better. The effect of Z_FILTERED is to force more Huffman - coding and less string matching; it is somewhat intermediate between - Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as - fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data. The - strategy parameter only affects the compression ratio but not the - correctness of the compressed output even if it is not set appropriately. - Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler - decoder for special applications. - - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid - method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is - incompatible with the version assumed by the caller (ZLIB_VERSION). msg is - set to null if there is no error message. deflateInit2 does not perform any - compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the compression dictionary from the given byte sequence - without producing any compressed output. This function must be called - immediately after deflateInit, deflateInit2 or deflateReset, before any call - of deflate. The compressor and decompressor must use exactly the same - dictionary (see inflateSetDictionary). - - The dictionary should consist of strings (byte sequences) that are likely - to be encountered later in the data to be compressed, with the most commonly - used strings preferably put towards the end of the dictionary. Using a - dictionary is most useful when the data to be compressed is short and can be - predicted with good accuracy; the data can then be compressed better than - with the default empty dictionary. - - Depending on the size of the compression data structures selected by - deflateInit or deflateInit2, a part of the dictionary may in effect be - discarded, for example if the dictionary is larger than the window size - provided in deflateInit or deflateInit2. Thus the strings most likely to be - useful should be put at the end of the dictionary, not at the front. In - addition, the current implementation of deflate will use at most the window - size minus 262 bytes of the provided dictionary. - - Upon return of this function, strm->adler is set to the adler32 value - of the dictionary; the decompressor may later use this value to determine - which dictionary has been used by the compressor. (The adler32 value - applies to the whole dictionary even if only a subset of the dictionary is - actually used by the compressor.) If a raw deflate was requested, then the - adler32 value is not computed and strm->adler is not set. - - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent (for example if deflate has already been called for this stream - or if the compression method is bsort). deflateSetDictionary does not - perform any compression: this will be done by deflate(). -*/ - -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when several compression strategies will be - tried, for example when there are several ways of pre-processing the input - data with a filter. The streams that will be discarded should then be freed - by calling deflateEnd. Note that deflateCopy duplicates the internal - compression state which can be quite large, so this strategy is slow and can - consume lots of memory. - - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm)); -/* - This function is equivalent to deflateEnd followed by deflateInit, - but does not free and reallocate all the internal compression state. The - stream will keep the same compression level and any other attributes that - may have been set by deflateInit2. - - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm, - int level, - int strategy)); -/* - Dynamically update the compression level and compression strategy. The - interpretation of level and strategy is as in deflateInit2. This can be - used to switch between compression and straight copy of the input data, or - to switch to a different kind of input data requiring a different strategy. - If the compression level is changed, the input available so far is - compressed with the old level (and may be flushed); the new level will take - effect only at the next call of deflate(). - - Before the call of deflateParams, the stream state must be set as for - a call of deflate(), since the currently available input may have to be - compressed and flushed. In particular, strm->avail_out must be non-zero. - - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if - strm->avail_out was zero. -*/ - -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm, - int good_length, - int max_lazy, - int nice_length, - int max_chain)); -/* - Fine tune deflate's internal compression parameters. This should only be - used by someone who understands the algorithm used by zlib's deflate for - searching for the best matching string, and even then only by the most - fanatic optimizer trying to squeeze out the last compressed bit for their - specific input data. Read the deflate.c source code for the meaning of the - max_lazy, good_length, nice_length, and max_chain parameters. - - deflateTune() can be called after deflateInit() or deflateInit2(), and - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream. - */ - -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm, - uLong sourceLen)); -/* - deflateBound() returns an upper bound on the compressed size after - deflation of sourceLen bytes. It must be called after deflateInit() or - deflateInit2(), and after deflateSetHeader(), if used. This would be used - to allocate an output buffer for deflation in a single pass, and so would be - called before deflate(). -*/ - -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - deflatePrime() inserts bits in the deflate output stream. The intent - is that this function is used to start off the deflate output with the bits - leftover from a previous deflate stream when appending to it. As such, this - function can only be used for raw deflate, and must be used before the first - deflate() call after a deflateInit2() or deflateReset(). bits must be less - than or equal to 16, and that many of the least significant bits of value - will be inserted in the output. - - deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm, - gz_headerp head)); -/* - deflateSetHeader() provides gzip header information for when a gzip - stream is requested by deflateInit2(). deflateSetHeader() may be called - after deflateInit2() or deflateReset() and before the first call of - deflate(). The text, time, os, extra field, name, and comment information - in the provided gz_header structure are written to the gzip header (xflag is - ignored -- the extra flags are set according to the compression level). The - caller must assure that, if not Z_NULL, name and comment are terminated with - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are - available there. If hcrc is true, a gzip header crc is included. Note that - the current versions of the command-line version of gzip (up through version - 1.3.x) do not support header crc's, and will report that it is a "multi-part - gzip file" and give up. - - If deflateSetHeader is not used, the default gzip header has text false, - the time set to zero, and os set to 255, with no extra, name, or comment - fields. The gzip header is returned to the default state by deflateReset(). - - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm, - int windowBits)); - - This is another version of inflateInit with an extra parameter. The - fields next_in, avail_in, zalloc, zfree and opaque must be initialized - before by the caller. - - The windowBits parameter is the base two logarithm of the maximum window - size (the size of the history buffer). It should be in the range 8..15 for - this version of the library. The default value is 15 if inflateInit is used - instead. windowBits must be greater than or equal to the windowBits value - provided to deflateInit2() while compressing, or it must be equal to 15 if - deflateInit2() was not used. If a compressed stream with a larger window - size is given as input, inflate() will return with the error code - Z_DATA_ERROR instead of trying to allocate a larger window. - - windowBits can also be zero to request that inflate use the window size in - the zlib header of the compressed stream. - - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits - determines the window size. inflate() will then process raw deflate data, - not looking for a zlib or gzip header, not generating a check value, and not - looking for any check values for comparison at the end of the stream. This - is for use with other formats that use the deflate compressed data format - such as zip. Those formats provide their own check values. If a custom - format is developed using the raw deflate format for compressed data, it is - recommended that a check value such as an adler32 or a crc32 be applied to - the uncompressed data as is done in the zlib, gzip, and zip formats. For - most applications, the zlib format should be used as is. Note that comments - above on the use in deflateInit2() applies to the magnitude of windowBits. - - windowBits can also be greater than 15 for optional gzip decoding. Add - 32 to windowBits to enable zlib and gzip decoding with automatic header - detection, or add 16 to decode only the gzip format (the zlib format will - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is a - crc32 instead of an adler32. - - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the - version assumed by the caller, or Z_STREAM_ERROR if the parameters are - invalid, such as a null pointer to the structure. msg is set to null if - there is no error message. inflateInit2 does not perform any decompression - apart from possibly reading the zlib header if present: actual decompression - will be done by inflate(). (So next_in and avail_in may be modified, but - next_out and avail_out are unused and unchanged.) The current implementation - of inflateInit2() does not process any header information -- that is - deferred until inflate() is called. -*/ - -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm, - const Bytef *dictionary, - uInt dictLength)); -/* - Initializes the decompression dictionary from the given uncompressed byte - sequence. This function must be called immediately after a call of inflate, - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor - can be determined from the adler32 value returned by that call of inflate. - The compressor and decompressor must use exactly the same dictionary (see - deflateSetDictionary). For raw inflate, this function can be called - immediately after inflateInit2() or inflateReset() and before any call of - inflate() to set the dictionary. The application must insure that the - dictionary that was used for compression is provided. - - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a - parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the - expected one (incorrect adler32 value). inflateSetDictionary does not - perform any decompression: this will be done by subsequent calls of - inflate(). -*/ - -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm)); -/* - Skips invalid compressed data until a full flush point (see above the - description of deflate with Z_FULL_FLUSH) can be found, or until all - available input is skipped. No output is provided. - - inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR - if no more input was provided, Z_DATA_ERROR if no flush point has been - found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the - success case, the application may save the current current value of total_in - which indicates where valid compressed data was found. In the error case, - the application may repeatedly call inflateSync, providing more input each - time, until success or end of the input data. -*/ - -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest, - z_streamp source)); -/* - Sets the destination stream as a complete copy of the source stream. - - This function can be useful when randomly accessing a large stream. The - first pass through the stream can periodically record the inflate state, - allowing restarting inflate at those points when randomly accessing the - stream. - - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent - (such as zalloc being Z_NULL). msg is left unchanged in both source and - destination. -*/ - -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm)); -/* - This function is equivalent to inflateEnd followed by inflateInit, - but does not free and reallocate all the internal decompression state. The - stream will keep attributes that may have been set by inflateInit2. - - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL). -*/ - -ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm, - int windowBits)); -/* - This function is the same as inflateReset, but it also permits changing - the wrap and window size requests. The windowBits parameter is interpreted - the same as it is for inflateInit2. - - inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent (such as zalloc or state being Z_NULL), or if - the windowBits parameter is invalid. -*/ - -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm, - int bits, - int value)); -/* - This function inserts bits in the inflate input stream. The intent is - that this function is used to start inflating at a bit position in the - middle of a byte. The provided bits will be used before any bytes are used - from next_in. This function should only be used with raw inflate, and - should be used before the first inflate() call after inflateInit2() or - inflateReset(). bits must be less than or equal to 16, and that many of the - least significant bits of value will be inserted in the input. - - If bits is negative, then the input stream bit buffer is emptied. Then - inflatePrime() can be called again to put bits in the buffer. This is used - to clear out bits leftover after feeding inflate a block description prior - to feeding inflate codes. - - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm)); -/* - This function returns two values, one in the lower 16 bits of the return - value, and the other in the remaining upper bits, obtained by shifting the - return value down 16 bits. If the upper value is -1 and the lower value is - zero, then inflate() is currently decoding information outside of a block. - If the upper value is -1 and the lower value is non-zero, then inflate is in - the middle of a stored block, with the lower value equaling the number of - bytes from the input remaining to copy. If the upper value is not -1, then - it is the number of bits back from the current bit position in the input of - the code (literal or length/distance pair) currently being processed. In - that case the lower value is the number of bytes already emitted for that - code. - - A code is being processed if inflate is waiting for more input to complete - decoding of the code, or if it has completed decoding but is waiting for - more output space to write the literal or match data. - - inflateMark() is used to mark locations in the input data for random - access, which may be at bit positions, and to note those cases where the - output of a code may span boundaries of random access blocks. The current - location in the input stream can be determined from avail_in and data_type - as noted in the description for the Z_BLOCK flush parameter for inflate. - - inflateMark returns the value noted above or -1 << 16 if the provided - source stream state was inconsistent. -*/ - -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm, - gz_headerp head)); -/* - inflateGetHeader() requests that gzip header information be stored in the - provided gz_header structure. inflateGetHeader() may be called after - inflateInit2() or inflateReset(), and before the first call of inflate(). - As inflate() processes the gzip stream, head->done is zero until the header - is completed, at which time head->done is set to one. If a zlib stream is - being decoded, then head->done is set to -1 to indicate that there will be - no gzip header information forthcoming. Note that Z_BLOCK or Z_TREES can be - used to force inflate() to return immediately after header processing is - complete and before any actual data is decompressed. - - The text, time, xflags, and os fields are filled in with the gzip header - contents. hcrc is set to true if there is a header CRC. (The header CRC - was valid if done is set to one.) If extra is not Z_NULL, then extra_max - contains the maximum number of bytes to write to extra. Once done is true, - extra_len contains the actual extra field length, and extra contains the - extra field, or that field truncated if extra_max is less than extra_len. - If name is not Z_NULL, then up to name_max characters are written there, - terminated with a zero unless the length is greater than name_max. If - comment is not Z_NULL, then up to comm_max characters are written there, - terminated with a zero unless the length is greater than comm_max. When any - of extra, name, or comment are not Z_NULL and the respective field is not - present in the header, then that field is set to Z_NULL to signal its - absence. This allows the use of deflateSetHeader() with the returned - structure to duplicate the header. However if those fields are set to - allocated memory, then the application will need to save those pointers - elsewhere so that they can be eventually freed. - - If inflateGetHeader is not used, then the header information is simply - discarded. The header is always checked for validity, including the header - CRC if present. inflateReset() will reset the process to discard the header - information. The application would need to call inflateGetHeader() again to - retrieve the header from the next gzip stream. - - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source - stream state was inconsistent. -*/ - -/* -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits, - unsigned char FAR *window)); - - Initialize the internal stream state for decompression using inflateBack() - calls. The fields zalloc, zfree and opaque in strm must be initialized - before the call. If zalloc and zfree are Z_NULL, then the default library- - derived memory allocation routines are used. windowBits is the base two - logarithm of the window size, in the range 8..15. window is a caller - supplied buffer of that size. Except for special applications where it is - assured that deflate was used with small window sizes, windowBits must be 15 - and a 32K byte window must be supplied to be able to decompress general - deflate streams. - - See inflateBack() for the usage of these routines. - - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of - the paramaters are invalid, Z_MEM_ERROR if the internal state could not be - allocated, or Z_VERSION_ERROR if the version of the library does not match - the version of the header file. -*/ - -typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *)); -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned)); - -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, - in_func in, void FAR *in_desc, - out_func out, void FAR *out_desc)); -/* - inflateBack() does a raw inflate with a single call using a call-back - interface for input and output. This is more efficient than inflate() for - file i/o applications in that it avoids copying between the output and the - sliding window by simply making the window itself the output buffer. This - function trusts the application to not change the output buffer passed by - the output function, at least until inflateBack() returns. - - inflateBackInit() must be called first to allocate the internal state - and to initialize the state with the user-provided window buffer. - inflateBack() may then be used multiple times to inflate a complete, raw - deflate stream with each call. inflateBackEnd() is then called to free the - allocated state. - - A raw deflate stream is one with no zlib or gzip header or trailer. - This routine would normally be used in a utility that reads zip or gzip - files and writes out uncompressed files. The utility would decode the - header and process the trailer on its own, hence this routine expects only - the raw deflate stream to decompress. This is different from the normal - behavior of inflate(), which expects either a zlib or gzip header and - trailer around the deflate stream. - - inflateBack() uses two subroutines supplied by the caller that are then - called by inflateBack() for input and output. inflateBack() calls those - routines until it reads a complete deflate stream and writes out all of the - uncompressed data, or until it encounters an error. The function's - parameters and return types are defined above in the in_func and out_func - typedefs. inflateBack() will call in(in_desc, &buf) which should return the - number of bytes of provided input, and a pointer to that input in buf. If - there is no input available, in() must return zero--buf is ignored in that - case--and inflateBack() will return a buffer error. inflateBack() will call - out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out() - should return zero on success, or non-zero on failure. If out() returns - non-zero, inflateBack() will return with an error. Neither in() nor out() - are permitted to change the contents of the window provided to - inflateBackInit(), which is also the buffer that out() uses to write from. - The length written by out() will be at most the window size. Any non-zero - amount of input may be provided by in(). - - For convenience, inflateBack() can be provided input on the first call by - setting strm->next_in and strm->avail_in. If that input is exhausted, then - in() will be called. Therefore strm->next_in must be initialized before - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in - must also be initialized, and then if strm->avail_in is not zero, input will - initially be taken from strm->next_in[0 .. strm->avail_in - 1]. - - The in_desc and out_desc parameters of inflateBack() is passed as the - first parameter of in() and out() respectively when they are called. These - descriptors can be optionally used to pass any information that the caller- - supplied in() and out() functions need to do their job. - - On return, inflateBack() will set strm->next_in and strm->avail_in to - pass back any unused input that was provided by the last in() call. The - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR - if in() or out() returned an error, Z_DATA_ERROR if there was a format error - in the deflate stream (in which case strm->msg is set to indicate the nature - of the error), or Z_STREAM_ERROR if the stream was not properly initialized. - In the case of Z_BUF_ERROR, an input or output error can be distinguished - using strm->next_in which will be Z_NULL only if in() returned an error. If - strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning - non-zero. (in() will always be called before out(), so strm->next_in is - assured to be defined if out() returns non-zero.) Note that inflateBack() - cannot return Z_OK. -*/ - -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm)); -/* - All memory allocated by inflateBackInit() is freed. - - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream - state was inconsistent. -*/ - -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void)); -/* Return flags indicating compile-time options. - - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other: - 1.0: size of uInt - 3.2: size of uLong - 5.4: size of voidpf (pointer) - 7.6: size of z_off_t - - Compiler, assembler, and debug options: - 8: DEBUG - 9: ASMV or ASMINF -- use ASM code - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention - 11: 0 (reserved) - - One-time table building (smaller code, but not thread-safe if true): - 12: BUILDFIXED -- build static block decoding tables when needed - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed - 14,15: 0 (reserved) - - Library content (indicates missing functionality): - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking - deflate code when not needed) - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect - and decode gzip streams (to avoid linking crc code) - 18-19: 0 (reserved) - - Operation variations (changes in library functionality): - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate - 21: FASTEST -- deflate algorithm with only one, lowest compression level - 22,23: 0 (reserved) - - The sprintf variant used by gzprintf (zero is best): - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure! - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned - - Remainder: - 27-31: 0 (reserved) - */ - - - /* utility functions */ - -/* - The following utility functions are implemented on top of the basic - stream-oriented functions. To simplify the interface, some default options - are assumed (compression level and memory usage, standard memory allocation - functions). The source code of these utility functions can be modified if - you need special options. -*/ - -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Compresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer. -*/ - -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen, - int level)); -/* - Compresses the source buffer into the destination buffer. The level - parameter has the same meaning as in deflateInit. sourceLen is the byte - length of the source buffer. Upon entry, destLen is the total size of the - destination buffer, which must be at least the value returned by - compressBound(sourceLen). Upon exit, destLen is the actual size of the - compressed buffer. - - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough - memory, Z_BUF_ERROR if there was not enough room in the output buffer, - Z_STREAM_ERROR if the level parameter is invalid. -*/ - -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen)); -/* - compressBound() returns an upper bound on the compressed size after - compress() or compress2() on sourceLen bytes. It would be used before a - compress() or compress2() call to allocate the destination buffer. -*/ - -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen, - const Bytef *source, uLong sourceLen)); -/* - Decompresses the source buffer into the destination buffer. sourceLen is - the byte length of the source buffer. Upon entry, destLen is the total size - of the destination buffer, which must be large enough to hold the entire - uncompressed data. (The size of the uncompressed data must have been saved - previously by the compressor and transmitted to the decompressor by some - mechanism outside the scope of this compression library.) Upon exit, destLen - is the actual size of the uncompressed buffer. - - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not - enough memory, Z_BUF_ERROR if there was not enough room in the output - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. -*/ - - - /* gzip file access functions */ - -/* - This library supports reading and writing files in gzip (.gz) format with - an interface similar to that of stdio, using the functions that start with - "gz". The gzip format is different from the zlib format. gzip is a gzip - wrapper, documented in RFC 1952, wrapped around a deflate stream. -*/ - -typedef voidp gzFile; /* opaque gzip file descriptor */ - -/* -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode)); - - Opens a gzip (.gz) file for reading or writing. The mode parameter is as - in fopen ("rb" or "wb") but can also include a compression level ("wb9") or - a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only - compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F' - for fixed code compression as in "wb9F". (See the description of - deflateInit2 for more information about the strategy parameter.) Also "a" - can be used instead of "w" to request that the gzip stream that will be - written be appended to the file. "+" will result in an error, since reading - and writing to the same gzip file is not supported. - - gzopen can be used to read a file which is not in gzip format; in this - case gzread will directly read from the file without decompression. - - gzopen returns NULL if the file could not be opened, if there was - insufficient memory to allocate the gzFile state, or if an invalid mode was - specified (an 'r', 'w', or 'a' was not provided, or '+' was provided). - errno can be checked to determine if the reason gzopen failed was that the - file could not be opened. -*/ - -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode)); -/* - gzdopen associates a gzFile with the file descriptor fd. File descriptors - are obtained from calls like open, dup, creat, pipe or fileno (if the file - has been previously opened with fopen). The mode parameter is as in gzopen. - - The next call of gzclose on the returned gzFile will also close the file - descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor - fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd, - mode);. The duplicated descriptor should be saved to avoid a leak, since - gzdopen does not close fd if it fails. - - gzdopen returns NULL if there was insufficient memory to allocate the - gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not - provided, or '+' was provided), or if fd is -1. The file descriptor is not - used until the next gz* read, write, seek, or close operation, so gzdopen - will not detect if fd is invalid (unless fd is -1). -*/ - -ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size)); -/* - Set the internal buffer size used by this library's functions. The - default buffer size is 8192 bytes. This function must be called after - gzopen() or gzdopen(), and before any other calls that read or write the - file. The buffer memory allocation is always deferred to the first read or - write. Two buffers are allocated, either both of the specified size when - writing, or one of the specified size and the other twice that size when - reading. A larger buffer size of, for example, 64K or 128K bytes will - noticeably increase the speed of decompression (reading). - - The new buffer size also affects the maximum length for gzprintf(). - - gzbuffer() returns 0 on success, or -1 on failure, such as being called - too late. -*/ - -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy)); -/* - Dynamically update the compression level or strategy. See the description - of deflateInit2 for the meaning of these parameters. - - gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not - opened for writing. -*/ - -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len)); -/* - Reads the given number of uncompressed bytes from the compressed file. If - the input file was not in gzip format, gzread copies the given number of - bytes into the buffer. - - After reaching the end of a gzip stream in the input, gzread will continue - to read, looking for another gzip stream, or failing that, reading the rest - of the input file directly without decompression. The entire input file - will be read if gzread is called until it returns less than the requested - len. - - gzread returns the number of uncompressed bytes actually read, less than - len for end of file, or -1 for error. -*/ - -ZEXTERN int ZEXPORT gzwrite OF((gzFile file, - voidpc buf, unsigned len)); -/* - Writes the given number of uncompressed bytes into the compressed file. - gzwrite returns the number of uncompressed bytes written or 0 in case of - error. -*/ - -ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...)); -/* - Converts, formats, and writes the arguments to the compressed file under - control of the format string, as in fprintf. gzprintf returns the number of - uncompressed bytes actually written, or 0 in case of error. The number of - uncompressed bytes written is limited to 8191, or one less than the buffer - size given to gzbuffer(). The caller should assure that this limit is not - exceeded. If it is exceeded, then gzprintf() will return an error (0) with - nothing written. In this case, there may also be a buffer overflow with - unpredictable consequences, which is possible only if zlib was compiled with - the insecure functions sprintf() or vsprintf() because the secure snprintf() - or vsnprintf() functions were not available. This can be determined using - zlibCompileFlags(). -*/ - -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s)); -/* - Writes the given null-terminated string to the compressed file, excluding - the terminating null character. - - gzputs returns the number of characters written, or -1 in case of error. -*/ - -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len)); -/* - Reads bytes from the compressed file until len-1 characters are read, or a - newline character is read and transferred to buf, or an end-of-file - condition is encountered. If any characters are read or if len == 1, the - string is terminated with a null character. If no characters are read due - to an end-of-file or len < 1, then the buffer is left untouched. - - gzgets returns buf which is a null-terminated string, or it returns NULL - for end-of-file or in case of error. If there was an error, the contents at - buf are indeterminate. -*/ - -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c)); -/* - Writes c, converted to an unsigned char, into the compressed file. gzputc - returns the value that was written, or -1 in case of error. -*/ - -ZEXTERN int ZEXPORT gzgetc OF((gzFile file)); -/* - Reads one byte from the compressed file. gzgetc returns this byte or -1 - in case of end of file or error. -*/ - -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file)); -/* - Push one character back onto the stream to be read as the first character - on the next read. At least one character of push-back is allowed. - gzungetc() returns the character pushed, or -1 on failure. gzungetc() will - fail if c is -1, and may fail if a character has been pushed but not read - yet. If gzungetc is used immediately after gzopen or gzdopen, at least the - output buffer size of pushed characters is allowed. (See gzbuffer above.) - The pushed character will be discarded if the stream is repositioned with - gzseek() or gzrewind(). -*/ - -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush)); -/* - Flushes all pending output into the compressed file. The parameter flush - is as in the deflate() function. The return value is the zlib error number - (see function gzerror below). gzflush is only permitted when writing. - - If the flush parameter is Z_FINISH, the remaining data is written and the - gzip stream is completed in the output. If gzwrite() is called again, a new - gzip stream will be started in the output. gzread() is able to read such - concatented gzip streams. - - gzflush should be called only when strictly necessary because it will - degrade compression if called too often. -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file, - z_off_t offset, int whence)); - - Sets the starting position for the next gzread or gzwrite on the given - compressed file. The offset represents a number of bytes in the - uncompressed data stream. The whence parameter is defined as in lseek(2); - the value SEEK_END is not supported. - - If the file is opened for reading, this function is emulated but can be - extremely slow. If the file is opened for writing, only forward seeks are - supported; gzseek then compresses a sequence of zeroes up to the new - starting position. - - gzseek returns the resulting offset location as measured in bytes from - the beginning of the uncompressed stream, or -1 in case of error, in - particular if the file is opened for writing and the new starting position - would be before the current position. -*/ - -ZEXTERN int ZEXPORT gzrewind OF((gzFile file)); -/* - Rewinds the given file. This function is supported only for reading. - - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file)); - - Returns the starting position for the next gzread or gzwrite on the given - compressed file. This position represents a number of bytes in the - uncompressed data stream, and is zero when starting, even if appending or - reading a gzip stream from the middle of a file using gzdopen(). - - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR) -*/ - -/* -ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file)); - - Returns the current offset in the file being read or written. This offset - includes the count of bytes that precede the gzip stream, for example when - appending or when using gzdopen() for reading. When reading, the offset - does not include as yet unused buffered input. This information can be used - for a progress indicator. On error, gzoffset() returns -1. -*/ - -ZEXTERN int ZEXPORT gzeof OF((gzFile file)); -/* - Returns true (1) if the end-of-file indicator has been set while reading, - false (0) otherwise. Note that the end-of-file indicator is set only if the - read tried to go past the end of the input, but came up short. Therefore, - just like feof(), gzeof() may return false even if there is no more data to - read, in the event that the last read request was for the exact number of - bytes remaining in the input file. This will happen if the input file size - is an exact multiple of the buffer size. - - If gzeof() returns true, then the read functions will return no more data, - unless the end-of-file indicator is reset by gzclearerr() and the input file - has grown since the previous end of file was detected. -*/ - -ZEXTERN int ZEXPORT gzdirect OF((gzFile file)); -/* - Returns true (1) if file is being copied directly while reading, or false - (0) if file is a gzip stream being decompressed. This state can change from - false to true while reading the input file if the end of a gzip stream is - reached, but is followed by data that is not another gzip stream. - - If the input file is empty, gzdirect() will return true, since the input - does not contain a gzip stream. - - If gzdirect() is used immediately after gzopen() or gzdopen() it will - cause buffers to be allocated to allow reading the file to determine if it - is a gzip file. Therefore if gzbuffer() is used, it should be called before - gzdirect(). -*/ - -ZEXTERN int ZEXPORT gzclose OF((gzFile file)); -/* - Flushes all pending output if necessary, closes the compressed file and - deallocates the (de)compression state. Note that once file is closed, you - cannot call gzerror with file, since its structures have been deallocated. - gzclose must not be called more than once on the same file, just as free - must not be called more than once on the same allocation. - - gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a - file operation error, or Z_OK on success. -*/ - -ZEXTERN int ZEXPORT gzclose_r OF((gzFile file)); -ZEXTERN int ZEXPORT gzclose_w OF((gzFile file)); -/* - Same as gzclose(), but gzclose_r() is only for use when reading, and - gzclose_w() is only for use when writing or appending. The advantage to - using these instead of gzclose() is that they avoid linking in zlib - compression or decompression code that is not used when only reading or only - writing respectively. If gzclose() is used, then both compression and - decompression code will be included the application when linking to a static - zlib library. -*/ - -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum)); -/* - Returns the error message for the last error which occurred on the given - compressed file. errnum is set to zlib error number. If an error occurred - in the file system and not in the compression library, errnum is set to - Z_ERRNO and the application may consult errno to get the exact error code. - - The application must not modify the returned string. Future calls to - this function may invalidate the previously returned string. If file is - closed, then the string previously returned by gzerror will no longer be - available. - - gzerror() should be used to distinguish errors from end-of-file for those - functions above that do not distinguish those cases in their return values. -*/ - -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file)); -/* - Clears the error and end-of-file flags for file. This is analogous to the - clearerr() function in stdio. This is useful for continuing to read a gzip - file that is being written concurrently. -*/ - - - /* checksum functions */ - -/* - These functions are not related to compression but are exported - anyway because they might be useful in applications using the compression - library. -*/ - -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len)); -/* - Update a running Adler-32 checksum with the bytes buf[0..len-1] and - return the updated checksum. If buf is Z_NULL, this function returns the - required initial value for the checksum. - - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed - much faster. - - Usage example: - - uLong adler = adler32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - adler = adler32(adler, buffer, length); - } - if (adler != original_adler) error(); -*/ - -/* -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2, - z_off_t len2)); - - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. -*/ - -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len)); -/* - Update a running CRC-32 with the bytes buf[0..len-1] and return the - updated CRC-32. If buf is Z_NULL, this function returns the required - initial value for the for the crc. Pre- and post-conditioning (one's - complement) is performed within this function so it shouldn't be done by the - application. - - Usage example: - - uLong crc = crc32(0L, Z_NULL, 0); - - while (read_buffer(buffer, length) != EOF) { - crc = crc32(crc, buffer, length); - } - if (crc != original_crc) error(); -*/ - -/* -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2)); - - Combine two CRC-32 check values into one. For two sequences of bytes, - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and - len2. -*/ - - - /* various hacks, don't look :) */ - -/* deflateInit and inflateInit are macros to allow checking the zlib version - * and the compiler's view of z_stream: - */ -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method, - int windowBits, int memLevel, - int strategy, const char *version, - int stream_size)); -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits, - const char *version, int stream_size)); -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits, - unsigned char FAR *window, - const char *version, - int stream_size)); -#define deflateInit(strm, level) \ - deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit(strm) \ - inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream)) -#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \ - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ - (strategy), ZLIB_VERSION, sizeof(z_stream)) -#define inflateInit2(strm, windowBits) \ - inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream)) -#define inflateBackInit(strm, windowBits, window) \ - inflateBackInit_((strm), (windowBits), (window), \ - ZLIB_VERSION, sizeof(z_stream)) - -/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or - * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if - * both are true, the application gets the *64 functions, and the regular - * functions are changed to 64 bits) -- in case these are set on systems - * without large file support, _LFS64_LARGEFILE must also be true - */ -#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int)); - ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t)); -#endif - -#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0 -# define gzopen gzopen64 -# define gzseek gzseek64 -# define gztell gztell64 -# define gzoffset gzoffset64 -# define adler32_combine adler32_combine64 -# define crc32_combine crc32_combine64 -# ifdef _LARGEFILE64_SOURCE - ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); -# endif -#else - ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *)); - ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int)); - ZEXTERN z_off_t ZEXPORT gztell OF((gzFile)); - ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile)); - ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t)); -#endif - -/* hack for buggy compilers */ -#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) - struct internal_state {int dummy;}; -#endif - -/* undocumented functions */ -ZEXTERN const char * ZEXPORT zError OF((int)); -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); -ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void)); -ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int)); - -#ifdef __cplusplus -} -#endif - -#endif /* ZLIB_H */ diff --git a/deps/zlib/zutil.c b/deps/zlib/zutil.c deleted file mode 100644 index 898ed345b0e..00000000000 --- a/deps/zlib/zutil.c +++ /dev/null @@ -1,318 +0,0 @@ -/* zutil.c -- target dependent utility functions for the compression library - * Copyright (C) 1995-2005, 2010 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* @(#) $Id$ */ - -#include "zutil.h" - -#ifndef NO_DUMMY_DECL -struct internal_state {int dummy;}; /* for buggy compilers */ -#endif - -const char * const z_errmsg[10] = { -"need dictionary", /* Z_NEED_DICT 2 */ -"stream end", /* Z_STREAM_END 1 */ -"", /* Z_OK 0 */ -"file error", /* Z_ERRNO (-1) */ -"stream error", /* Z_STREAM_ERROR (-2) */ -"data error", /* Z_DATA_ERROR (-3) */ -"insufficient memory", /* Z_MEM_ERROR (-4) */ -"buffer error", /* Z_BUF_ERROR (-5) */ -"incompatible version",/* Z_VERSION_ERROR (-6) */ -""}; - - -const char * ZEXPORT zlibVersion() -{ - return ZLIB_VERSION; -} - -uLong ZEXPORT zlibCompileFlags() -{ - uLong flags; - - flags = 0; - switch ((int)(sizeof(uInt))) { - case 2: break; - case 4: flags += 1; break; - case 8: flags += 2; break; - default: flags += 3; - } - switch ((int)(sizeof(uLong))) { - case 2: break; - case 4: flags += 1 << 2; break; - case 8: flags += 2 << 2; break; - default: flags += 3 << 2; - } - switch ((int)(sizeof(voidpf))) { - case 2: break; - case 4: flags += 1 << 4; break; - case 8: flags += 2 << 4; break; - default: flags += 3 << 4; - } - switch ((int)(sizeof(z_off_t))) { - case 2: break; - case 4: flags += 1 << 6; break; - case 8: flags += 2 << 6; break; - default: flags += 3 << 6; - } -#ifdef DEBUG - flags += 1 << 8; -#endif -#if defined(ASMV) || defined(ASMINF) - flags += 1 << 9; -#endif -#ifdef ZLIB_WINAPI - flags += 1 << 10; -#endif -#ifdef BUILDFIXED - flags += 1 << 12; -#endif -#ifdef DYNAMIC_CRC_TABLE - flags += 1 << 13; -#endif -#ifdef NO_GZCOMPRESS - flags += 1L << 16; -#endif -#ifdef NO_GZIP - flags += 1L << 17; -#endif -#ifdef PKZIP_BUG_WORKAROUND - flags += 1L << 20; -#endif -#ifdef FASTEST - flags += 1L << 21; -#endif -#ifdef STDC -# ifdef NO_vsnprintf - flags += 1L << 25; -# ifdef HAS_vsprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_vsnprintf_void - flags += 1L << 26; -# endif -# endif -#else - flags += 1L << 24; -# ifdef NO_snprintf - flags += 1L << 25; -# ifdef HAS_sprintf_void - flags += 1L << 26; -# endif -# else -# ifdef HAS_snprintf_void - flags += 1L << 26; -# endif -# endif -#endif - return flags; -} - -#ifdef DEBUG - -# ifndef verbose -# define verbose 0 -# endif -int ZLIB_INTERNAL z_verbose = verbose; - -void ZLIB_INTERNAL z_error (m) - char *m; -{ - fprintf(stderr, "%s\n", m); - exit(1); -} -#endif - -/* exported to allow conversion of error code to string for compress() and - * uncompress() - */ -const char * ZEXPORT zError(err) - int err; -{ - return ERR_MSG(err); -} - -#if defined(_WIN32_WCE) - /* The Microsoft C Run-Time Library for Windows CE doesn't have - * errno. We define it as a global variable to simplify porting. - * Its value is always 0 and should not be used. - */ - int errno = 0; -#endif - -#ifndef HAVE_MEMCPY - -void ZLIB_INTERNAL zmemcpy(dest, source, len) - Bytef* dest; - const Bytef* source; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = *source++; /* ??? to be unrolled */ - } while (--len != 0); -} - -int ZLIB_INTERNAL zmemcmp(s1, s2, len) - const Bytef* s1; - const Bytef* s2; - uInt len; -{ - uInt j; - - for (j = 0; j < len; j++) { - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1; - } - return 0; -} - -void ZLIB_INTERNAL zmemzero(dest, len) - Bytef* dest; - uInt len; -{ - if (len == 0) return; - do { - *dest++ = 0; /* ??? to be unrolled */ - } while (--len != 0); -} -#endif - - -#ifdef SYS16BIT - -#ifdef __TURBOC__ -/* Turbo C in 16-bit mode */ - -# define MY_ZCALLOC - -/* Turbo C malloc() does not allow dynamic allocation of 64K bytes - * and farmalloc(64K) returns a pointer with an offset of 8, so we - * must fix the pointer. Warning: the pointer must be put back to its - * original form in order to free it, use zcfree(). - */ - -#define MAX_PTR 10 -/* 10*64K = 640K */ - -local int next_ptr = 0; - -typedef struct ptr_table_s { - voidpf org_ptr; - voidpf new_ptr; -} ptr_table; - -local ptr_table table[MAX_PTR]; -/* This table is used to remember the original form of pointers - * to large buffers (64K). Such pointers are normalized with a zero offset. - * Since MSDOS is not a preemptive multitasking OS, this table is not - * protected from concurrent access. This hack doesn't work anyway on - * a protected system like OS/2. Use Microsoft C instead. - */ - -voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size) -{ - voidpf buf = opaque; /* just to make some compilers happy */ - ulg bsize = (ulg)items*size; - - /* If we allocate less than 65520 bytes, we assume that farmalloc - * will return a usable pointer which doesn't have to be normalized. - */ - if (bsize < 65520L) { - buf = farmalloc(bsize); - if (*(ush*)&buf != 0) return buf; - } else { - buf = farmalloc(bsize + 16L); - } - if (buf == NULL || next_ptr >= MAX_PTR) return NULL; - table[next_ptr].org_ptr = buf; - - /* Normalize the pointer to seg:0 */ - *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4; - *(ush*)&buf = 0; - table[next_ptr++].new_ptr = buf; - return buf; -} - -void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) -{ - int n; - if (*(ush*)&ptr != 0) { /* object < 64K */ - farfree(ptr); - return; - } - /* Find the original pointer */ - for (n = 0; n < next_ptr; n++) { - if (ptr != table[n].new_ptr) continue; - - farfree(table[n].org_ptr); - while (++n < next_ptr) { - table[n-1] = table[n]; - } - next_ptr--; - return; - } - ptr = opaque; /* just to make some compilers happy */ - Assert(0, "zcfree: ptr not found"); -} - -#endif /* __TURBOC__ */ - - -#ifdef M_I86 -/* Microsoft C in 16-bit mode */ - -# define MY_ZCALLOC - -#if (!defined(_MSC_VER) || (_MSC_VER <= 600)) -# define _halloc halloc -# define _hfree hfree -#endif - -voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - return _halloc((long)items, size); -} - -void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr) -{ - if (opaque) opaque = 0; /* to make compiler happy */ - _hfree(ptr); -} - -#endif /* M_I86 */ - -#endif /* SYS16BIT */ - - -#ifndef MY_ZCALLOC /* Any system without a special alloc function */ - -#ifndef STDC -extern voidp malloc OF((uInt size)); -extern voidp calloc OF((uInt items, uInt size)); -extern void free OF((voidpf ptr)); -#endif - -voidpf ZLIB_INTERNAL zcalloc (opaque, items, size) - voidpf opaque; - unsigned items; - unsigned size; -{ - if (opaque) items += size - size; /* make compiler happy */ - return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) : - (voidpf)calloc(items, size); -} - -void ZLIB_INTERNAL zcfree (opaque, ptr) - voidpf opaque; - voidpf ptr; -{ - free(ptr); - if (opaque) return; /* make compiler happy */ -} - -#endif /* MY_ZCALLOC */ diff --git a/deps/zlib/zutil.h b/deps/zlib/zutil.h deleted file mode 100644 index 258fa88799a..00000000000 --- a/deps/zlib/zutil.h +++ /dev/null @@ -1,274 +0,0 @@ -/* zutil.h -- internal interface and configuration of the compression library - * Copyright (C) 1995-2010 Jean-loup Gailly. - * For conditions of distribution and use, see copyright notice in zlib.h - */ - -/* WARNING: this file should *not* be used by applications. It is - part of the implementation of the compression library and is - subject to change. Applications should only use zlib.h. - */ - -/* @(#) $Id$ */ - -#ifndef ZUTIL_H -#define ZUTIL_H - -#if ((__GNUC__-0) * 10 + __GNUC_MINOR__-0 >= 33) && !defined(NO_VIZ) -# define ZLIB_INTERNAL __attribute__((visibility ("hidden"))) -#else -# define ZLIB_INTERNAL -#endif - -#include "zlib.h" - -#ifdef STDC -# if !(defined(_WIN32_WCE) && defined(_MSC_VER)) -# include -# endif -# include -# include -#endif - -#ifndef local -# define local static -#endif -/* compile with -Dlocal if your debugger can't find static symbols */ - -typedef unsigned char uch; -typedef uch FAR uchf; -typedef unsigned short ush; -typedef ush FAR ushf; -typedef unsigned long ulg; - -extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */ -/* (size given to avoid silly warnings with Visual C++) */ - -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)] - -#define ERR_RETURN(strm,err) \ - return (strm->msg = (char*)ERR_MSG(err), (err)) -/* To be used only when the state is known to be valid */ - - /* common constants */ - -#ifndef DEF_WBITS -# define DEF_WBITS MAX_WBITS -#endif -/* default windowBits for decompression. MAX_WBITS is for compression only */ - -#if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -#else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -#endif -/* default memLevel */ - -#define STORED_BLOCK 0 -#define STATIC_TREES 1 -#define DYN_TREES 2 -/* The three kinds of block type */ - -#define MIN_MATCH 3 -#define MAX_MATCH 258 -/* The minimum and maximum match lengths */ - -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */ - - /* target dependencies */ - -#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32)) -# define OS_CODE 0x00 -# if defined(__TURBOC__) || defined(__BORLANDC__) -# if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__)) - /* Allow compilation with ANSI keywords only enabled */ - void _Cdecl farfree( void *block ); - void *_Cdecl farmalloc( unsigned long nbytes ); -# else -# include -# endif -# else /* MSC or DJGPP */ -# include -# endif -#endif - -#ifdef AMIGA -# define OS_CODE 0x01 -#endif - -#if defined(VAXC) || defined(VMS) -# define OS_CODE 0x02 -# define F_OPEN(name, mode) \ - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512") -#endif - -#if defined(ATARI) || defined(atarist) -# define OS_CODE 0x05 -#endif - -#ifdef OS2 -# define OS_CODE 0x06 -# ifdef M_I86 -# include -# endif -#endif - -#if defined(MACOS) || defined(TARGET_OS_MAC) -# define OS_CODE 0x07 -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os -# include /* for fdopen */ -# else -# ifndef fdopen -# define fdopen(fd,mode) NULL /* No fdopen() */ -# endif -# endif -#endif - -#ifdef TOPS20 -# define OS_CODE 0x0a -#endif - -#ifdef WIN32 -# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */ -# define OS_CODE 0x0b -# endif -#endif - -#ifdef __50SERIES /* Prime/PRIMOS */ -# define OS_CODE 0x0f -#endif - -#if defined(_BEOS_) || defined(RISCOS) -# define fdopen(fd,mode) NULL /* No fdopen() */ -#endif - -#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX -# if defined(_WIN32_WCE) -# define fdopen(fd,mode) NULL /* No fdopen() */ -# ifndef _PTRDIFF_T_DEFINED - typedef int ptrdiff_t; -# define _PTRDIFF_T_DEFINED -# endif -# else -# define fdopen(fd,type) _fdopen(fd,type) -# endif -#endif - -#if defined(__BORLANDC__) - #pragma warn -8004 - #pragma warn -8008 - #pragma warn -8066 -#endif - -/* provide prototypes for these when building zlib without LFS */ -#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0 - ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t)); - ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t)); -#endif - - /* common defaults */ - -#ifndef OS_CODE -# define OS_CODE 0x03 /* assume Unix */ -#endif - -#ifndef F_OPEN -# define F_OPEN(name, mode) fopen((name), (mode)) -#endif - - /* functions */ - -#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif -#if defined(__CYGWIN__) -# ifndef HAVE_VSNPRINTF -# define HAVE_VSNPRINTF -# endif -#endif -#ifndef HAVE_VSNPRINTF -# ifdef MSDOS - /* vsnprintf may exist on some MS-DOS compilers (DJGPP?), - but for now we just assume it doesn't. */ -# define NO_vsnprintf -# endif -# ifdef __TURBOC__ -# define NO_vsnprintf -# endif -# ifdef WIN32 - /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */ -# if !defined(vsnprintf) && !defined(NO_vsnprintf) -# if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 ) -# define vsnprintf _vsnprintf -# endif -# endif -# endif -# ifdef __SASC -# define NO_vsnprintf -# endif -#endif -#ifdef VMS -# define NO_vsnprintf -#endif - -#if defined(pyr) -# define NO_MEMCPY -#endif -#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__) - /* Use our own functions for small and medium model with MSC <= 5.0. - * You may have to use the same strategy for Borland C (untested). - * The __SC__ check is for Symantec. - */ -# define NO_MEMCPY -#endif -#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY) -# define HAVE_MEMCPY -#endif -#ifdef HAVE_MEMCPY -# ifdef SMALL_MEDIUM /* MSDOS small or medium model */ -# define zmemcpy _fmemcpy -# define zmemcmp _fmemcmp -# define zmemzero(dest, len) _fmemset(dest, 0, len) -# else -# define zmemcpy memcpy -# define zmemcmp memcmp -# define zmemzero(dest, len) memset(dest, 0, len) -# endif -#else - void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len)); - int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len)); - void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len)); -#endif - -/* Diagnostic functions */ -#ifdef DEBUG -# include - extern int ZLIB_INTERNAL z_verbose; - extern void ZLIB_INTERNAL z_error OF((char *m)); -# define Assert(cond,msg) {if(!(cond)) z_error(msg);} -# define Trace(x) {if (z_verbose>=0) fprintf x ;} -# define Tracev(x) {if (z_verbose>0) fprintf x ;} -# define Tracevv(x) {if (z_verbose>1) fprintf x ;} -# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;} -# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;} -#else -# define Assert(cond,msg) -# define Trace(x) -# define Tracev(x) -# define Tracevv(x) -# define Tracec(c,x) -# define Tracecv(c,x) -#endif - - -voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items, - unsigned size)); -void ZLIB_INTERNAL zcfree OF((voidpf opaque, voidpf ptr)); - -#define ZALLOC(strm, items, size) \ - (*((strm)->zalloc))((strm)->opaque, (items), (size)) -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr)) -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);} - -#endif /* ZUTIL_H */ diff --git a/docs/error-handling.md b/docs/error-handling.md deleted file mode 100644 index 655afeba8a8..00000000000 --- a/docs/error-handling.md +++ /dev/null @@ -1,111 +0,0 @@ -Error reporting in libgit2 -========================== - -Error reporting is performed on an explicit `git_error **` argument, which appears at the end of all API calls that can return an error. Yes, this does clutter the API. - -When a function fails, an error is set on the error variable **and** returns one of the generic error codes. - -~~~c -int git_repository_open(git_repository **repository, const char *path, git_error **error) -{ - // perform some opening - if (p_exists(path) < 0) { - giterr_set(error, GITERR_REPOSITORY, "The path '%s' doesn't exist", path); - return GIT_ENOTFOUND; - } - - ... - - if (try_to_parse(path, error) < 0) - return GIT_ERROR; - - ... -} -~~~ - -The simple error API --------------------- - -- `void giterr_set(git_error **, int, const char *, ...)`: the main function used to set an error. It allocates a new error object and stores it in the passed error pointer. It has no return value. The arguments for `giterr_set` are as follows: - - - `git_error **error_ptr`: the pointer where the error will be created. - - `int error_class`: the class for the error. This is **not** an error code: this is an specific enum that specifies the error family. The point is to map these families 1-1 with Exception types on higher level languages (e.g. GitRepositoryException) - - `const char *error_str, ...`: the error string, with optional formatting arguments - -- `void giterr_free(git_error *)`: takes an error and frees it. This function is available in the external API. - -- `void giterr_clear(git_error **)`: clears an error previously set in an error pointer, setting it to NULL and calling `giterr_free` on it. - -- `void giterr_propagate(git_error **, git_error *)`: moves an error to a given error pointer, handling the case when the error pointer is NULL (in that case the error gets freed, because it cannot be propagated). - -The new error code return values --------------------------------- - -We are doing this the POSIX way: one error code for each "expected failure", and a generic error code for all the critical failures. - -For instance: A reference lookup can have an expected failure (which is when the reference cannot be found), and a critical failure (which could be any of a long list of things that could go wrong, such as the refs packfile being corrupted, a loose ref being written with the wrong permissions, etc). We cannot have distinct error codes for every single error in the library, hence `git_reference_lookup` would return GIT_SUCCESS if the operation was successful, GIT_ENOTFOUND when the reference doesn't exist, and GIT_ERROR when an error happens -- **the error is then detailed in the `git_error` parameter**. - -Please be smart when returning error codes. Functions have max two "expected errors", and in most cases only one. - -Writing error messages ----------------------- - -Here are some guidelines when writing error messages: - -- Use proper English, and an impersonal or past tenses: *The given path does not exist*, *Failed to lookup object in ODB* - -- Use short, direct and objective messages. **One line, max**. libgit2 is a low level library: think that all the messages reported will be thrown as Ruby or Python exceptions. Think how long are common exception messages in those languages. - -- **Do not add redundant information to the error message**, specially information that can be inferred from the context. - - E.g. in `git_repository_open`, do not report a message like "Failed to open repository: path not found". Somebody is - calling that function. If it fails, he already knows that the repository failed to open! - -General guidelines for error reporting --------------------------------------- - -- We never handle programming errors with these functions. Programming errors are `assert`ed, and when their source is internal, fixed as soon as possible. This is C, people. - - Example of programming errors that would **not** be handled: passing NULL to a function that expects a valid pointer; passing a `git_tree` to a function that expects a `git_commit`. All these cases need to be identified with `assert` and fixed asap. - - Example of a runtime error: failing to parse a `git_tree` because it contains invalid data. Failing to open a file because it doesn't exist on disk. These errors would be handled, and a `git_error` would be set. - -- The `git_error **` argument is always the last in the signature of all API calls. No exceptions. - -- When the programmer (or us, internally) doesn't need error handling, he can pass `NULL` to the `git_error **` param. This means that the errors won't be *reported*, but obviously they still will be handled (i.e. the failing function will interrupt and return cleanly). This is transparently handled by `giterr_set` - -- `git_error *` **must be initialized to `NULL` before passing its value to a function!!** - - ~~~c - git_error *err; - git_error *good_error = NULL; - - git_foo_func(arg1, arg2, &error); // invalid: `error` is not initialized - git_foo_func2(arg1, arg2, &good_error); // OK! - git_foo_func3(arg1, arg2, NULL); // OK! But no error reporting! - ~~~ - -- Piling up errors is an error! Don't do this! Errors must always be free'd when a function returns. - - ~~~c - git_error *error = NULL; - - git_foo_func1(arg1, &error); - git_foo_func2(arg2, &error); // WRONG! What if func1 failed? `error` would leak! - ~~~ - -- Likewise: do not rethrow errors internally! - - ~~~c - int git_commit_create(..., git_error **error) - { - if (git_reference_exists("HEAD", error) < 0) { - /* HEAD does not exist; create it so we can commit... */ - if (git_reference_create("HEAD", error) < 0) { - /* error could be rethrown */ - } - } - -- Remember that errors are now allocated, and hence they need to be free'd after they've been used. Failure to do so internally (e.g. in the already seen examples of error piling) will be reported by Valgrind, so we can easily find where are we rethrowing errors. - -- Remember that any function that fails **will set an error object**, and that object will be freed. diff --git a/ex/HEAD/clone.html b/ex/HEAD/clone.html new file mode 100644 index 00000000000..528c250579f --- /dev/null +++ b/ex/HEAD/clone.html @@ -0,0 +1,159 @@ + + + + + clone.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

clone.c

+
+ +
+ +
+
#include "common.h"
+#include <git2.h>
+#include <git2/clone.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <unistd.h>
+
+struct dl_data {
+  git_indexer_stats fetch_stats;
+  git_indexer_stats checkout_stats;
+  git_checkout_opts opts;
+  int ret;
+  int finished;
+  const char *url;
+  const char *path;
+};
+
+static void *clone_thread(void *ptr)
+{
+  struct dl_data *data = (struct dl_data *)ptr;
+  git_repository *repo = NULL;
+
+
+ +
+

Kick off the clone

+
+
  data->ret = git_clone(&repo, data->url, data->path,
+                 &data->fetch_stats, &data->checkout_stats, 
+                 &data->opts);
+  if (repo) git_repository_free(repo);
+  data->finished = 1;
+
+  pthread_exit(&data->ret);
+}
+
+int do_clone(git_repository *repo, int argc, char **argv)
+{
+  struct dl_data data = {0};
+  pthread_t worker;
+
+
+ +
+

Validate args

+
+
  if (argc < 3) {
+    printf("USAGE: %s <url> <path>\n", argv[0]);
+    return -1;
+  }
+
+
+ +
+

Data for background thread

+
+
  data.url = argv[1];
+  data.path = argv[2];
+  data.opts.disable_filters = 1;
+  printf("Cloning '%s' to '%s'\n", data.url, data.path);
+
+
+ +
+

Create the worker thread

+
+
  pthread_create(&worker, NULL, clone_thread, &data);
+
+
+ +
+

Watch for progress information

+ +
+
  do {
+    usleep(10000);
+    printf("Fetch %d/%d  –  Checkout %d/%d\n",
+         data.fetch_stats.processed, data.fetch_stats.total,
+         data.checkout_stats.processed, data.checkout_stats.total);
+  } while (!data.finished);
+  printf("Fetch %d/%d  –  Checkout %d/%d\n",
+       data.fetch_stats.processed, data.fetch_stats.total,
+       data.checkout_stats.processed, data.checkout_stats.total);
+
+  return data.ret;
+}
+
+
+ diff --git a/ex/HEAD/diff.html b/ex/HEAD/diff.html new file mode 100644 index 00000000000..5e6d7129e7c --- /dev/null +++ b/ex/HEAD/diff.html @@ -0,0 +1,289 @@ + + + + + diff.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + +

diff.c

+
+ +
+ + +
+
#include <stdio.h>
+#include <git2.h>
+#include <stdlib.h>
+#include <string.h>
+
+void check(int error, const char *message)
+{
+  if (error) {
+    fprintf(stderr, "%s (%d)\n", message, error);
+    exit(1);
+  }
+}
+
+int resolve_to_tree(git_repository *repo, const char *identifier, git_tree **tree)
+{
+  int err = 0;
+  size_t len = strlen(identifier);
+  git_oid oid;
+  git_object *obj = NULL;
+
+  /* try to resolve as OID */
+  if (git_oid_fromstrn(&oid, identifier, len) == 0)
+    git_object_lookup_prefix(&obj, repo, &oid, len, GIT_OBJ_ANY);
+
+  /* try to resolve as reference */
+  if (obj == NULL) {
+    git_reference *ref, *resolved;
+    if (git_reference_lookup(&ref, repo, identifier) == 0) {
+      git_reference_resolve(&resolved, ref);
+      git_reference_free(ref);
+      if (resolved) {
+        git_object_lookup(&obj, repo, git_reference_oid(resolved), GIT_OBJ_ANY);
+        git_reference_free(resolved);
+      }
+    }
+  }
+
+  if (obj == NULL)
+    return GIT_ENOTFOUND;
+
+  switch (git_object_type(obj)) {
+  case GIT_OBJ_TREE:
+    *tree = (git_tree *)obj;
+    break;
+  case GIT_OBJ_COMMIT:
+    err = git_commit_tree(tree, (git_commit *)obj);
+    git_object_free(obj);
+    break;
+  default:
+    err = GIT_ENOTFOUND;
+  }
+
+  return err;
+}
+
+char *colors[] = {
+  "\033[m", /* reset */
+  "\033[1m", /* bold */
+  "\033[31m", /* red */
+  "\033[32m", /* green */
+  "\033[36m" /* cyan */
+};
+
+int printer(
+  void *data,
+  git_diff_delta *delta,
+  git_diff_range *range,
+  char usage,
+  const char *line,
+  size_t line_len)
+{
+  int *last_color = data, color = 0;
+
+  if (*last_color >= 0) {
+    switch (usage) {
+    case GIT_DIFF_LINE_ADDITION: color = 3; break;
+    case GIT_DIFF_LINE_DELETION: color = 2; break;
+    case GIT_DIFF_LINE_ADD_EOFNL: color = 3; break;
+    case GIT_DIFF_LINE_DEL_EOFNL: color = 2; break;
+    case GIT_DIFF_LINE_FILE_HDR: color = 1; break;
+    case GIT_DIFF_LINE_HUNK_HDR: color = 4; break;
+    default: color = 0;
+    }
+    if (color != *last_color) {
+      if (*last_color == 1 || color == 1)
+        fputs(colors[0], stdout);
+      fputs(colors[color], stdout);
+      *last_color = color;
+    }
+  }
+
+  fputs(line, stdout);
+  return 0;
+}
+
+int check_uint16_param(const char *arg, const char *pattern, uint16_t *val)
+{
+  size_t len = strlen(pattern);
+  uint16_t strval;
+  char *endptr = NULL;
+  if (strncmp(arg, pattern, len))
+    return 0;
+  strval = strtoul(arg + len, &endptr, 0);
+  if (endptr == arg)
+    return 0;
+  *val = strval;
+  return 1;
+}
+
+int check_str_param(const char *arg, const char *pattern, char **val)
+{
+  size_t len = strlen(pattern);
+  if (strncmp(arg, pattern, len))
+    return 0;
+  *val = (char *)(arg + len);
+  return 1;
+}
+
+void usage(const char *message, const char *arg)
+{
+  if (message && arg)
+    fprintf(stderr, "%s: %s\n", message, arg);
+  else if (message)
+    fprintf(stderr, "%s\n", message);
+  fprintf(stderr, "usage: diff [<tree-oid> [<tree-oid>]]\n");
+  exit(1);
+}
+
+int main(int argc, char *argv[])
+{
+  char path[GIT_PATH_MAX];
+  git_repository *repo = NULL;
+  git_tree *t1 = NULL, *t2 = NULL;
+  git_diff_options opts = {0};
+  git_diff_list *diff;
+  int i, color = -1, compact = 0, cached = 0;
+  char *a, *dir = ".", *treeish1 = NULL, *treeish2 = NULL;
+
+  /* parse arguments as copied from git-diff */
+
+  for (i = 1; i < argc; ++i) {
+    a = argv[i];
+
+    if (a[0] != '-') {
+      if (treeish1 == NULL)
+        treeish1 = a;
+      else if (treeish2 == NULL)
+        treeish2 = a;
+      else
+        usage("Only one or two tree identifiers can be provided", NULL);
+    }
+    else if (!strcmp(a, "-p") || !strcmp(a, "-u") ||
+      !strcmp(a, "--patch"))
+      compact = 0;
+    else if (!strcmp(a, "--cached"))
+      cached = 1;
+    else if (!strcmp(a, "--name-status"))
+      compact = 1;
+    else if (!strcmp(a, "--color"))
+      color = 0;
+    else if (!strcmp(a, "--no-color"))
+      color = -1;
+    else if (!strcmp(a, "-R"))
+      opts.flags |= GIT_DIFF_REVERSE;
+    else if (!strcmp(a, "-a") || !strcmp(a, "--text"))
+      opts.flags |= GIT_DIFF_FORCE_TEXT;
+    else if (!strcmp(a, "--ignore-space-at-eol"))
+      opts.flags |= GIT_DIFF_IGNORE_WHITESPACE_EOL;
+    else if (!strcmp(a, "-b") || !strcmp(a, "--ignore-space-change"))
+      opts.flags |= GIT_DIFF_IGNORE_WHITESPACE_CHANGE;
+    else if (!strcmp(a, "-w") || !strcmp(a, "--ignore-all-space"))
+      opts.flags |= GIT_DIFF_IGNORE_WHITESPACE;
+    else if (!strcmp(a, "--ignored"))
+      opts.flags |= GIT_DIFF_INCLUDE_IGNORED;
+    else if (!strcmp(a, "--untracked"))
+      opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED;
+    else if (!check_uint16_param(a, "-U", &opts.context_lines) &&
+      !check_uint16_param(a, "--unified=", &opts.context_lines) &&
+      !check_uint16_param(a, "--inter-hunk-context=",
+        &opts.interhunk_lines) &&
+      !check_str_param(a, "--src-prefix=", &opts.old_prefix) &&
+      !check_str_param(a, "--dst-prefix=", &opts.new_prefix))
+      usage("Unknown arg", a);
+  }
+
+  /* open repo */
+
+  check(git_repository_open_ext(&repo, dir, 0, NULL),
+    "Could not open repository");
+
+  if (treeish1)
+    check(resolve_to_tree(repo, treeish1, &t1), "Looking up first tree");
+  if (treeish2)
+    check(resolve_to_tree(repo, treeish2, &t2), "Looking up second tree");
+
+  /* <sha1> <sha2> */
+  /* <sha1> --cached */
+  /* <sha1> */
+  /* --cached */
+  /* nothing */
+
+  if (t1 && t2)
+    check(git_diff_tree_to_tree(repo, &opts, t1, t2, &diff), "Diff");
+  else if (t1 && cached)
+    check(git_diff_index_to_tree(repo, &opts, t1, &diff), "Diff");
+  else if (t1) {
+    git_diff_list *diff2;
+    check(git_diff_index_to_tree(repo, &opts, t1, &diff), "Diff");
+    check(git_diff_workdir_to_index(repo, &opts, &diff2), "Diff");
+    check(git_diff_merge(diff, diff2), "Merge diffs");
+    git_diff_list_free(diff2);
+  }
+  else if (cached) {
+    check(resolve_to_tree(repo, "HEAD", &t1), "looking up HEAD");
+    check(git_diff_index_to_tree(repo, &opts, t1, &diff), "Diff");
+  }
+  else
+    check(git_diff_workdir_to_index(repo, &opts, &diff), "Diff");
+
+  if (color >= 0)
+    fputs(colors[0], stdout);
+
+  if (compact)
+    check(git_diff_print_compact(diff, &color, printer), "Displaying diff");
+  else
+    check(git_diff_print_patch(diff, &color, printer), "Displaying diff");
+
+  if (color >= 0)
+    fputs(colors[0], stdout);
+
+  git_diff_list_free(diff);
+  git_tree_free(t1);
+  git_tree_free(t2);
+  git_repository_free(repo);
+
+  return 0;
+}
+
+
+ diff --git a/ex/HEAD/fetch.html b/ex/HEAD/fetch.html new file mode 100644 index 00000000000..7b60a537b39 --- /dev/null +++ b/ex/HEAD/fetch.html @@ -0,0 +1,254 @@ + + + + + fetch.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

fetch.c

+
+ +
+ +
+
#include "common.h"
+#include <git2.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <unistd.h>
+
+struct dl_data {
+  git_remote *remote;
+  git_off_t *bytes;
+  git_indexer_stats *stats;
+  int ret;
+  int finished;
+};
+
+static void progress_cb(const char *str, int len, void *data)
+{
+  data = data;
+  printf("remote: %.*s", len, str);
+  fflush(stdout); /* We don't have the \n to force the flush */
+}
+
+static void *download(void *ptr)
+{
+  struct dl_data *data = (struct dl_data *)ptr;
+
+
+ +
+

Connect to the remote end specifying that we want to fetch +information from it.

+
+
  if (git_remote_connect(data->remote, GIT_DIR_FETCH) < 0) {
+    data->ret = -1;
+    goto exit;
+  }
+
+
+ +
+

Download the packfile and index it. This function updates the +amount of received data and the indexer stats which lets you +inform the user about progress.

+
+
  if (git_remote_download(data->remote, data->bytes, data->stats) < 0) {
+    data->ret = -1;
+    goto exit;
+  }
+
+  data->ret = 0;
+
+exit:
+  data->finished = 1;
+  pthread_exit(&data->ret);
+}
+
+static int update_cb(const char *refname, const git_oid *a, const git_oid *b, void *data)
+{
+  char a_str[GIT_OID_HEXSZ+1], b_str[GIT_OID_HEXSZ+1];
+  data = data;
+
+  git_oid_fmt(b_str, b);
+  b_str[GIT_OID_HEXSZ] = '\0';
+
+  if (git_oid_iszero(a)) {
+    printf("[new]     %.20s %s\n", b_str, refname);
+  } else {
+    git_oid_fmt(a_str, a);
+    a_str[GIT_OID_HEXSZ] = '\0';
+    printf("[updated] %.10s..%.10s %s\n", a_str, b_str, refname);
+  }
+
+  return 0;
+}
+
+int fetch(git_repository *repo, int argc, char **argv)
+{
+  git_remote *remote = NULL;
+  git_off_t bytes = 0;
+  git_indexer_stats stats;
+  pthread_t worker;
+  struct dl_data data;
+  git_remote_callbacks callbacks;
+
+  argc = argc;
+
+
+ +
+

Figure out whether it’s a named remote or a URL

+
+
  printf("Fetching %s\n", argv[1]);
+  if (git_remote_load(&remote, repo, argv[1]) < 0) {
+    if (git_remote_new(&remote, repo, NULL, argv[1], NULL) < 0)
+      return -1;
+  }
+
+
+ +
+

Set up the callbacks (only update_tips for now)

+
+
  memset(&callbacks, 0, sizeof(callbacks));
+  callbacks.update_tips = &update_cb;
+  callbacks.progress = &progress_cb;
+  git_remote_set_callbacks(remote, &callbacks);
+
+
+ +
+

Set up the information for the background worker thread

+
+
  data.remote = remote;
+  data.bytes = &bytes;
+  data.stats = &stats;
+  data.ret = 0;
+  data.finished = 0;
+  memset(&stats, 0, sizeof(stats));
+
+  pthread_create(&worker, NULL, download, &data);
+
+
+ +
+

Loop while the worker thread is still running. Here we show processed +and total objects in the pack and the amount of received +data. Most frontends will probably want to show a percentage and +the download rate.

+
+
  do {
+    usleep(10000);
+
+    if (stats.total > 0)
+      printf("Received %d/%d objects (%d) in %d bytes\r",
+             stats.received, stats.total, stats.processed, bytes);
+  } while (!data.finished);
+
+  if (data.ret < 0)
+    goto on_error;
+
+  pthread_join(worker, NULL);
+  printf("\rReceived %d/%d objects in %zu bytes\n", stats.processed, stats.total, bytes);
+
+
+ +
+

Disconnect the underlying connection to prevent from idling.

+
+ +
+
+ +
+

Update the references in the remote’s namespace to point to the +right commits. This may be needed even if there was no packfile +to download, which can happen e.g. when the branches have been +changed but all the neede objects are available locally.

+ +
+
  if (git_remote_update_tips(remote) < 0)
+    return -1;
+
+  git_remote_free(remote);
+
+  return 0;
+
+ on_error:
+  git_remote_free(remote);
+  return -1;
+}
+
+
+ diff --git a/ex/HEAD/general.html b/ex/HEAD/general.html new file mode 100644 index 00000000000..281f445f269 --- /dev/null +++ b/ex/HEAD/general.html @@ -0,0 +1,912 @@ + + + + + general.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

general.c

+
+ +
+

libgit2 is a portable, pure C implementation of the Git core methods +provided as a re-entrant linkable library with a solid API, allowing you +to write native speed custom Git applications in any language which +supports C bindings.

+ +

This file is an example of using that API in a real, compilable C file. +As the API is updated, this file will be updated to demonstrate the +new functionality.

+ +

If you’re trying to write something in C using libgit2, you will also want +to check out the generated API documentation and the Usage Guide. We’ve +tried to link to the relevant sections of the API docs in each section in this file.

+ +

libgit2 only implements the core plumbing functions, not really the higher +level porcelain stuff. For a primer on Git Internals that you will need to know +to work with Git at this level, check out Chapter 9 of the Pro Git book.

+
+
+
+
+ +
+

Includes

+
+
+
+
+ +
+

Including the git2.h header will include all the other libgit2 headers that you need. +It should be the only thing you need to include in order to compile properly and get +all the libgit2 API.

+
+
#include <git2.h>
+#include <stdio.h>
+
+int main (int argc, char** argv)
+{
+
+
+ +
+

Opening the Repository

+
+
+
+
+ +
+

There are a couple of methods for opening a repository, this being the simplest. +There are also methods for specifying the index file and work tree locations, here +we are assuming they are in the normal places.

+
+
  git_repository *repo;
+  if (argc > 1) {
+    git_repository_open(&repo, argv[1]);
+  } else {
+    git_repository_open(&repo, "/opt/libgit2-test/.git");
+  }
+
+
+ +
+

SHA-1 Value Conversions

+
+
+
+
+ +
+

For our first example, we will convert a 40 character hex value to the 20 byte raw SHA1 value.

+
+
  printf("*Hex to Raw*\n");
+  char hex[] = "fd6e612585290339ea8bf39c692a7ff6a29cb7c3";
+
+
+ +
+

The git_oid is the structure that keeps the SHA value. We will use this throughout the example +for storing the value of the current SHA key we’re working with.

+
+
  git_oid oid;
+  git_oid_fromstr(&oid, hex);
+
+
+ +
+

Once we’ve converted the string into the oid value, we can get the raw value of the SHA.

+
+
  printf("Raw 20 bytes: [%.20s]\n", (&oid)->id);
+
+
+ +
+

Next we will convert the 20 byte raw SHA1 value to a human readable 40 char hex value.

+
+
  printf("\n*Raw to Hex*\n");
+  char out[41];
+  out[40] = '\0';
+
+
+ +
+

If you have a oid, you can easily get the hex value of the SHA as well.

+
+
  git_oid_fmt(out, &oid);
+  printf("SHA hex string: %s\n", out);
+
+
+ +
+

Working with the Object Database

+ +

libgit2 provides direct access to the object database. +The object database is where the actual objects are stored in Git. For +working with raw objects, we’ll need to get this structure from the +repository.

+
+
  git_odb *odb;
+  git_repository_odb(&odb, repo);
+
+
+ +
+

Raw Object Reading

+
+
  printf("\n*Raw Object Read*\n");
+  git_odb_object *obj;
+  git_otype otype;
+  const unsigned char *data;
+  const char *str_type;
+  int error;
+
+
+ +
+

We can read raw objects directly from the object database if we have the oid (SHA) +of the object. This allows us to access objects without knowing thier type and inspect +the raw bytes unparsed.

+
+
  error = git_odb_read(&obj, odb, &oid);
+
+
+ +
+

A raw object only has three properties – the type (commit, blob, tree or tag), the size +of the raw data and the raw, unparsed data itself. For a commit or tag, that raw data +is human readable plain ASCII text. For a blob it is just file contents, so it could be +text or binary data. For a tree it is a special binary format, so it’s unlikely to be +hugely helpful as a raw object.

+
+
  data = (const unsigned char *)git_odb_object_data(obj);
+  otype = git_odb_object_type(obj);
+
+
+ +
+

We provide methods to convert from the object type which is an enum, to a string +representation of that value (and vice-versa).

+
+
  str_type = git_object_type2string(otype);
+  printf("object length and type: %d, %s\n",
+      (int)git_odb_object_size(obj),
+      str_type);
+
+
+ +
+

For proper memory management, close the object when you are done with it or it will leak +memory.

+
+ +
+
+ +
+

Raw Object Writing

+
+
  printf("\n*Raw Object Write*\n");
+
+
+ +
+

You can also write raw object data to Git. This is pretty cool because it gives you +direct access to the key/value properties of Git. Here we’ll write a new blob object +that just contains a simple string. Notice that we have to specify the object type as +the git_otype enum.

+
+
  git_odb_write(&oid, odb, "test data", sizeof("test data") - 1, GIT_OBJ_BLOB);
+
+
+ +
+

Now that we’ve written the object, we can check out what SHA1 was generated when the +object was written to our database.

+
+
  git_oid_fmt(out, &oid);
+  printf("Written Object: %s\n", out);
+
+
+ +
+

Object Parsing

+ +

libgit2 has methods to parse every object type in Git so you don’t have to work directly +with the raw data. This is much faster and simpler than trying to deal with the raw data +yourself.

+
+
+
+
+ +
+

Commit Parsing

+ +

Parsing commit objects is simple and gives you access to all the data in the commit +– the // author (name, email, datetime), committer (same), tree, message, encoding and parent(s).

+
+
  printf("\n*Commit Parsing*\n");
+
+  git_commit *commit;
+  git_oid_fromstr(&oid, "f0877d0b841d75172ec404fc9370173dfffc20d1");
+
+  error = git_commit_lookup(&commit, repo, &oid);
+
+  const git_signature *author, *cmtter;
+  const char *message;
+  time_t ctime;
+  unsigned int parents, p;
+
+
+ +
+

Each of the properties of the commit object are accessible via methods, including commonly +needed variations, such as git_commit_time which returns the author time and _message +which gives you the commit message.

+
+
  message  = git_commit_message(commit);
+  author   = git_commit_author(commit);
+  cmtter   = git_commit_committer(commit);
+  ctime    = git_commit_time(commit);
+
+
+ +
+

The author and committer methods return [git_signature] structures, which give you name, email +and when, which is a git_time structure, giving you a timestamp and timezone offset.

+
+
  printf("Author: %s (%s)\n", author->name, author->email);
+
+
+ +
+

Commits can have zero or more parents. The first (root) commit will have no parents, most commits +will have one, which is the commit it was based on, and merge commits will have two or more. +Commits can technically have any number, though it’s pretty rare to have more than two.

+
+
  parents  = git_commit_parentcount(commit);
+  for (p = 0;p < parents;p++) {
+    git_commit *parent;
+    git_commit_parent(&parent, commit, p);
+    git_oid_fmt(out, git_commit_id(parent));
+    printf("Parent: %s\n", out);
+    git_commit_free(parent);
+  }
+
+
+ +
+

Don’t forget to close the object to prevent memory leaks. You will have to do this for +all the objects you open and parse.

+
+
  git_commit_free(commit);
+
+
+ +
+

Writing Commits

+ +

libgit2 provides a couple of methods to create commit objects easily as well. There are four +different create signatures, we’ll just show one of them here. You can read about the other +ones in the commit API docs.

+
+
  printf("\n*Commit Writing*\n");
+  git_oid tree_id, parent_id, commit_id;
+  git_tree *tree;
+  git_commit *parent;
+
+
+ +
+

Creating signatures for an authoring identity and time is pretty simple – you will need to have +this to create a commit in order to specify who created it and when. Default values for the name +and email should be found in the user.name and user.email configuration options. See the config +section of this example file to see how to access config values.

+
+
  git_signature_new((git_signature **)&author, "Scott Chacon", "schacon@gmail.com",
+      123456789, 60);
+  git_signature_new((git_signature **)&cmtter, "Scott A Chacon", "scott@github.com",
+      987654321, 90);
+
+
+ +
+

Commit objects need a tree to point to and optionally one or more parents. Here we’re creating oid +objects to create the commit with, but you can also use

+
+
  git_oid_fromstr(&tree_id, "28873d96b4e8f4e33ea30f4c682fd325f7ba56ac");
+  git_tree_lookup(&tree, repo, &tree_id);
+  git_oid_fromstr(&parent_id, "f0877d0b841d75172ec404fc9370173dfffc20d1");
+  git_commit_lookup(&parent, repo, &parent_id);
+
+
+ +
+

Here we actually create the commit object with a single call with all the values we need to create +the commit. The SHA key is written to the commit_id variable here.

+
+
  git_commit_create_v(
+    &commit_id, /* out id */
+    repo,
+    NULL, /* do not update the HEAD */
+    author,
+    cmtter,
+    NULL, /* use default message encoding */
+    "example commit",
+    tree,
+    1, parent);
+
+
+ +
+

Now we can take a look at the commit SHA we’ve generated.

+
+
  git_oid_fmt(out, &commit_id);
+  printf("New Commit: %s\n", out);
+
+
+ +
+

Tag Parsing

+ +

You can parse and create tags with the tag management API, which functions very similarly +to the commit lookup, parsing and creation methods, since the objects themselves are very similar.

+
+
  printf("\n*Tag Parsing*\n");
+  git_tag *tag;
+  const char *tmessage, *tname;
+  git_otype ttype;
+
+
+ +
+

We create an oid for the tag object if we know the SHA and look it up in the repository the same +way that we would a commit (or any other) object.

+
+
  git_oid_fromstr(&oid, "bc422d45275aca289c51d79830b45cecebff7c3a");
+
+  error = git_tag_lookup(&tag, repo, &oid);
+
+
+ +
+

Now that we have the tag object, we can extract the information it generally contains: the target +(usually a commit object), the type of the target object (usually ‘commit’), the name (‘v1.0’), +the tagger (a git_signature – name, email, timestamp), and the tag message.

+
+
  git_tag_target((git_object **)&commit, tag);
+  tname = git_tag_name(tag);    // "test"
+  ttype = git_tag_type(tag);    // GIT_OBJ_COMMIT (otype enum)
+  tmessage = git_tag_message(tag); // "tag message\n"
+  printf("Tag Message: %s\n", tmessage);
+
+  git_commit_free(commit);
+
+
+ +
+

Tree Parsing

+ +

Tree parsing is a bit different than the other objects, in that we have a subtype which is the +tree entry. This is not an actual object type in Git, but a useful structure for parsing and +traversing tree entries.

+
+
  printf("\n*Tree Parsing*\n");
+
+  const git_tree_entry *entry;
+  git_object *objt;
+
+
+ +
+

Create the oid and lookup the tree object just like the other objects.

+
+
  git_oid_fromstr(&oid, "2a741c18ac5ff082a7caaec6e74db3075a1906b5");
+  git_tree_lookup(&tree, repo, &oid);
+
+
+ +
+

Getting the count of entries in the tree so you can iterate over them if you want to.

+
+
  int cnt = git_tree_entrycount(tree); // 3
+  printf("tree entries: %d\n", cnt);
+
+  entry = git_tree_entry_byindex(tree, 0);
+  printf("Entry name: %s\n", git_tree_entry_name(entry)); // "hello.c"
+
+
+ +
+

You can also access tree entries by name if you know the name of the entry you’re looking for.

+
+
  entry = git_tree_entry_byname(tree, "hello.c");
+  git_tree_entry_name(entry); // "hello.c"
+
+
+ +
+

Once you have the entry object, you can access the content or subtree (or commit, in the case +of submodules) that it points to. You can also get the mode if you want.

+
+
  git_tree_entry_to_object(&objt, repo, entry); // blob
+
+
+ +
+

Remember to close the looked-up object once you are done using it

+
+ +
+
+ +
+

Blob Parsing

+ +

The last object type is the simplest and requires the least parsing help. Blobs are just file +contents and can contain anything, there is no structure to it. The main advantage to using the +simple blob api is that when you’re creating blobs you don’t have to calculate the size +of the content. There is also a helper for reading a file from disk and writing it to the db and +getting the oid back so you don’t have to do all those steps yourself.

+
+
  printf("\n*Blob Parsing*\n");
+  git_blob *blob;
+
+  git_oid_fromstr(&oid, "af7574ea73f7b166f869ef1a39be126d9a186ae0");
+  git_blob_lookup(&blob, repo, &oid);
+
+
+ +
+

You can access a buffer with the raw contents of the blob directly. +Note that this buffer may not be contain ASCII data for certain blobs (e.g. binary files): +do not consider the buffer a NULL-terminated string, and use the git_blob_rawsize attribute to +find out its exact size in bytes

+
+
  printf("Blob Size: %ld\n", git_blob_rawsize(blob)); // 8
+  git_blob_rawcontent(blob); // "content"
+
+
+ +
+

Revwalking

+ +

The libgit2 revision walking api provides methods to traverse the directed graph created +by the parent pointers of the commit objects. Since all commits point back to the commit that +came directly before them, you can walk this parentage as a graph and find all the commits that +were ancestors of (reachable from) a given starting point. This can allow you to create git log +type functionality.

+
+
  printf("\n*Revwalking*\n");
+  git_revwalk *walk;
+  git_commit *wcommit;
+
+  git_oid_fromstr(&oid, "f0877d0b841d75172ec404fc9370173dfffc20d1");
+
+
+ +
+

To use the revwalker, create a new walker, tell it how you want to sort the output and then push +one or more starting points onto the walker. If you want to emulate the output of git log you +would push the SHA of the commit that HEAD points to into the walker and then start traversing them. +You can also ‘hide’ commits that you want to stop at or not see any of their ancestors. So if you +want to emulate git log branch1..branch2, you would push the oid of branch2 and hide the oid +of branch1.

+
+
  git_revwalk_new(&walk, repo);
+  git_revwalk_sorting(walk, GIT_SORT_TOPOLOGICAL | GIT_SORT_REVERSE);
+  git_revwalk_push(walk, &oid);
+
+  const git_signature *cauth;
+  const char *cmsg;
+
+
+ +
+

Now that we have the starting point pushed onto the walker, we can start asking for ancestors. It +will return them in the sorting order we asked for as commit oids. +We can then lookup and parse the commited pointed at by the returned OID; +note that this operation is specially fast since the raw contents of the commit object will +be cached in memory

+
+
  while ((git_revwalk_next(&oid, walk)) == 0) {
+    error = git_commit_lookup(&wcommit, repo, &oid);
+    cmsg  = git_commit_message(wcommit);
+    cauth = git_commit_author(wcommit);
+    printf("%s (%s)\n", cmsg, cauth->email);
+    git_commit_free(wcommit);
+  }
+
+
+ +
+

Like the other objects, be sure to free the revwalker when you’re done to prevent memory leaks. +Also, make sure that the repository being walked it not deallocated while the walk is in +progress, or it will result in undefined behavior

+
+ +
+
+ +
+

Index File Manipulation

+ +

The index file API allows you to read, traverse, update and write the Git index file +(sometimes thought of as the staging area).

+
+
  printf("\n*Index Walking*\n");
+
+  git_index *index;
+  unsigned int i, ecount;
+
+
+ +
+

You can either open the index from the standard location in an open repository, as we’re doing +here, or you can open and manipulate any index file with git_index_open_bare(). The index +for the repository will be located and loaded from disk.

+
+
  git_repository_index(&index, repo);
+
+
+ +
+

For each entry in the index, you can get a bunch of information including the SHA (oid), path +and mode which map to the tree objects that are written out. It also has filesystem properties +to help determine what to inspect for changes (ctime, mtime, dev, ino, uid, gid, file_size and flags) +All these properties are exported publicly in the git_index_entry struct

+
+
  ecount = git_index_entrycount(index);
+  for (i = 0; i < ecount; ++i) {
+    git_index_entry *e = git_index_get(index, i);
+
+    printf("path: %s\n", e->path);
+    printf("mtime: %d\n", (int)e->mtime.seconds);
+    printf("fs: %d\n", (int)e->file_size);
+  }
+
+  git_index_free(index);
+
+
+ +
+

References

+ +

The reference API allows you to list, resolve, create and update references such as +branches, tags and remote references (everything in the .git/refs directory).

+
+
  printf("\n*Reference Listing*\n");
+
+
+ +
+

Here we will implement something like git for-each-ref simply listing out all available +references and the object SHA they resolve to.

+
+
  git_strarray ref_list;
+  git_reference_list(&ref_list, repo, GIT_REF_LISTALL);
+
+  const char *refname;
+  git_reference *ref;
+
+
+ +
+

Now that we have the list of reference names, we can lookup each ref one at a time and +resolve them to the SHA, then print both values out.

+
+
  for (i = 0; i < ref_list.count; ++i) {
+    refname = ref_list.strings[i];
+    git_reference_lookup(&ref, repo, refname);
+
+    switch (git_reference_type(ref)) {
+    case GIT_REF_OID:
+      git_oid_fmt(out, git_reference_oid(ref));
+      printf("%s [%s]\n", refname, out);
+      break;
+
+    case GIT_REF_SYMBOLIC:
+      printf("%s => %s\n", refname, git_reference_target(ref));
+      break;
+    default:
+      fprintf(stderr, "Unexpected reference type\n");
+      exit(1);
+    }
+  }
+
+  git_strarray_free(&ref_list);
+
+
+ +
+

Config Files

+ +

The config API allows you to list and updatee config values in +any of the accessible config file locations (system, global, local).

+
+
  printf("\n*Config Listing*\n");
+
+  const char *email;
+  int32_t j;
+
+  git_config *cfg;
+
+
+ +
+

Open a config object so we can read global values from it.

+
+
  git_config_open_ondisk(&cfg, "~/.gitconfig");
+
+  git_config_get_int32(cfg, "help.autocorrect", &j);
+  printf("Autocorrect: %d\n", j);
+
+  git_config_get_string(cfg, "user.email", &email);
+  printf("Email: %s\n", email);
+
+
+ +
+

Finally, when you’re done with the repository, you can free it as well.

+ +
+
  git_repository_free(repo);
+
+  return 0;
+}
+
+
+ diff --git a/ex/HEAD/git2.html b/ex/HEAD/git2.html new file mode 100644 index 00000000000..33ba0b1602a --- /dev/null +++ b/ex/HEAD/git2.html @@ -0,0 +1,138 @@ + + + + + git2.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + + + + + + + + + + + + + +

git2.c

+
+ +
+ +
+
#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "common.h"
+
+
+ +
+

This part is not strictly libgit2-dependent, but you can use this +as a starting point for a git-like tool

+
+
struct {
+  char *name;
+  git_cb fn;
+} commands[] = {
+  {"ls-remote", ls_remote},
+  {"fetch", fetch},
+  {"clone", do_clone},
+  {"index-pack", index_pack},
+  { NULL, NULL}
+};
+
+static int run_command(git_cb fn, int argc, char **argv)
+{
+  int error;
+  git_repository *repo;
+
+
+ +
+

Before running the actual command, create an instance of the local +repository and pass it to the function.

+
+
  error = git_repository_open(&repo, ".git");
+  if (error < 0)
+    repo = NULL;
+
+
+ +
+

Run the command. If something goes wrong, print the error message to stderr

+ +
+
  error = fn(repo, argc, argv);
+  if (error < 0) {
+    if (giterr_last() == NULL)
+      fprintf(stderr, "Error without message");
+    else
+      fprintf(stderr, "Bad news:\n %s\n", giterr_last()->message);
+  }
+
+  if(repo)
+    git_repository_free(repo);
+
+  return !!error;
+}
+
+int main(int argc, char **argv)
+{
+  int i;
+
+  if (argc < 2) {
+    fprintf(stderr, "usage: %s <cmd> [repo]\n", argv[0]);
+    exit(EXIT_FAILURE);
+  }
+
+  for (i = 0; commands[i].name != NULL; ++i) {
+    if (!strcmp(argv[1], commands[i].name))
+      return run_command(commands[i].fn, --argc, ++argv);
+  }
+
+  fprintf(stderr, "Command not found: %s\n", argv[1]);
+  return 1;
+}
+
+
+ diff --git a/ex/HEAD/index-pack.html b/ex/HEAD/index-pack.html new file mode 100644 index 00000000000..2c24e7babe3 --- /dev/null +++ b/ex/HEAD/index-pack.html @@ -0,0 +1,135 @@ + + + + + index-pack.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + + + + + +

index-pack.c

+
+ +
+ +
+
#include <git2.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "common.h"
+
+
+ +
+

This could be run in the main loop whilst the application waits for +the indexing to finish in a worker thread

+ +
+
static int index_cb(const git_indexer_stats *stats, void *data)
+{
+  data = data;
+  printf("\rProcessing %d of %d", stats->processed, stats->total);
+
+  return 0;
+}
+
+int index_pack(git_repository *repo, int argc, char **argv)
+{
+  git_indexer_stream *idx;
+  git_indexer_stats stats = {0, 0};
+  int error, fd;
+  char hash[GIT_OID_HEXSZ + 1] = {0};
+  ssize_t read_bytes;
+  char buf[512];
+
+  repo = repo;
+  if (argc < 2) {
+    fprintf(stderr, "I need a packfile\n");
+    return EXIT_FAILURE;
+  }
+
+  if (git_indexer_stream_new(&idx, ".") < 0) {
+    puts("bad idx");
+    return -1;
+  }
+
+  if ((fd = open(argv[1], 0)) < 0) {
+    perror("open");
+    return -1;
+  }
+
+  do {
+    read_bytes = read(fd, buf, sizeof(buf));
+    if (read_bytes < 0)
+      break;
+
+    if ((error = git_indexer_stream_add(idx, buf, read_bytes, &stats)) < 0)
+      goto cleanup;
+
+    index_cb(&stats, NULL);
+  } while (read_bytes > 0);
+
+  if (read_bytes < 0) {
+    error = -1;
+    perror("failed reading");
+    goto cleanup;
+  }
+
+  if ((error = git_indexer_stream_finalize(idx, &stats)) < 0)
+    goto cleanup;
+
+  printf("\rIndexing %d of %d\n", stats.processed, stats.total);
+
+  git_oid_fmt(hash, git_indexer_stream_hash(idx));
+  puts(hash);
+
+ cleanup:
+  close(fd);
+  git_indexer_stream_free(idx);
+  return error;
+}
+
+
+ diff --git a/ex/HEAD/ls-remote.html b/ex/HEAD/ls-remote.html new file mode 100644 index 00000000000..7db8730d80d --- /dev/null +++ b/ex/HEAD/ls-remote.html @@ -0,0 +1,170 @@ + + + + + ls-remote.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

ls-remote.c

+
+ +
+ +
+
#include <git2.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "common.h"
+
+static int show_ref__cb(git_remote_head *head, void *payload)
+{
+  char oid[GIT_OID_HEXSZ + 1] = {0};
+
+  payload = payload;
+  git_oid_fmt(oid, &head->oid);
+  printf("%s\t%s\n", oid, head->name);
+  return 0;
+}
+
+static int use_unnamed(git_repository *repo, const char *url)
+{
+  git_remote *remote = NULL;
+  int error;
+
+
+ +
+

Create an instance of a remote from the URL. The transport to use +is detected from the URL

+
+
  error = git_remote_new(&remote, repo, NULL, url, NULL);
+  if (error < 0)
+    goto cleanup;
+
+
+ +
+

When connecting, the underlying code needs to know wether we +want to push or fetch

+
+
  error = git_remote_connect(remote, GIT_DIR_FETCH);
+  if (error < 0)
+    goto cleanup;
+
+
+ +
+

With git_remote_ls we can retrieve the advertised heads

+
+
  error = git_remote_ls(remote, &show_ref__cb, NULL);
+
+cleanup:
+  git_remote_free(remote);
+  return error;
+}
+
+static int use_remote(git_repository *repo, char *name)
+{
+  git_remote *remote = NULL;
+  int error;
+
+
+ +
+

Find the remote by name

+
+
  error = git_remote_load(&remote, repo, name);
+  if (error < 0)
+    goto cleanup;
+
+  error = git_remote_connect(remote, GIT_DIR_FETCH);
+  if (error < 0)
+    goto cleanup;
+
+  error = git_remote_ls(remote, &show_ref__cb, NULL);
+
+cleanup:
+  git_remote_free(remote);
+  return error;
+}
+
+
+ +
+

This gets called to do the work. The remote can be given either as +the name of a configured remote or an URL.

+ +
+
int ls_remote(git_repository *repo, int argc, char **argv)
+{
+  int error;
+
+  argc = argc;
+  /* If there's a ':' in the name, assume it's an URL */
+  if (strchr(argv[1], ':') != NULL) {
+    error = use_unnamed(repo, argv[1]);
+  } else {
+    error = use_remote(repo, argv[1]);
+  }
+
+  return error;
+}
+
+
+ diff --git a/ex/HEAD/showindex.html b/ex/HEAD/showindex.html new file mode 100644 index 00000000000..df57c3782e8 --- /dev/null +++ b/ex/HEAD/showindex.html @@ -0,0 +1,94 @@ + + + + + showindex.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + +

showindex.c

+
+ +
+ + +
+
#include <git2.h>
+#include <stdio.h>
+
+int main (int argc, char** argv)
+{
+  git_repository *repo;
+  git_index *index;
+  unsigned int i, e, ecount;
+  git_index_entry **entries;
+  git_oid oid;
+
+  char out[41];
+  out[40] = '\0';
+
+  git_repository_open(&repo, "/opt/libgit2-test/.git");
+
+  git_repository_index(&index, repo);
+  git_index_read(index);
+
+  ecount = git_index_entrycount(index);
+  for (i = 0; i < ecount; ++i) {
+    git_index_entry *e = git_index_get(index, i);
+
+    oid = e->oid;
+    git_oid_fmt(out, &oid);
+
+    printf("File Path: %s\n", e->path);
+    printf(" Blob SHA: %s\n", out);
+    printf("File Size: %d\n", (int)e->file_size);
+    printf("   Device: %d\n", (int)e->dev);
+    printf("    Inode: %d\n", (int)e->ino);
+    printf("      UID: %d\n", (int)e->uid);
+    printf("      GID: %d\n", (int)e->gid);
+    printf("    ctime: %d\n", (int)e->ctime.seconds);
+    printf("    mtime: %d\n", (int)e->mtime.seconds);
+    printf("\n");
+  }
+
+  git_index_free(index);
+
+  git_repository_free(repo);
+}
+
+
+ diff --git a/ex/v0.13.0/general.html b/ex/v0.13.0/general.html new file mode 100644 index 00000000000..adca66cfcfe --- /dev/null +++ b/ex/v0.13.0/general.html @@ -0,0 +1,894 @@ + + + + + general.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

general.c

+
+ +
+

libgit2 is a portable, pure C implementation of the Git core methods +provided as a re-entrant linkable library with a solid API, allowing you +to write native speed custom Git applications in any language which +supports C bindings.

+ +

This file is an example of using that API in a real, compilable C file. +As the API is updated, this file will be updated to demonstrate the +new functionality.

+ +

If you’re trying to write something in C using libgit2, you will also want +to check out the generated API documentation and the Usage Guide. We’ve +tried to link to the relevant sections of the API docs in each section in this file.

+ +

libgit2 only implements the core plumbing functions, not really the higher +level porcelain stuff. For a primer on Git Internals that you will need to know +to work with Git at this level, check out Chapter 9 of the Pro Git book.

+
+
+
+
+ +
+

Includes

+
+
+
+
+ +
+

Including the git2.h header will include all the other libgit2 headers that you need. +It should be the only thing you need to include in order to compile properly and get +all the libgit2 API.

+
+
#include <git2.h>
+#include <stdio.h>
+
+int main (int argc, char** argv)
+{
+
+
+ +
+

Opening the Repository

+
+
+
+
+ +
+

There are a couple of methods for opening a repository, this being the simplest. +There are also methods for specifying the index file and work tree locations, here +we are assuming they are in the normal places.

+
+
  git_repository *repo;
+  git_repository_open(&repo, "/opt/libgit2-test/.git");
+
+
+ +
+

SHA-1 Value Conversions

+
+
+
+
+ +
+

For our first example, we will convert a 40 character hex value to the 20 byte raw SHA1 value.

+
+
  printf("*Hex to Raw*\n");
+  char hex[] = "fd6e612585290339ea8bf39c692a7ff6a29cb7c3";
+
+
+ +
+

The git_oid is the structure that keeps the SHA value. We will use this throughout the example +for storing the value of the current SHA key we’re working with.

+
+
  git_oid oid;
+  git_oid_fromstr(&oid, hex);
+
+
+ +
+

Once we’ve converted the string into the oid value, we can get the raw value of the SHA.

+
+
  printf("Raw 20 bytes: [%s]\n", (&oid)->id);
+
+
+ +
+

Next we will convert the 20 byte raw SHA1 value to a human readable 40 char hex value.

+
+
  printf("\n*Raw to Hex*\n");
+  char out[41];
+  out[40] = '\0';
+
+
+ +
+

If you have a oid, you can easily get the hex value of the SHA as well.

+
+
  git_oid_fmt(out, &oid);
+  printf("SHA hex string: %s\n", out);
+
+
+ +
+

Working with the Object Database

+ +

libgit2 provides direct access to the object database. +The object database is where the actual objects are stored in Git. For +working with raw objects, we’ll need to get this structure from the +repository.

+
+
  git_odb *odb;
+  odb = git_repository_database(repo);
+
+
+ +
+

Raw Object Reading

+
+
  printf("\n*Raw Object Read*\n");
+  git_odb_object *obj;
+  git_otype otype;
+  const unsigned char *data;
+  const char *str_type;
+  int error;
+
+
+ +
+

We can read raw objects directly from the object database if we have the oid (SHA) +of the object. This allows us to access objects without knowing thier type and inspect +the raw bytes unparsed.

+
+
  error = git_odb_read(&obj, odb, &oid);
+
+
+ +
+

A raw object only has three properties – the type (commit, blob, tree or tag), the size +of the raw data and the raw, unparsed data itself. For a commit or tag, that raw data +is human readable plain ASCII text. For a blob it is just file contents, so it could be +text or binary data. For a tree it is a special binary format, so it’s unlikely to be +hugely helpful as a raw object.

+
+
  data = (const unsigned char *)git_odb_object_data(obj);
+  otype = git_odb_object_type(obj);
+
+
+ +
+

We provide methods to convert from the object type which is an enum, to a string +representation of that value (and vice-versa).

+
+
  str_type = git_object_type2string(otype);
+  printf("object length and type: %d, %s\n", 
+      (int)git_odb_object_size(obj),
+      str_type);
+
+
+ +
+

For proper memory management, close the object when you are done with it or it will leak +memory.

+
+ +
+
+ +
+

Raw Object Writing

+
+
  printf("\n*Raw Object Write*\n");
+
+
+ +
+

You can also write raw object data to Git. This is pretty cool because it gives you +direct access to the key/value properties of Git. Here we’ll write a new blob object +that just contains a simple string. Notice that we have to specify the object type as +the git_otype enum.

+
+
  git_odb_write(&oid, odb, "test data", sizeof("test data") - 1, GIT_OBJ_BLOB);
+
+
+ +
+

Now that we’ve written the object, we can check out what SHA1 was generated when the +object was written to our database.

+
+
  git_oid_fmt(out, &oid);
+  printf("Written Object: %s\n", out);
+
+
+ +
+

Object Parsing

+ +

libgit2 has methods to parse every object type in Git so you don’t have to work directly +with the raw data. This is much faster and simpler than trying to deal with the raw data +yourself.

+
+
+
+
+ +
+

Commit Parsing

+ +

Parsing commit objects is simple and gives you access to all the data in the commit +– the // author (name, email, datetime), committer (same), tree, message, encoding and parent(s).

+
+
  printf("\n*Commit Parsing*\n");
+
+  git_commit *commit;
+  git_oid_fromstr(&oid, "f0877d0b841d75172ec404fc9370173dfffc20d1");
+
+  error = git_commit_lookup(&commit, repo, &oid);
+
+  const git_signature *author, *cmtter;
+  const char *message, *message_short;
+  time_t ctime;
+  unsigned int parents, p;
+
+
+ +
+

Each of the properties of the commit object are accessible via methods, including commonly +needed variations, such as git_commit_time which returns the author time and _message_short +which gives you just the first line of the commit message.

+
+
  message  = git_commit_message(commit);
+  message_short = git_commit_message_short(commit);
+  author   = git_commit_author(commit);
+  cmtter   = git_commit_committer(commit);
+  ctime    = git_commit_time(commit);
+
+
+ +
+

The author and committer methods return [git_signature] structures, which give you name, email +and when, which is a git_time structure, giving you a timestamp and timezone offset.

+
+
  printf("Author: %s (%s)\n", author->name, author->email);
+
+
+ +
+

Commits can have zero or more parents. The first (root) commit will have no parents, most commits +will have one, which is the commit it was based on, and merge commits will have two or more. +Commits can technically have any number, though it’s pretty rare to have more than two.

+
+
  parents  = git_commit_parentcount(commit);
+  for (p = 0;p < parents;p++) {
+    git_commit *parent;
+    git_commit_parent(&parent, commit, p);
+    git_oid_fmt(out, git_commit_id(parent));
+    printf("Parent: %s\n", out);
+    git_commit_close(parent);
+  }
+
+
+ +
+

Don’t forget to close the object to prevent memory leaks. You will have to do this for +all the objects you open and parse.

+
+ +
+
+ +
+

Writing Commits

+ +

libgit2 provides a couple of methods to create commit objects easily as well. There are four +different create signatures, we’ll just show one of them here. You can read about the other +ones in the commit API docs.

+
+
  printf("\n*Commit Writing*\n");
+  git_oid tree_id, parent_id, commit_id;
+
+
+ +
+

Creating signatures for an authoring identity and time is pretty simple – you will need to have +this to create a commit in order to specify who created it and when. Default values for the name +and email should be found in the user.name and user.email configuration options. See the config +section of this example file to see how to access config values.

+
+
  author = git_signature_new("Scott Chacon", "schacon@gmail.com",
+      123456789, 60);
+  cmtter = git_signature_new("Scott A Chacon", "scott@github.com",
+      987654321, 90);
+
+
+ +
+

Commit objects need a tree to point to and optionally one or more parents. Here we’re creating oid +objects to create the commit with, but you can also use

+
+
  git_oid_fromstr(&tree_id, "28873d96b4e8f4e33ea30f4c682fd325f7ba56ac");
+  git_oid_fromstr(&parent_id, "f0877d0b841d75172ec404fc9370173dfffc20d1");
+
+
+ +
+

Here we actually create the commit object with a single call with all the values we need to create +the commit. The SHA key is written to the commit_id variable here.

+
+
  git_commit_create_v(
+    &commit_id, /* out id */
+    repo,
+    NULL, /* do not update the HEAD */
+    author,
+    cmtter,
+    "example commit",
+    &tree_id,
+    1, &parent_id);
+
+
+ +
+

Now we can take a look at the commit SHA we’ve generated.

+
+
  git_oid_fmt(out, &commit_id);
+  printf("New Commit: %s\n", out);
+
+
+ +
+

Tag Parsing

+ +

You can parse and create tags with the tag management API, which functions very similarly +to the commit lookup, parsing and creation methods, since the objects themselves are very similar.

+
+
  printf("\n*Tag Parsing*\n");
+  git_tag *tag;
+  const char *tmessage, *tname;
+  git_otype ttype;
+
+
+ +
+

We create an oid for the tag object if we know the SHA and look it up in the repository the same +way that we would a commit (or any other) object.

+
+
  git_oid_fromstr(&oid, "bc422d45275aca289c51d79830b45cecebff7c3a");
+
+  error = git_tag_lookup(&tag, repo, &oid);
+
+
+ +
+

Now that we have the tag object, we can extract the information it generally contains: the target +(usually a commit object), the type of the target object (usually ‘commit’), the name (‘v1.0’), +the tagger (a git_signature – name, email, timestamp), and the tag message.

+
+
  git_tag_target((git_object **)&commit, tag);
+  tname = git_tag_name(tag);    // "test"
+  ttype = git_tag_type(tag);    // GIT_OBJ_COMMIT (otype enum)
+  tmessage = git_tag_message(tag); // "tag message\n"
+  printf("Tag Message: %s\n", tmessage);
+
+  git_commit_close(commit);
+
+
+ +
+

Tree Parsing

+ +

Tree parsing is a bit different than the other objects, in that we have a subtype which is the +tree entry. This is not an actual object type in Git, but a useful structure for parsing and +traversing tree entries.

+
+
  printf("\n*Tree Parsing*\n");
+
+  git_tree *tree;
+  const git_tree_entry *entry;
+  git_object *objt;
+
+
+ +
+

Create the oid and lookup the tree object just like the other objects.

+
+
  git_oid_fromstr(&oid, "2a741c18ac5ff082a7caaec6e74db3075a1906b5");
+  git_tree_lookup(&tree, repo, &oid);
+
+
+ +
+

Getting the count of entries in the tree so you can iterate over them if you want to.

+
+
  int cnt = git_tree_entrycount(tree); // 3
+  printf("tree entries: %d\n", cnt);
+
+  entry = git_tree_entry_byindex(tree, 0);
+  printf("Entry name: %s\n", git_tree_entry_name(entry)); // "hello.c"
+
+
+ +
+

You can also access tree entries by name if you know the name of the entry you’re looking for.

+
+
  entry = git_tree_entry_byname(tree, "hello.c");
+  git_tree_entry_name(entry); // "hello.c"
+
+
+ +
+

Once you have the entry object, you can access the content or subtree (or commit, in the case +of submodules) that it points to. You can also get the mode if you want.

+
+
  git_tree_entry_2object(&objt, repo, entry); // blob
+
+
+ +
+

Remember to close the looked-up object once you are done using it

+
+ +
+
+ +
+

Blob Parsing

+ +

The last object type is the simplest and requires the least parsing help. Blobs are just file +contents and can contain anything, there is no structure to it. The main advantage to using the +simple blob api is that when you’re creating blobs you don’t have to calculate the size +of the content. There is also a helper for reading a file from disk and writing it to the db and +getting the oid back so you don’t have to do all those steps yourself.

+
+
  printf("\n*Blob Parsing*\n");
+  git_blob *blob;
+
+  git_oid_fromstr(&oid, "af7574ea73f7b166f869ef1a39be126d9a186ae0");
+  git_blob_lookup(&blob, repo, &oid);
+
+
+ +
+

You can access a buffer with the raw contents of the blob directly. +Note that this buffer may not be contain ASCII data for certain blobs (e.g. binary files): +do not consider the buffer a NULL-terminated string, and use the git_blob_rawsize attribute to +find out its exact size in bytes

+
+
  printf("Blob Size: %d\n", git_blob_rawsize(blob)); // 8
+  git_blob_rawcontent(blob); // "content"
+
+
+ +
+

Revwalking

+ +

The libgit2 revision walking api provides methods to traverse the directed graph created +by the parent pointers of the commit objects. Since all commits point back to the commit that +came directly before them, you can walk this parentage as a graph and find all the commits that +were ancestors of (reachable from) a given starting point. This can allow you to create git log +type functionality.

+
+
  printf("\n*Revwalking*\n");
+  git_revwalk *walk;
+  git_commit *wcommit;
+
+  git_oid_fromstr(&oid, "f0877d0b841d75172ec404fc9370173dfffc20d1");
+
+
+ +
+

To use the revwalker, create a new walker, tell it how you want to sort the output and then push +one or more starting points onto the walker. If you want to emulate the output of git log you +would push the SHA of the commit that HEAD points to into the walker and then start traversing them. +You can also ‘hide’ commits that you want to stop at or not see any of their ancestors. So if you +want to emulate git log branch1..branch2, you would push the oid of branch2 and hide the oid +of branch1.

+
+
  git_revwalk_new(&walk, repo);
+  git_revwalk_sorting(walk, GIT_SORT_TOPOLOGICAL | GIT_SORT_REVERSE);
+  git_revwalk_push(walk, &oid);
+
+  const git_signature *cauth;
+  const char *cmsg;
+
+
+ +
+

Now that we have the starting point pushed onto the walker, we can start asking for ancestors. It +will return them in the sorting order we asked for as commit oids. +We can then lookup and parse the commited pointed at by the returned OID; +note that this operation is specially fast since the raw contents of the commit object will +be cached in memory

+
+
  while ((git_revwalk_next(&oid, walk)) == GIT_SUCCESS) {
+    error = git_commit_lookup(&wcommit, repo, &oid);
+    cmsg  = git_commit_message_short(wcommit);
+    cauth = git_commit_author(wcommit);
+    printf("%s (%s)\n", cmsg, cauth->email);
+    git_commit_close(wcommit);
+  }
+
+
+ +
+

Like the other objects, be sure to free the revwalker when you’re done to prevent memory leaks. +Also, make sure that the repository being walked it not deallocated while the walk is in +progress, or it will result in undefined behavior

+
+ +
+
+ +
+

Index File Manipulation

+ +

The index file API allows you to read, traverse, update and write the Git index file +(sometimes thought of as the staging area).

+
+
  printf("\n*Index Walking*\n");
+
+  git_index *index;
+  unsigned int i, e, ecount;
+
+
+ +
+

You can either open the index from the standard location in an open repository, as we’re doing +here, or you can open and manipulate any index file with git_index_open_bare(). The index +for the repository will be located and loaded from disk.

+
+
  git_repository_index(&index, repo);
+
+
+ +
+

For each entry in the index, you can get a bunch of information including the SHA (oid), path +and mode which map to the tree objects that are written out. It also has filesystem properties +to help determine what to inspect for changes (ctime, mtime, dev, ino, uid, gid, file_size and flags) +All these properties are exported publicly in the git_index_entry struct

+
+
  ecount = git_index_entrycount(index);
+  for (i = 0; i < ecount; ++i) {
+    git_index_entry *e = git_index_get(index, i);
+
+    printf("path: %s\n", e->path);
+    printf("mtime: %d\n", (int)e->mtime.seconds);
+    printf("fs: %d\n", (int)e->file_size);
+  }
+
+  git_index_free(index);
+
+
+ +
+

References

+ +

The reference API allows you to list, resolve, create and update references such as +branches, tags and remote references (everything in the .git/refs directory).

+
+
  printf("\n*Reference Listing*\n");
+
+
+ +
+

Here we will implement something like git for-each-ref simply listing out all available +references and the object SHA they resolve to.

+
+
  git_strarray ref_list;
+  git_reference_listall(&ref_list, repo, GIT_REF_LISTALL);
+
+  const char *refname, *reftarget;
+  git_reference *ref;
+
+
+ +
+

Now that we have the list of reference names, we can lookup each ref one at a time and +resolve them to the SHA, then print both values out.

+
+
  for (i = 0; i < ref_list.count; ++i) {
+    refname = ref_list.strings[i];
+    git_reference_lookup(&ref, repo, refname);
+
+    switch (git_reference_type(ref)) {
+    case GIT_REF_OID:
+      git_oid_fmt(out, git_reference_oid(ref));
+      printf("%s [%s]\n", refname, out);
+      break;
+
+    case GIT_REF_SYMBOLIC:
+      printf("%s => %s\n", refname, git_reference_target(ref));
+      break;
+    }
+  }
+
+  git_strarray_free(&ref_list);
+
+
+ +
+

Config Files

+ +

The config API allows you to list and updatee config values in +any of the accessible config file locations (system, global, local).

+
+
  printf("\n*Config Listing*\n");
+
+  const char *email;
+  int j;
+
+  git_config *cfg;
+
+
+ +
+

Open a config object so we can read global values from it.

+
+
  git_config_open_ondisk(&cfg, "~/.gitconfig");
+
+  git_config_get_int(cfg, "help.autocorrect", &j);
+  printf("Autocorrect: %d\n", j);
+
+  git_config_get_string(cfg, "user.email", &email);
+  printf("Email: %s\n", email);
+
+
+ +
+

Finally, when you’re done with the repository, you can free it as well.

+ +
+ +
+
+ diff --git a/ex/v0.13.0/showindex.html b/ex/v0.13.0/showindex.html new file mode 100644 index 00000000000..0bfec4f181b --- /dev/null +++ b/ex/v0.13.0/showindex.html @@ -0,0 +1,88 @@ + + + + + showindex.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + +

showindex.c

+
+ +
+ + +
+
#include <git2.h>
+#include <stdio.h>
+
+int main (int argc, char** argv)
+{
+  git_repository *repo;
+  git_index *index;
+  unsigned int i, e, ecount;
+  git_index_entry **entries;
+  git_oid oid;
+
+  char out[41];
+  out[40] = '\0';
+
+  git_repository_open(&repo, "/opt/libgit2-test/.git");
+
+  git_repository_index(&index, repo);
+  git_index_read(index);
+
+  ecount = git_index_entrycount(index);
+  for (i = 0; i < ecount; ++i) {
+    git_index_entry *e = git_index_get(index, i);
+
+    oid = e->oid;
+    git_oid_fmt(out, &oid);
+
+    printf("File Path: %s\n", e->path);
+    printf(" Blob SHA: %s\n", out);
+    printf("File Size: %d\n", (int)e->file_size);
+    printf("   Device: %d\n", (int)e->dev);
+    printf("    Inode: %d\n", (int)e->ino);
+    printf("      UID: %d\n", (int)e->uid);
+    printf("      GID: %d\n", (int)e->gid);
+    printf("    ctime: %d\n", (int)e->ctime.seconds);
+    printf("    mtime: %d\n", (int)e->mtime.seconds);
+    printf("\n");
+  }
+
+  git_index_free(index);
+
+  git_repository_free(repo);
+}
+
+
+ diff --git a/ex/v0.14.0/general.html b/ex/v0.14.0/general.html new file mode 100644 index 00000000000..2d6456641e7 --- /dev/null +++ b/ex/v0.14.0/general.html @@ -0,0 +1,902 @@ + + + + + general.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

general.c

+
+ +
+

libgit2 is a portable, pure C implementation of the Git core methods +provided as a re-entrant linkable library with a solid API, allowing you +to write native speed custom Git applications in any language which +supports C bindings.

+ +

This file is an example of using that API in a real, compilable C file. +As the API is updated, this file will be updated to demonstrate the +new functionality.

+ +

If you’re trying to write something in C using libgit2, you will also want +to check out the generated API documentation and the Usage Guide. We’ve +tried to link to the relevant sections of the API docs in each section in this file.

+ +

libgit2 only implements the core plumbing functions, not really the higher +level porcelain stuff. For a primer on Git Internals that you will need to know +to work with Git at this level, check out Chapter 9 of the Pro Git book.

+
+
+
+
+ +
+

Includes

+
+
+
+
+ +
+

Including the git2.h header will include all the other libgit2 headers that you need. +It should be the only thing you need to include in order to compile properly and get +all the libgit2 API.

+
+
#include <git2.h>
+#include <stdio.h>
+
+int main (int argc, char** argv)
+{
+
+
+ +
+

Opening the Repository

+
+
+
+
+ +
+

There are a couple of methods for opening a repository, this being the simplest. +There are also methods for specifying the index file and work tree locations, here +we are assuming they are in the normal places.

+
+
  git_repository *repo;
+  git_repository_open(&repo, "/opt/libgit2-test/.git");
+
+
+ +
+

SHA-1 Value Conversions

+
+
+
+
+ +
+

For our first example, we will convert a 40 character hex value to the 20 byte raw SHA1 value.

+
+
  printf("*Hex to Raw*\n");
+  char hex[] = "fd6e612585290339ea8bf39c692a7ff6a29cb7c3";
+
+
+ +
+

The git_oid is the structure that keeps the SHA value. We will use this throughout the example +for storing the value of the current SHA key we’re working with.

+
+
  git_oid oid;
+  git_oid_fromstr(&oid, hex);
+
+
+ +
+

Once we’ve converted the string into the oid value, we can get the raw value of the SHA.

+
+
  printf("Raw 20 bytes: [%s]\n", (&oid)->id);
+
+
+ +
+

Next we will convert the 20 byte raw SHA1 value to a human readable 40 char hex value.

+
+
  printf("\n*Raw to Hex*\n");
+  char out[41];
+  out[40] = '\0';
+
+
+ +
+

If you have a oid, you can easily get the hex value of the SHA as well.

+
+
  git_oid_fmt(out, &oid);
+  printf("SHA hex string: %s\n", out);
+
+
+ +
+

Working with the Object Database

+ +

libgit2 provides direct access to the object database. +The object database is where the actual objects are stored in Git. For +working with raw objects, we’ll need to get this structure from the +repository.

+
+
  git_odb *odb;
+  odb = git_repository_database(repo);
+
+
+ +
+

Raw Object Reading

+
+
  printf("\n*Raw Object Read*\n");
+  git_odb_object *obj;
+  git_otype otype;
+  const unsigned char *data;
+  const char *str_type;
+  int error;
+
+
+ +
+

We can read raw objects directly from the object database if we have the oid (SHA) +of the object. This allows us to access objects without knowing thier type and inspect +the raw bytes unparsed.

+
+
  error = git_odb_read(&obj, odb, &oid);
+
+
+ +
+

A raw object only has three properties – the type (commit, blob, tree or tag), the size +of the raw data and the raw, unparsed data itself. For a commit or tag, that raw data +is human readable plain ASCII text. For a blob it is just file contents, so it could be +text or binary data. For a tree it is a special binary format, so it’s unlikely to be +hugely helpful as a raw object.

+
+
  data = (const unsigned char *)git_odb_object_data(obj);
+  otype = git_odb_object_type(obj);
+
+
+ +
+

We provide methods to convert from the object type which is an enum, to a string +representation of that value (and vice-versa).

+
+
  str_type = git_object_type2string(otype);
+  printf("object length and type: %d, %s\n",
+      (int)git_odb_object_size(obj),
+      str_type);
+
+
+ +
+

For proper memory management, close the object when you are done with it or it will leak +memory.

+
+ +
+
+ +
+

Raw Object Writing

+
+
  printf("\n*Raw Object Write*\n");
+
+
+ +
+

You can also write raw object data to Git. This is pretty cool because it gives you +direct access to the key/value properties of Git. Here we’ll write a new blob object +that just contains a simple string. Notice that we have to specify the object type as +the git_otype enum.

+
+
  git_odb_write(&oid, odb, "test data", sizeof("test data") - 1, GIT_OBJ_BLOB);
+
+
+ +
+

Now that we’ve written the object, we can check out what SHA1 was generated when the +object was written to our database.

+
+
  git_oid_fmt(out, &oid);
+  printf("Written Object: %s\n", out);
+
+
+ +
+

Object Parsing

+ +

libgit2 has methods to parse every object type in Git so you don’t have to work directly +with the raw data. This is much faster and simpler than trying to deal with the raw data +yourself.

+
+
+
+
+ +
+

Commit Parsing

+ +

Parsing commit objects is simple and gives you access to all the data in the commit +– the // author (name, email, datetime), committer (same), tree, message, encoding and parent(s).

+
+
  printf("\n*Commit Parsing*\n");
+
+  git_commit *commit;
+  git_oid_fromstr(&oid, "f0877d0b841d75172ec404fc9370173dfffc20d1");
+
+  error = git_commit_lookup(&commit, repo, &oid);
+
+  const git_signature *author, *cmtter;
+  const char *message, *message_short;
+  time_t ctime;
+  unsigned int parents, p;
+
+
+ +
+

Each of the properties of the commit object are accessible via methods, including commonly +needed variations, such as git_commit_time which returns the author time and _message_short +which gives you just the first line of the commit message.

+
+
  message  = git_commit_message(commit);
+  message_short = git_commit_message_short(commit);
+  author   = git_commit_author(commit);
+  cmtter   = git_commit_committer(commit);
+  ctime    = git_commit_time(commit);
+
+
+ +
+

The author and committer methods return [git_signature] structures, which give you name, email +and when, which is a git_time structure, giving you a timestamp and timezone offset.

+
+
  printf("Author: %s (%s)\n", author->name, author->email);
+
+
+ +
+

Commits can have zero or more parents. The first (root) commit will have no parents, most commits +will have one, which is the commit it was based on, and merge commits will have two or more. +Commits can technically have any number, though it’s pretty rare to have more than two.

+
+
  parents  = git_commit_parentcount(commit);
+  for (p = 0;p < parents;p++) {
+    git_commit *parent;
+    git_commit_parent(&parent, commit, p);
+    git_oid_fmt(out, git_commit_id(parent));
+    printf("Parent: %s\n", out);
+    git_commit_close(parent);
+  }
+
+
+ +
+

Don’t forget to close the object to prevent memory leaks. You will have to do this for +all the objects you open and parse.

+
+ +
+
+ +
+

Writing Commits

+ +

libgit2 provides a couple of methods to create commit objects easily as well. There are four +different create signatures, we’ll just show one of them here. You can read about the other +ones in the commit API docs.

+
+
  printf("\n*Commit Writing*\n");
+  git_oid tree_id, parent_id, commit_id;
+  git_tree *tree;
+  git_commit *parent;
+
+
+ +
+

Creating signatures for an authoring identity and time is pretty simple – you will need to have +this to create a commit in order to specify who created it and when. Default values for the name +and email should be found in the user.name and user.email configuration options. See the config +section of this example file to see how to access config values.

+
+
  author = git_signature_new("Scott Chacon", "schacon@gmail.com",
+      123456789, 60);
+  cmtter = git_signature_new("Scott A Chacon", "scott@github.com",
+      987654321, 90);
+
+
+ +
+

Commit objects need a tree to point to and optionally one or more parents. Here we’re creating oid +objects to create the commit with, but you can also use

+
+
  git_oid_fromstr(&tree_id, "28873d96b4e8f4e33ea30f4c682fd325f7ba56ac");
+  git_tree_lookup(&tree, repo, &tree_id);
+  git_oid_fromstr(&parent_id, "f0877d0b841d75172ec404fc9370173dfffc20d1");
+  git_commit_lookup(&parent, repo, &parent_id);
+
+
+ +
+

Here we actually create the commit object with a single call with all the values we need to create +the commit. The SHA key is written to the commit_id variable here.

+
+
  git_commit_create_v(
+    &commit_id, /* out id */
+    repo,
+    NULL, /* do not update the HEAD */
+    author,
+    cmtter,
+    "example commit",
+    tree,
+    1, parent);
+
+
+ +
+

Now we can take a look at the commit SHA we’ve generated.

+
+
  git_oid_fmt(out, &commit_id);
+  printf("New Commit: %s\n", out);
+
+
+ +
+

Tag Parsing

+ +

You can parse and create tags with the tag management API, which functions very similarly +to the commit lookup, parsing and creation methods, since the objects themselves are very similar.

+
+
  printf("\n*Tag Parsing*\n");
+  git_tag *tag;
+  const char *tmessage, *tname;
+  git_otype ttype;
+
+
+ +
+

We create an oid for the tag object if we know the SHA and look it up in the repository the same +way that we would a commit (or any other) object.

+
+
  git_oid_fromstr(&oid, "bc422d45275aca289c51d79830b45cecebff7c3a");
+
+  error = git_tag_lookup(&tag, repo, &oid);
+
+
+ +
+

Now that we have the tag object, we can extract the information it generally contains: the target +(usually a commit object), the type of the target object (usually ‘commit’), the name (‘v1.0’), +the tagger (a git_signature – name, email, timestamp), and the tag message.

+
+
  git_tag_target((git_object **)&commit, tag);
+  tname = git_tag_name(tag);    // "test"
+  ttype = git_tag_type(tag);    // GIT_OBJ_COMMIT (otype enum)
+  tmessage = git_tag_message(tag); // "tag message\n"
+  printf("Tag Message: %s\n", tmessage);
+
+  git_commit_close(commit);
+
+
+ +
+

Tree Parsing

+ +

Tree parsing is a bit different than the other objects, in that we have a subtype which is the +tree entry. This is not an actual object type in Git, but a useful structure for parsing and +traversing tree entries.

+
+
  printf("\n*Tree Parsing*\n");
+
+  const git_tree_entry *entry;
+  git_object *objt;
+
+
+ +
+

Create the oid and lookup the tree object just like the other objects.

+
+
  git_oid_fromstr(&oid, "2a741c18ac5ff082a7caaec6e74db3075a1906b5");
+  git_tree_lookup(&tree, repo, &oid);
+
+
+ +
+

Getting the count of entries in the tree so you can iterate over them if you want to.

+
+
  int cnt = git_tree_entrycount(tree); // 3
+  printf("tree entries: %d\n", cnt);
+
+  entry = git_tree_entry_byindex(tree, 0);
+  printf("Entry name: %s\n", git_tree_entry_name(entry)); // "hello.c"
+
+
+ +
+

You can also access tree entries by name if you know the name of the entry you’re looking for.

+
+
  entry = git_tree_entry_byname(tree, "hello.c");
+  git_tree_entry_name(entry); // "hello.c"
+
+
+ +
+

Once you have the entry object, you can access the content or subtree (or commit, in the case +of submodules) that it points to. You can also get the mode if you want.

+
+
  git_tree_entry_2object(&objt, repo, entry); // blob
+
+
+ +
+

Remember to close the looked-up object once you are done using it

+
+ +
+
+ +
+

Blob Parsing

+ +

The last object type is the simplest and requires the least parsing help. Blobs are just file +contents and can contain anything, there is no structure to it. The main advantage to using the +simple blob api is that when you’re creating blobs you don’t have to calculate the size +of the content. There is also a helper for reading a file from disk and writing it to the db and +getting the oid back so you don’t have to do all those steps yourself.

+
+
  printf("\n*Blob Parsing*\n");
+  git_blob *blob;
+
+  git_oid_fromstr(&oid, "af7574ea73f7b166f869ef1a39be126d9a186ae0");
+  git_blob_lookup(&blob, repo, &oid);
+
+
+ +
+

You can access a buffer with the raw contents of the blob directly. +Note that this buffer may not be contain ASCII data for certain blobs (e.g. binary files): +do not consider the buffer a NULL-terminated string, and use the git_blob_rawsize attribute to +find out its exact size in bytes

+
+
  printf("Blob Size: %d\n", git_blob_rawsize(blob)); // 8
+  git_blob_rawcontent(blob); // "content"
+
+
+ +
+

Revwalking

+ +

The libgit2 revision walking api provides methods to traverse the directed graph created +by the parent pointers of the commit objects. Since all commits point back to the commit that +came directly before them, you can walk this parentage as a graph and find all the commits that +were ancestors of (reachable from) a given starting point. This can allow you to create git log +type functionality.

+
+
  printf("\n*Revwalking*\n");
+  git_revwalk *walk;
+  git_commit *wcommit;
+
+  git_oid_fromstr(&oid, "f0877d0b841d75172ec404fc9370173dfffc20d1");
+
+
+ +
+

To use the revwalker, create a new walker, tell it how you want to sort the output and then push +one or more starting points onto the walker. If you want to emulate the output of git log you +would push the SHA of the commit that HEAD points to into the walker and then start traversing them. +You can also ‘hide’ commits that you want to stop at or not see any of their ancestors. So if you +want to emulate git log branch1..branch2, you would push the oid of branch2 and hide the oid +of branch1.

+
+
  git_revwalk_new(&walk, repo);
+  git_revwalk_sorting(walk, GIT_SORT_TOPOLOGICAL | GIT_SORT_REVERSE);
+  git_revwalk_push(walk, &oid);
+
+  const git_signature *cauth;
+  const char *cmsg;
+
+
+ +
+

Now that we have the starting point pushed onto the walker, we can start asking for ancestors. It +will return them in the sorting order we asked for as commit oids. +We can then lookup and parse the commited pointed at by the returned OID; +note that this operation is specially fast since the raw contents of the commit object will +be cached in memory

+
+
  while ((git_revwalk_next(&oid, walk)) == GIT_SUCCESS) {
+    error = git_commit_lookup(&wcommit, repo, &oid);
+    cmsg  = git_commit_message_short(wcommit);
+    cauth = git_commit_author(wcommit);
+    printf("%s (%s)\n", cmsg, cauth->email);
+    git_commit_close(wcommit);
+  }
+
+
+ +
+

Like the other objects, be sure to free the revwalker when you’re done to prevent memory leaks. +Also, make sure that the repository being walked it not deallocated while the walk is in +progress, or it will result in undefined behavior

+
+ +
+
+ +
+

Index File Manipulation

+ +

The index file API allows you to read, traverse, update and write the Git index file +(sometimes thought of as the staging area).

+
+
  printf("\n*Index Walking*\n");
+
+  git_index *index;
+  unsigned int i, ecount;
+
+
+ +
+

You can either open the index from the standard location in an open repository, as we’re doing +here, or you can open and manipulate any index file with git_index_open_bare(). The index +for the repository will be located and loaded from disk.

+
+
  git_repository_index(&index, repo);
+
+
+ +
+

For each entry in the index, you can get a bunch of information including the SHA (oid), path +and mode which map to the tree objects that are written out. It also has filesystem properties +to help determine what to inspect for changes (ctime, mtime, dev, ino, uid, gid, file_size and flags) +All these properties are exported publicly in the git_index_entry struct

+
+
  ecount = git_index_entrycount(index);
+  for (i = 0; i < ecount; ++i) {
+    git_index_entry *e = git_index_get(index, i);
+
+    printf("path: %s\n", e->path);
+    printf("mtime: %d\n", (int)e->mtime.seconds);
+    printf("fs: %d\n", (int)e->file_size);
+  }
+
+  git_index_free(index);
+
+
+ +
+

References

+ +

The reference API allows you to list, resolve, create and update references such as +branches, tags and remote references (everything in the .git/refs directory).

+
+
  printf("\n*Reference Listing*\n");
+
+
+ +
+

Here we will implement something like git for-each-ref simply listing out all available +references and the object SHA they resolve to.

+
+
  git_strarray ref_list;
+  git_reference_listall(&ref_list, repo, GIT_REF_LISTALL);
+
+  const char *refname;
+  git_reference *ref;
+
+
+ +
+

Now that we have the list of reference names, we can lookup each ref one at a time and +resolve them to the SHA, then print both values out.

+
+
  for (i = 0; i < ref_list.count; ++i) {
+    refname = ref_list.strings[i];
+    git_reference_lookup(&ref, repo, refname);
+
+    switch (git_reference_type(ref)) {
+    case GIT_REF_OID:
+      git_oid_fmt(out, git_reference_oid(ref));
+      printf("%s [%s]\n", refname, out);
+      break;
+
+    case GIT_REF_SYMBOLIC:
+      printf("%s => %s\n", refname, git_reference_target(ref));
+      break;
+    default:
+      fprintf(stderr, "Unexpected reference type\n");
+      exit(1);
+    }
+  }
+
+  git_strarray_free(&ref_list);
+
+
+ +
+

Config Files

+ +

The config API allows you to list and updatee config values in +any of the accessible config file locations (system, global, local).

+
+
  printf("\n*Config Listing*\n");
+
+  const char *email;
+  int j;
+
+  git_config *cfg;
+
+
+ +
+

Open a config object so we can read global values from it.

+
+
  git_config_open_ondisk(&cfg, "~/.gitconfig");
+
+  git_config_get_int(cfg, "help.autocorrect", &j);
+  printf("Autocorrect: %d\n", j);
+
+  git_config_get_string(cfg, "user.email", &email);
+  printf("Email: %s\n", email);
+
+
+ +
+

Finally, when you’re done with the repository, you can free it as well.

+ +
+
  git_repository_free(repo);
+
+  return 0;
+}
+
+
+ diff --git a/ex/v0.14.0/showindex.html b/ex/v0.14.0/showindex.html new file mode 100644 index 00000000000..f29508626b5 --- /dev/null +++ b/ex/v0.14.0/showindex.html @@ -0,0 +1,88 @@ + + + + + showindex.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + +

showindex.c

+
+ +
+ + +
+
#include <git2.h>
+#include <stdio.h>
+
+int main (int argc, char** argv)
+{
+  git_repository *repo;
+  git_index *index;
+  unsigned int i, e, ecount;
+  git_index_entry **entries;
+  git_oid oid;
+
+  char out[41];
+  out[40] = '\0';
+
+  git_repository_open(&repo, "/opt/libgit2-test/.git");
+
+  git_repository_index(&index, repo);
+  git_index_read(index);
+
+  ecount = git_index_entrycount(index);
+  for (i = 0; i < ecount; ++i) {
+    git_index_entry *e = git_index_get(index, i);
+
+    oid = e->oid;
+    git_oid_fmt(out, &oid);
+
+    printf("File Path: %s\n", e->path);
+    printf(" Blob SHA: %s\n", out);
+    printf("File Size: %d\n", (int)e->file_size);
+    printf("   Device: %d\n", (int)e->dev);
+    printf("    Inode: %d\n", (int)e->ino);
+    printf("      UID: %d\n", (int)e->uid);
+    printf("      GID: %d\n", (int)e->gid);
+    printf("    ctime: %d\n", (int)e->ctime.seconds);
+    printf("    mtime: %d\n", (int)e->mtime.seconds);
+    printf("\n");
+  }
+
+  git_index_free(index);
+
+  git_repository_free(repo);
+}
+
+
+ diff --git a/ex/v0.15.0/general.html b/ex/v0.15.0/general.html new file mode 100644 index 00000000000..abc8be200ec --- /dev/null +++ b/ex/v0.15.0/general.html @@ -0,0 +1,906 @@ + + + + + general.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

general.c

+
+ +
+

libgit2 is a portable, pure C implementation of the Git core methods +provided as a re-entrant linkable library with a solid API, allowing you +to write native speed custom Git applications in any language which +supports C bindings.

+ +

This file is an example of using that API in a real, compilable C file. +As the API is updated, this file will be updated to demonstrate the +new functionality.

+ +

If you’re trying to write something in C using libgit2, you will also want +to check out the generated API documentation and the Usage Guide. We’ve +tried to link to the relevant sections of the API docs in each section in this file.

+ +

libgit2 only implements the core plumbing functions, not really the higher +level porcelain stuff. For a primer on Git Internals that you will need to know +to work with Git at this level, check out Chapter 9 of the Pro Git book.

+
+
+
+
+ +
+

Includes

+
+
+
+
+ +
+

Including the git2.h header will include all the other libgit2 headers that you need. +It should be the only thing you need to include in order to compile properly and get +all the libgit2 API.

+
+
#include <git2.h>
+#include <stdio.h>
+
+int main (int argc, char** argv)
+{
+
+
+ +
+

Opening the Repository

+
+
+
+
+ +
+

There are a couple of methods for opening a repository, this being the simplest. +There are also methods for specifying the index file and work tree locations, here +we are assuming they are in the normal places.

+
+
  git_repository *repo;
+  if (argc > 1) {
+    git_repository_open(&repo, argv[1]);
+  } else {
+    git_repository_open(&repo, "/opt/libgit2-test/.git");
+  }
+
+
+ +
+

SHA-1 Value Conversions

+
+
+
+
+ +
+

For our first example, we will convert a 40 character hex value to the 20 byte raw SHA1 value.

+
+
  printf("*Hex to Raw*\n");
+  char hex[] = "fd6e612585290339ea8bf39c692a7ff6a29cb7c3";
+
+
+ +
+

The git_oid is the structure that keeps the SHA value. We will use this throughout the example +for storing the value of the current SHA key we’re working with.

+
+
  git_oid oid;
+  git_oid_fromstr(&oid, hex);
+
+
+ +
+

Once we’ve converted the string into the oid value, we can get the raw value of the SHA.

+
+
  printf("Raw 20 bytes: [%.20s]\n", (&oid)->id);
+
+
+ +
+

Next we will convert the 20 byte raw SHA1 value to a human readable 40 char hex value.

+
+
  printf("\n*Raw to Hex*\n");
+  char out[41];
+  out[40] = '\0';
+
+
+ +
+

If you have a oid, you can easily get the hex value of the SHA as well.

+
+
  git_oid_fmt(out, &oid);
+  printf("SHA hex string: %s\n", out);
+
+
+ +
+

Working with the Object Database

+ +

libgit2 provides direct access to the object database. +The object database is where the actual objects are stored in Git. For +working with raw objects, we’ll need to get this structure from the +repository.

+
+
  git_odb *odb;
+  odb = git_repository_database(repo);
+
+
+ +
+

Raw Object Reading

+
+
  printf("\n*Raw Object Read*\n");
+  git_odb_object *obj;
+  git_otype otype;
+  const unsigned char *data;
+  const char *str_type;
+  int error;
+
+
+ +
+

We can read raw objects directly from the object database if we have the oid (SHA) +of the object. This allows us to access objects without knowing thier type and inspect +the raw bytes unparsed.

+
+
  error = git_odb_read(&obj, odb, &oid);
+
+
+ +
+

A raw object only has three properties – the type (commit, blob, tree or tag), the size +of the raw data and the raw, unparsed data itself. For a commit or tag, that raw data +is human readable plain ASCII text. For a blob it is just file contents, so it could be +text or binary data. For a tree it is a special binary format, so it’s unlikely to be +hugely helpful as a raw object.

+
+
  data = (const unsigned char *)git_odb_object_data(obj);
+  otype = git_odb_object_type(obj);
+
+
+ +
+

We provide methods to convert from the object type which is an enum, to a string +representation of that value (and vice-versa).

+
+
  str_type = git_object_type2string(otype);
+  printf("object length and type: %d, %s\n",
+      (int)git_odb_object_size(obj),
+      str_type);
+
+
+ +
+

For proper memory management, close the object when you are done with it or it will leak +memory.

+
+ +
+
+ +
+

Raw Object Writing

+
+
  printf("\n*Raw Object Write*\n");
+
+
+ +
+

You can also write raw object data to Git. This is pretty cool because it gives you +direct access to the key/value properties of Git. Here we’ll write a new blob object +that just contains a simple string. Notice that we have to specify the object type as +the git_otype enum.

+
+
  git_odb_write(&oid, odb, "test data", sizeof("test data") - 1, GIT_OBJ_BLOB);
+
+
+ +
+

Now that we’ve written the object, we can check out what SHA1 was generated when the +object was written to our database.

+
+
  git_oid_fmt(out, &oid);
+  printf("Written Object: %s\n", out);
+
+
+ +
+

Object Parsing

+ +

libgit2 has methods to parse every object type in Git so you don’t have to work directly +with the raw data. This is much faster and simpler than trying to deal with the raw data +yourself.

+
+
+
+
+ +
+

Commit Parsing

+ +

Parsing commit objects is simple and gives you access to all the data in the commit +– the // author (name, email, datetime), committer (same), tree, message, encoding and parent(s).

+
+
  printf("\n*Commit Parsing*\n");
+
+  git_commit *commit;
+  git_oid_fromstr(&oid, "f0877d0b841d75172ec404fc9370173dfffc20d1");
+
+  error = git_commit_lookup(&commit, repo, &oid);
+
+  const git_signature *author, *cmtter;
+  const char *message;
+  time_t ctime;
+  unsigned int parents, p;
+
+
+ +
+

Each of the properties of the commit object are accessible via methods, including commonly +needed variations, such as git_commit_time which returns the author time and _message +which gives you the commit message.

+
+
  message  = git_commit_message(commit);
+  author   = git_commit_author(commit);
+  cmtter   = git_commit_committer(commit);
+  ctime    = git_commit_time(commit);
+
+
+ +
+

The author and committer methods return [git_signature] structures, which give you name, email +and when, which is a git_time structure, giving you a timestamp and timezone offset.

+
+
  printf("Author: %s (%s)\n", author->name, author->email);
+
+
+ +
+

Commits can have zero or more parents. The first (root) commit will have no parents, most commits +will have one, which is the commit it was based on, and merge commits will have two or more. +Commits can technically have any number, though it’s pretty rare to have more than two.

+
+
  parents  = git_commit_parentcount(commit);
+  for (p = 0;p < parents;p++) {
+    git_commit *parent;
+    git_commit_parent(&parent, commit, p);
+    git_oid_fmt(out, git_commit_id(parent));
+    printf("Parent: %s\n", out);
+    git_commit_close(parent);
+  }
+
+
+ +
+

Don’t forget to close the object to prevent memory leaks. You will have to do this for +all the objects you open and parse.

+
+ +
+
+ +
+

Writing Commits

+ +

libgit2 provides a couple of methods to create commit objects easily as well. There are four +different create signatures, we’ll just show one of them here. You can read about the other +ones in the commit API docs.

+
+
  printf("\n*Commit Writing*\n");
+  git_oid tree_id, parent_id, commit_id;
+  git_tree *tree;
+  git_commit *parent;
+
+
+ +
+

Creating signatures for an authoring identity and time is pretty simple – you will need to have +this to create a commit in order to specify who created it and when. Default values for the name +and email should be found in the user.name and user.email configuration options. See the config +section of this example file to see how to access config values.

+
+
  git_signature_new((git_signature **)&author, "Scott Chacon", "schacon@gmail.com",
+      123456789, 60);
+  git_signature_new((git_signature **)&cmtter, "Scott A Chacon", "scott@github.com",
+      987654321, 90);
+
+
+ +
+

Commit objects need a tree to point to and optionally one or more parents. Here we’re creating oid +objects to create the commit with, but you can also use

+
+
  git_oid_fromstr(&tree_id, "28873d96b4e8f4e33ea30f4c682fd325f7ba56ac");
+  git_tree_lookup(&tree, repo, &tree_id);
+  git_oid_fromstr(&parent_id, "f0877d0b841d75172ec404fc9370173dfffc20d1");
+  git_commit_lookup(&parent, repo, &parent_id);
+
+
+ +
+

Here we actually create the commit object with a single call with all the values we need to create +the commit. The SHA key is written to the commit_id variable here.

+
+
  git_commit_create_v(
+    &commit_id, /* out id */
+    repo,
+    NULL, /* do not update the HEAD */
+    author,
+    cmtter,
+    NULL, /* use default message encoding */
+    "example commit",
+    tree,
+    1, parent);
+
+
+ +
+

Now we can take a look at the commit SHA we’ve generated.

+
+
  git_oid_fmt(out, &commit_id);
+  printf("New Commit: %s\n", out);
+
+
+ +
+

Tag Parsing

+ +

You can parse and create tags with the tag management API, which functions very similarly +to the commit lookup, parsing and creation methods, since the objects themselves are very similar.

+
+
  printf("\n*Tag Parsing*\n");
+  git_tag *tag;
+  const char *tmessage, *tname;
+  git_otype ttype;
+
+
+ +
+

We create an oid for the tag object if we know the SHA and look it up in the repository the same +way that we would a commit (or any other) object.

+
+
  git_oid_fromstr(&oid, "bc422d45275aca289c51d79830b45cecebff7c3a");
+
+  error = git_tag_lookup(&tag, repo, &oid);
+
+
+ +
+

Now that we have the tag object, we can extract the information it generally contains: the target +(usually a commit object), the type of the target object (usually ‘commit’), the name (‘v1.0’), +the tagger (a git_signature – name, email, timestamp), and the tag message.

+
+
  git_tag_target((git_object **)&commit, tag);
+  tname = git_tag_name(tag);    // "test"
+  ttype = git_tag_type(tag);    // GIT_OBJ_COMMIT (otype enum)
+  tmessage = git_tag_message(tag); // "tag message\n"
+  printf("Tag Message: %s\n", tmessage);
+
+  git_commit_close(commit);
+
+
+ +
+

Tree Parsing

+ +

Tree parsing is a bit different than the other objects, in that we have a subtype which is the +tree entry. This is not an actual object type in Git, but a useful structure for parsing and +traversing tree entries.

+
+
  printf("\n*Tree Parsing*\n");
+
+  const git_tree_entry *entry;
+  git_object *objt;
+
+
+ +
+

Create the oid and lookup the tree object just like the other objects.

+
+
  git_oid_fromstr(&oid, "2a741c18ac5ff082a7caaec6e74db3075a1906b5");
+  git_tree_lookup(&tree, repo, &oid);
+
+
+ +
+

Getting the count of entries in the tree so you can iterate over them if you want to.

+
+
  int cnt = git_tree_entrycount(tree); // 3
+  printf("tree entries: %d\n", cnt);
+
+  entry = git_tree_entry_byindex(tree, 0);
+  printf("Entry name: %s\n", git_tree_entry_name(entry)); // "hello.c"
+
+
+ +
+

You can also access tree entries by name if you know the name of the entry you’re looking for.

+
+
  entry = git_tree_entry_byname(tree, "hello.c");
+  git_tree_entry_name(entry); // "hello.c"
+
+
+ +
+

Once you have the entry object, you can access the content or subtree (or commit, in the case +of submodules) that it points to. You can also get the mode if you want.

+
+
  git_tree_entry_2object(&objt, repo, entry); // blob
+
+
+ +
+

Remember to close the looked-up object once you are done using it

+
+ +
+
+ +
+

Blob Parsing

+ +

The last object type is the simplest and requires the least parsing help. Blobs are just file +contents and can contain anything, there is no structure to it. The main advantage to using the +simple blob api is that when you’re creating blobs you don’t have to calculate the size +of the content. There is also a helper for reading a file from disk and writing it to the db and +getting the oid back so you don’t have to do all those steps yourself.

+
+
  printf("\n*Blob Parsing*\n");
+  git_blob *blob;
+
+  git_oid_fromstr(&oid, "af7574ea73f7b166f869ef1a39be126d9a186ae0");
+  git_blob_lookup(&blob, repo, &oid);
+
+
+ +
+

You can access a buffer with the raw contents of the blob directly. +Note that this buffer may not be contain ASCII data for certain blobs (e.g. binary files): +do not consider the buffer a NULL-terminated string, and use the git_blob_rawsize attribute to +find out its exact size in bytes

+
+
  printf("Blob Size: %ld\n", git_blob_rawsize(blob)); // 8
+  git_blob_rawcontent(blob); // "content"
+
+
+ +
+

Revwalking

+ +

The libgit2 revision walking api provides methods to traverse the directed graph created +by the parent pointers of the commit objects. Since all commits point back to the commit that +came directly before them, you can walk this parentage as a graph and find all the commits that +were ancestors of (reachable from) a given starting point. This can allow you to create git log +type functionality.

+
+
  printf("\n*Revwalking*\n");
+  git_revwalk *walk;
+  git_commit *wcommit;
+
+  git_oid_fromstr(&oid, "f0877d0b841d75172ec404fc9370173dfffc20d1");
+
+
+ +
+

To use the revwalker, create a new walker, tell it how you want to sort the output and then push +one or more starting points onto the walker. If you want to emulate the output of git log you +would push the SHA of the commit that HEAD points to into the walker and then start traversing them. +You can also ‘hide’ commits that you want to stop at or not see any of their ancestors. So if you +want to emulate git log branch1..branch2, you would push the oid of branch2 and hide the oid +of branch1.

+
+
  git_revwalk_new(&walk, repo);
+  git_revwalk_sorting(walk, GIT_SORT_TOPOLOGICAL | GIT_SORT_REVERSE);
+  git_revwalk_push(walk, &oid);
+
+  const git_signature *cauth;
+  const char *cmsg;
+
+
+ +
+

Now that we have the starting point pushed onto the walker, we can start asking for ancestors. It +will return them in the sorting order we asked for as commit oids. +We can then lookup and parse the commited pointed at by the returned OID; +note that this operation is specially fast since the raw contents of the commit object will +be cached in memory

+
+
  while ((git_revwalk_next(&oid, walk)) == GIT_SUCCESS) {
+    error = git_commit_lookup(&wcommit, repo, &oid);
+    cmsg  = git_commit_message(wcommit);
+    cauth = git_commit_author(wcommit);
+    printf("%s (%s)\n", cmsg, cauth->email);
+    git_commit_close(wcommit);
+  }
+
+
+ +
+

Like the other objects, be sure to free the revwalker when you’re done to prevent memory leaks. +Also, make sure that the repository being walked it not deallocated while the walk is in +progress, or it will result in undefined behavior

+
+ +
+
+ +
+

Index File Manipulation

+ +

The index file API allows you to read, traverse, update and write the Git index file +(sometimes thought of as the staging area).

+
+
  printf("\n*Index Walking*\n");
+
+  git_index *index;
+  unsigned int i, ecount;
+
+
+ +
+

You can either open the index from the standard location in an open repository, as we’re doing +here, or you can open and manipulate any index file with git_index_open_bare(). The index +for the repository will be located and loaded from disk.

+
+
  git_repository_index(&index, repo);
+
+
+ +
+

For each entry in the index, you can get a bunch of information including the SHA (oid), path +and mode which map to the tree objects that are written out. It also has filesystem properties +to help determine what to inspect for changes (ctime, mtime, dev, ino, uid, gid, file_size and flags) +All these properties are exported publicly in the git_index_entry struct

+
+
  ecount = git_index_entrycount(index);
+  for (i = 0; i < ecount; ++i) {
+    git_index_entry *e = git_index_get(index, i);
+
+    printf("path: %s\n", e->path);
+    printf("mtime: %d\n", (int)e->mtime.seconds);
+    printf("fs: %d\n", (int)e->file_size);
+  }
+
+  git_index_free(index);
+
+
+ +
+

References

+ +

The reference API allows you to list, resolve, create and update references such as +branches, tags and remote references (everything in the .git/refs directory).

+
+
  printf("\n*Reference Listing*\n");
+
+
+ +
+

Here we will implement something like git for-each-ref simply listing out all available +references and the object SHA they resolve to.

+
+
  git_strarray ref_list;
+  git_reference_listall(&ref_list, repo, GIT_REF_LISTALL);
+
+  const char *refname;
+  git_reference *ref;
+
+
+ +
+

Now that we have the list of reference names, we can lookup each ref one at a time and +resolve them to the SHA, then print both values out.

+
+
  for (i = 0; i < ref_list.count; ++i) {
+    refname = ref_list.strings[i];
+    git_reference_lookup(&ref, repo, refname);
+
+    switch (git_reference_type(ref)) {
+    case GIT_REF_OID:
+      git_oid_fmt(out, git_reference_oid(ref));
+      printf("%s [%s]\n", refname, out);
+      break;
+
+    case GIT_REF_SYMBOLIC:
+      printf("%s => %s\n", refname, git_reference_target(ref));
+      break;
+    default:
+      fprintf(stderr, "Unexpected reference type\n");
+      exit(1);
+    }
+  }
+
+  git_strarray_free(&ref_list);
+
+
+ +
+

Config Files

+ +

The config API allows you to list and updatee config values in +any of the accessible config file locations (system, global, local).

+
+
  printf("\n*Config Listing*\n");
+
+  const char *email;
+  int j;
+
+  git_config *cfg;
+
+
+ +
+

Open a config object so we can read global values from it.

+
+
  git_config_open_ondisk(&cfg, "~/.gitconfig");
+
+  git_config_get_int(cfg, "help.autocorrect", &j);
+  printf("Autocorrect: %d\n", j);
+
+  git_config_get_string(cfg, "user.email", &email);
+  printf("Email: %s\n", email);
+
+
+ +
+

Finally, when you’re done with the repository, you can free it as well.

+ +
+
  git_repository_free(repo);
+
+  return 0;
+}
+
+
+ diff --git a/ex/v0.15.0/showindex.html b/ex/v0.15.0/showindex.html new file mode 100644 index 00000000000..d3d3b4a5ecb --- /dev/null +++ b/ex/v0.15.0/showindex.html @@ -0,0 +1,88 @@ + + + + + showindex.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + +

showindex.c

+
+ +
+ + +
+
#include <git2.h>
+#include <stdio.h>
+
+int main (int argc, char** argv)
+{
+  git_repository *repo;
+  git_index *index;
+  unsigned int i, e, ecount;
+  git_index_entry **entries;
+  git_oid oid;
+
+  char out[41];
+  out[40] = '\0';
+
+  git_repository_open(&repo, "/opt/libgit2-test/.git");
+
+  git_repository_index(&index, repo);
+  git_index_read(index);
+
+  ecount = git_index_entrycount(index);
+  for (i = 0; i < ecount; ++i) {
+    git_index_entry *e = git_index_get(index, i);
+
+    oid = e->oid;
+    git_oid_fmt(out, &oid);
+
+    printf("File Path: %s\n", e->path);
+    printf(" Blob SHA: %s\n", out);
+    printf("File Size: %d\n", (int)e->file_size);
+    printf("   Device: %d\n", (int)e->dev);
+    printf("    Inode: %d\n", (int)e->ino);
+    printf("      UID: %d\n", (int)e->uid);
+    printf("      GID: %d\n", (int)e->gid);
+    printf("    ctime: %d\n", (int)e->ctime.seconds);
+    printf("    mtime: %d\n", (int)e->mtime.seconds);
+    printf("\n");
+  }
+
+  git_index_free(index);
+
+  git_repository_free(repo);
+}
+
+
+ diff --git a/ex/v0.16.0/fetch.html b/ex/v0.16.0/fetch.html new file mode 100644 index 00000000000..cca37b2b30a --- /dev/null +++ b/ex/v0.16.0/fetch.html @@ -0,0 +1,212 @@ + + + + + fetch.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

fetch.c

+
+ +
+ +
+
#include "common.h"
+#include <git2.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static int rename_packfile(char *packname, git_indexer *idx)
+{
+  char path[GIT_PATH_MAX], oid[GIT_OID_HEXSZ + 1], *slash;
+  int ret;
+
+  strcpy(path, packname);
+  slash = strrchr(path, '/');
+
+  if (!slash)
+    return GIT_EINVALIDARGS;
+
+  memset(oid, 0x0, sizeof(oid));
+
+
+ +
+

The name of the packfile is given by it’s hash which you can get +with git_indexer_hash after the index has been written out to +disk. Rename the packfile to its “real” name in the same +directory as it was originally (libgit2 stores it in the folder +where the packs go, so a rename in place is the right thing to do here

+
+
  git_oid_fmt(oid, git_indexer_hash(idx));
+  ret = sprintf(slash + 1, "pack-%s.pack", oid);
+  if(ret < 0)
+    return GIT_EOSERR;
+
+  printf("Renaming pack to %s\n", path);
+  return rename(packname, path);
+}
+
+int fetch(git_repository *repo, int argc, char **argv)
+{
+  git_remote *remote = NULL;
+  git_indexer *idx = NULL;
+  git_indexer_stats stats;
+  int error;
+  char *packname = NULL;
+
+
+ +
+

Get the remote and connect to it

+
+
  printf("Fetching %s\n", argv[1]);
+  error = git_remote_new(&remote, repo, argv[1], NULL);
+  if (error < GIT_SUCCESS)
+    return error;
+
+  error = git_remote_connect(remote, GIT_DIR_FETCH);
+  if (error < GIT_SUCCESS)
+    return error;
+
+
+ +
+

Download the packfile from the server. As we don’t know its hash +yet, it will get a temporary filename

+
+
  error = git_remote_download(&packname, remote);
+  if (error < GIT_SUCCESS)
+    return error;
+
+
+ +
+

No error and a NULL packname means no packfile was needed

+
+
  if (packname != NULL) {
+    printf("The packname is %s\n", packname);
+
+
+ +
+

Create a new instance indexer

+
+
    error = git_indexer_new(&idx, packname);
+    if (error < GIT_SUCCESS)
+      return error;
+
+
+ +
+

This should be run in paralel, but it’d be too complicated for the example

+
+
    error = git_indexer_run(idx, &stats);
+    if (error < GIT_SUCCESS)
+      return error;
+
+    printf("Received %d objects\n", stats.total);
+
+
+ +
+

Write the index file. The index will be stored with the +correct filename

+
+
    error = git_indexer_write(idx);
+    if (error < GIT_SUCCESS)
+      return error;
+
+    error = rename_packfile(packname, idx);
+    if (error < GIT_SUCCESS)
+      return error;
+  }
+
+
+ +
+

Update the references in the remote’s namespace to point to the +right commits. This may be needed even if there was no packfile +to download, which can happen e.g. when the branches have been +changed but all the neede objects are available locally.

+ +
+
  error = git_remote_update_tips(remote);
+  if (error < GIT_SUCCESS)
+    return error;
+
+  free(packname);
+  git_indexer_free(idx);
+  git_remote_free(remote);
+
+  return GIT_SUCCESS;
+}
+
+
+ diff --git a/ex/v0.16.0/general.html b/ex/v0.16.0/general.html new file mode 100644 index 00000000000..d79a8274af6 --- /dev/null +++ b/ex/v0.16.0/general.html @@ -0,0 +1,910 @@ + + + + + general.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

general.c

+
+ +
+

libgit2 is a portable, pure C implementation of the Git core methods +provided as a re-entrant linkable library with a solid API, allowing you +to write native speed custom Git applications in any language which +supports C bindings.

+ +

This file is an example of using that API in a real, compilable C file. +As the API is updated, this file will be updated to demonstrate the +new functionality.

+ +

If you’re trying to write something in C using libgit2, you will also want +to check out the generated API documentation and the Usage Guide. We’ve +tried to link to the relevant sections of the API docs in each section in this file.

+ +

libgit2 only implements the core plumbing functions, not really the higher +level porcelain stuff. For a primer on Git Internals that you will need to know +to work with Git at this level, check out Chapter 9 of the Pro Git book.

+
+
+
+
+ +
+

Includes

+
+
+
+
+ +
+

Including the git2.h header will include all the other libgit2 headers that you need. +It should be the only thing you need to include in order to compile properly and get +all the libgit2 API.

+
+
#include <git2.h>
+#include <stdio.h>
+
+int main (int argc, char** argv)
+{
+
+
+ +
+

Opening the Repository

+
+
+
+
+ +
+

There are a couple of methods for opening a repository, this being the simplest. +There are also methods for specifying the index file and work tree locations, here +we are assuming they are in the normal places.

+
+
  git_repository *repo;
+  if (argc > 1) {
+    git_repository_open(&repo, argv[1]);
+  } else {
+    git_repository_open(&repo, "/opt/libgit2-test/.git");
+  }
+
+
+ +
+

SHA-1 Value Conversions

+
+
+
+
+ +
+

For our first example, we will convert a 40 character hex value to the 20 byte raw SHA1 value.

+
+
  printf("*Hex to Raw*\n");
+  char hex[] = "fd6e612585290339ea8bf39c692a7ff6a29cb7c3";
+
+
+ +
+

The git_oid is the structure that keeps the SHA value. We will use this throughout the example +for storing the value of the current SHA key we’re working with.

+
+
  git_oid oid;
+  git_oid_fromstr(&oid, hex);
+
+
+ +
+

Once we’ve converted the string into the oid value, we can get the raw value of the SHA.

+
+
  printf("Raw 20 bytes: [%.20s]\n", (&oid)->id);
+
+
+ +
+

Next we will convert the 20 byte raw SHA1 value to a human readable 40 char hex value.

+
+
  printf("\n*Raw to Hex*\n");
+  char out[41];
+  out[40] = '\0';
+
+
+ +
+

If you have a oid, you can easily get the hex value of the SHA as well.

+
+
  git_oid_fmt(out, &oid);
+  printf("SHA hex string: %s\n", out);
+
+
+ +
+

Working with the Object Database

+ +

libgit2 provides direct access to the object database. +The object database is where the actual objects are stored in Git. For +working with raw objects, we’ll need to get this structure from the +repository.

+
+
  git_odb *odb;
+  git_repository_odb(&odb, repo);
+
+
+ +
+

Raw Object Reading

+
+
  printf("\n*Raw Object Read*\n");
+  git_odb_object *obj;
+  git_otype otype;
+  const unsigned char *data;
+  const char *str_type;
+  int error;
+
+
+ +
+

We can read raw objects directly from the object database if we have the oid (SHA) +of the object. This allows us to access objects without knowing thier type and inspect +the raw bytes unparsed.

+
+
  error = git_odb_read(&obj, odb, &oid);
+
+
+ +
+

A raw object only has three properties – the type (commit, blob, tree or tag), the size +of the raw data and the raw, unparsed data itself. For a commit or tag, that raw data +is human readable plain ASCII text. For a blob it is just file contents, so it could be +text or binary data. For a tree it is a special binary format, so it’s unlikely to be +hugely helpful as a raw object.

+
+
  data = (const unsigned char *)git_odb_object_data(obj);
+  otype = git_odb_object_type(obj);
+
+
+ +
+

We provide methods to convert from the object type which is an enum, to a string +representation of that value (and vice-versa).

+
+
  str_type = git_object_type2string(otype);
+  printf("object length and type: %d, %s\n",
+      (int)git_odb_object_size(obj),
+      str_type);
+
+
+ +
+

For proper memory management, close the object when you are done with it or it will leak +memory.

+
+ +
+
+ +
+

Raw Object Writing

+
+
  printf("\n*Raw Object Write*\n");
+
+
+ +
+

You can also write raw object data to Git. This is pretty cool because it gives you +direct access to the key/value properties of Git. Here we’ll write a new blob object +that just contains a simple string. Notice that we have to specify the object type as +the git_otype enum.

+
+
  git_odb_write(&oid, odb, "test data", sizeof("test data") - 1, GIT_OBJ_BLOB);
+
+
+ +
+

Now that we’ve written the object, we can check out what SHA1 was generated when the +object was written to our database.

+
+
  git_oid_fmt(out, &oid);
+  printf("Written Object: %s\n", out);
+
+
+ +
+

Object Parsing

+ +

libgit2 has methods to parse every object type in Git so you don’t have to work directly +with the raw data. This is much faster and simpler than trying to deal with the raw data +yourself.

+
+
+
+
+ +
+

Commit Parsing

+ +

Parsing commit objects is simple and gives you access to all the data in the commit +– the // author (name, email, datetime), committer (same), tree, message, encoding and parent(s).

+
+
  printf("\n*Commit Parsing*\n");
+
+  git_commit *commit;
+  git_oid_fromstr(&oid, "f0877d0b841d75172ec404fc9370173dfffc20d1");
+
+  error = git_commit_lookup(&commit, repo, &oid);
+
+  const git_signature *author, *cmtter;
+  const char *message;
+  time_t ctime;
+  unsigned int parents, p;
+
+
+ +
+

Each of the properties of the commit object are accessible via methods, including commonly +needed variations, such as git_commit_time which returns the author time and _message +which gives you the commit message.

+
+
  message  = git_commit_message(commit);
+  author   = git_commit_author(commit);
+  cmtter   = git_commit_committer(commit);
+  ctime    = git_commit_time(commit);
+
+
+ +
+

The author and committer methods return [git_signature] structures, which give you name, email +and when, which is a git_time structure, giving you a timestamp and timezone offset.

+
+
  printf("Author: %s (%s)\n", author->name, author->email);
+
+
+ +
+

Commits can have zero or more parents. The first (root) commit will have no parents, most commits +will have one, which is the commit it was based on, and merge commits will have two or more. +Commits can technically have any number, though it’s pretty rare to have more than two.

+
+
  parents  = git_commit_parentcount(commit);
+  for (p = 0;p < parents;p++) {
+    git_commit *parent;
+    git_commit_parent(&parent, commit, p);
+    git_oid_fmt(out, git_commit_id(parent));
+    printf("Parent: %s\n", out);
+    git_commit_free(parent);
+  }
+
+
+ +
+

Don’t forget to close the object to prevent memory leaks. You will have to do this for +all the objects you open and parse.

+
+
  git_commit_free(commit);
+
+
+ +
+

Writing Commits

+ +

libgit2 provides a couple of methods to create commit objects easily as well. There are four +different create signatures, we’ll just show one of them here. You can read about the other +ones in the commit API docs.

+
+
  printf("\n*Commit Writing*\n");
+  git_oid tree_id, parent_id, commit_id;
+  git_tree *tree;
+  git_commit *parent;
+
+
+ +
+

Creating signatures for an authoring identity and time is pretty simple – you will need to have +this to create a commit in order to specify who created it and when. Default values for the name +and email should be found in the user.name and user.email configuration options. See the config +section of this example file to see how to access config values.

+
+
  git_signature_new((git_signature **)&author, "Scott Chacon", "schacon@gmail.com",
+      123456789, 60);
+  git_signature_new((git_signature **)&cmtter, "Scott A Chacon", "scott@github.com",
+      987654321, 90);
+
+
+ +
+

Commit objects need a tree to point to and optionally one or more parents. Here we’re creating oid +objects to create the commit with, but you can also use

+
+
  git_oid_fromstr(&tree_id, "28873d96b4e8f4e33ea30f4c682fd325f7ba56ac");
+  git_tree_lookup(&tree, repo, &tree_id);
+  git_oid_fromstr(&parent_id, "f0877d0b841d75172ec404fc9370173dfffc20d1");
+  git_commit_lookup(&parent, repo, &parent_id);
+
+
+ +
+

Here we actually create the commit object with a single call with all the values we need to create +the commit. The SHA key is written to the commit_id variable here.

+
+
  git_commit_create_v(
+    &commit_id, /* out id */
+    repo,
+    NULL, /* do not update the HEAD */
+    author,
+    cmtter,
+    NULL, /* use default message encoding */
+    "example commit",
+    tree,
+    1, parent);
+
+
+ +
+

Now we can take a look at the commit SHA we’ve generated.

+
+
  git_oid_fmt(out, &commit_id);
+  printf("New Commit: %s\n", out);
+
+
+ +
+

Tag Parsing

+ +

You can parse and create tags with the tag management API, which functions very similarly +to the commit lookup, parsing and creation methods, since the objects themselves are very similar.

+
+
  printf("\n*Tag Parsing*\n");
+  git_tag *tag;
+  const char *tmessage, *tname;
+  git_otype ttype;
+
+
+ +
+

We create an oid for the tag object if we know the SHA and look it up in the repository the same +way that we would a commit (or any other) object.

+
+
  git_oid_fromstr(&oid, "bc422d45275aca289c51d79830b45cecebff7c3a");
+
+  error = git_tag_lookup(&tag, repo, &oid);
+
+
+ +
+

Now that we have the tag object, we can extract the information it generally contains: the target +(usually a commit object), the type of the target object (usually ‘commit’), the name (‘v1.0’), +the tagger (a git_signature – name, email, timestamp), and the tag message.

+
+
  git_tag_target((git_object **)&commit, tag);
+  tname = git_tag_name(tag);    // "test"
+  ttype = git_tag_type(tag);    // GIT_OBJ_COMMIT (otype enum)
+  tmessage = git_tag_message(tag); // "tag message\n"
+  printf("Tag Message: %s\n", tmessage);
+
+  git_commit_free(commit);
+
+
+ +
+

Tree Parsing

+ +

Tree parsing is a bit different than the other objects, in that we have a subtype which is the +tree entry. This is not an actual object type in Git, but a useful structure for parsing and +traversing tree entries.

+
+
  printf("\n*Tree Parsing*\n");
+
+  const git_tree_entry *entry;
+  git_object *objt;
+
+
+ +
+

Create the oid and lookup the tree object just like the other objects.

+
+
  git_oid_fromstr(&oid, "2a741c18ac5ff082a7caaec6e74db3075a1906b5");
+  git_tree_lookup(&tree, repo, &oid);
+
+
+ +
+

Getting the count of entries in the tree so you can iterate over them if you want to.

+
+
  int cnt = git_tree_entrycount(tree); // 3
+  printf("tree entries: %d\n", cnt);
+
+  entry = git_tree_entry_byindex(tree, 0);
+  printf("Entry name: %s\n", git_tree_entry_name(entry)); // "hello.c"
+
+
+ +
+

You can also access tree entries by name if you know the name of the entry you’re looking for.

+
+
  entry = git_tree_entry_byname(tree, "hello.c");
+  git_tree_entry_name(entry); // "hello.c"
+
+
+ +
+

Once you have the entry object, you can access the content or subtree (or commit, in the case +of submodules) that it points to. You can also get the mode if you want.

+
+
  git_tree_entry_2object(&objt, repo, entry); // blob
+
+
+ +
+

Remember to close the looked-up object once you are done using it

+
+ +
+
+ +
+

Blob Parsing

+ +

The last object type is the simplest and requires the least parsing help. Blobs are just file +contents and can contain anything, there is no structure to it. The main advantage to using the +simple blob api is that when you’re creating blobs you don’t have to calculate the size +of the content. There is also a helper for reading a file from disk and writing it to the db and +getting the oid back so you don’t have to do all those steps yourself.

+
+
  printf("\n*Blob Parsing*\n");
+  git_blob *blob;
+
+  git_oid_fromstr(&oid, "af7574ea73f7b166f869ef1a39be126d9a186ae0");
+  git_blob_lookup(&blob, repo, &oid);
+
+
+ +
+

You can access a buffer with the raw contents of the blob directly. +Note that this buffer may not be contain ASCII data for certain blobs (e.g. binary files): +do not consider the buffer a NULL-terminated string, and use the git_blob_rawsize attribute to +find out its exact size in bytes

+
+
  printf("Blob Size: %ld\n", git_blob_rawsize(blob)); // 8
+  git_blob_rawcontent(blob); // "content"
+
+
+ +
+

Revwalking

+ +

The libgit2 revision walking api provides methods to traverse the directed graph created +by the parent pointers of the commit objects. Since all commits point back to the commit that +came directly before them, you can walk this parentage as a graph and find all the commits that +were ancestors of (reachable from) a given starting point. This can allow you to create git log +type functionality.

+
+
  printf("\n*Revwalking*\n");
+  git_revwalk *walk;
+  git_commit *wcommit;
+
+  git_oid_fromstr(&oid, "f0877d0b841d75172ec404fc9370173dfffc20d1");
+
+
+ +
+

To use the revwalker, create a new walker, tell it how you want to sort the output and then push +one or more starting points onto the walker. If you want to emulate the output of git log you +would push the SHA of the commit that HEAD points to into the walker and then start traversing them. +You can also ‘hide’ commits that you want to stop at or not see any of their ancestors. So if you +want to emulate git log branch1..branch2, you would push the oid of branch2 and hide the oid +of branch1.

+
+
  git_revwalk_new(&walk, repo);
+  git_revwalk_sorting(walk, GIT_SORT_TOPOLOGICAL | GIT_SORT_REVERSE);
+  git_revwalk_push(walk, &oid);
+
+  const git_signature *cauth;
+  const char *cmsg;
+
+
+ +
+

Now that we have the starting point pushed onto the walker, we can start asking for ancestors. It +will return them in the sorting order we asked for as commit oids. +We can then lookup and parse the commited pointed at by the returned OID; +note that this operation is specially fast since the raw contents of the commit object will +be cached in memory

+
+
  while ((git_revwalk_next(&oid, walk)) == GIT_SUCCESS) {
+    error = git_commit_lookup(&wcommit, repo, &oid);
+    cmsg  = git_commit_message(wcommit);
+    cauth = git_commit_author(wcommit);
+    printf("%s (%s)\n", cmsg, cauth->email);
+    git_commit_free(wcommit);
+  }
+
+
+ +
+

Like the other objects, be sure to free the revwalker when you’re done to prevent memory leaks. +Also, make sure that the repository being walked it not deallocated while the walk is in +progress, or it will result in undefined behavior

+
+ +
+
+ +
+

Index File Manipulation

+ +

The index file API allows you to read, traverse, update and write the Git index file +(sometimes thought of as the staging area).

+
+
  printf("\n*Index Walking*\n");
+
+  git_index *index;
+  unsigned int i, ecount;
+
+
+ +
+

You can either open the index from the standard location in an open repository, as we’re doing +here, or you can open and manipulate any index file with git_index_open_bare(). The index +for the repository will be located and loaded from disk.

+
+
  git_repository_index(&index, repo);
+
+
+ +
+

For each entry in the index, you can get a bunch of information including the SHA (oid), path +and mode which map to the tree objects that are written out. It also has filesystem properties +to help determine what to inspect for changes (ctime, mtime, dev, ino, uid, gid, file_size and flags) +All these properties are exported publicly in the git_index_entry struct

+
+
  ecount = git_index_entrycount(index);
+  for (i = 0; i < ecount; ++i) {
+    git_index_entry *e = git_index_get(index, i);
+
+    printf("path: %s\n", e->path);
+    printf("mtime: %d\n", (int)e->mtime.seconds);
+    printf("fs: %d\n", (int)e->file_size);
+  }
+
+  git_index_free(index);
+
+
+ +
+

References

+ +

The reference API allows you to list, resolve, create and update references such as +branches, tags and remote references (everything in the .git/refs directory).

+
+
  printf("\n*Reference Listing*\n");
+
+
+ +
+

Here we will implement something like git for-each-ref simply listing out all available +references and the object SHA they resolve to.

+
+
  git_strarray ref_list;
+  git_reference_listall(&ref_list, repo, GIT_REF_LISTALL);
+
+  const char *refname;
+  git_reference *ref;
+
+
+ +
+

Now that we have the list of reference names, we can lookup each ref one at a time and +resolve them to the SHA, then print both values out.

+
+
  for (i = 0; i < ref_list.count; ++i) {
+    refname = ref_list.strings[i];
+    git_reference_lookup(&ref, repo, refname);
+
+    switch (git_reference_type(ref)) {
+    case GIT_REF_OID:
+      git_oid_fmt(out, git_reference_oid(ref));
+      printf("%s [%s]\n", refname, out);
+      break;
+
+    case GIT_REF_SYMBOLIC:
+      printf("%s => %s\n", refname, git_reference_target(ref));
+      break;
+    default:
+      fprintf(stderr, "Unexpected reference type\n");
+      exit(1);
+    }
+  }
+
+  git_strarray_free(&ref_list);
+
+
+ +
+

Config Files

+ +

The config API allows you to list and updatee config values in +any of the accessible config file locations (system, global, local).

+
+
  printf("\n*Config Listing*\n");
+
+  const char *email;
+  int32_t j;
+
+  git_config *cfg;
+
+
+ +
+

Open a config object so we can read global values from it.

+
+
  git_config_open_ondisk(&cfg, "~/.gitconfig");
+
+  git_config_get_int32(cfg, "help.autocorrect", &j);
+  printf("Autocorrect: %d\n", j);
+
+  git_config_get_string(cfg, "user.email", &email);
+  printf("Email: %s\n", email);
+
+
+ +
+

Finally, when you’re done with the repository, you can free it as well.

+ +
+
  git_repository_free(repo);
+
+  return 0;
+}
+
+
+ diff --git a/ex/v0.16.0/git2.html b/ex/v0.16.0/git2.html new file mode 100644 index 00000000000..64eab6ef8be --- /dev/null +++ b/ex/v0.16.0/git2.html @@ -0,0 +1,130 @@ + + + + + git2.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + + + + + + + + + + + + + +

git2.c

+
+ +
+ +
+
#include <stdlib.h>
+#include <stdio.h>
+
+#include "common.h"
+
+
+ +
+

This part is not strictly libgit2-dependent, but you can use this +as a starting point for a git-like tool

+
+
struct {
+  char *name;
+  git_cb fn;
+} commands[] = {
+  {"ls-remote", ls_remote},
+  {"fetch", fetch},
+  {"index-pack", index_pack},
+  { NULL, NULL}
+};
+
+int run_command(git_cb fn, int argc, char **argv)
+{
+  int error;
+  git_repository *repo;
+
+
+ +
+

Before running the actual command, create an instance of the local +repository and pass it to the function.

+
+
  error = git_repository_open(&repo, ".git");
+  if (error < GIT_SUCCESS)
+    repo = NULL;
+
+
+ +
+

Run the command. If something goes wrong, print the error message to stderr

+ +
+
  error = fn(repo, argc, argv);
+  if (error < GIT_SUCCESS)
+    fprintf(stderr, "Bad news:\n %s\n", git_lasterror());
+
+  if(repo)
+    git_repository_free(repo);
+
+  return !!error;
+}
+
+int main(int argc, char **argv)
+{
+  int i, error;
+
+  if (argc < 2) {
+    fprintf(stderr, "usage: %s <cmd> [repo]\n", argv[0]);
+    exit(EXIT_FAILURE);
+  }
+
+  for (i = 0; commands[i].name != NULL; ++i) {
+    if (!strcmp(argv[1], commands[i].name))
+      return run_command(commands[i].fn, --argc, ++argv);
+  }
+
+  fprintf(stderr, "Command not found: %s\n", argv[1]);
+  return 1;
+}
+
+
+ diff --git a/ex/v0.16.0/index-pack.html b/ex/v0.16.0/index-pack.html new file mode 100644 index 00000000000..e7185a9ba3c --- /dev/null +++ b/ex/v0.16.0/index-pack.html @@ -0,0 +1,137 @@ + + + + + index-pack.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

index-pack.c

+
+ +
+ +
+
#include <git2.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "common.h"
+
+
+ +
+

This could be run in the main loop whilst the application waits for +the indexing to finish in a worker thread

+
+
int index_cb(const git_indexer_stats *stats, void *data)
+{
+  printf("\rProcessing %d of %d", stats->processed, stats->total);
+}
+
+int index_pack(git_repository *repo, int argc, char **argv)
+{
+  git_indexer *indexer;
+  git_indexer_stats stats;
+  int error;
+  char hash[GIT_OID_HEXSZ + 1] = {0};
+
+  if (argc < 2) {
+    fprintf(stderr, "I need a packfile\n");
+    return EXIT_FAILURE;
+  }
+
+
+ +
+

Create a new indexer

+
+
  error = git_indexer_new(&indexer, argv[1]);
+  if (error < GIT_SUCCESS)
+    return error;
+
+
+ +
+

Index the packfile. This function can take a very long time and +should be run in a worker thread.

+
+
  error = git_indexer_run(indexer, &stats);
+  if (error < GIT_SUCCESS)
+    return error;
+
+
+ +
+

Write the information out to an index file

+
+
  error = git_indexer_write(indexer);
+
+
+ +
+

Get the packfile’s hash (which should become it’s filename)

+ +
+
  git_oid_fmt(hash, git_indexer_hash(indexer));
+  puts(hash);
+
+  git_indexer_free(indexer);
+
+  return GIT_SUCCESS;
+}
+
+
+ diff --git a/ex/v0.16.0/ls-remote.html b/ex/v0.16.0/ls-remote.html new file mode 100644 index 00000000000..66516862543 --- /dev/null +++ b/ex/v0.16.0/ls-remote.html @@ -0,0 +1,165 @@ + + + + + ls-remote.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

ls-remote.c

+
+ +
+ +
+
#include <git2.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "common.h"
+
+static int show_ref__cb(git_remote_head *head, void *payload)
+{
+  char oid[GIT_OID_HEXSZ + 1] = {0};
+  git_oid_fmt(oid, &head->oid);
+  printf("%s\t%s\n", oid, head->name);
+  return GIT_SUCCESS;
+}
+
+int use_unnamed(git_repository *repo, const char *url)
+{
+  git_remote *remote = NULL;
+  int error;
+
+
+ +
+

Create an instance of a remote from the URL. The transport to use +is detected from the URL

+
+
  error = git_remote_new(&remote, repo, url, NULL);
+  if (error < GIT_SUCCESS)
+    goto cleanup;
+
+
+ +
+

When connecting, the underlying code needs to know wether we +want to push or fetch

+
+
  error = git_remote_connect(remote, GIT_DIR_FETCH);
+  if (error < GIT_SUCCESS)
+    goto cleanup;
+
+
+ +
+

With git_remote_ls we can retrieve the advertised heads

+
+
  error = git_remote_ls(remote, &show_ref__cb, NULL);
+
+cleanup:
+  git_remote_free(remote);
+  return error;
+}
+
+int use_remote(git_repository *repo, char *name)
+{
+  git_remote *remote = NULL;
+  int error;
+
+
+ +
+

Find the remote by name

+
+
  error = git_remote_load(&remote, repo, name);
+  if (error < GIT_SUCCESS)
+    goto cleanup;
+
+  error = git_remote_connect(remote, GIT_DIR_FETCH);
+  if (error < GIT_SUCCESS)
+    goto cleanup;
+
+  error = git_remote_ls(remote, &show_ref__cb, NULL);
+
+cleanup:
+  git_remote_free(remote);
+  return error;
+}
+
+
+ +
+

This gets called to do the work. The remote can be given either as +the name of a configured remote or an URL.

+ +
+
int ls_remote(git_repository *repo, int argc, char **argv)
+{
+  int error, i;
+
+  /* If there's a ':' in the name, assume it's an URL */
+  if (strchr(argv[1], ':') != NULL) {
+    error = use_unnamed(repo, argv[1]);
+  } else {
+    error = use_remote(repo, argv[1]);
+  }
+
+  return error;
+}
+
+
+ diff --git a/ex/v0.16.0/showindex.html b/ex/v0.16.0/showindex.html new file mode 100644 index 00000000000..8992e9f7fa7 --- /dev/null +++ b/ex/v0.16.0/showindex.html @@ -0,0 +1,92 @@ + + + + + showindex.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + +

showindex.c

+
+ +
+ + +
+
#include <git2.h>
+#include <stdio.h>
+
+int main (int argc, char** argv)
+{
+  git_repository *repo;
+  git_index *index;
+  unsigned int i, e, ecount;
+  git_index_entry **entries;
+  git_oid oid;
+
+  char out[41];
+  out[40] = '\0';
+
+  git_repository_open(&repo, "/opt/libgit2-test/.git");
+
+  git_repository_index(&index, repo);
+  git_index_read(index);
+
+  ecount = git_index_entrycount(index);
+  for (i = 0; i < ecount; ++i) {
+    git_index_entry *e = git_index_get(index, i);
+
+    oid = e->oid;
+    git_oid_fmt(out, &oid);
+
+    printf("File Path: %s\n", e->path);
+    printf(" Blob SHA: %s\n", out);
+    printf("File Size: %d\n", (int)e->file_size);
+    printf("   Device: %d\n", (int)e->dev);
+    printf("    Inode: %d\n", (int)e->ino);
+    printf("      UID: %d\n", (int)e->uid);
+    printf("      GID: %d\n", (int)e->gid);
+    printf("    ctime: %d\n", (int)e->ctime.seconds);
+    printf("    mtime: %d\n", (int)e->mtime.seconds);
+    printf("\n");
+  }
+
+  git_index_free(index);
+
+  git_repository_free(repo);
+}
+
+
+ diff --git a/ex/v0.17.0/diff.html b/ex/v0.17.0/diff.html new file mode 100644 index 00000000000..efe240a1624 --- /dev/null +++ b/ex/v0.17.0/diff.html @@ -0,0 +1,290 @@ + + + + + diff.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + +

diff.c

+
+ +
+ + +
+
#include <stdio.h>
+#include <git2.h>
+#include <stdlib.h>
+#include <string.h>
+
+void check(int error, const char *message)
+{
+  if (error) {
+    fprintf(stderr, "%s (%d)\n", message, error);
+    exit(1);
+  }
+}
+
+int resolve_to_tree(git_repository *repo, const char *identifier, git_tree **tree)
+{
+  int err = 0;
+  size_t len = strlen(identifier);
+  git_oid oid;
+  git_object *obj = NULL;
+
+  /* try to resolve as OID */
+  if (git_oid_fromstrn(&oid, identifier, len) == 0)
+    git_object_lookup_prefix(&obj, repo, &oid, len, GIT_OBJ_ANY);
+
+  /* try to resolve as reference */
+  if (obj == NULL) {
+    git_reference *ref, *resolved;
+    if (git_reference_lookup(&ref, repo, identifier) == 0) {
+      git_reference_resolve(&resolved, ref);
+      git_reference_free(ref);
+      if (resolved) {
+        git_object_lookup(&obj, repo, git_reference_oid(resolved), GIT_OBJ_ANY);
+        git_reference_free(resolved);
+      }
+    }
+  }
+
+  if (obj == NULL)
+    return GIT_ENOTFOUND;
+
+  switch (git_object_type(obj)) {
+  case GIT_OBJ_TREE:
+    *tree = (git_tree *)obj;
+    break;
+  case GIT_OBJ_COMMIT:
+    err = git_commit_tree(tree, (git_commit *)obj);
+    git_object_free(obj);
+    break;
+  default:
+    err = GIT_ENOTFOUND;
+  }
+
+  return err;
+}
+
+char *colors[] = {
+  "\033[m", /* reset */
+  "\033[1m", /* bold */
+  "\033[31m", /* red */
+  "\033[32m", /* green */
+  "\033[36m" /* cyan */
+};
+
+int printer(
+  void *data,
+  git_diff_delta *delta,
+  git_diff_range *range,
+  char usage,
+  const char *line,
+  size_t line_len)
+{
+  int *last_color = data, color = 0;
+
+  if (*last_color >= 0) {
+    switch (usage) {
+    case GIT_DIFF_LINE_ADDITION: color = 3; break;
+    case GIT_DIFF_LINE_DELETION: color = 2; break;
+    case GIT_DIFF_LINE_ADD_EOFNL: color = 3; break;
+    case GIT_DIFF_LINE_DEL_EOFNL: color = 2; break;
+    case GIT_DIFF_LINE_FILE_HDR: color = 1; break;
+    case GIT_DIFF_LINE_HUNK_HDR: color = 4; break;
+    default: color = 0;
+    }
+    if (color != *last_color) {
+      if (*last_color == 1 || color == 1)
+        fputs(colors[0], stdout);
+      fputs(colors[color], stdout);
+      *last_color = color;
+    }
+  }
+
+  fputs(line, stdout);
+  return 0;
+}
+
+int check_uint16_param(const char *arg, const char *pattern, uint16_t *val)
+{
+  size_t len = strlen(pattern);
+  uint16_t strval;
+  char *endptr = NULL;
+  if (strncmp(arg, pattern, len))
+    return 0;
+  strval = strtoul(arg + len, &endptr, 0);
+  if (endptr == arg)
+    return 0;
+  *val = strval;
+  return 1;
+}
+
+int check_str_param(const char *arg, const char *pattern, char **val)
+{
+  size_t len = strlen(pattern);
+  if (strncmp(arg, pattern, len))
+    return 0;
+  *val = (char *)(arg + len);
+  return 1;
+}
+
+void usage(const char *message, const char *arg)
+{
+  if (message && arg)
+    fprintf(stderr, "%s: %s\n", message, arg);
+  else if (message)
+    fprintf(stderr, "%s\n", message);
+  fprintf(stderr, "usage: diff [<tree-oid> [<tree-oid>]]\n");
+  exit(1);
+}
+
+int main(int argc, char *argv[])
+{
+  char path[GIT_PATH_MAX];
+  git_repository *repo = NULL;
+  git_tree *t1 = NULL, *t2 = NULL;
+  git_diff_options opts = {0};
+  git_diff_list *diff;
+  int i, color = -1, compact = 0, cached = 0;
+  char *a, *dir = ".", *treeish1 = NULL, *treeish2 = NULL;
+
+  /* parse arguments as copied from git-diff */
+
+  for (i = 1; i < argc; ++i) {
+    a = argv[i];
+
+    if (a[0] != '-') {
+      if (treeish1 == NULL)
+        treeish1 = a;
+      else if (treeish2 == NULL)
+        treeish2 = a;
+      else
+        usage("Only one or two tree identifiers can be provided", NULL);
+    }
+    else if (!strcmp(a, "-p") || !strcmp(a, "-u") ||
+      !strcmp(a, "--patch"))
+      compact = 0;
+    else if (!strcmp(a, "--cached"))
+      cached = 1;
+    else if (!strcmp(a, "--name-status"))
+      compact = 1;
+    else if (!strcmp(a, "--color"))
+      color = 0;
+    else if (!strcmp(a, "--no-color"))
+      color = -1;
+    else if (!strcmp(a, "-R"))
+      opts.flags |= GIT_DIFF_REVERSE;
+    else if (!strcmp(a, "-a") || !strcmp(a, "--text"))
+      opts.flags |= GIT_DIFF_FORCE_TEXT;
+    else if (!strcmp(a, "--ignore-space-at-eol"))
+      opts.flags |= GIT_DIFF_IGNORE_WHITESPACE_EOL;
+    else if (!strcmp(a, "-b") || !strcmp(a, "--ignore-space-change"))
+      opts.flags |= GIT_DIFF_IGNORE_WHITESPACE_CHANGE;
+    else if (!strcmp(a, "-w") || !strcmp(a, "--ignore-all-space"))
+      opts.flags |= GIT_DIFF_IGNORE_WHITESPACE;
+    else if (!strcmp(a, "--ignored"))
+      opts.flags |= GIT_DIFF_INCLUDE_IGNORED;
+    else if (!strcmp(a, "--untracked"))
+      opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED;
+    else if (!check_uint16_param(a, "-U", &opts.context_lines) &&
+      !check_uint16_param(a, "--unified=", &opts.context_lines) &&
+      !check_uint16_param(a, "--inter-hunk-context=",
+        &opts.interhunk_lines) &&
+      !check_str_param(a, "--src-prefix=", &opts.old_prefix) &&
+      !check_str_param(a, "--dst-prefix=", &opts.new_prefix))
+      usage("Unknown arg", a);
+  }
+
+  /* open repo */
+
+  check(git_repository_discover(path, sizeof(path), dir, 0, "/"),
+    "Could not discover repository");
+  check(git_repository_open(&repo, path),
+    "Could not open repository");
+
+  if (treeish1)
+    check(resolve_to_tree(repo, treeish1, &t1), "Looking up first tree");
+  if (treeish2)
+    check(resolve_to_tree(repo, treeish2, &t2), "Looking up second tree");
+
+  /* <sha1> <sha2> */
+  /* <sha1> --cached */
+  /* <sha1> */
+  /* --cached */
+  /* nothing */
+
+  if (t1 && t2)
+    check(git_diff_tree_to_tree(repo, &opts, t1, t2, &diff), "Diff");
+  else if (t1 && cached)
+    check(git_diff_index_to_tree(repo, &opts, t1, &diff), "Diff");
+  else if (t1) {
+    git_diff_list *diff2;
+    check(git_diff_index_to_tree(repo, &opts, t1, &diff), "Diff");
+    check(git_diff_workdir_to_index(repo, &opts, &diff2), "Diff");
+    check(git_diff_merge(diff, diff2), "Merge diffs");
+    git_diff_list_free(diff2);
+  }
+  else if (cached) {
+    check(resolve_to_tree(repo, "HEAD", &t1), "looking up HEAD");
+    check(git_diff_index_to_tree(repo, &opts, t1, &diff), "Diff");
+  }
+  else
+    check(git_diff_workdir_to_index(repo, &opts, &diff), "Diff");
+
+  if (color >= 0)
+    fputs(colors[0], stdout);
+
+  if (compact)
+    check(git_diff_print_compact(diff, &color, printer), "Displaying diff");
+  else
+    check(git_diff_print_patch(diff, &color, printer), "Displaying diff");
+
+  if (color >= 0)
+    fputs(colors[0], stdout);
+
+  git_diff_list_free(diff);
+  git_tree_free(t1);
+  git_tree_free(t2);
+  git_repository_free(repo);
+
+  return 0;
+}
+
+
+ diff --git a/ex/v0.17.0/fetch.html b/ex/v0.17.0/fetch.html new file mode 100644 index 00000000000..a5df11ae410 --- /dev/null +++ b/ex/v0.17.0/fetch.html @@ -0,0 +1,220 @@ + + + + + fetch.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

fetch.c

+
+ +
+ +
+
#include "common.h"
+#include <git2.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+
+struct dl_data {
+  git_remote *remote;
+  git_off_t *bytes;
+  git_indexer_stats *stats;
+  int ret;
+  int finished;
+};
+
+static void *download(void *ptr)
+{
+  struct dl_data *data = (struct dl_data *)ptr;
+
+
+ +
+

Connect to the remote end specifying that we want to fetch +information from it.

+
+
  if (git_remote_connect(data->remote, GIT_DIR_FETCH) < 0) {
+    data->ret = -1;
+    goto exit;
+  }
+
+
+ +
+

Download the packfile and index it. This function updates the +amount of received data and the indexer stats which lets you +inform the user about progress.

+
+
  if (git_remote_download(data->remote, data->bytes, data->stats) < 0) {
+    data->ret = -1;
+    goto exit;
+  }
+
+  data->ret = 0;
+
+exit:
+  data->finished = 1;
+  pthread_exit(&data->ret);
+}
+
+int update_cb(const char *refname, const git_oid *a, const git_oid *b)
+{
+  const char *action;
+  char a_str[GIT_OID_HEXSZ+1], b_str[GIT_OID_HEXSZ+1];
+
+  git_oid_fmt(b_str, b);
+  b_str[GIT_OID_HEXSZ] = '\0';
+
+  if (git_oid_iszero(a)) {
+    printf("[new]     %.20s %s\n", b_str, refname);
+  } else {
+    git_oid_fmt(a_str, a);
+    a_str[GIT_OID_HEXSZ] = '\0';
+    printf("[updated] %.10s..%.10s %s\n", a_str, b_str, refname);
+  }
+
+  return 0;
+}
+
+int fetch(git_repository *repo, int argc, char **argv)
+{
+  git_remote *remote = NULL;
+  git_off_t bytes = 0;
+  git_indexer_stats stats;
+  pthread_t worker;
+  struct dl_data data;
+
+
+ +
+

Figure out whether it’s a named remote or a URL

+
+
  printf("Fetching %s\n", argv[1]);
+  if (git_remote_load(&remote, repo, argv[1]) < 0) {
+    if (git_remote_new(&remote, repo, NULL, argv[1], NULL) < 0)
+      return -1;
+  }
+
+
+ +
+

Set up the information for the background worker thread

+
+
  data.remote = remote;
+  data.bytes = &bytes;
+  data.stats = &stats;
+  data.ret = 0;
+  data.finished = 0;
+  memset(&stats, 0, sizeof(stats));
+
+  pthread_create(&worker, NULL, download, &data);
+
+
+ +
+

Loop while the worker thread is still running. Here we show processed +and total objects in the pack and the amount of received +data. Most frontends will probably want to show a percentage and +the download rate.

+
+
  do {
+  usleep(10000);
+  printf("\rReceived %d/%d objects in %d bytes", stats.processed, stats.total, bytes);
+  } while (!data.finished);
+  printf("\rReceived %d/%d objects in %d bytes\n", stats.processed, stats.total, bytes);
+
+
+ +
+

Disconnect the underlying connection to prevent from idling.

+
+ +
+
+ +
+

Update the references in the remote’s namespace to point to the +right commits. This may be needed even if there was no packfile +to download, which can happen e.g. when the branches have been +changed but all the neede objects are available locally.

+ +
+
  if (git_remote_update_tips(remote, update_cb) < 0)
+    return -1;
+
+  git_remote_free(remote);
+
+  return 0;
+
+on_error:
+  git_remote_free(remote);
+  return -1;
+}
+
+
+ diff --git a/ex/v0.17.0/general.html b/ex/v0.17.0/general.html new file mode 100644 index 00000000000..44ae6d9f071 --- /dev/null +++ b/ex/v0.17.0/general.html @@ -0,0 +1,911 @@ + + + + + general.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

general.c

+
+ +
+

libgit2 is a portable, pure C implementation of the Git core methods +provided as a re-entrant linkable library with a solid API, allowing you +to write native speed custom Git applications in any language which +supports C bindings.

+ +

This file is an example of using that API in a real, compilable C file. +As the API is updated, this file will be updated to demonstrate the +new functionality.

+ +

If you’re trying to write something in C using libgit2, you will also want +to check out the generated API documentation and the Usage Guide. We’ve +tried to link to the relevant sections of the API docs in each section in this file.

+ +

libgit2 only implements the core plumbing functions, not really the higher +level porcelain stuff. For a primer on Git Internals that you will need to know +to work with Git at this level, check out Chapter 9 of the Pro Git book.

+
+
+
+
+ +
+

Includes

+
+
+
+
+ +
+

Including the git2.h header will include all the other libgit2 headers that you need. +It should be the only thing you need to include in order to compile properly and get +all the libgit2 API.

+
+
#include <git2.h>
+#include <stdio.h>
+
+int main (int argc, char** argv)
+{
+
+
+ +
+

Opening the Repository

+
+
+
+
+ +
+

There are a couple of methods for opening a repository, this being the simplest. +There are also methods for specifying the index file and work tree locations, here +we are assuming they are in the normal places.

+
+
  git_repository *repo;
+  if (argc > 1) {
+    git_repository_open(&repo, argv[1]);
+  } else {
+    git_repository_open(&repo, "/opt/libgit2-test/.git");
+  }
+
+
+ +
+

SHA-1 Value Conversions

+
+
+
+
+ +
+

For our first example, we will convert a 40 character hex value to the 20 byte raw SHA1 value.

+
+
  printf("*Hex to Raw*\n");
+  char hex[] = "fd6e612585290339ea8bf39c692a7ff6a29cb7c3";
+
+
+ +
+

The git_oid is the structure that keeps the SHA value. We will use this throughout the example +for storing the value of the current SHA key we’re working with.

+
+
  git_oid oid;
+  git_oid_fromstr(&oid, hex);
+
+
+ +
+

Once we’ve converted the string into the oid value, we can get the raw value of the SHA.

+
+
  printf("Raw 20 bytes: [%.20s]\n", (&oid)->id);
+
+
+ +
+

Next we will convert the 20 byte raw SHA1 value to a human readable 40 char hex value.

+
+
  printf("\n*Raw to Hex*\n");
+  char out[41];
+  out[40] = '\0';
+
+
+ +
+

If you have a oid, you can easily get the hex value of the SHA as well.

+
+
  git_oid_fmt(out, &oid);
+  printf("SHA hex string: %s\n", out);
+
+
+ +
+

Working with the Object Database

+ +

libgit2 provides direct access to the object database. +The object database is where the actual objects are stored in Git. For +working with raw objects, we’ll need to get this structure from the +repository.

+
+
  git_odb *odb;
+  git_repository_odb(&odb, repo);
+
+
+ +
+

Raw Object Reading

+
+
  printf("\n*Raw Object Read*\n");
+  git_odb_object *obj;
+  git_otype otype;
+  const unsigned char *data;
+  const char *str_type;
+  int error;
+
+
+ +
+

We can read raw objects directly from the object database if we have the oid (SHA) +of the object. This allows us to access objects without knowing thier type and inspect +the raw bytes unparsed.

+
+
  error = git_odb_read(&obj, odb, &oid);
+
+
+ +
+

A raw object only has three properties – the type (commit, blob, tree or tag), the size +of the raw data and the raw, unparsed data itself. For a commit or tag, that raw data +is human readable plain ASCII text. For a blob it is just file contents, so it could be +text or binary data. For a tree it is a special binary format, so it’s unlikely to be +hugely helpful as a raw object.

+
+
  data = (const unsigned char *)git_odb_object_data(obj);
+  otype = git_odb_object_type(obj);
+
+
+ +
+

We provide methods to convert from the object type which is an enum, to a string +representation of that value (and vice-versa).

+
+
  str_type = git_object_type2string(otype);
+  printf("object length and type: %d, %s\n",
+      (int)git_odb_object_size(obj),
+      str_type);
+
+
+ +
+

For proper memory management, close the object when you are done with it or it will leak +memory.

+
+ +
+
+ +
+

Raw Object Writing

+
+
  printf("\n*Raw Object Write*\n");
+
+
+ +
+

You can also write raw object data to Git. This is pretty cool because it gives you +direct access to the key/value properties of Git. Here we’ll write a new blob object +that just contains a simple string. Notice that we have to specify the object type as +the git_otype enum.

+
+
  git_odb_write(&oid, odb, "test data", sizeof("test data") - 1, GIT_OBJ_BLOB);
+
+
+ +
+

Now that we’ve written the object, we can check out what SHA1 was generated when the +object was written to our database.

+
+
  git_oid_fmt(out, &oid);
+  printf("Written Object: %s\n", out);
+
+
+ +
+

Object Parsing

+ +

libgit2 has methods to parse every object type in Git so you don’t have to work directly +with the raw data. This is much faster and simpler than trying to deal with the raw data +yourself.

+
+
+
+
+ +
+

Commit Parsing

+ +

Parsing commit objects is simple and gives you access to all the data in the commit +– the // author (name, email, datetime), committer (same), tree, message, encoding and parent(s).

+
+
  printf("\n*Commit Parsing*\n");
+
+  git_commit *commit;
+  git_oid_fromstr(&oid, "f0877d0b841d75172ec404fc9370173dfffc20d1");
+
+  error = git_commit_lookup(&commit, repo, &oid);
+
+  const git_signature *author, *cmtter;
+  const char *message;
+  time_t ctime;
+  unsigned int parents, p;
+
+
+ +
+

Each of the properties of the commit object are accessible via methods, including commonly +needed variations, such as git_commit_time which returns the author time and _message +which gives you the commit message.

+
+
  message  = git_commit_message(commit);
+  author   = git_commit_author(commit);
+  cmtter   = git_commit_committer(commit);
+  ctime    = git_commit_time(commit);
+
+
+ +
+

The author and committer methods return [git_signature] structures, which give you name, email +and when, which is a git_time structure, giving you a timestamp and timezone offset.

+
+
  printf("Author: %s (%s)\n", author->name, author->email);
+
+
+ +
+

Commits can have zero or more parents. The first (root) commit will have no parents, most commits +will have one, which is the commit it was based on, and merge commits will have two or more. +Commits can technically have any number, though it’s pretty rare to have more than two.

+
+
  parents  = git_commit_parentcount(commit);
+  for (p = 0;p < parents;p++) {
+    git_commit *parent;
+    git_commit_parent(&parent, commit, p);
+    git_oid_fmt(out, git_commit_id(parent));
+    printf("Parent: %s\n", out);
+    git_commit_free(parent);
+  }
+
+
+ +
+

Don’t forget to close the object to prevent memory leaks. You will have to do this for +all the objects you open and parse.

+
+
  git_commit_free(commit);
+
+
+ +
+

Writing Commits

+ +

libgit2 provides a couple of methods to create commit objects easily as well. There are four +different create signatures, we’ll just show one of them here. You can read about the other +ones in the commit API docs.

+
+
  printf("\n*Commit Writing*\n");
+  git_oid tree_id, parent_id, commit_id;
+  git_tree *tree;
+  git_commit *parent;
+
+
+ +
+

Creating signatures for an authoring identity and time is pretty simple – you will need to have +this to create a commit in order to specify who created it and when. Default values for the name +and email should be found in the user.name and user.email configuration options. See the config +section of this example file to see how to access config values.

+
+
  git_signature_new((git_signature **)&author, "Scott Chacon", "schacon@gmail.com",
+      123456789, 60);
+  git_signature_new((git_signature **)&cmtter, "Scott A Chacon", "scott@github.com",
+      987654321, 90);
+
+
+ +
+

Commit objects need a tree to point to and optionally one or more parents. Here we’re creating oid +objects to create the commit with, but you can also use

+
+
  git_oid_fromstr(&tree_id, "28873d96b4e8f4e33ea30f4c682fd325f7ba56ac");
+  git_tree_lookup(&tree, repo, &tree_id);
+  git_oid_fromstr(&parent_id, "f0877d0b841d75172ec404fc9370173dfffc20d1");
+  git_commit_lookup(&parent, repo, &parent_id);
+
+
+ +
+

Here we actually create the commit object with a single call with all the values we need to create +the commit. The SHA key is written to the commit_id variable here.

+
+
  git_commit_create_v(
+    &commit_id, /* out id */
+    repo,
+    NULL, /* do not update the HEAD */
+    author,
+    cmtter,
+    NULL, /* use default message encoding */
+    "example commit",
+    tree,
+    1, parent);
+
+
+ +
+

Now we can take a look at the commit SHA we’ve generated.

+
+
  git_oid_fmt(out, &commit_id);
+  printf("New Commit: %s\n", out);
+
+
+ +
+

Tag Parsing

+ +

You can parse and create tags with the tag management API, which functions very similarly +to the commit lookup, parsing and creation methods, since the objects themselves are very similar.

+
+
  printf("\n*Tag Parsing*\n");
+  git_tag *tag;
+  const char *tmessage, *tname;
+  git_otype ttype;
+
+
+ +
+

We create an oid for the tag object if we know the SHA and look it up in the repository the same +way that we would a commit (or any other) object.

+
+
  git_oid_fromstr(&oid, "bc422d45275aca289c51d79830b45cecebff7c3a");
+
+  error = git_tag_lookup(&tag, repo, &oid);
+
+
+ +
+

Now that we have the tag object, we can extract the information it generally contains: the target +(usually a commit object), the type of the target object (usually ‘commit’), the name (‘v1.0’), +the tagger (a git_signature – name, email, timestamp), and the tag message.

+
+
  git_tag_target((git_object **)&commit, tag);
+  tname = git_tag_name(tag);    // "test"
+  ttype = git_tag_type(tag);    // GIT_OBJ_COMMIT (otype enum)
+  tmessage = git_tag_message(tag); // "tag message\n"
+  printf("Tag Message: %s\n", tmessage);
+
+  git_commit_free(commit);
+
+
+ +
+

Tree Parsing

+ +

Tree parsing is a bit different than the other objects, in that we have a subtype which is the +tree entry. This is not an actual object type in Git, but a useful structure for parsing and +traversing tree entries.

+
+
  printf("\n*Tree Parsing*\n");
+
+  const git_tree_entry *entry;
+  git_object *objt;
+
+
+ +
+

Create the oid and lookup the tree object just like the other objects.

+
+
  git_oid_fromstr(&oid, "2a741c18ac5ff082a7caaec6e74db3075a1906b5");
+  git_tree_lookup(&tree, repo, &oid);
+
+
+ +
+

Getting the count of entries in the tree so you can iterate over them if you want to.

+
+
  int cnt = git_tree_entrycount(tree); // 3
+  printf("tree entries: %d\n", cnt);
+
+  entry = git_tree_entry_byindex(tree, 0);
+  printf("Entry name: %s\n", git_tree_entry_name(entry)); // "hello.c"
+
+
+ +
+

You can also access tree entries by name if you know the name of the entry you’re looking for.

+
+
  entry = git_tree_entry_byname(tree, "hello.c");
+  git_tree_entry_name(entry); // "hello.c"
+
+
+ +
+

Once you have the entry object, you can access the content or subtree (or commit, in the case +of submodules) that it points to. You can also get the mode if you want.

+
+
  git_tree_entry_to_object(&objt, repo, entry); // blob
+
+
+ +
+

Remember to close the looked-up object once you are done using it

+
+ +
+
+ +
+

Blob Parsing

+ +

The last object type is the simplest and requires the least parsing help. Blobs are just file +contents and can contain anything, there is no structure to it. The main advantage to using the +simple blob api is that when you’re creating blobs you don’t have to calculate the size +of the content. There is also a helper for reading a file from disk and writing it to the db and +getting the oid back so you don’t have to do all those steps yourself.

+
+
  printf("\n*Blob Parsing*\n");
+  git_blob *blob;
+
+  git_oid_fromstr(&oid, "af7574ea73f7b166f869ef1a39be126d9a186ae0");
+  git_blob_lookup(&blob, repo, &oid);
+
+
+ +
+

You can access a buffer with the raw contents of the blob directly. +Note that this buffer may not be contain ASCII data for certain blobs (e.g. binary files): +do not consider the buffer a NULL-terminated string, and use the git_blob_rawsize attribute to +find out its exact size in bytes

+
+
  printf("Blob Size: %ld\n", git_blob_rawsize(blob)); // 8
+  git_blob_rawcontent(blob); // "content"
+
+
+ +
+

Revwalking

+ +

The libgit2 revision walking api provides methods to traverse the directed graph created +by the parent pointers of the commit objects. Since all commits point back to the commit that +came directly before them, you can walk this parentage as a graph and find all the commits that +were ancestors of (reachable from) a given starting point. This can allow you to create git log +type functionality.

+
+
  printf("\n*Revwalking*\n");
+  git_revwalk *walk;
+  git_commit *wcommit;
+
+  git_oid_fromstr(&oid, "f0877d0b841d75172ec404fc9370173dfffc20d1");
+
+
+ +
+

To use the revwalker, create a new walker, tell it how you want to sort the output and then push +one or more starting points onto the walker. If you want to emulate the output of git log you +would push the SHA of the commit that HEAD points to into the walker and then start traversing them. +You can also ‘hide’ commits that you want to stop at or not see any of their ancestors. So if you +want to emulate git log branch1..branch2, you would push the oid of branch2 and hide the oid +of branch1.

+
+
  git_revwalk_new(&walk, repo);
+  git_revwalk_sorting(walk, GIT_SORT_TOPOLOGICAL | GIT_SORT_REVERSE);
+  git_revwalk_push(walk, &oid);
+
+  const git_signature *cauth;
+  const char *cmsg;
+
+
+ +
+

Now that we have the starting point pushed onto the walker, we can start asking for ancestors. It +will return them in the sorting order we asked for as commit oids. +We can then lookup and parse the commited pointed at by the returned OID; +note that this operation is specially fast since the raw contents of the commit object will +be cached in memory

+
+
  while ((git_revwalk_next(&oid, walk)) == 0) {
+    error = git_commit_lookup(&wcommit, repo, &oid);
+    cmsg  = git_commit_message(wcommit);
+    cauth = git_commit_author(wcommit);
+    printf("%s (%s)\n", cmsg, cauth->email);
+    git_commit_free(wcommit);
+  }
+
+
+ +
+

Like the other objects, be sure to free the revwalker when you’re done to prevent memory leaks. +Also, make sure that the repository being walked it not deallocated while the walk is in +progress, or it will result in undefined behavior

+
+ +
+
+ +
+

Index File Manipulation

+ +

The index file API allows you to read, traverse, update and write the Git index file +(sometimes thought of as the staging area).

+
+
  printf("\n*Index Walking*\n");
+
+  git_index *index;
+  unsigned int i, ecount;
+
+
+ +
+

You can either open the index from the standard location in an open repository, as we’re doing +here, or you can open and manipulate any index file with git_index_open_bare(). The index +for the repository will be located and loaded from disk.

+
+
  git_repository_index(&index, repo);
+
+
+ +
+

For each entry in the index, you can get a bunch of information including the SHA (oid), path +and mode which map to the tree objects that are written out. It also has filesystem properties +to help determine what to inspect for changes (ctime, mtime, dev, ino, uid, gid, file_size and flags) +All these properties are exported publicly in the git_index_entry struct

+
+
  ecount = git_index_entrycount(index);
+  for (i = 0; i < ecount; ++i) {
+    git_index_entry *e = git_index_get(index, i);
+
+    printf("path: %s\n", e->path);
+    printf("mtime: %d\n", (int)e->mtime.seconds);
+    printf("fs: %d\n", (int)e->file_size);
+  }
+
+  git_index_free(index);
+
+
+ +
+

References

+ +

The reference API allows you to list, resolve, create and update references such as +branches, tags and remote references (everything in the .git/refs directory).

+
+
  printf("\n*Reference Listing*\n");
+
+
+ +
+

Here we will implement something like git for-each-ref simply listing out all available +references and the object SHA they resolve to.

+
+
  git_strarray ref_list;
+  git_reference_listall(&ref_list, repo, GIT_REF_LISTALL);
+
+  const char *refname;
+  git_reference *ref;
+
+
+ +
+

Now that we have the list of reference names, we can lookup each ref one at a time and +resolve them to the SHA, then print both values out.

+
+
  for (i = 0; i < ref_list.count; ++i) {
+    refname = ref_list.strings[i];
+    git_reference_lookup(&ref, repo, refname);
+
+    switch (git_reference_type(ref)) {
+    case GIT_REF_OID:
+      git_oid_fmt(out, git_reference_oid(ref));
+      printf("%s [%s]\n", refname, out);
+      break;
+
+    case GIT_REF_SYMBOLIC:
+      printf("%s => %s\n", refname, git_reference_target(ref));
+      break;
+    default:
+      fprintf(stderr, "Unexpected reference type\n");
+      exit(1);
+    }
+  }
+
+  git_strarray_free(&ref_list);
+
+
+ +
+

Config Files

+ +

The config API allows you to list and updatee config values in +any of the accessible config file locations (system, global, local).

+
+
  printf("\n*Config Listing*\n");
+
+  const char *email;
+  int32_t j;
+
+  git_config *cfg;
+
+
+ +
+

Open a config object so we can read global values from it.

+
+
  git_config_open_ondisk(&cfg, "~/.gitconfig");
+
+  git_config_get_int32(cfg, "help.autocorrect", &j);
+  printf("Autocorrect: %d\n", j);
+
+  git_config_get_string(cfg, "user.email", &email);
+  printf("Email: %s\n", email);
+
+
+ +
+

Finally, when you’re done with the repository, you can free it as well.

+ +
+
  git_repository_free(repo);
+
+  return 0;
+}
+
+
+ diff --git a/ex/v0.17.0/git2.html b/ex/v0.17.0/git2.html new file mode 100644 index 00000000000..7b8f4021461 --- /dev/null +++ b/ex/v0.17.0/git2.html @@ -0,0 +1,135 @@ + + + + + git2.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + + + + + + + + + + + + + +

git2.c

+
+ +
+ +
+
#include <stdlib.h>
+#include <stdio.h>
+
+#include "common.h"
+
+
+ +
+

This part is not strictly libgit2-dependent, but you can use this +as a starting point for a git-like tool

+
+
struct {
+  char *name;
+  git_cb fn;
+} commands[] = {
+  {"ls-remote", ls_remote},
+  {"fetch", fetch},
+  {"index-pack", index_pack},
+  { NULL, NULL}
+};
+
+int run_command(git_cb fn, int argc, char **argv)
+{
+  int error;
+  git_repository *repo;
+
+
+ +
+

Before running the actual command, create an instance of the local +repository and pass it to the function.

+
+
  error = git_repository_open(&repo, ".git");
+  if (error < 0)
+    repo = NULL;
+
+
+ +
+

Run the command. If something goes wrong, print the error message to stderr

+ +
+
  error = fn(repo, argc, argv);
+  if (error < 0) {
+    if (giterr_last() == NULL)
+      fprintf(stderr, "Error without message");
+    else
+      fprintf(stderr, "Bad news:\n %s\n", giterr_last()->message);
+  }
+
+  if(repo)
+    git_repository_free(repo);
+
+  return !!error;
+}
+
+int main(int argc, char **argv)
+{
+  int i, error;
+
+  if (argc < 2) {
+    fprintf(stderr, "usage: %s <cmd> [repo]\n", argv[0]);
+    exit(EXIT_FAILURE);
+  }
+
+  for (i = 0; commands[i].name != NULL; ++i) {
+    if (!strcmp(argv[1], commands[i].name))
+      return run_command(commands[i].fn, --argc, ++argv);
+  }
+
+  fprintf(stderr, "Command not found: %s\n", argv[1]);
+  return 1;
+}
+
+
+ diff --git a/ex/v0.17.0/index-pack.html b/ex/v0.17.0/index-pack.html new file mode 100644 index 00000000000..b86a9ccf7ca --- /dev/null +++ b/ex/v0.17.0/index-pack.html @@ -0,0 +1,193 @@ + + + + + index-pack.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

index-pack.c

+
+ +
+ +
+
#include <git2.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "common.h"
+
+
+ +
+

This could be run in the main loop whilst the application waits for +the indexing to finish in a worker thread

+
+
int index_cb(const git_indexer_stats *stats, void *data)
+{
+  printf("\rProcessing %d of %d", stats->processed, stats->total);
+}
+
+int index_pack(git_repository *repo, int argc, char **argv)
+{
+  git_indexer_stream *idx;
+  git_indexer_stats stats = {0, 0};
+  int error, fd;
+  char hash[GIT_OID_HEXSZ + 1] = {0};
+  ssize_t read_bytes;
+  char buf[512];
+
+  if (argc < 2) {
+    fprintf(stderr, "I need a packfile\n");
+    return EXIT_FAILURE;
+  }
+
+  if (git_indexer_stream_new(&idx, ".git") < 0) {
+    puts("bad idx");
+    return -1;
+  }
+
+  if ((fd = open(argv[1], 0)) < 0) {
+    perror("open");
+    return -1;
+  }
+
+  do {
+    read_bytes = read(fd, buf, sizeof(buf));
+    if (read_bytes < 0)
+      break;
+
+    if ((error = git_indexer_stream_add(idx, buf, read_bytes, &stats)) < 0)
+      goto cleanup;
+
+    printf("\rIndexing %d of %d", stats.processed, stats.total);
+  } while (read_bytes > 0);
+
+  if (read_bytes < 0) {
+    error = -1;
+    perror("failed reading");
+    goto cleanup;
+  }
+
+  if ((error = git_indexer_stream_finalize(idx, &stats)) < 0)
+    goto cleanup;
+
+  printf("\rIndexing %d of %d\n", stats.processed, stats.total);
+
+  git_oid_fmt(hash, git_indexer_stream_hash(idx));
+  puts(hash);
+
+cleanup:
+  close(fd);
+  git_indexer_stream_free(idx);
+  return error;
+}
+
+int index_pack_old(git_repository *repo, int argc, char **argv)
+{
+  git_indexer *indexer;
+  git_indexer_stats stats;
+  int error;
+  char hash[GIT_OID_HEXSZ + 1] = {0};
+
+  if (argc < 2) {
+    fprintf(stderr, "I need a packfile\n");
+    return EXIT_FAILURE;
+  }
+
+
+ +
+

Create a new indexer

+
+
  error = git_indexer_new(&indexer, argv[1]);
+  if (error < 0)
+    return error;
+
+
+ +
+

Index the packfile. This function can take a very long time and +should be run in a worker thread.

+
+
  error = git_indexer_run(indexer, &stats);
+  if (error < 0)
+    return error;
+
+
+ +
+

Write the information out to an index file

+
+
  error = git_indexer_write(indexer);
+
+
+ +
+

Get the packfile’s hash (which should become it’s filename)

+ +
+
  git_oid_fmt(hash, git_indexer_hash(indexer));
+  puts(hash);
+
+  git_indexer_free(indexer);
+
+  return 0;
+}
+
+
+ diff --git a/ex/v0.17.0/ls-remote.html b/ex/v0.17.0/ls-remote.html new file mode 100644 index 00000000000..d92ad1df8ee --- /dev/null +++ b/ex/v0.17.0/ls-remote.html @@ -0,0 +1,166 @@ + + + + + ls-remote.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

ls-remote.c

+
+ +
+ +
+
#include <git2.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include "common.h"
+
+static int show_ref__cb(git_remote_head *head, void *payload)
+{
+  char oid[GIT_OID_HEXSZ + 1] = {0};
+  git_oid_fmt(oid, &head->oid);
+  printf("%s\t%s\n", oid, head->name);
+  return 0;
+}
+
+int use_unnamed(git_repository *repo, const char *url)
+{
+  git_remote *remote = NULL;
+  int error;
+
+
+ +
+

Create an instance of a remote from the URL. The transport to use +is detected from the URL

+
+
  error = git_remote_new(&remote, repo, NULL, url, NULL);
+  if (error < 0)
+    goto cleanup;
+
+
+ +
+

When connecting, the underlying code needs to know wether we +want to push or fetch

+
+
  error = git_remote_connect(remote, GIT_DIR_FETCH);
+  if (error < 0)
+    goto cleanup;
+
+
+ +
+

With git_remote_ls we can retrieve the advertised heads

+
+
  error = git_remote_ls(remote, &show_ref__cb, NULL);
+
+cleanup:
+  git_remote_free(remote);
+  return error;
+}
+
+int use_remote(git_repository *repo, char *name)
+{
+  git_remote *remote = NULL;
+  int error;
+
+
+ +
+

Find the remote by name

+
+
  error = git_remote_load(&remote, repo, name);
+  if (error < 0)
+    goto cleanup;
+
+  error = git_remote_connect(remote, GIT_DIR_FETCH);
+  if (error < 0)
+    goto cleanup;
+
+  error = git_remote_ls(remote, &show_ref__cb, NULL);
+
+cleanup:
+  git_remote_free(remote);
+  return error;
+}
+
+
+ +
+

This gets called to do the work. The remote can be given either as +the name of a configured remote or an URL.

+ +
+
int ls_remote(git_repository *repo, int argc, char **argv)
+{
+  int error, i;
+
+  /* If there's a ':' in the name, assume it's an URL */
+  if (strchr(argv[1], ':') != NULL) {
+    error = use_unnamed(repo, argv[1]);
+  } else {
+    error = use_remote(repo, argv[1]);
+  }
+
+  return error;
+}
+
+
+ diff --git a/ex/v0.17.0/showindex.html b/ex/v0.17.0/showindex.html new file mode 100644 index 00000000000..fcf17e85e3c --- /dev/null +++ b/ex/v0.17.0/showindex.html @@ -0,0 +1,93 @@ + + + + + showindex.c + + + + +
+
+
+ Jump To … + +
+ + + + + + + + + + + + +

showindex.c

+
+ +
+ + +
+
#include <git2.h>
+#include <stdio.h>
+
+int main (int argc, char** argv)
+{
+  git_repository *repo;
+  git_index *index;
+  unsigned int i, e, ecount;
+  git_index_entry **entries;
+  git_oid oid;
+
+  char out[41];
+  out[40] = '\0';
+
+  git_repository_open(&repo, "/opt/libgit2-test/.git");
+
+  git_repository_index(&index, repo);
+  git_index_read(index);
+
+  ecount = git_index_entrycount(index);
+  for (i = 0; i < ecount; ++i) {
+    git_index_entry *e = git_index_get(index, i);
+
+    oid = e->oid;
+    git_oid_fmt(out, &oid);
+
+    printf("File Path: %s\n", e->path);
+    printf(" Blob SHA: %s\n", out);
+    printf("File Size: %d\n", (int)e->file_size);
+    printf("   Device: %d\n", (int)e->dev);
+    printf("    Inode: %d\n", (int)e->ino);
+    printf("      UID: %d\n", (int)e->uid);
+    printf("      GID: %d\n", (int)e->gid);
+    printf("    ctime: %d\n", (int)e->ctime.seconds);
+    printf("    mtime: %d\n", (int)e->mtime.seconds);
+    printf("\n");
+  }
+
+  git_index_free(index);
+
+  git_repository_free(repo);
+}
+
+
+ diff --git a/examples/.gitignore b/examples/.gitignore deleted file mode 100644 index 4c34e4ab5ff..00000000000 --- a/examples/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -general -showindex diff --git a/examples/Makefile b/examples/Makefile deleted file mode 100644 index fe99c75cb87..00000000000 --- a/examples/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -.PHONY: all - -CC = gcc -CFLAGS = -g -I../include -I../src -LFLAGS = -L../build -lgit2 -lz -APPS = general showindex diff - -all: $(APPS) - -% : %.c - $(CC) -o $@ $(CFLAGS) $< $(LFLAGS) - -clean: - $(RM) $(APPS) - $(RM) -r *.dSYM diff --git a/examples/README.md b/examples/README.md deleted file mode 100644 index f2b6d7d234f..00000000000 --- a/examples/README.md +++ /dev/null @@ -1,11 +0,0 @@ -libgit2 examples -================ - -These examples are meant as thin, easy-to-read snippets for Docurium -(https://github.com/github/docurium) rather than full-blown -implementations of Git commands. They are not vetted as carefully -for bugs, error handling, or cross-platform compatibility as the -rest of the code in libgit2, so copy with some caution. - -For HTML versions, check "Examples" at http://libgit2.github.com/libgit2 - diff --git a/examples/diff.c b/examples/diff.c deleted file mode 100644 index b72a75e1c93..00000000000 --- a/examples/diff.c +++ /dev/null @@ -1,238 +0,0 @@ -#include -#include -#include -#include - -void check(int error, const char *message) -{ - if (error) { - fprintf(stderr, "%s (%d)\n", message, error); - exit(1); - } -} - -int resolve_to_tree(git_repository *repo, const char *identifier, git_tree **tree) -{ - int err = 0; - size_t len = strlen(identifier); - git_oid oid; - git_object *obj = NULL; - - /* try to resolve as OID */ - if (git_oid_fromstrn(&oid, identifier, len) == 0) - git_object_lookup_prefix(&obj, repo, &oid, len, GIT_OBJ_ANY); - - /* try to resolve as reference */ - if (obj == NULL) { - git_reference *ref, *resolved; - if (git_reference_lookup(&ref, repo, identifier) == 0) { - git_reference_resolve(&resolved, ref); - git_reference_free(ref); - if (resolved) { - git_object_lookup(&obj, repo, git_reference_oid(resolved), GIT_OBJ_ANY); - git_reference_free(resolved); - } - } - } - - if (obj == NULL) - return GIT_ENOTFOUND; - - switch (git_object_type(obj)) { - case GIT_OBJ_TREE: - *tree = (git_tree *)obj; - break; - case GIT_OBJ_COMMIT: - err = git_commit_tree(tree, (git_commit *)obj); - git_object_free(obj); - break; - default: - err = GIT_ENOTFOUND; - } - - return err; -} - -char *colors[] = { - "\033[m", /* reset */ - "\033[1m", /* bold */ - "\033[31m", /* red */ - "\033[32m", /* green */ - "\033[36m" /* cyan */ -}; - -int printer( - void *data, - git_diff_delta *delta, - git_diff_range *range, - char usage, - const char *line, - size_t line_len) -{ - int *last_color = data, color = 0; - - if (*last_color >= 0) { - switch (usage) { - case GIT_DIFF_LINE_ADDITION: color = 3; break; - case GIT_DIFF_LINE_DELETION: color = 2; break; - case GIT_DIFF_LINE_ADD_EOFNL: color = 3; break; - case GIT_DIFF_LINE_DEL_EOFNL: color = 2; break; - case GIT_DIFF_LINE_FILE_HDR: color = 1; break; - case GIT_DIFF_LINE_HUNK_HDR: color = 4; break; - default: color = 0; - } - if (color != *last_color) { - if (*last_color == 1 || color == 1) - fputs(colors[0], stdout); - fputs(colors[color], stdout); - *last_color = color; - } - } - - fputs(line, stdout); - return 0; -} - -int check_uint16_param(const char *arg, const char *pattern, uint16_t *val) -{ - size_t len = strlen(pattern); - uint16_t strval; - char *endptr = NULL; - if (strncmp(arg, pattern, len)) - return 0; - strval = strtoul(arg + len, &endptr, 0); - if (endptr == arg) - return 0; - *val = strval; - return 1; -} - -int check_str_param(const char *arg, const char *pattern, char **val) -{ - size_t len = strlen(pattern); - if (strncmp(arg, pattern, len)) - return 0; - *val = (char *)(arg + len); - return 1; -} - -void usage(const char *message, const char *arg) -{ - if (message && arg) - fprintf(stderr, "%s: %s\n", message, arg); - else if (message) - fprintf(stderr, "%s\n", message); - fprintf(stderr, "usage: diff [ []]\n"); - exit(1); -} - -int main(int argc, char *argv[]) -{ - char path[GIT_PATH_MAX]; - git_repository *repo = NULL; - git_tree *t1 = NULL, *t2 = NULL; - git_diff_options opts = {0}; - git_diff_list *diff; - int i, color = -1, compact = 0, cached = 0; - char *a, *dir = ".", *treeish1 = NULL, *treeish2 = NULL; - - /* parse arguments as copied from git-diff */ - - for (i = 1; i < argc; ++i) { - a = argv[i]; - - if (a[0] != '-') { - if (treeish1 == NULL) - treeish1 = a; - else if (treeish2 == NULL) - treeish2 = a; - else - usage("Only one or two tree identifiers can be provided", NULL); - } - else if (!strcmp(a, "-p") || !strcmp(a, "-u") || - !strcmp(a, "--patch")) - compact = 0; - else if (!strcmp(a, "--cached")) - cached = 1; - else if (!strcmp(a, "--name-status")) - compact = 1; - else if (!strcmp(a, "--color")) - color = 0; - else if (!strcmp(a, "--no-color")) - color = -1; - else if (!strcmp(a, "-R")) - opts.flags |= GIT_DIFF_REVERSE; - else if (!strcmp(a, "-a") || !strcmp(a, "--text")) - opts.flags |= GIT_DIFF_FORCE_TEXT; - else if (!strcmp(a, "--ignore-space-at-eol")) - opts.flags |= GIT_DIFF_IGNORE_WHITESPACE_EOL; - else if (!strcmp(a, "-b") || !strcmp(a, "--ignore-space-change")) - opts.flags |= GIT_DIFF_IGNORE_WHITESPACE_CHANGE; - else if (!strcmp(a, "-w") || !strcmp(a, "--ignore-all-space")) - opts.flags |= GIT_DIFF_IGNORE_WHITESPACE; - else if (!strcmp(a, "--ignored")) - opts.flags |= GIT_DIFF_INCLUDE_IGNORED; - else if (!strcmp(a, "--untracked")) - opts.flags |= GIT_DIFF_INCLUDE_UNTRACKED; - else if (!check_uint16_param(a, "-U", &opts.context_lines) && - !check_uint16_param(a, "--unified=", &opts.context_lines) && - !check_uint16_param(a, "--inter-hunk-context=", - &opts.interhunk_lines) && - !check_str_param(a, "--src-prefix=", &opts.old_prefix) && - !check_str_param(a, "--dst-prefix=", &opts.new_prefix)) - usage("Unknown arg", a); - } - - /* open repo */ - - check(git_repository_open_ext(&repo, dir, 0, NULL), - "Could not open repository"); - - if (treeish1) - check(resolve_to_tree(repo, treeish1, &t1), "Looking up first tree"); - if (treeish2) - check(resolve_to_tree(repo, treeish2, &t2), "Looking up second tree"); - - /* */ - /* --cached */ - /* */ - /* --cached */ - /* nothing */ - - if (t1 && t2) - check(git_diff_tree_to_tree(repo, &opts, t1, t2, &diff), "Diff"); - else if (t1 && cached) - check(git_diff_index_to_tree(repo, &opts, t1, &diff), "Diff"); - else if (t1) { - git_diff_list *diff2; - check(git_diff_index_to_tree(repo, &opts, t1, &diff), "Diff"); - check(git_diff_workdir_to_index(repo, &opts, &diff2), "Diff"); - check(git_diff_merge(diff, diff2), "Merge diffs"); - git_diff_list_free(diff2); - } - else if (cached) { - check(resolve_to_tree(repo, "HEAD", &t1), "looking up HEAD"); - check(git_diff_index_to_tree(repo, &opts, t1, &diff), "Diff"); - } - else - check(git_diff_workdir_to_index(repo, &opts, &diff), "Diff"); - - if (color >= 0) - fputs(colors[0], stdout); - - if (compact) - check(git_diff_print_compact(diff, &color, printer), "Displaying diff"); - else - check(git_diff_print_patch(diff, &color, printer), "Displaying diff"); - - if (color >= 0) - fputs(colors[0], stdout); - - git_diff_list_free(diff); - git_tree_free(t1); - git_tree_free(t2); - git_repository_free(repo); - - return 0; -} - diff --git a/examples/general.c b/examples/general.c deleted file mode 100644 index 5269785f211..00000000000 --- a/examples/general.c +++ /dev/null @@ -1,451 +0,0 @@ -// [**libgit2**][lg] is a portable, pure C implementation of the Git core methods -// provided as a re-entrant linkable library with a solid API, allowing you -// to write native speed custom Git applications in any language which -// supports C bindings. -// -// This file is an example of using that API in a real, compilable C file. -// As the API is updated, this file will be updated to demonstrate the -// new functionality. -// -// If you're trying to write something in C using [libgit2][lg], you will also want -// to check out the generated [API documentation][ap] and the [Usage Guide][ug]. We've -// tried to link to the relevant sections of the API docs in each section in this file. -// -// **libgit2** only implements the core plumbing functions, not really the higher -// level porcelain stuff. For a primer on Git Internals that you will need to know -// to work with Git at this level, check out [Chapter 9][pg] of the Pro Git book. -// -// [lg]: http://libgit2.github.com -// [ap]: http://libgit2.github.com/libgit2 -// [ug]: http://libgit2.github.com/api.html -// [pg]: http://progit.org/book/ch9-0.html - -// ### Includes - -// Including the `git2.h` header will include all the other libgit2 headers that you need. -// It should be the only thing you need to include in order to compile properly and get -// all the libgit2 API. -#include -#include - -int main (int argc, char** argv) -{ - // ### Opening the Repository - - // There are a couple of methods for opening a repository, this being the simplest. - // There are also [methods][me] for specifying the index file and work tree locations, here - // we are assuming they are in the normal places. - // - // [me]: http://libgit2.github.com/libgit2/#HEAD/group/repository - git_repository *repo; - if (argc > 1) { - git_repository_open(&repo, argv[1]); - } else { - git_repository_open(&repo, "/opt/libgit2-test/.git"); - } - - // ### SHA-1 Value Conversions - - // For our first example, we will convert a 40 character hex value to the 20 byte raw SHA1 value. - printf("*Hex to Raw*\n"); - char hex[] = "fd6e612585290339ea8bf39c692a7ff6a29cb7c3"; - - // The `git_oid` is the structure that keeps the SHA value. We will use this throughout the example - // for storing the value of the current SHA key we're working with. - git_oid oid; - git_oid_fromstr(&oid, hex); - - // Once we've converted the string into the oid value, we can get the raw value of the SHA. - printf("Raw 20 bytes: [%.20s]\n", (&oid)->id); - - // Next we will convert the 20 byte raw SHA1 value to a human readable 40 char hex value. - printf("\n*Raw to Hex*\n"); - char out[41]; - out[40] = '\0'; - - // If you have a oid, you can easily get the hex value of the SHA as well. - git_oid_fmt(out, &oid); - printf("SHA hex string: %s\n", out); - - // ### Working with the Object Database - // **libgit2** provides [direct access][odb] to the object database. - // The object database is where the actual objects are stored in Git. For - // working with raw objects, we'll need to get this structure from the - // repository. - // [odb]: http://libgit2.github.com/libgit2/#HEAD/group/odb - git_odb *odb; - git_repository_odb(&odb, repo); - - // #### Raw Object Reading - - printf("\n*Raw Object Read*\n"); - git_odb_object *obj; - git_otype otype; - const unsigned char *data; - const char *str_type; - int error; - - // We can read raw objects directly from the object database if we have the oid (SHA) - // of the object. This allows us to access objects without knowing thier type and inspect - // the raw bytes unparsed. - error = git_odb_read(&obj, odb, &oid); - - // A raw object only has three properties - the type (commit, blob, tree or tag), the size - // of the raw data and the raw, unparsed data itself. For a commit or tag, that raw data - // is human readable plain ASCII text. For a blob it is just file contents, so it could be - // text or binary data. For a tree it is a special binary format, so it's unlikely to be - // hugely helpful as a raw object. - data = (const unsigned char *)git_odb_object_data(obj); - otype = git_odb_object_type(obj); - - // We provide methods to convert from the object type which is an enum, to a string - // representation of that value (and vice-versa). - str_type = git_object_type2string(otype); - printf("object length and type: %d, %s\n", - (int)git_odb_object_size(obj), - str_type); - - // For proper memory management, close the object when you are done with it or it will leak - // memory. - git_odb_object_free(obj); - - // #### Raw Object Writing - - printf("\n*Raw Object Write*\n"); - - // You can also write raw object data to Git. This is pretty cool because it gives you - // direct access to the key/value properties of Git. Here we'll write a new blob object - // that just contains a simple string. Notice that we have to specify the object type as - // the `git_otype` enum. - git_odb_write(&oid, odb, "test data", sizeof("test data") - 1, GIT_OBJ_BLOB); - - // Now that we've written the object, we can check out what SHA1 was generated when the - // object was written to our database. - git_oid_fmt(out, &oid); - printf("Written Object: %s\n", out); - - // ### Object Parsing - // libgit2 has methods to parse every object type in Git so you don't have to work directly - // with the raw data. This is much faster and simpler than trying to deal with the raw data - // yourself. - - // #### Commit Parsing - // [Parsing commit objects][pco] is simple and gives you access to all the data in the commit - // - the // author (name, email, datetime), committer (same), tree, message, encoding and parent(s). - // [pco]: http://libgit2.github.com/libgit2/#HEAD/group/commit - - printf("\n*Commit Parsing*\n"); - - git_commit *commit; - git_oid_fromstr(&oid, "f0877d0b841d75172ec404fc9370173dfffc20d1"); - - error = git_commit_lookup(&commit, repo, &oid); - - const git_signature *author, *cmtter; - const char *message; - time_t ctime; - unsigned int parents, p; - - // Each of the properties of the commit object are accessible via methods, including commonly - // needed variations, such as `git_commit_time` which returns the author time and `_message` - // which gives you the commit message. - message = git_commit_message(commit); - author = git_commit_author(commit); - cmtter = git_commit_committer(commit); - ctime = git_commit_time(commit); - - // The author and committer methods return [git_signature] structures, which give you name, email - // and `when`, which is a `git_time` structure, giving you a timestamp and timezone offset. - printf("Author: %s (%s)\n", author->name, author->email); - - // Commits can have zero or more parents. The first (root) commit will have no parents, most commits - // will have one, which is the commit it was based on, and merge commits will have two or more. - // Commits can technically have any number, though it's pretty rare to have more than two. - parents = git_commit_parentcount(commit); - for (p = 0;p < parents;p++) { - git_commit *parent; - git_commit_parent(&parent, commit, p); - git_oid_fmt(out, git_commit_id(parent)); - printf("Parent: %s\n", out); - git_commit_free(parent); - } - - // Don't forget to close the object to prevent memory leaks. You will have to do this for - // all the objects you open and parse. - git_commit_free(commit); - - // #### Writing Commits - // - // libgit2 provides a couple of methods to create commit objects easily as well. There are four - // different create signatures, we'll just show one of them here. You can read about the other - // ones in the [commit API docs][cd]. - // [cd]: http://libgit2.github.com/libgit2/#HEAD/group/commit - - printf("\n*Commit Writing*\n"); - git_oid tree_id, parent_id, commit_id; - git_tree *tree; - git_commit *parent; - - // Creating signatures for an authoring identity and time is pretty simple - you will need to have - // this to create a commit in order to specify who created it and when. Default values for the name - // and email should be found in the `user.name` and `user.email` configuration options. See the `config` - // section of this example file to see how to access config values. - git_signature_new((git_signature **)&author, "Scott Chacon", "schacon@gmail.com", - 123456789, 60); - git_signature_new((git_signature **)&cmtter, "Scott A Chacon", "scott@github.com", - 987654321, 90); - - // Commit objects need a tree to point to and optionally one or more parents. Here we're creating oid - // objects to create the commit with, but you can also use - git_oid_fromstr(&tree_id, "28873d96b4e8f4e33ea30f4c682fd325f7ba56ac"); - git_tree_lookup(&tree, repo, &tree_id); - git_oid_fromstr(&parent_id, "f0877d0b841d75172ec404fc9370173dfffc20d1"); - git_commit_lookup(&parent, repo, &parent_id); - - // Here we actually create the commit object with a single call with all the values we need to create - // the commit. The SHA key is written to the `commit_id` variable here. - git_commit_create_v( - &commit_id, /* out id */ - repo, - NULL, /* do not update the HEAD */ - author, - cmtter, - NULL, /* use default message encoding */ - "example commit", - tree, - 1, parent); - - // Now we can take a look at the commit SHA we've generated. - git_oid_fmt(out, &commit_id); - printf("New Commit: %s\n", out); - - // #### Tag Parsing - // You can parse and create tags with the [tag management API][tm], which functions very similarly - // to the commit lookup, parsing and creation methods, since the objects themselves are very similar. - // [tm]: http://libgit2.github.com/libgit2/#HEAD/group/tag - printf("\n*Tag Parsing*\n"); - git_tag *tag; - const char *tmessage, *tname; - git_otype ttype; - - // We create an oid for the tag object if we know the SHA and look it up in the repository the same - // way that we would a commit (or any other) object. - git_oid_fromstr(&oid, "bc422d45275aca289c51d79830b45cecebff7c3a"); - - error = git_tag_lookup(&tag, repo, &oid); - - // Now that we have the tag object, we can extract the information it generally contains: the target - // (usually a commit object), the type of the target object (usually 'commit'), the name ('v1.0'), - // the tagger (a git_signature - name, email, timestamp), and the tag message. - git_tag_target((git_object **)&commit, tag); - tname = git_tag_name(tag); // "test" - ttype = git_tag_type(tag); // GIT_OBJ_COMMIT (otype enum) - tmessage = git_tag_message(tag); // "tag message\n" - printf("Tag Message: %s\n", tmessage); - - git_commit_free(commit); - - // #### Tree Parsing - // [Tree parsing][tp] is a bit different than the other objects, in that we have a subtype which is the - // tree entry. This is not an actual object type in Git, but a useful structure for parsing and - // traversing tree entries. - // - // [tp]: http://libgit2.github.com/libgit2/#HEAD/group/tree - printf("\n*Tree Parsing*\n"); - - const git_tree_entry *entry; - git_object *objt; - - // Create the oid and lookup the tree object just like the other objects. - git_oid_fromstr(&oid, "2a741c18ac5ff082a7caaec6e74db3075a1906b5"); - git_tree_lookup(&tree, repo, &oid); - - // Getting the count of entries in the tree so you can iterate over them if you want to. - int cnt = git_tree_entrycount(tree); // 3 - printf("tree entries: %d\n", cnt); - - entry = git_tree_entry_byindex(tree, 0); - printf("Entry name: %s\n", git_tree_entry_name(entry)); // "hello.c" - - // You can also access tree entries by name if you know the name of the entry you're looking for. - entry = git_tree_entry_byname(tree, "hello.c"); - git_tree_entry_name(entry); // "hello.c" - - // Once you have the entry object, you can access the content or subtree (or commit, in the case - // of submodules) that it points to. You can also get the mode if you want. - git_tree_entry_to_object(&objt, repo, entry); // blob - - // Remember to close the looked-up object once you are done using it - git_object_free(objt); - - // #### Blob Parsing - // - // The last object type is the simplest and requires the least parsing help. Blobs are just file - // contents and can contain anything, there is no structure to it. The main advantage to using the - // [simple blob api][ba] is that when you're creating blobs you don't have to calculate the size - // of the content. There is also a helper for reading a file from disk and writing it to the db and - // getting the oid back so you don't have to do all those steps yourself. - // - // [ba]: http://libgit2.github.com/libgit2/#HEAD/group/blob - - printf("\n*Blob Parsing*\n"); - git_blob *blob; - - git_oid_fromstr(&oid, "af7574ea73f7b166f869ef1a39be126d9a186ae0"); - git_blob_lookup(&blob, repo, &oid); - - // You can access a buffer with the raw contents of the blob directly. - // Note that this buffer may not be contain ASCII data for certain blobs (e.g. binary files): - // do not consider the buffer a NULL-terminated string, and use the `git_blob_rawsize` attribute to - // find out its exact size in bytes - printf("Blob Size: %ld\n", git_blob_rawsize(blob)); // 8 - git_blob_rawcontent(blob); // "content" - - // ### Revwalking - // - // The libgit2 [revision walking api][rw] provides methods to traverse the directed graph created - // by the parent pointers of the commit objects. Since all commits point back to the commit that - // came directly before them, you can walk this parentage as a graph and find all the commits that - // were ancestors of (reachable from) a given starting point. This can allow you to create `git log` - // type functionality. - // - // [rw]: http://libgit2.github.com/libgit2/#HEAD/group/revwalk - - printf("\n*Revwalking*\n"); - git_revwalk *walk; - git_commit *wcommit; - - git_oid_fromstr(&oid, "f0877d0b841d75172ec404fc9370173dfffc20d1"); - - // To use the revwalker, create a new walker, tell it how you want to sort the output and then push - // one or more starting points onto the walker. If you want to emulate the output of `git log` you - // would push the SHA of the commit that HEAD points to into the walker and then start traversing them. - // You can also 'hide' commits that you want to stop at or not see any of their ancestors. So if you - // want to emulate `git log branch1..branch2`, you would push the oid of `branch2` and hide the oid - // of `branch1`. - git_revwalk_new(&walk, repo); - git_revwalk_sorting(walk, GIT_SORT_TOPOLOGICAL | GIT_SORT_REVERSE); - git_revwalk_push(walk, &oid); - - const git_signature *cauth; - const char *cmsg; - - // Now that we have the starting point pushed onto the walker, we can start asking for ancestors. It - // will return them in the sorting order we asked for as commit oids. - // We can then lookup and parse the commited pointed at by the returned OID; - // note that this operation is specially fast since the raw contents of the commit object will - // be cached in memory - while ((git_revwalk_next(&oid, walk)) == 0) { - error = git_commit_lookup(&wcommit, repo, &oid); - cmsg = git_commit_message(wcommit); - cauth = git_commit_author(wcommit); - printf("%s (%s)\n", cmsg, cauth->email); - git_commit_free(wcommit); - } - - // Like the other objects, be sure to free the revwalker when you're done to prevent memory leaks. - // Also, make sure that the repository being walked it not deallocated while the walk is in - // progress, or it will result in undefined behavior - git_revwalk_free(walk); - - // ### Index File Manipulation - // - // The [index file API][gi] allows you to read, traverse, update and write the Git index file - // (sometimes thought of as the staging area). - // - // [gi]: http://libgit2.github.com/libgit2/#HEAD/group/index - - printf("\n*Index Walking*\n"); - - git_index *index; - unsigned int i, ecount; - - // You can either open the index from the standard location in an open repository, as we're doing - // here, or you can open and manipulate any index file with `git_index_open_bare()`. The index - // for the repository will be located and loaded from disk. - git_repository_index(&index, repo); - - // For each entry in the index, you can get a bunch of information including the SHA (oid), path - // and mode which map to the tree objects that are written out. It also has filesystem properties - // to help determine what to inspect for changes (ctime, mtime, dev, ino, uid, gid, file_size and flags) - // All these properties are exported publicly in the `git_index_entry` struct - ecount = git_index_entrycount(index); - for (i = 0; i < ecount; ++i) { - git_index_entry *e = git_index_get(index, i); - - printf("path: %s\n", e->path); - printf("mtime: %d\n", (int)e->mtime.seconds); - printf("fs: %d\n", (int)e->file_size); - } - - git_index_free(index); - - // ### References - // - // The [reference API][ref] allows you to list, resolve, create and update references such as - // branches, tags and remote references (everything in the .git/refs directory). - // - // [ref]: http://libgit2.github.com/libgit2/#HEAD/group/reference - - printf("\n*Reference Listing*\n"); - - // Here we will implement something like `git for-each-ref` simply listing out all available - // references and the object SHA they resolve to. - git_strarray ref_list; - git_reference_list(&ref_list, repo, GIT_REF_LISTALL); - - const char *refname; - git_reference *ref; - - // Now that we have the list of reference names, we can lookup each ref one at a time and - // resolve them to the SHA, then print both values out. - for (i = 0; i < ref_list.count; ++i) { - refname = ref_list.strings[i]; - git_reference_lookup(&ref, repo, refname); - - switch (git_reference_type(ref)) { - case GIT_REF_OID: - git_oid_fmt(out, git_reference_oid(ref)); - printf("%s [%s]\n", refname, out); - break; - - case GIT_REF_SYMBOLIC: - printf("%s => %s\n", refname, git_reference_target(ref)); - break; - default: - fprintf(stderr, "Unexpected reference type\n"); - exit(1); - } - } - - git_strarray_free(&ref_list); - - // ### Config Files - // - // The [config API][config] allows you to list and updatee config values in - // any of the accessible config file locations (system, global, local). - // - // [config]: http://libgit2.github.com/libgit2/#HEAD/group/config - - printf("\n*Config Listing*\n"); - - const char *email; - int32_t j; - - git_config *cfg; - - // Open a config object so we can read global values from it. - git_config_open_ondisk(&cfg, "~/.gitconfig"); - - git_config_get_int32(cfg, "help.autocorrect", &j); - printf("Autocorrect: %d\n", j); - - git_config_get_string(cfg, "user.email", &email); - printf("Email: %s\n", email); - - // Finally, when you're done with the repository, you can free it as well. - git_repository_free(repo); - - return 0; -} - diff --git a/examples/network/.gitignore b/examples/network/.gitignore deleted file mode 100644 index 1b48e66ed98..00000000000 --- a/examples/network/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/git2 diff --git a/examples/network/Makefile b/examples/network/Makefile deleted file mode 100644 index 835be24ccd6..00000000000 --- a/examples/network/Makefile +++ /dev/null @@ -1,15 +0,0 @@ -default: all - -CC = gcc -CFLAGS += -g -CFLAGS += -I../../include -L../../build -L../.. -lgit2 -lpthread - -OBJECTS = \ - git2.o \ - ls-remote.o \ - fetch.o \ - clone.o \ - index-pack.o - -all: $(OBJECTS) - $(CC) $(CFLAGS) -o git2 $(OBJECTS) diff --git a/examples/network/clone.c b/examples/network/clone.c deleted file mode 100644 index fb571bd3afa..00000000000 --- a/examples/network/clone.c +++ /dev/null @@ -1,68 +0,0 @@ -#include "common.h" -#include -#include -#include -#include -#include -#include -#include - -struct dl_data { - git_indexer_stats fetch_stats; - git_indexer_stats checkout_stats; - git_checkout_opts opts; - int ret; - int finished; - const char *url; - const char *path; -}; - -static void *clone_thread(void *ptr) -{ - struct dl_data *data = (struct dl_data *)ptr; - git_repository *repo = NULL; - - // Kick off the clone - data->ret = git_clone(&repo, data->url, data->path, - &data->fetch_stats, &data->checkout_stats, - &data->opts); - if (repo) git_repository_free(repo); - data->finished = 1; - - pthread_exit(&data->ret); -} - -int do_clone(git_repository *repo, int argc, char **argv) -{ - struct dl_data data = {0}; - pthread_t worker; - - // Validate args - if (argc < 3) { - printf("USAGE: %s \n", argv[0]); - return -1; - } - - // Data for background thread - data.url = argv[1]; - data.path = argv[2]; - data.opts.disable_filters = 1; - printf("Cloning '%s' to '%s'\n", data.url, data.path); - - // Create the worker thread - pthread_create(&worker, NULL, clone_thread, &data); - - // Watch for progress information - do { - usleep(10000); - printf("Fetch %d/%d – Checkout %d/%d\n", - data.fetch_stats.processed, data.fetch_stats.total, - data.checkout_stats.processed, data.checkout_stats.total); - } while (!data.finished); - printf("Fetch %d/%d – Checkout %d/%d\n", - data.fetch_stats.processed, data.fetch_stats.total, - data.checkout_stats.processed, data.checkout_stats.total); - - return data.ret; -} - diff --git a/examples/network/common.h b/examples/network/common.h deleted file mode 100644 index c82eaa1c86d..00000000000 --- a/examples/network/common.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef __COMMON_H__ -#define __COMMON_H__ - -#include - -typedef int (*git_cb)(git_repository *, int , char **); - -int ls_remote(git_repository *repo, int argc, char **argv); -int parse_pkt_line(git_repository *repo, int argc, char **argv); -int show_remote(git_repository *repo, int argc, char **argv); -int fetch(git_repository *repo, int argc, char **argv); -int index_pack(git_repository *repo, int argc, char **argv); -int do_clone(git_repository *repo, int argc, char **argv); - -#endif /* __COMMON_H__ */ diff --git a/examples/network/fetch.c b/examples/network/fetch.c deleted file mode 100644 index fa941b97adf..00000000000 --- a/examples/network/fetch.c +++ /dev/null @@ -1,137 +0,0 @@ -#include "common.h" -#include -#include -#include -#include -#include -#include - -struct dl_data { - git_remote *remote; - git_off_t *bytes; - git_indexer_stats *stats; - int ret; - int finished; -}; - -static void progress_cb(const char *str, int len, void *data) -{ - data = data; - printf("remote: %.*s", len, str); - fflush(stdout); /* We don't have the \n to force the flush */ -} - -static void *download(void *ptr) -{ - struct dl_data *data = (struct dl_data *)ptr; - - // Connect to the remote end specifying that we want to fetch - // information from it. - if (git_remote_connect(data->remote, GIT_DIR_FETCH) < 0) { - data->ret = -1; - goto exit; - } - - // Download the packfile and index it. This function updates the - // amount of received data and the indexer stats which lets you - // inform the user about progress. - if (git_remote_download(data->remote, data->bytes, data->stats) < 0) { - data->ret = -1; - goto exit; - } - - data->ret = 0; - -exit: - data->finished = 1; - pthread_exit(&data->ret); -} - -static int update_cb(const char *refname, const git_oid *a, const git_oid *b, void *data) -{ - char a_str[GIT_OID_HEXSZ+1], b_str[GIT_OID_HEXSZ+1]; - data = data; - - git_oid_fmt(b_str, b); - b_str[GIT_OID_HEXSZ] = '\0'; - - if (git_oid_iszero(a)) { - printf("[new] %.20s %s\n", b_str, refname); - } else { - git_oid_fmt(a_str, a); - a_str[GIT_OID_HEXSZ] = '\0'; - printf("[updated] %.10s..%.10s %s\n", a_str, b_str, refname); - } - - return 0; -} - -int fetch(git_repository *repo, int argc, char **argv) -{ - git_remote *remote = NULL; - git_off_t bytes = 0; - git_indexer_stats stats; - pthread_t worker; - struct dl_data data; - git_remote_callbacks callbacks; - - argc = argc; - // Figure out whether it's a named remote or a URL - printf("Fetching %s\n", argv[1]); - if (git_remote_load(&remote, repo, argv[1]) < 0) { - if (git_remote_new(&remote, repo, NULL, argv[1], NULL) < 0) - return -1; - } - - // Set up the callbacks (only update_tips for now) - memset(&callbacks, 0, sizeof(callbacks)); - callbacks.update_tips = &update_cb; - callbacks.progress = &progress_cb; - git_remote_set_callbacks(remote, &callbacks); - - // Set up the information for the background worker thread - data.remote = remote; - data.bytes = &bytes; - data.stats = &stats; - data.ret = 0; - data.finished = 0; - memset(&stats, 0, sizeof(stats)); - - pthread_create(&worker, NULL, download, &data); - - // Loop while the worker thread is still running. Here we show processed - // and total objects in the pack and the amount of received - // data. Most frontends will probably want to show a percentage and - // the download rate. - do { - usleep(10000); - - if (stats.total > 0) - printf("Received %d/%d objects (%d) in %d bytes\r", - stats.received, stats.total, stats.processed, bytes); - } while (!data.finished); - - if (data.ret < 0) - goto on_error; - - pthread_join(worker, NULL); - printf("\rReceived %d/%d objects in %zu bytes\n", stats.processed, stats.total, bytes); - - // Disconnect the underlying connection to prevent from idling. - git_remote_disconnect(remote); - - // Update the references in the remote's namespace to point to the - // right commits. This may be needed even if there was no packfile - // to download, which can happen e.g. when the branches have been - // changed but all the neede objects are available locally. - if (git_remote_update_tips(remote) < 0) - return -1; - - git_remote_free(remote); - - return 0; - - on_error: - git_remote_free(remote); - return -1; -} diff --git a/examples/network/git2.c b/examples/network/git2.c deleted file mode 100644 index ecb16630b65..00000000000 --- a/examples/network/git2.c +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include -#include - -#include "common.h" - -// This part is not strictly libgit2-dependent, but you can use this -// as a starting point for a git-like tool - -struct { - char *name; - git_cb fn; -} commands[] = { - {"ls-remote", ls_remote}, - {"fetch", fetch}, - {"clone", do_clone}, - {"index-pack", index_pack}, - { NULL, NULL} -}; - -static int run_command(git_cb fn, int argc, char **argv) -{ - int error; - git_repository *repo; - -// Before running the actual command, create an instance of the local -// repository and pass it to the function. - - error = git_repository_open(&repo, ".git"); - if (error < 0) - repo = NULL; - - // Run the command. If something goes wrong, print the error message to stderr - error = fn(repo, argc, argv); - if (error < 0) { - if (giterr_last() == NULL) - fprintf(stderr, "Error without message"); - else - fprintf(stderr, "Bad news:\n %s\n", giterr_last()->message); - } - - if(repo) - git_repository_free(repo); - - return !!error; -} - -int main(int argc, char **argv) -{ - int i; - - if (argc < 2) { - fprintf(stderr, "usage: %s [repo]\n", argv[0]); - exit(EXIT_FAILURE); - } - - for (i = 0; commands[i].name != NULL; ++i) { - if (!strcmp(argv[1], commands[i].name)) - return run_command(commands[i].fn, --argc, ++argv); - } - - fprintf(stderr, "Command not found: %s\n", argv[1]); - return 1; -} diff --git a/examples/network/index-pack.c b/examples/network/index-pack.c deleted file mode 100644 index 85aac4aff86..00000000000 --- a/examples/network/index-pack.c +++ /dev/null @@ -1,75 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include "common.h" - -// This could be run in the main loop whilst the application waits for -// the indexing to finish in a worker thread -static int index_cb(const git_indexer_stats *stats, void *data) -{ - data = data; - printf("\rProcessing %d of %d", stats->processed, stats->total); - - return 0; -} - -int index_pack(git_repository *repo, int argc, char **argv) -{ - git_indexer_stream *idx; - git_indexer_stats stats = {0, 0}; - int error, fd; - char hash[GIT_OID_HEXSZ + 1] = {0}; - ssize_t read_bytes; - char buf[512]; - - repo = repo; - if (argc < 2) { - fprintf(stderr, "I need a packfile\n"); - return EXIT_FAILURE; - } - - if (git_indexer_stream_new(&idx, ".") < 0) { - puts("bad idx"); - return -1; - } - - if ((fd = open(argv[1], 0)) < 0) { - perror("open"); - return -1; - } - - do { - read_bytes = read(fd, buf, sizeof(buf)); - if (read_bytes < 0) - break; - - if ((error = git_indexer_stream_add(idx, buf, read_bytes, &stats)) < 0) - goto cleanup; - - index_cb(&stats, NULL); - } while (read_bytes > 0); - - if (read_bytes < 0) { - error = -1; - perror("failed reading"); - goto cleanup; - } - - if ((error = git_indexer_stream_finalize(idx, &stats)) < 0) - goto cleanup; - - printf("\rIndexing %d of %d\n", stats.processed, stats.total); - - git_oid_fmt(hash, git_indexer_stream_hash(idx)); - puts(hash); - - cleanup: - close(fd); - git_indexer_stream_free(idx); - return error; -} diff --git a/examples/network/ls-remote.c b/examples/network/ls-remote.c deleted file mode 100644 index 822d6f66818..00000000000 --- a/examples/network/ls-remote.c +++ /dev/null @@ -1,79 +0,0 @@ -#include -#include -#include -#include -#include "common.h" - -static int show_ref__cb(git_remote_head *head, void *payload) -{ - char oid[GIT_OID_HEXSZ + 1] = {0}; - - payload = payload; - git_oid_fmt(oid, &head->oid); - printf("%s\t%s\n", oid, head->name); - return 0; -} - -static int use_unnamed(git_repository *repo, const char *url) -{ - git_remote *remote = NULL; - int error; - - // Create an instance of a remote from the URL. The transport to use - // is detected from the URL - error = git_remote_new(&remote, repo, NULL, url, NULL); - if (error < 0) - goto cleanup; - - // When connecting, the underlying code needs to know wether we - // want to push or fetch - error = git_remote_connect(remote, GIT_DIR_FETCH); - if (error < 0) - goto cleanup; - - // With git_remote_ls we can retrieve the advertised heads - error = git_remote_ls(remote, &show_ref__cb, NULL); - -cleanup: - git_remote_free(remote); - return error; -} - -static int use_remote(git_repository *repo, char *name) -{ - git_remote *remote = NULL; - int error; - - // Find the remote by name - error = git_remote_load(&remote, repo, name); - if (error < 0) - goto cleanup; - - error = git_remote_connect(remote, GIT_DIR_FETCH); - if (error < 0) - goto cleanup; - - error = git_remote_ls(remote, &show_ref__cb, NULL); - -cleanup: - git_remote_free(remote); - return error; -} - -// This gets called to do the work. The remote can be given either as -// the name of a configured remote or an URL. - -int ls_remote(git_repository *repo, int argc, char **argv) -{ - int error; - - argc = argc; - /* If there's a ':' in the name, assume it's an URL */ - if (strchr(argv[1], ':') != NULL) { - error = use_unnamed(repo, argv[1]); - } else { - error = use_remote(repo, argv[1]); - } - - return error; -} diff --git a/examples/showindex.c b/examples/showindex.c deleted file mode 100644 index 7f2130b90a5..00000000000 --- a/examples/showindex.c +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include - -int main (int argc, char** argv) -{ - git_repository *repo; - git_index *index; - unsigned int i, e, ecount; - git_index_entry **entries; - git_oid oid; - - char out[41]; - out[40] = '\0'; - - git_repository_open(&repo, "/opt/libgit2-test/.git"); - - git_repository_index(&index, repo); - git_index_read(index); - - ecount = git_index_entrycount(index); - for (i = 0; i < ecount; ++i) { - git_index_entry *e = git_index_get(index, i); - - oid = e->oid; - git_oid_fmt(out, &oid); - - printf("File Path: %s\n", e->path); - printf(" Blob SHA: %s\n", out); - printf("File Size: %d\n", (int)e->file_size); - printf(" Device: %d\n", (int)e->dev); - printf(" Inode: %d\n", (int)e->ino); - printf(" UID: %d\n", (int)e->uid); - printf(" GID: %d\n", (int)e->gid); - printf(" ctime: %d\n", (int)e->ctime.seconds); - printf(" mtime: %d\n", (int)e->mtime.seconds); - printf("\n"); - } - - git_index_free(index); - - git_repository_free(repo); -} - diff --git a/git.git-authors b/git.git-authors deleted file mode 100644 index 026b35fa82a..00000000000 --- a/git.git-authors +++ /dev/null @@ -1,67 +0,0 @@ -# This document lists the authors that have given voice to -# their decision regarding relicensing the GPL'd code from -# git.git to the GPL + gcc-exception license used by libgit2. -# -# Note that the permission is given for libgit2 use only. For -# other uses, you must ask each of the contributors yourself. -# -# To show the owners of a file in git.git, one can run the -# following command: -# -# git blame -C -C -M -- file | \ -# sed -e 's/[^(]*(\([^0-9]*\).*/\1/' -e 's/[\t ]*$//' | \ -# sort | uniq -c | sort -nr -# -# If everyone on the list that produces are on the list in -# the recently added file "git.git-authors", it *should* be -# safe to include that code in libgit2, but make sure to -# read the file to ensure the code doesn't originate from -# somewhere else. -# -# The format of this list is -# "ok/no/ask/???""Author""" -# -# "ok" means the author consents to relicensing all their -# contributed code (possibly with some exceptions) -# "no" means the author does not consent -# "ask" means that the contributor wants to give/withhold -# his/her consent on a patch-by-patch basis. -# "???" means the person is a prominent contributor who has -# not yet made his/her standpoint clear. -# "ign" means the authors consent is ignored for the purpose -# of libification. This is because the author has contributed -# to areas that aren't interesting for the library. -# -# Please try to keep the list alphabetically ordered. It will -# help in case we get all 600-ish git.git authors on it. -# -# (Paul Kocher is the author of the mozilla-sha1 implementation -# but has otherwise not contributed to git.) -# -ok Adam Simpkins (http transport) -ok Andreas Ericsson -ok Boyd Lynn Gerber -ok Brian Gernhardt -ok Christian Couder -ok Daniel Barkalow -ok Jeff King -ok Johannes Schindelin -ok Johannes Sixt -ok Junio C Hamano -ok Kristian Høgsberg -ok Linus Torvalds -ok Lukas Sandström -ok Matthieu Moy -ign Mike McCormack (imap-send) -ok Nicolas Pitre -ok Paolo Bonzini -ok Paul Kocher -ok Peter Hagervall -ok Pierre Habouzit -ok Pieter de Bie -ok René Scharfe -ign Robert Shearman (imap-send) -ok Sebastian Schuberth -ok Shawn O. Pearce -ok Steffen Prohaska -ok Sven Verdoolaege diff --git a/images/search_icon.png b/images/search_icon.png new file mode 100644 index 00000000000..98f3fb21ef4 Binary files /dev/null and b/images/search_icon.png differ diff --git a/include/git2.h b/include/git2.h deleted file mode 100644 index 805044abbd2..00000000000 --- a/include/git2.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ - -#ifndef INCLUDE_git_git_h__ -#define INCLUDE_git_git_h__ - -#include "git2/version.h" - -#include "git2/common.h" -#include "git2/threads.h" -#include "git2/errors.h" - -#include "git2/types.h" - -#include "git2/oid.h" -#include "git2/signature.h" -#include "git2/odb.h" - -#include "git2/repository.h" -#include "git2/revwalk.h" -#include "git2/merge.h" -#include "git2/refs.h" -#include "git2/reflog.h" -#include "git2/revparse.h" - -#include "git2/object.h" -#include "git2/blob.h" -#include "git2/commit.h" -#include "git2/tag.h" -#include "git2/tree.h" -#include "git2/diff.h" - -#include "git2/index.h" -#include "git2/config.h" -#include "git2/remote.h" -#include "git2/clone.h" -#include "git2/checkout.h" - -#include "git2/attr.h" -#include "git2/ignore.h" -#include "git2/branch.h" -#include "git2/refspec.h" -#include "git2/net.h" -#include "git2/status.h" -#include "git2/indexer.h" -#include "git2/submodule.h" -#include "git2/notes.h" -#include "git2/reset.h" -#include "git2/message.h" - -#endif diff --git a/include/git2/attr.h b/include/git2/attr.h deleted file mode 100644 index 2de9f4b0ee7..00000000000 --- a/include/git2/attr.h +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_attr_h__ -#define INCLUDE_git_attr_h__ - -#include "common.h" -#include "types.h" - -/** - * @file git2/attr.h - * @brief Git attribute management routines - * @defgroup git_attr Git attribute management routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * GIT_ATTR_TRUE checks if an attribute is set on. In core git - * parlance, this the value for "Set" attributes. - * - * For example, if the attribute file contains: - * - * *.c foo - * - * Then for file `xyz.c` looking up attribute "foo" gives a value for - * which `GIT_ATTR_TRUE(value)` is true. - */ -#define GIT_ATTR_TRUE(attr) (git_attr_value(attr) == GIT_ATTR_TRUE_T) - -/** - * GIT_ATTR_FALSE checks if an attribute is set off. In core git - * parlance, this is the value for attributes that are "Unset" (not to - * be confused with values that a "Unspecified"). - * - * For example, if the attribute file contains: - * - * *.h -foo - * - * Then for file `zyx.h` looking up attribute "foo" gives a value for - * which `GIT_ATTR_FALSE(value)` is true. - */ -#define GIT_ATTR_FALSE(attr) (git_attr_value(attr) == GIT_ATTR_FALSE_T) - -/** - * GIT_ATTR_UNSPECIFIED checks if an attribute is unspecified. This - * may be due to the attribute not being mentioned at all or because - * the attribute was explicitly set unspecified via the `!` operator. - * - * For example, if the attribute file contains: - * - * *.c foo - * *.h -foo - * onefile.c !foo - * - * Then for `onefile.c` looking up attribute "foo" yields a value with - * `GIT_ATTR_UNSPECIFIED(value)` of true. Also, looking up "foo" on - * file `onefile.rb` or looking up "bar" on any file will all give - * `GIT_ATTR_UNSPECIFIED(value)` of true. - */ -#define GIT_ATTR_UNSPECIFIED(attr) (git_attr_value(attr) == GIT_ATTR_UNSPECIFIED_T) - -/** - * GIT_ATTR_HAS_VALUE checks if an attribute is set to a value (as - * opposed to TRUE, FALSE or UNSPECIFIED). This would be the case if - * for a file with something like: - * - * *.txt eol=lf - * - * Given this, looking up "eol" for `onefile.txt` will give back the - * string "lf" and `GIT_ATTR_SET_TO_VALUE(attr)` will return true. - */ -#define GIT_ATTR_HAS_VALUE(attr) (git_attr_value(attr) == GIT_ATTR_VALUE_T) - -typedef enum { - GIT_ATTR_UNSPECIFIED_T = 0, - GIT_ATTR_TRUE_T, - GIT_ATTR_FALSE_T, - GIT_ATTR_VALUE_T, -} git_attr_t; - -/* - * Return the value type for a given attribute. - * - * This can be either `TRUE`, `FALSE`, `UNSPECIFIED` (if the attribute - * was not set at all), or `VALUE`, if the attribute was set to - * an actual string. - * - * If the attribute has a `VALUE` string, it can be accessed normally - * as a NULL-terminated C string. - * - * @param attr The attribute - * @return the value type for the attribute - */ -GIT_EXTERN(git_attr_t) git_attr_value(const char *attr); - -/** - * Check attribute flags: Reading values from index and working directory. - * - * When checking attributes, it is possible to check attribute files - * in both the working directory (if there is one) and the index (if - * there is one). You can explicitly choose where to check and in - * which order using the following flags. - * - * Core git usually checks the working directory then the index, - * except during a checkout when it checks the index first. It will - * use index only for creating archives or for a bare repo (if an - * index has been specified for the bare repo). - */ -#define GIT_ATTR_CHECK_FILE_THEN_INDEX 0 -#define GIT_ATTR_CHECK_INDEX_THEN_FILE 1 -#define GIT_ATTR_CHECK_INDEX_ONLY 2 - -/** - * Check attribute flags: Using the system attributes file. - * - * Normally, attribute checks include looking in the /etc (or system - * equivalent) directory for a `gitattributes` file. Passing this - * flag will cause attribute checks to ignore that file. - */ -#define GIT_ATTR_CHECK_NO_SYSTEM (1 << 2) - -/** - * Look up the value of one git attribute for path. - * - * @param value_out Output of the value of the attribute. Use the GIT_ATTR_... - * macros to test for TRUE, FALSE, UNSPECIFIED, etc. or just - * use the string value for attributes set to a value. You - * should NOT modify or free this value. - * @param repo The repository containing the path. - * @param flags A combination of GIT_ATTR_CHECK... flags. - * @param path The path to check for attributes. Relative paths are - * interpreted relative to the repo root. The file does - * not have to exist, but if it does not, then it will be - * treated as a plain file (not a directory). - * @param name The name of the attribute to look up. - */ -GIT_EXTERN(int) git_attr_get( - const char **value_out, - git_repository *repo, - uint32_t flags, - const char *path, - const char *name); - -/** - * Look up a list of git attributes for path. - * - * Use this if you have a known list of attributes that you want to - * look up in a single call. This is somewhat more efficient than - * calling `git_attr_get()` multiple times. - * - * For example, you might write: - * - * const char *attrs[] = { "crlf", "diff", "foo" }; - * const char **values[3]; - * git_attr_get_many(values, repo, 0, "my/fun/file.c", 3, attrs); - * - * Then you could loop through the 3 values to get the settings for - * the three attributes you asked about. - * - * @param values An array of num_attr entries that will have string - * pointers written into it for the values of the attributes. - * You should not modify or free the values that are written - * into this array (although of course, you should free the - * array itself if you allocated it). - * @param repo The repository containing the path. - * @param flags A combination of GIT_ATTR_CHECK... flags. - * @param path The path inside the repo to check attributes. This - * does not have to exist, but if it does not, then - * it will be treated as a plain file (i.e. not a directory). - * @param num_attr The number of attributes being looked up - * @param names An array of num_attr strings containing attribute names. - */ -GIT_EXTERN(int) git_attr_get_many( - const char **values_out, - git_repository *repo, - uint32_t flags, - const char *path, - size_t num_attr, - const char **names); - -/** - * Loop over all the git attributes for a path. - * - * @param repo The repository containing the path. - * @param flags A combination of GIT_ATTR_CHECK... flags. - * @param path Path inside the repo to check attributes. This does not have - * to exist, but if it does not, then it will be treated as a - * plain file (i.e. not a directory). - * @param callback Function to invoke on each attribute name and value. The - * value may be NULL is the attribute is explicitly set to - * UNSPECIFIED using the '!' sign. Callback will be invoked - * only once per attribute name, even if there are multiple - * rules for a given file. The highest priority rule will be - * used. Return a non-zero value from this to stop looping. - * @param payload Passed on as extra parameter to callback function. - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_attr_foreach( - git_repository *repo, - uint32_t flags, - const char *path, - int (*callback)(const char *name, const char *value, void *payload), - void *payload); - -/** - * Flush the gitattributes cache. - * - * Call this if you have reason to believe that the attributes files on - * disk no longer match the cached contents of memory. This will cause - * the attributes files to be reloaded the next time that an attribute - * access function is called. - */ -GIT_EXTERN(void) git_attr_cache_flush( - git_repository *repo); - -/** - * Add a macro definition. - * - * Macros will automatically be loaded from the top level `.gitattributes` - * file of the repository (plus the build-in "binary" macro). This - * function allows you to add others. For example, to add the default - * macro, you would call: - * - * git_attr_add_macro(repo, "binary", "-diff -crlf"); - */ -GIT_EXTERN(int) git_attr_add_macro( - git_repository *repo, - const char *name, - const char *values); - -/** @} */ -GIT_END_DECL -#endif - diff --git a/include/git2/blob.h b/include/git2/blob.h deleted file mode 100644 index f0719f15d9d..00000000000 --- a/include/git2/blob.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_blob_h__ -#define INCLUDE_git_blob_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" -#include "object.h" - -/** - * @file git2/blob.h - * @brief Git blob load and write routines - * @defgroup git_blob Git blob load and write routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Lookup a blob object from a repository. - * - * @param blob pointer to the looked up blob - * @param repo the repo to use when locating the blob. - * @param id identity of the blob to locate. - * @return 0 or an error code - */ -GIT_INLINE(int) git_blob_lookup(git_blob **blob, git_repository *repo, const git_oid *id) -{ - return git_object_lookup((git_object **)blob, repo, id, GIT_OBJ_BLOB); -} - -/** - * Lookup a blob object from a repository, - * given a prefix of its identifier (short id). - * - * @see git_object_lookup_prefix - * - * @param blob pointer to the looked up blob - * @param repo the repo to use when locating the blob. - * @param id identity of the blob to locate. - * @param len the length of the short identifier - * @return 0 or an error code - */ -GIT_INLINE(int) git_blob_lookup_prefix(git_blob **blob, git_repository *repo, const git_oid *id, size_t len) -{ - return git_object_lookup_prefix((git_object **)blob, repo, id, len, GIT_OBJ_BLOB); -} - -/** - * Close an open blob - * - * This is a wrapper around git_object_free() - * - * IMPORTANT: - * It *is* necessary to call this method when you stop - * using a blob. Failure to do so will cause a memory leak. - * - * @param blob the blob to close - */ - -GIT_INLINE(void) git_blob_free(git_blob *blob) -{ - git_object_free((git_object *) blob); -} - - -/** - * Get a read-only buffer with the raw content of a blob. - * - * A pointer to the raw content of a blob is returned; - * this pointer is owned internally by the object and shall - * not be free'd. The pointer may be invalidated at a later - * time. - * - * @param blob pointer to the blob - * @return the pointer; NULL if the blob has no contents - */ -GIT_EXTERN(const void *) git_blob_rawcontent(git_blob *blob); - -/** - * Get the size in bytes of the contents of a blob - * - * @param blob pointer to the blob - * @return size on bytes - */ -GIT_EXTERN(size_t) git_blob_rawsize(git_blob *blob); - -/** - * Read a file from the working folder of a repository - * and write it to the Object Database as a loose blob - * - * @param oid return the id of the written blob - * @param repo repository where the blob will be written. - * this repository cannot be bare - * @param path file from which the blob will be created, - * relative to the repository's working dir - * @return 0 or an error code - */ -GIT_EXTERN(int) git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *path); - -/** - * Read a file from the filesystem and write its content - * to the Object Database as a loose blob - * - * @param oid return the id of the written blob - * @param repo repository where the blob will be written. - * this repository can be bare or not - * @param path file from which the blob will be created - * @return 0 or an error code - */ -GIT_EXTERN(int) git_blob_create_fromdisk(git_oid *oid, git_repository *repo, const char *path); - -/** - * Write a loose blob to the Object Database from a - * provider of chunks of data. - * - * Provided the `hintpath` parameter is filled, its value - * will help to determine what git filters should be applied - * to the object before it can be placed to the object database. - * - * - * The implementation of the callback has to respect the - * following rules: - * - * - `content` will have to be filled by the consumer. The maximum number - * of bytes that the buffer can accept per call is defined by the - * `max_length` parameter. Allocation and freeing of the buffer will be taken - * care of by the function. - * - * - The callback is expected to return the number of bytes - * that `content` have been filled with. - * - * - When there is no more data to stream, the callback should - * return 0. This will prevent it from being invoked anymore. - * - * - When an error occurs, the callback should return -1. - * - * - * @param oid Return the id of the written blob - * - * @param repo repository where the blob will be written. - * This repository can be bare or not. - * - * @param hintpath if not NULL, will help selecting the filters - * to apply onto the content of the blob to be created. - * - * @return GIT_SUCCESS or an error code - */ -GIT_EXTERN(int) git_blob_create_fromchunks( - git_oid *oid, - git_repository *repo, - const char *hintpath, - int (*source_cb)(char *content, size_t max_length, void *payload), - void *payload); - -/** - * Write an in-memory buffer to the ODB as a blob - * - * @param oid return the oid of the written blob - * @param repo repository where to blob will be written - * @param buffer data to be written into the blob - * @param len length of the data - * @return 0 or an error code - */ -GIT_EXTERN(int) git_blob_create_frombuffer(git_oid *oid, git_repository *repo, const void *buffer, size_t len); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/branch.h b/include/git2/branch.h deleted file mode 100644 index f072799c5ac..00000000000 --- a/include/git2/branch.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_branch_h__ -#define INCLUDE_git_branch_h__ - -#include "common.h" -#include "oid.h" -#include "types.h" - -/** - * @file git2/branch.h - * @brief Git branch parsing routines - * @defgroup git_branch Git branch management - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Create a new branch pointing at a target commit - * - * A new direct reference will be created pointing to - * this target commit. If `force` is true and a reference - * already exists with the given name, it'll be replaced. - * - * The returned reference must be freed by the user. - * - * @param branch_out Pointer where to store the underlying reference. - * - * @param branch_name Name for the branch; this name is - * validated for consistency. It should also not conflict with - * an already existing branch name. - * - * @param target Object to which this branch should point. This object - * must belong to the given `repo` and can either be a git_commit or a - * git_tag. When a git_tag is being passed, it should be dereferencable - * to a git_commit which oid will be used as the target of the branch. - * - * @param force Overwrite existing branch. - * - * @return 0 or an error code. - * A proper reference is written in the refs/heads namespace - * pointing to the provided target commit. - */ -GIT_EXTERN(int) git_branch_create( - git_reference **branch_out, - git_repository *repo, - const char *branch_name, - const git_object *target, - int force); - -/** - * Delete an existing branch reference. - * - * If the branch is successfully deleted, the passed reference - * object will be freed and invalidated. - * - * @param branch A valid reference representing a branch - * @return 0 on success, or an error code. - */ -GIT_EXTERN(int) git_branch_delete(git_reference *branch); - -/** - * Loop over all the branches and issue a callback for each one. - * - * If the callback returns a non-zero value, this will stop looping. - * - * @param repo Repository where to find the branches. - * - * @param list_flags Filtering flags for the branch - * listing. Valid values are GIT_BRANCH_LOCAL, GIT_BRANCH_REMOTE - * or a combination of the two. - * - * @param branch_cb Callback to invoke per found branch. - * - * @param payload Extra parameter to callback function. - * - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_branch_foreach( - git_repository *repo, - unsigned int list_flags, - int (*branch_cb)( - const char *branch_name, - git_branch_t branch_type, - void *payload), - void *payload -); - -/** - * Move/rename an existing local branch reference. - * - * @param branch Current underlying reference of the branch. - * - * @param new_branch_name Target name of the branch once the move - * is performed; this name is validated for consistency. - * - * @param force Overwrite existing branch. - * - * @return 0 on success, or an error code. - */ -GIT_EXTERN(int) git_branch_move( - git_reference *branch, - const char *new_branch_name, - int force); - -/** - * Lookup a branch by its name in a repository. - * - * The generated reference must be freed by the user. - * - * @param branch_out pointer to the looked-up branch reference - * - * @param repo the repository to look up the branch - * - * @param branch_name Name of the branch to be looked-up; - * this name is validated for consistency. - * - * @param branch_type Type of the considered branch. This should - * be valued with either GIT_BRANCH_LOCAL or GIT_BRANCH_REMOTE. - * - * @return 0 on success; GIT_ENOTFOUND when no matching branch - * exists, otherwise an error code. - */ -GIT_EXTERN(int) git_branch_lookup( - git_reference **branch_out, - git_repository *repo, - const char *branch_name, - git_branch_t branch_type); - -/** - * Return the reference supporting the remote tracking branch, - * given a local branch reference. - * - * @param tracking_out Pointer where to store the retrieved - * reference. - * - * @param branch Current underlying reference of the branch. - * - * @return 0 on success; GIT_ENOTFOUND when no remote tracking - * reference exists, otherwise an error code. - */ -GIT_EXTERN(int) git_branch_tracking( - git_reference **tracking_out, - git_reference *branch); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/checkout.h b/include/git2/checkout.h deleted file mode 100644 index ef3badbe994..00000000000 --- a/include/git2/checkout.h +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_checkout_h__ -#define INCLUDE_git_checkout_h__ - -#include "common.h" -#include "types.h" -#include "indexer.h" - - -/** - * @file git2/checkout.h - * @brief Git checkout routines - * @defgroup git_checkout Git checkout routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -enum { - GIT_CHECKOUT_DEFAULT = (1 << 0), - GIT_CHECKOUT_OVERWRITE_MODIFIED = (1 << 1), - GIT_CHECKOUT_CREATE_MISSING = (1 << 2), - GIT_CHECKOUT_REMOVE_UNTRACKED = (1 << 3), -}; - -/* Use zeros to indicate default settings */ -typedef struct git_checkout_opts { - unsigned int checkout_strategy; /* default: GIT_CHECKOUT_DEFAULT */ - int disable_filters; - int dir_mode; /* default is 0755 */ - int file_mode; /* default is 0644 */ - int file_open_flags; /* default is O_CREAT | O_TRUNC | O_WRONLY */ - - /* Optional callback to notify the consumer of files that - * haven't be checked out because a modified version of them - * exist in the working directory. - * - * When provided, this callback will be invoked when the flag - * GIT_CHECKOUT_OVERWRITE_MODIFIED isn't part of the checkout strategy. - */ - int (* skipped_notify_cb)( - const char *skipped_file, - const git_oid *blob_oid, - int file_mode, - void *payload); - - void *notify_payload; - - /* when not NULL, arrays of fnmatch pattern specifying - * which paths should be taken into account - */ - git_strarray paths; -} git_checkout_opts; - -/** - * Updates files in the index and the working tree to match the content of the - * commit pointed at by HEAD. - * - * @param repo repository to check out (must be non-bare) - * @param opts specifies checkout options (may be NULL) - * @param stats structure through which progress information is reported - * @return 0 on success, GIT_ERROR otherwise (use giterr_last for information - * about the error) - */ -GIT_EXTERN(int) git_checkout_head( - git_repository *repo, - git_checkout_opts *opts, - git_indexer_stats *stats); - -/** - * Updates files in the working tree to match the content of the index. - * - * @param repo repository to check out (must be non-bare) - * @param opts specifies checkout options (may be NULL) - * @param stats structure through which progress information is reported - * @return 0 on success, GIT_ERROR otherwise (use giterr_last for information - * about the error) - */ -GIT_EXTERN(int) git_checkout_index( - git_repository *repo, - git_checkout_opts *opts, - git_indexer_stats *stats); - -/** - * Updates files in the index and working tree to match the content of the - * tree pointed at by the treeish. - * - * @param repo repository to check out (must be non-bare) - * @param treeish a commit, tag or tree which content will be used to update - * the working directory - * @param opts specifies checkout options (may be NULL) - * @param stats structure through which progress information is reported - * @return 0 on success, GIT_ERROR otherwise (use giterr_last for information - * about the error) - */ -GIT_EXTERN(int) git_checkout_tree( - git_repository *repo, - git_object *treeish, - git_checkout_opts *opts, - git_indexer_stats *stats); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/clone.h b/include/git2/clone.h deleted file mode 100644 index 40292ed59f6..00000000000 --- a/include/git2/clone.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_clone_h__ -#define INCLUDE_git_clone_h__ - -#include "common.h" -#include "types.h" -#include "indexer.h" -#include "checkout.h" - - -/** - * @file git2/clone.h - * @brief Git cloning routines - * @defgroup git_clone Git cloning routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Clone a remote repository, and checkout the branch pointed to by the remote - * HEAD. - * - * @param out pointer that will receive the resulting repository object - * @param origin_url repository to clone from - * @param workdir_path local directory to clone to - * @param fetch_stats pointer to structure that receives fetch progress information (may be NULL) - * @param checkout_opts options for the checkout step (may be NULL) - * @return 0 on success, GIT_ERROR otherwise (use giterr_last for information about the error) - */ -GIT_EXTERN(int) git_clone(git_repository **out, - const char *origin_url, - const char *workdir_path, - git_indexer_stats *fetch_stats, - git_indexer_stats *checkout_stats, - git_checkout_opts *checkout_opts); - -/** - * Create a bare clone of a remote repository. - * - * @param out pointer that will receive the resulting repository object - * @param origin_url repository to clone from - * @param dest_path local directory to clone to - * @param fetch_stats pointer to structure that receives fetch progress information (may be NULL) - * @return 0 on success, GIT_ERROR otherwise (use giterr_last for information about the error) - */ -GIT_EXTERN(int) git_clone_bare(git_repository **out, - const char *origin_url, - const char *dest_path, - git_indexer_stats *fetch_stats); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/commit.h b/include/git2/commit.h deleted file mode 100644 index a159b79e1dc..00000000000 --- a/include/git2/commit.h +++ /dev/null @@ -1,289 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_commit_h__ -#define INCLUDE_git_commit_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" -#include "object.h" - -/** - * @file git2/commit.h - * @brief Git commit parsing, formatting routines - * @defgroup git_commit Git commit parsing, formatting routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Lookup a commit object from a repository. - * - * @param commit pointer to the looked up commit - * @param repo the repo to use when locating the commit. - * @param id identity of the commit to locate. If the object is - * an annotated tag it will be peeled back to the commit. - * @return 0 or an error code - */ -GIT_INLINE(int) git_commit_lookup(git_commit **commit, git_repository *repo, const git_oid *id) -{ - return git_object_lookup((git_object **)commit, repo, id, GIT_OBJ_COMMIT); -} - -/** - * Lookup a commit object from a repository, - * given a prefix of its identifier (short id). - * - * @see git_object_lookup_prefix - * - * @param commit pointer to the looked up commit - * @param repo the repo to use when locating the commit. - * @param id identity of the commit to locate. If the object is - * an annotated tag it will be peeled back to the commit. - * @param len the length of the short identifier - * @return 0 or an error code - */ -GIT_INLINE(int) git_commit_lookup_prefix(git_commit **commit, git_repository *repo, const git_oid *id, size_t len) -{ - return git_object_lookup_prefix((git_object **)commit, repo, id, len, GIT_OBJ_COMMIT); -} - -/** - * Close an open commit - * - * This is a wrapper around git_object_free() - * - * IMPORTANT: - * It *is* necessary to call this method when you stop - * using a commit. Failure to do so will cause a memory leak. - * - * @param commit the commit to close - */ - -GIT_INLINE(void) git_commit_free(git_commit *commit) -{ - git_object_free((git_object *) commit); -} - -/** - * Get the id of a commit. - * - * @param commit a previously loaded commit. - * @return object identity for the commit. - */ -GIT_EXTERN(const git_oid *) git_commit_id(git_commit *commit); - -/** - * Get the encoding for the message of a commit, - * as a string representing a standard encoding name. - * - * The encoding may be NULL if the `encoding` header - * in the commit is missing; in that case UTF-8 is assumed. - * - * @param commit a previously loaded commit. - * @return NULL, or the encoding - */ -GIT_EXTERN(const char *) git_commit_message_encoding(git_commit *commit); - -/** - * Get the full message of a commit. - * - * @param commit a previously loaded commit. - * @return the message of a commit - */ -GIT_EXTERN(const char *) git_commit_message(git_commit *commit); - -/** - * Get the commit time (i.e. committer time) of a commit. - * - * @param commit a previously loaded commit. - * @return the time of a commit - */ -GIT_EXTERN(git_time_t) git_commit_time(git_commit *commit); - -/** - * Get the commit timezone offset (i.e. committer's preferred timezone) of a commit. - * - * @param commit a previously loaded commit. - * @return positive or negative timezone offset, in minutes from UTC - */ -GIT_EXTERN(int) git_commit_time_offset(git_commit *commit); - -/** - * Get the committer of a commit. - * - * @param commit a previously loaded commit. - * @return the committer of a commit - */ -GIT_EXTERN(const git_signature *) git_commit_committer(git_commit *commit); - -/** - * Get the author of a commit. - * - * @param commit a previously loaded commit. - * @return the author of a commit - */ -GIT_EXTERN(const git_signature *) git_commit_author(git_commit *commit); - -/** - * Get the tree pointed to by a commit. - * - * @param tree_out pointer where to store the tree object - * @param commit a previously loaded commit. - * @return 0 or an error code - */ -GIT_EXTERN(int) git_commit_tree(git_tree **tree_out, git_commit *commit); - -/** - * Get the id of the tree pointed to by a commit. This differs from - * `git_commit_tree` in that no attempts are made to fetch an object - * from the ODB. - * - * @param commit a previously loaded commit. - * @return the id of tree pointed to by commit. - */ -GIT_EXTERN(const git_oid *) git_commit_tree_oid(git_commit *commit); - -/** - * Get the number of parents of this commit - * - * @param commit a previously loaded commit. - * @return integer of count of parents - */ -GIT_EXTERN(unsigned int) git_commit_parentcount(git_commit *commit); - -/** - * Get the specified parent of the commit. - * - * @param parent Pointer where to store the parent commit - * @param commit a previously loaded commit. - * @param n the position of the parent (from 0 to `parentcount`) - * @return 0 or an error code - */ -GIT_EXTERN(int) git_commit_parent(git_commit **parent, git_commit *commit, unsigned int n); - -/** - * Get the oid of a specified parent for a commit. This is different from - * `git_commit_parent`, which will attempt to load the parent commit from - * the ODB. - * - * @param commit a previously loaded commit. - * @param n the position of the parent (from 0 to `parentcount`) - * @return the id of the parent, NULL on error. - */ -GIT_EXTERN(const git_oid *) git_commit_parent_oid(git_commit *commit, unsigned int n); - -/** - * Get the commit object that is the th generation ancestor - * of the named commit object, following only the first parents. - * The returned commit has to be freed by the caller. - * - * Passing `0` as the generation number returns another instance of the - * base commit itself. - * - * @param ancestor Pointer where to store the ancestor commit - * @param commit a previously loaded commit. - * @param n the requested generation - * @return 0 on success; GIT_ENOTFOUND if no matching ancestor exists - * or an error code - */ -GIT_EXTERN(int) git_commit_nth_gen_ancestor( - git_commit **ancestor, - const git_commit *commit, - unsigned int n); - -/** - * Create a new commit in the repository using `git_object` - * instances as parameters. - * - * The message will not be cleaned up. This can be achieved - * through `git_message_prettify()`. - * - * @param oid Pointer where to store the OID of the - * newly created commit - * - * @param repo Repository where to store the commit - * - * @param update_ref If not NULL, name of the reference that - * will be updated to point to this commit. If the reference - * is not direct, it will be resolved to a direct reference. - * Use "HEAD" to update the HEAD of the current branch and - * make it point to this commit. If the reference doesn't - * exist yet, it will be created. - * - * @param author Signature representing the author and the authory - * time of this commit - * - * @param committer Signature representing the committer and the - * commit time of this commit - * - * @param message_encoding The encoding for the message in the - * commit, represented with a standard encoding name. - * E.g. "UTF-8". If NULL, no encoding header is written and - * UTF-8 is assumed. - * - * @param message Full message for this commit - * - * @param tree An instance of a `git_tree` object that will - * be used as the tree for the commit. This tree object must - * also be owned by the given `repo`. - * - * @param parent_count Number of parents for this commit - * - * @param parents[] Array of `parent_count` pointers to `git_commit` - * objects that will be used as the parents for this commit. This - * array may be NULL if `parent_count` is 0 (root commit). All the - * given commits must be owned by the `repo`. - * - * @return 0 or an error code - * The created commit will be written to the Object Database and - * the given reference will be updated to point to it - */ -GIT_EXTERN(int) git_commit_create( - git_oid *oid, - git_repository *repo, - const char *update_ref, - const git_signature *author, - const git_signature *committer, - const char *message_encoding, - const char *message, - const git_tree *tree, - int parent_count, - const git_commit *parents[]); - -/** - * Create a new commit in the repository using a variable - * argument list. - * - * The message will be cleaned up from excess whitespace - * it will be made sure that the last line ends with a '\n'. - * - * The parents for the commit are specified as a variable - * list of pointers to `const git_commit *`. Note that this - * is a convenience method which may not be safe to export - * for certain languages or compilers - * - * All other parameters remain the same - * - * @see git_commit_create - */ -GIT_EXTERN(int) git_commit_create_v( - git_oid *oid, - git_repository *repo, - const char *update_ref, - const git_signature *author, - const git_signature *committer, - const char *message_encoding, - const char *message, - const git_tree *tree, - int parent_count, - ...); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/common.h b/include/git2/common.h deleted file mode 100644 index 0af37e81f36..00000000000 --- a/include/git2/common.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_common_h__ -#define INCLUDE_git_common_h__ - -#include -#include - -#ifdef _MSC_VER -# include "inttypes.h" -#else -# include -#endif - -#ifdef __cplusplus -# define GIT_BEGIN_DECL extern "C" { -# define GIT_END_DECL } -#else - /** Start declarations in C mode */ -# define GIT_BEGIN_DECL /* empty */ - /** End declarations in C mode */ -# define GIT_END_DECL /* empty */ -#endif - -/** Declare a public function exported for application use. */ -#if __GNUC__ >= 4 -# define GIT_EXTERN(type) extern \ - __attribute__((visibility("default"))) \ - type -#elif defined(_MSC_VER) -# define GIT_EXTERN(type) __declspec(dllexport) type -#else -# define GIT_EXTERN(type) extern type -#endif - -/** Declare a function as always inlined. */ -#if defined(_MSC_VER) -# define GIT_INLINE(type) static __inline type -#else -# define GIT_INLINE(type) static inline type -#endif - -/** Declare a function's takes printf style arguments. */ -#ifdef __GNUC__ -# define GIT_FORMAT_PRINTF(a,b) __attribute__((format (printf, a, b))) -#else -# define GIT_FORMAT_PRINTF(a,b) /* empty */ -#endif - -#if (defined(_WIN32)) && !defined(__CYGWIN__) -#define GIT_WIN32 1 -#endif - -#ifdef __amigaos4__ -#include -#endif - -/** - * @file git2/common.h - * @brief Git common platform definitions - * @defgroup git_common Git common platform definitions - * @ingroup Git - * @{ - */ - -GIT_BEGIN_DECL - -/** - * The separator used in path list strings (ie like in the PATH - * environment variable). A semi-colon ";" is used on Windows, and - * a colon ":" for all other systems. - */ -#ifdef GIT_WIN32 -#define GIT_PATH_LIST_SEPARATOR ';' -#else -#define GIT_PATH_LIST_SEPARATOR ':' -#endif - -/** - * The maximum length of a valid git path. - */ -#define GIT_PATH_MAX 4096 - -typedef struct { - char **strings; - size_t count; -} git_strarray; - -GIT_EXTERN(void) git_strarray_free(git_strarray *array); -GIT_EXTERN(int) git_strarray_copy(git_strarray *tgt, const git_strarray *src); - -/** - * Return the version of the libgit2 library - * being currently used. - * - * @param major Store the major version number - * @param minor Store the minor version number - * @param rev Store the revision (patch) number - */ -GIT_EXTERN(void) git_libgit2_version(int *major, int *minor, int *rev); - -/** - * Combinations of these values describe the capabilities of libgit2. - */ -enum { - GIT_CAP_THREADS = ( 1 << 0 ), - GIT_CAP_HTTPS = ( 1 << 1 ) -}; - -/** - * Query compile time options for libgit2. - * - * @return A combination of GIT_CAP_* values. - * - * - GIT_CAP_THREADS - * Libgit2 was compiled with thread support. Note that thread support is still to be seen as a - * 'work in progress'. - * - * - GIT_CAP_HTTPS - * Libgit2 supports the https:// protocol. This requires the open ssl library to be - * found when compiling libgit2. - */ -GIT_EXTERN(int) git_libgit2_capabilities(void); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/config.h b/include/git2/config.h deleted file mode 100644 index 21d8a0b05dd..00000000000 --- a/include/git2/config.h +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_config_h__ -#define INCLUDE_git_config_h__ - -#include "common.h" -#include "types.h" - -/** - * @file git2/config.h - * @brief Git config management routines - * @defgroup git_config Git config management routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Generic backend that implements the interface to - * access a configuration file - */ -struct git_config_file { - struct git_config *cfg; - - /* Open means open the file/database and parse if necessary */ - int (*open)(struct git_config_file *); - int (*get)(struct git_config_file *, const char *key, const char **value); - int (*get_multivar)(struct git_config_file *, const char *key, const char *regexp, int (*fn)(const char *, void *), void *data); - int (*set)(struct git_config_file *, const char *key, const char *value); - int (*set_multivar)(git_config_file *cfg, const char *name, const char *regexp, const char *value); - int (*del)(struct git_config_file *, const char *key); - int (*foreach)(struct git_config_file *, const char *, int (*fn)(const char *, const char *, void *), void *data); - void (*free)(struct git_config_file *); -}; - -typedef enum { - GIT_CVAR_FALSE = 0, - GIT_CVAR_TRUE = 1, - GIT_CVAR_INT32, - GIT_CVAR_STRING -} git_cvar_t; - -typedef struct { - git_cvar_t cvar_type; - const char *str_match; - int map_value; -} git_cvar_map; - -/** - * Locate the path to the global configuration file - * - * The user or global configuration file is usually - * located in `$HOME/.gitconfig`. - * - * This method will try to guess the full path to that - * file, if the file exists. The returned path - * may be used on any `git_config` call to load the - * global configuration file. - * - * @param global_config_path Buffer of GIT_PATH_MAX length to store the path - * @return 0 if a global configuration file has been - * found. Its path will be stored in `buffer`. - */ -GIT_EXTERN(int) git_config_find_global(char *global_config_path, size_t length); - -/** - * Locate the path to the system configuration file - * - * If /etc/gitconfig doesn't exist, it will look for - * %PROGRAMFILES%\Git\etc\gitconfig. - - * @param system_config_path Buffer of GIT_PATH_MAX length to store the path - * @return 0 if a system configuration file has been - * found. Its path will be stored in `buffer`. - */ -GIT_EXTERN(int) git_config_find_system(char *system_config_path, size_t length); - -/** - * Open the global and system configuration files - * - * Utility wrapper that finds the global and system configuration files - * and opens them into a single prioritized config object that can be - * used when accessing default config data outside a repository. - * - * @param out Pointer to store the config instance - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_open_default(git_config **out); - -/** - * Create a configuration file backend for ondisk files - * - * These are the normal `.gitconfig` files that Core Git - * processes. Note that you first have to add this file to a - * configuration object before you can query it for configuration - * variables. - * - * @param out the new backend - * @param path where the config file is located - */ -GIT_EXTERN(int) git_config_file__ondisk(struct git_config_file **out, const char *path); - -/** - * Allocate a new configuration object - * - * This object is empty, so you have to add a file to it before you - * can do anything with it. - * - * @param out pointer to the new configuration - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_new(git_config **out); - -/** - * Add a generic config file instance to an existing config - * - * Note that the configuration object will free the file - * automatically. - * - * Further queries on this config object will access each - * of the config file instances in order (instances with - * a higher priority will be accessed first). - * - * @param cfg the configuration to add the file to - * @param file the configuration file (backend) to add - * @param priority the priority the backend should have - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_add_file(git_config *cfg, git_config_file *file, int priority); - -/** - * Add an on-disk config file instance to an existing config - * - * The on-disk file pointed at by `path` will be opened and - * parsed; it's expected to be a native Git config file following - * the default Git config syntax (see man git-config). - * - * Note that the configuration object will free the file - * automatically. - * - * Further queries on this config object will access each - * of the config file instances in order (instances with - * a higher priority will be accessed first). - * - * @param cfg the configuration to add the file to - * @param path path to the configuration file (backend) to add - * @param priority the priority the backend should have - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_add_file_ondisk(git_config *cfg, const char *path, int priority); - - -/** - * Create a new config instance containing a single on-disk file - * - * This method is a simple utility wrapper for the following sequence - * of calls: - * - git_config_new - * - git_config_add_file_ondisk - * - * @param cfg The configuration instance to create - * @param path Path to the on-disk file to open - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_open_ondisk(git_config **cfg, const char *path); - -/** - * Free the configuration and its associated memory and files - * - * @param cfg the configuration to free - */ -GIT_EXTERN(void) git_config_free(git_config *cfg); - -/** - * Get the value of an integer config variable. - * - * @param out pointer to the variable where the value should be stored - * @param cfg where to look for the variable - * @param name the variable's name - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_get_int32(int32_t *out, git_config *cfg, const char *name); - -/** - * Get the value of a long integer config variable. - * - * @param out pointer to the variable where the value should be stored - * @param cfg where to look for the variable - * @param name the variable's name - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_get_int64(int64_t *out, git_config *cfg, const char *name); - -/** - * Get the value of a boolean config variable. - * - * This function uses the usual C convention of 0 being false and - * anything else true. - * - * @param out pointer to the variable where the value should be stored - * @param cfg where to look for the variable - * @param name the variable's name - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_get_bool(int *out, git_config *cfg, const char *name); - -/** - * Get the value of a string config variable. - * - * The string is owned by the variable and should not be freed by the - * user. - * - * @param out pointer to the variable's value - * @param cfg where to look for the variable - * @param name the variable's name - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_get_string(const char **out, git_config *cfg, const char *name); - -/** - * Get each value of a multivar. - * - * The callback will be called on each variable found - * - * @param cfg where to look for the variable - * @param name the variable's name - * @param regexp regular expression to filter which variables we're - * interested in. Use NULL to indicate all - * @param fn the function to be called on each value of the variable - * @param data opaque pointer to pass to the callback - */ -GIT_EXTERN(int) git_config_get_multivar(git_config *cfg, const char *name, const char *regexp, int (*fn)(const char *, void *), void *data); - -/** - * Set the value of an integer config variable. - * - * @param cfg where to look for the variable - * @param name the variable's name - * @param value Integer value for the variable - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_set_int32(git_config *cfg, const char *name, int32_t value); - -/** - * Set the value of a long integer config variable. - * - * @param cfg where to look for the variable - * @param name the variable's name - * @param value Long integer value for the variable - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_set_int64(git_config *cfg, const char *name, int64_t value); - -/** - * Set the value of a boolean config variable. - * - * @param cfg where to look for the variable - * @param name the variable's name - * @param value the value to store - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_set_bool(git_config *cfg, const char *name, int value); - -/** - * Set the value of a string config variable. - * - * A copy of the string is made and the user is free to use it - * afterwards. - * - * @param cfg where to look for the variable - * @param name the variable's name - * @param value the string to store. - * @return 0 or an error code - */ -GIT_EXTERN(int) git_config_set_string(git_config *cfg, const char *name, const char *value); - - -/** - * Set a multivar - * - * @param cfg where to look for the variable - * @param name the variable's name - * @param regexp a regular expression to indicate which values to replace - * @param value the new value. - */ -GIT_EXTERN(int) git_config_set_multivar(git_config *cfg, const char *name, const char *regexp, const char *value); - -/** - * Delete a config variable - * - * @param cfg the configuration - * @param name the variable to delete - */ -GIT_EXTERN(int) git_config_delete(git_config *cfg, const char *name); - -/** - * Perform an operation on each config variable. - * - * The callback receives the normalized name and value of each variable - * in the config backend, and the data pointer passed to this function. - * As soon as one of the callback functions returns something other than 0, - * this function stops iterating and returns `GIT_EUSER`. - * - * @param cfg where to get the variables from - * @param callback the function to call on each variable - * @param payload the data to pass to the callback - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_config_foreach( - git_config *cfg, - int (*callback)(const char *var_name, const char *value, void *payload), - void *payload); - -/** - * Perform an operation on each config variable matching a regular expression. - * - * This behaviors like `git_config_foreach` with an additional filter of a - * regular expression that filters which config keys are passed to the - * callback. - * - * @param cfg where to get the variables from - * @param regexp regular expression to match against config names - * @param callback the function to call on each variable - * @param payload the data to pass to the callback - * @return 0 or the return value of the callback which didn't return 0 - */ -GIT_EXTERN(int) git_config_foreach_match( - git_config *cfg, - const char *regexp, - int (*callback)(const char *var_name, const char *value, void *payload), - void *payload); - -/** - * Query the value of a config variable and return it mapped to - * an integer constant. - * - * This is a helper method to easily map different possible values - * to a variable to integer constants that easily identify them. - * - * A mapping array looks as follows: - * - * git_cvar_map autocrlf_mapping[] = { - * {GIT_CVAR_FALSE, NULL, GIT_AUTO_CRLF_FALSE}, - * {GIT_CVAR_TRUE, NULL, GIT_AUTO_CRLF_TRUE}, - * {GIT_CVAR_STRING, "input", GIT_AUTO_CRLF_INPUT}, - * {GIT_CVAR_STRING, "default", GIT_AUTO_CRLF_DEFAULT}}; - * - * On any "false" value for the variable (e.g. "false", "FALSE", "no"), the - * mapping will store `GIT_AUTO_CRLF_FALSE` in the `out` parameter. - * - * The same thing applies for any "true" value such as "true", "yes" or "1", storing - * the `GIT_AUTO_CRLF_TRUE` variable. - * - * Otherwise, if the value matches the string "input" (with case insensitive comparison), - * the given constant will be stored in `out`, and likewise for "default". - * - * If not a single match can be made to store in `out`, an error code will be - * returned. - * - * @param out place to store the result of the mapping - * @param cfg config file to get the variables from - * @param name name of the config variable to lookup - * @param maps array of `git_cvar_map` objects specifying the possible mappings - * @param map_n number of mapping objects in `maps` - * @return 0 on success, error code otherwise - */ -GIT_EXTERN(int) git_config_get_mapped(int *out, git_config *cfg, const char *name, git_cvar_map *maps, size_t map_n); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/diff.h b/include/git2/diff.h deleted file mode 100644 index 05825c50db8..00000000000 --- a/include/git2/diff.h +++ /dev/null @@ -1,601 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_diff_h__ -#define INCLUDE_git_diff_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" -#include "tree.h" -#include "refs.h" - -/** - * @file git2/diff.h - * @brief Git tree and file differencing routines. - * - * Calculating diffs is generally done in two phases: building a diff list - * then traversing the diff list. This makes is easier to share logic - * across the various types of diffs (tree vs tree, workdir vs index, etc.), - * and also allows you to insert optional diff list post-processing phases, - * such as rename detected, in between the steps. When you are done with a - * diff list object, it must be freed. - * - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Flags for diff options. A combination of these flags can be passed - * in via the `flags` value in the `git_diff_options`. - */ -enum { - GIT_DIFF_NORMAL = 0, - GIT_DIFF_REVERSE = (1 << 0), - GIT_DIFF_FORCE_TEXT = (1 << 1), - GIT_DIFF_IGNORE_WHITESPACE = (1 << 2), - GIT_DIFF_IGNORE_WHITESPACE_CHANGE = (1 << 3), - GIT_DIFF_IGNORE_WHITESPACE_EOL = (1 << 4), - GIT_DIFF_IGNORE_SUBMODULES = (1 << 5), - GIT_DIFF_PATIENCE = (1 << 6), - GIT_DIFF_INCLUDE_IGNORED = (1 << 7), - GIT_DIFF_INCLUDE_UNTRACKED = (1 << 8), - GIT_DIFF_INCLUDE_UNMODIFIED = (1 << 9), - GIT_DIFF_RECURSE_UNTRACKED_DIRS = (1 << 10), - GIT_DIFF_DISABLE_PATHSPEC_MATCH = (1 << 11), -}; - -/** - * Structure describing options about how the diff should be executed. - * - * Setting all values of the structure to zero will yield the default - * values. Similarly, passing NULL for the options structure will - * give the defaults. The default values are marked below. - * - * - flags: a combination of the GIT_DIFF_... values above - * - context_lines: number of lines of context to show around diffs - * - interhunk_lines: min lines between diff hunks to merge them - * - old_prefix: "directory" to prefix to old file names (default "a") - * - new_prefix: "directory" to prefix to new file names (default "b") - * - pathspec: array of paths / patterns to constrain diff - * - max_size: maximum blob size to diff, above this treated as binary - */ -typedef struct { - uint32_t flags; /**< defaults to GIT_DIFF_NORMAL */ - uint16_t context_lines; /**< defaults to 3 */ - uint16_t interhunk_lines; /**< defaults to 0 */ - char *old_prefix; /**< defaults to "a" */ - char *new_prefix; /**< defaults to "b" */ - git_strarray pathspec; /**< defaults to show all paths */ - git_off_t max_size; /**< defaults to 512Mb */ -} git_diff_options; - -/** - * The diff list object that contains all individual file deltas. - */ -typedef struct git_diff_list git_diff_list; - -/** - * Flags that can be set for the file on side of a diff. - * - * Most of the flags are just for internal consumption by libgit2, - * but some of them may be interesting to external users. They are: - * - * - VALID_OID - the `oid` value is computed and correct - * - FREE_PATH - the `path` string is separated allocated memory - * - BINARY - this file should be considered binary data - * - NOT_BINARY - this file should be considered text data - * - FREE_DATA - the internal file data is kept in allocated memory - * - UNMAP_DATA - the internal file data is kept in mmap'ed memory - * - NO_DATA - this side of the diff should not be loaded - */ -enum { - GIT_DIFF_FILE_VALID_OID = (1 << 0), - GIT_DIFF_FILE_FREE_PATH = (1 << 1), - GIT_DIFF_FILE_BINARY = (1 << 2), - GIT_DIFF_FILE_NOT_BINARY = (1 << 3), - GIT_DIFF_FILE_FREE_DATA = (1 << 4), - GIT_DIFF_FILE_UNMAP_DATA = (1 << 5), - GIT_DIFF_FILE_NO_DATA = (1 << 6), -}; - -/** - * What type of change is described by a git_diff_delta? - */ -typedef enum { - GIT_DELTA_UNMODIFIED = 0, - GIT_DELTA_ADDED = 1, - GIT_DELTA_DELETED = 2, - GIT_DELTA_MODIFIED = 3, - GIT_DELTA_RENAMED = 4, - GIT_DELTA_COPIED = 5, - GIT_DELTA_IGNORED = 6, - GIT_DELTA_UNTRACKED = 7 -} git_delta_t; - -/** - * Description of one side of a diff. - */ -typedef struct { - git_oid oid; - char *path; - git_off_t size; - unsigned int flags; - uint16_t mode; -} git_diff_file; - -/** - * Description of changes to one file. - * - * When iterating over a diff list object, this will generally be passed to - * most callback functions and you can use the contents to understand - * exactly what has changed. - * - * Under some circumstances, not all fields will be filled in, but the code - * generally tries to fill in as much as possible. One example is that the - * "binary" field will not actually look at file contents if you do not - * pass in hunk and/or line callbacks to the diff foreach iteration function. - * It will just use the git attributes for those files. - */ -typedef struct { - git_diff_file old_file; - git_diff_file new_file; - git_delta_t status; - unsigned int similarity; /**< for RENAMED and COPIED, value 0-100 */ - int binary; -} git_diff_delta; - -/** - * When iterating over a diff, callback that will be made per file. - */ -typedef int (*git_diff_file_fn)( - void *cb_data, - git_diff_delta *delta, - float progress); - -/** - * Structure describing a hunk of a diff. - */ -typedef struct { - int old_start; - int old_lines; - int new_start; - int new_lines; -} git_diff_range; - -/** - * When iterating over a diff, callback that will be made per hunk. - */ -typedef int (*git_diff_hunk_fn)( - void *cb_data, - git_diff_delta *delta, - git_diff_range *range, - const char *header, - size_t header_len); - -/** - * Line origin constants. - * - * These values describe where a line came from and will be passed to - * the git_diff_data_fn when iterating over a diff. There are some - * special origin constants at the end that are used for the text - * output callbacks to demarcate lines that are actually part of - * the file or hunk headers. - */ -enum { - /* These values will be sent to `git_diff_data_fn` along with the line */ - GIT_DIFF_LINE_CONTEXT = ' ', - GIT_DIFF_LINE_ADDITION = '+', - GIT_DIFF_LINE_DELETION = '-', - GIT_DIFF_LINE_ADD_EOFNL = '\n', /**< Removed line w/o LF & added one with */ - GIT_DIFF_LINE_DEL_EOFNL = '\0', /**< LF was removed at end of file */ - - /* The following values will only be sent to a `git_diff_data_fn` when - * the content of a diff is being formatted (eg. through - * git_diff_print_patch() or git_diff_print_compact(), for instance). - */ - GIT_DIFF_LINE_FILE_HDR = 'F', - GIT_DIFF_LINE_HUNK_HDR = 'H', - GIT_DIFF_LINE_BINARY = 'B' -}; - -/** - * When iterating over a diff, callback that will be made per text diff - * line. In this context, the provided range will be NULL. - * - * When printing a diff, callback that will be made to output each line - * of text. This uses some extra GIT_DIFF_LINE_... constants for output - * of lines of file and hunk headers. - */ -typedef int (*git_diff_data_fn)( - void *cb_data, - git_diff_delta *delta, - git_diff_range *range, - char line_origin, /**< GIT_DIFF_LINE_... value from above */ - const char *content, - size_t content_len); - -/** - * The diff iterator object is used to scan a diff list. - */ -typedef struct git_diff_iterator git_diff_iterator; - -/** @name Diff List Generator Functions - * - * These are the functions you would use to create (or destroy) a - * git_diff_list from various objects in a repository. - */ -/**@{*/ - -/** - * Deallocate a diff list. - */ -GIT_EXTERN(void) git_diff_list_free(git_diff_list *diff); - -/** - * Compute a difference between two tree objects. - * - * This is equivalent to `git diff ` - * - * @param repo The repository containing the trees. - * @param opts Structure with options to influence diff or NULL for defaults. - * @param old_tree A git_tree object to diff from. - * @param new_tree A git_tree object to diff to. - * @param diff A pointer to a git_diff_list pointer that will be allocated. - */ -GIT_EXTERN(int) git_diff_tree_to_tree( - git_repository *repo, - const git_diff_options *opts, /**< can be NULL for defaults */ - git_tree *old_tree, - git_tree *new_tree, - git_diff_list **diff); - -/** - * Compute a difference between a tree and the index. - * - * This is equivalent to `git diff --cached ` or if you pass - * the HEAD tree, then like `git diff --cached`. - * - * @param repo The repository containing the tree and index. - * @param opts Structure with options to influence diff or NULL for defaults. - * @param old_tree A git_tree object to diff from. - * @param diff A pointer to a git_diff_list pointer that will be allocated. - */ -GIT_EXTERN(int) git_diff_index_to_tree( - git_repository *repo, - const git_diff_options *opts, /**< can be NULL for defaults */ - git_tree *old_tree, - git_diff_list **diff); - -/** - * Compute a difference between the working directory and the index. - * - * This matches the `git diff` command. See the note below on - * `git_diff_workdir_to_tree` for a discussion of the difference between - * `git diff` and `git diff HEAD` and how to emulate a `git diff ` - * using libgit2. - * - * @param repo The repository. - * @param opts Structure with options to influence diff or NULL for defaults. - * @param diff A pointer to a git_diff_list pointer that will be allocated. - */ -GIT_EXTERN(int) git_diff_workdir_to_index( - git_repository *repo, - const git_diff_options *opts, /**< can be NULL for defaults */ - git_diff_list **diff); - -/** - * Compute a difference between the working directory and a tree. - * - * This is *NOT* the same as `git diff `. Running `git diff HEAD` - * or the like actually uses information from the index, along with the tree - * and workdir dir info. - * - * This function returns strictly the differences between the tree and the - * files contained in the working directory, regardless of the state of - * files in the index. It may come as a surprise, but there is no direct - * equivalent in core git. - * - * To emulate `git diff `, you should call both - * `git_diff_index_to_tree` and `git_diff_workdir_to_index`, then call - * `git_diff_merge` on the results. That will yield a `git_diff_list` that - * matches the git output. - * - * If this seems confusing, take the case of a file with a staged deletion - * where the file has then been put back into the working dir and modified. - * The tree-to-workdir diff for that file is 'modified', but core git would - * show status 'deleted' since there is a pending deletion in the index. - * - * @param repo The repository containing the tree. - * @param opts Structure with options to influence diff or NULL for defaults. - * @param old_tree A git_tree object to diff from. - * @param diff A pointer to a git_diff_list pointer that will be allocated. - */ -GIT_EXTERN(int) git_diff_workdir_to_tree( - git_repository *repo, - const git_diff_options *opts, /**< can be NULL for defaults */ - git_tree *old_tree, - git_diff_list **diff); - -/** - * Merge one diff list into another. - * - * This merges items from the "from" list into the "onto" list. The - * resulting diff list will have all items that appear in either list. - * If an item appears in both lists, then it will be "merged" to appear - * as if the old version was from the "onto" list and the new version - * is from the "from" list (with the exception that if the item has a - * pending DELETE in the middle, then it will show as deleted). - * - * @param onto Diff to merge into. - * @param from Diff to merge. - */ -GIT_EXTERN(int) git_diff_merge( - git_diff_list *onto, - const git_diff_list *from); - -/**@}*/ - - -/** @name Diff List Processor Functions - * - * These are the functions you apply to a diff list to process it - * or read it in some way. - */ -/**@{*/ - -/** - * Iterate over a diff list issuing callbacks. - * - * This will iterate through all of the files described in a diff. You - * should provide a file callback to learn about each file. - * - * The "hunk" and "line" callbacks are optional, and the text diff of the - * files will only be calculated if they are not NULL. Of course, these - * callbacks will not be invoked for binary files on the diff list or for - * files whose only changed is a file mode change. - * - * Returning a non-zero value from any of the callbacks will terminate - * the iteration and cause this return `GIT_EUSER`. - * - * @param diff A git_diff_list generated by one of the above functions. - * @param cb_data Reference pointer that will be passed to your callbacks. - * @param file_cb Callback function to make per file in the diff. - * @param hunk_cb Optional callback to make per hunk of text diff. This - * callback is called to describe a range of lines in the - * diff. It will not be issued for binary files. - * @param line_cb Optional callback to make per line of diff text. This - * same callback will be made for context lines, added, and - * removed lines, and even for a deleted trailing newline. - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_diff_foreach( - git_diff_list *diff, - void *cb_data, - git_diff_file_fn file_cb, - git_diff_hunk_fn hunk_cb, - git_diff_data_fn line_cb); - -/** - * Create a diff iterator object that can be used to traverse a diff. - * - * This iterator can be used instead of `git_diff_foreach` in situations - * where callback functions are awkward to use. Because of the way that - * diffs are calculated internally, using an iterator will use somewhat - * more memory than `git_diff_foreach` would. - * - * @param iterator Output parameter of newly created iterator. - * @param diff Diff over which you wish to iterate. - * @return 0 on success, < 0 on error - */ -GIT_EXTERN(int) git_diff_iterator_new( - git_diff_iterator **iterator, - git_diff_list *diff); - -/** - * Release the iterator object. - * - * Call this when you are done using the iterator. - * - * @param iterator The diff iterator to be freed. - */ -GIT_EXTERN(void) git_diff_iterator_free(git_diff_iterator *iterator); - -/** - * Return progress value for traversing the diff. - * - * This returns a value between 0.0 and 1.0 that represents the progress - * through the diff iterator. The value is monotonically increasing and - * will advance gradually as you progress through the iteration. - * - * @param iterator The diff iterator - * @return Value between 0.0 and 1.0 - */ -GIT_EXTERN(float) git_diff_iterator_progress(git_diff_iterator *iterator); - -/** - * Return the number of hunks in the current file - * - * This will return the number of diff hunks in the current file. If the - * diff has not been performed yet, this may result in loading the file and - * performing the diff. - * - * @param iterator The iterator object - * @return The number of hunks in the current file or <0 on loading failure - */ -GIT_EXTERN(int) git_diff_iterator_num_hunks_in_file(git_diff_iterator *iterator); - -/** - * Return the number of lines in the hunk currently being examined. - * - * This will return the number of lines in the current hunk. If the diff - * has not been performed yet, this may result in loading the file and - * performing the diff. - * - * @param iterator The iterator object - * @return The number of lines in the current hunk (context, added, and - * removed all added together) or <0 on loading failure - */ -GIT_EXTERN(int) git_diff_iterator_num_lines_in_hunk(git_diff_iterator *iterator); - -/** - * Return the delta information for the next file in the diff. - * - * This will return a pointer to the next git_diff_delta` to be processed or - * NULL if the iterator is at the end of the diff, then advance. This - * returns the value `GIT_ITEROVER` after processing the last file. - * - * @param delta Output parameter for the next delta object - * @param iterator The iterator object - * @return 0 on success, GIT_ITEROVER when done, other value < 0 on error - */ -GIT_EXTERN(int) git_diff_iterator_next_file( - git_diff_delta **delta, - git_diff_iterator *iterator); - -/** - * Return the hunk information for the next hunk in the current file. - * - * It is recommended that you not call this if the file is a binary - * file, but it is allowed to do so. - * - * The `header` text output will contain the standard hunk header that - * would appear in diff output. The header string will be NUL terminated. - * - * WARNING! Call this function for the first time on a file is when the - * actual text diff will be computed (it cannot be computed incrementally) - * so the first call for a new file is expensive (at least in relative - * terms - in reality, it is still pretty darn fast). - * - * @param range Output pointer to range of lines covered by the hunk; - * This range object is owned by the library and should not be freed. - * @param header Output pointer to the text of the hunk header - * This string is owned by the library and should not be freed. - * @param header_len Output pointer to store the length of the header text - * @param iterator The iterator object - * @return 0 on success, GIT_ITEROVER when done with current file, other - * value < 0 on error - */ -GIT_EXTERN(int) git_diff_iterator_next_hunk( - git_diff_range **range, - const char **header, - size_t *header_len, - git_diff_iterator *iterator); - -/** - * Return the next line of the current hunk of diffs. - * - * The `line_origin` output will tell you what type of line this is - * (e.g. was it added or removed or is it just context for the diff). - * - * The `content` will be a pointer to the file data that goes in the - * line. IT WILL NOT BE NUL TERMINATED. You have to use the `content_len` - * value and only process that many bytes of data from the content string. - * - * @param line_origin Output pointer to store a GIT_DIFF_LINE value for this - * next chunk of data. The value is a single character, not a buffer. - * @param content Output pointer to store the content of the diff; this - * string is owned by the library and should not be freed. - * @param content_len Output pointer to store the length of the content. - * @param iterator The iterator object - * @return 0 on success, GIT_ITEROVER when done with current line, other - * value < 0 on error - */ -GIT_EXTERN(int) git_diff_iterator_next_line( - char *line_origin, /**< GIT_DIFF_LINE_... value from above */ - const char **content, - size_t *content_len, - git_diff_iterator *iterator); - -/** - * Iterate over a diff generating text output like "git diff --name-status". - * - * Returning a non-zero value from the callbacks will terminate the - * iteration and cause this return `GIT_EUSER`. - * - * @param diff A git_diff_list generated by one of the above functions. - * @param cb_data Reference pointer that will be passed to your callback. - * @param print_cb Callback to make per line of diff text. - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_diff_print_compact( - git_diff_list *diff, - void *cb_data, - git_diff_data_fn print_cb); - -/** - * Iterate over a diff generating text output like "git diff". - * - * This is a super easy way to generate a patch from a diff. - * - * Returning a non-zero value from the callbacks will terminate the - * iteration and cause this return `GIT_EUSER`. - * - * @param diff A git_diff_list generated by one of the above functions. - * @param cb_data Reference pointer that will be passed to your callbacks. - * @param print_cb Callback function to output lines of the diff. This - * same function will be called for file headers, hunk - * headers, and diff lines. Fortunately, you can probably - * use various GIT_DIFF_LINE constants to determine what - * text you are given. - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_diff_print_patch( - git_diff_list *diff, - void *cb_data, - git_diff_data_fn print_cb); - -/** - * Query how many diff records are there in a diff list. - * - * You can optionally pass in a `git_delta_t` value if you want a count - * of just entries that match that delta type, or pass -1 for all delta - * records. - * - * @param diff A git_diff_list generated by one of the above functions - * @param delta_t A git_delta_t value to filter the count, or -1 for all records - * @return Count of number of deltas matching delta_t type - */ -GIT_EXTERN(int) git_diff_entrycount( - git_diff_list *diff, - int delta_t); - -/**@}*/ - - -/* - * Misc - */ - -/** - * Directly run a text diff on two blobs. - * - * Compared to a file, a blob lacks some contextual information. As such, - * the `git_diff_file` parameters of the callbacks will be filled - * accordingly to the following: `mode` will be set to 0, `path` will be set - * to NULL. When dealing with a NULL blob, `oid` will be set to 0. - * - * When at least one of the blobs being dealt with is binary, the - * `git_diff_delta` binary attribute will be set to 1 and no call to the - * hunk_cb nor line_cb will be made. - * - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_diff_blobs( - git_blob *old_blob, - git_blob *new_blob, - git_diff_options *options, - void *cb_data, - git_diff_file_fn file_cb, - git_diff_hunk_fn hunk_cb, - git_diff_data_fn line_cb); - -GIT_END_DECL - -/** @} */ - -#endif diff --git a/include/git2/errors.h b/include/git2/errors.h deleted file mode 100644 index e5f435926ce..00000000000 --- a/include/git2/errors.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_errors_h__ -#define INCLUDE_git_errors_h__ - -#include "common.h" - -/** - * @file git2/errors.h - * @brief Git error handling routines and variables - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** Generic return codes */ -enum { - GIT_OK = 0, - GIT_ERROR = -1, - GIT_ENOTFOUND = -3, - GIT_EEXISTS = -4, - GIT_EAMBIGUOUS = -5, - GIT_EBUFS = -6, - GIT_EUSER = -7, - GIT_EBAREREPO = -8, - - GIT_PASSTHROUGH = -30, - GIT_ITEROVER = -31, -}; - -typedef struct { - char *message; - int klass; -} git_error; - -/** Error classes */ -typedef enum { - GITERR_NOMEMORY, - GITERR_OS, - GITERR_INVALID, - GITERR_REFERENCE, - GITERR_ZLIB, - GITERR_REPOSITORY, - GITERR_CONFIG, - GITERR_REGEX, - GITERR_ODB, - GITERR_INDEX, - GITERR_OBJECT, - GITERR_NET, - GITERR_TAG, - GITERR_TREE, - GITERR_INDEXER, - GITERR_SSL, - GITERR_SUBMODULE, -} git_error_t; - -/** - * Return the last `git_error` object that was generated for the - * current thread or NULL if no error has occurred. - * - * @return A git_error object. - */ -GIT_EXTERN(const git_error *) giterr_last(void); - -/** - * Clear the last library error that occurred for this thread. - */ -GIT_EXTERN(void) giterr_clear(void); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/ignore.h b/include/git2/ignore.h deleted file mode 100644 index f7e04e881a4..00000000000 --- a/include/git2/ignore.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_ignore_h__ -#define INCLUDE_git_ignore_h__ - -#include "common.h" -#include "types.h" - -GIT_BEGIN_DECL - -/** - * Add ignore rules for a repository. - * - * Excludesfile rules (i.e. .gitignore rules) are generally read from - * .gitignore files in the repository tree or from a shared system file - * only if a "core.excludesfile" config value is set. The library also - * keeps a set of per-repository internal ignores that can be configured - * in-memory and will not persist. This function allows you to add to - * that internal rules list. - * - * Example usage: - * - * error = git_ignore_add(myrepo, "*.c\ndir/\nFile with space\n"); - * - * This would add three rules to the ignores. - * - * @param repo The repository to add ignore rules to. - * @param rules Text of rules, a la the contents of a .gitignore file. - * It is okay to have multiple rules in the text; if so, - * each rule should be terminated with a newline. - * @return 0 on success - */ -GIT_EXTERN(int) git_ignore_add_rule( - git_repository *repo, - const char *rules); - -/** - * Clear ignore rules that were explicitly added. - * - * Clears the internal ignore rules that have been set up. This will not - * turn off the rules in .gitignore files that actually exist in the - * filesystem. - * - * @param repo The repository to remove ignore rules from. - * @return 0 on success - */ -GIT_EXTERN(int) git_ignore_clear_internal_rules( - git_repository *repo); - -/** - * Test if the ignore rules apply to a given path. - * - * This function simply checks the ignore rules to see if they would apply - * to the given file. This indicates if the file would be ignored regardless - * of whether the file is already in the index or commited to the repository. - * - * @param ignored boolean returning 0 if the file is not ignored, 1 if it is - * @param repo a repository object - * @param path the file to check ignores for, relative to the repo's workdir. - * @return 0 if ignore rules could be processed for the file (regardless - * of whether it exists or not), or an error < 0 if they could not. - */ -GIT_EXTERN(int) git_ignore_path_is_ignored( - int *ignored, - git_repository *repo, - const char *path); - -GIT_END_DECL - -#endif diff --git a/include/git2/index.h b/include/git2/index.h deleted file mode 100644 index 062932e1aa4..00000000000 --- a/include/git2/index.h +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_index_h__ -#define INCLUDE_git_index_h__ - -#include "common.h" -#include "indexer.h" -#include "types.h" -#include "oid.h" - -/** - * @file git2/index.h - * @brief Git index parsing and manipulation routines - * @defgroup git_index Git index parsing and manipulation routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -#define GIT_IDXENTRY_NAMEMASK (0x0fff) -#define GIT_IDXENTRY_STAGEMASK (0x3000) -#define GIT_IDXENTRY_EXTENDED (0x4000) -#define GIT_IDXENTRY_VALID (0x8000) -#define GIT_IDXENTRY_STAGESHIFT 12 - -/* - * Flags are divided into two parts: in-memory flags and - * on-disk ones. Flags in GIT_IDXENTRY_EXTENDED_FLAGS - * will get saved on-disk. - * - * In-memory only flags: - */ -#define GIT_IDXENTRY_UPDATE (1 << 0) -#define GIT_IDXENTRY_REMOVE (1 << 1) -#define GIT_IDXENTRY_UPTODATE (1 << 2) -#define GIT_IDXENTRY_ADDED (1 << 3) - -#define GIT_IDXENTRY_HASHED (1 << 4) -#define GIT_IDXENTRY_UNHASHED (1 << 5) -#define GIT_IDXENTRY_WT_REMOVE (1 << 6) /* remove in work directory */ -#define GIT_IDXENTRY_CONFLICTED (1 << 7) - -#define GIT_IDXENTRY_UNPACKED (1 << 8) -#define GIT_IDXENTRY_NEW_SKIP_WORKTREE (1 << 9) - -/* - * Extended on-disk flags: - */ -#define GIT_IDXENTRY_INTENT_TO_ADD (1 << 13) -#define GIT_IDXENTRY_SKIP_WORKTREE (1 << 14) -/* GIT_IDXENTRY_EXTENDED2 is for future extension */ -#define GIT_IDXENTRY_EXTENDED2 (1 << 15) - -#define GIT_IDXENTRY_EXTENDED_FLAGS (GIT_IDXENTRY_INTENT_TO_ADD | GIT_IDXENTRY_SKIP_WORKTREE) - -/** Time used in a git index entry */ -typedef struct { - git_time_t seconds; - /* nsec should not be stored as time_t compatible */ - unsigned int nanoseconds; -} git_index_time; - -/** Memory representation of a file entry in the index. */ -typedef struct git_index_entry { - git_index_time ctime; - git_index_time mtime; - - unsigned int dev; - unsigned int ino; - unsigned int mode; - unsigned int uid; - unsigned int gid; - git_off_t file_size; - - git_oid oid; - - unsigned short flags; - unsigned short flags_extended; - - char *path; -} git_index_entry; - -/** Representation of an unmerged file entry in the index. */ -typedef struct git_index_entry_unmerged { - unsigned int mode[3]; - git_oid oid[3]; - char *path; -} git_index_entry_unmerged; - -/** Capabilities of system that affect index actions. */ -enum { - GIT_INDEXCAP_IGNORE_CASE = 1, - GIT_INDEXCAP_NO_FILEMODE = 2, - GIT_INDEXCAP_NO_SYMLINKS = 4, - GIT_INDEXCAP_FROM_OWNER = ~0u -}; - -/** - * Create a new bare Git index object as a memory representation - * of the Git index file in 'index_path', without a repository - * to back it. - * - * Since there is no ODB or working directory behind this index, - * any Index methods which rely on these (e.g. index_add) will - * fail with the GIT_EBAREINDEX error code. - * - * If you need to access the index of an actual repository, - * use the `git_repository_index` wrapper. - * - * The index must be freed once it's no longer in use. - * - * @param index the pointer for the new index - * @param index_path the path to the index file in disk - * @return 0 or an error code - */ -GIT_EXTERN(int) git_index_open(git_index **index, const char *index_path); - -/** - * Clear the contents (all the entries) of an index object. - * This clears the index object in memory; changes must be manually - * written to disk for them to take effect. - * - * @param index an existing index object - */ -GIT_EXTERN(void) git_index_clear(git_index *index); - -/** - * Free an existing index object. - * - * @param index an existing index object - */ -GIT_EXTERN(void) git_index_free(git_index *index); - -/** - * Read index capabilities flags. - * - * @param index An existing index object - * @return A combination of GIT_INDEXCAP values - */ -GIT_EXTERN(unsigned int) git_index_caps(const git_index *index); - -/** - * Set index capabilities flags. - * - * If you pass `GIT_INDEXCAP_FROM_OWNER` for the caps, then the - * capabilities will be read from the config of the owner object, - * looking at `core.ignorecase`, `core.filemode`, `core.symlinks`. - * - * @param index An existing index object - * @param caps A combination of GIT_INDEXCAP values - * @return 0 on success, -1 on failure - */ -GIT_EXTERN(int) git_index_set_caps(git_index *index, unsigned int caps); - -/** - * Update the contents of an existing index object in memory - * by reading from the hard disk. - * - * @param index an existing index object - * @return 0 or an error code - */ -GIT_EXTERN(int) git_index_read(git_index *index); - -/** - * Write an existing index object from memory back to disk - * using an atomic file lock. - * - * @param index an existing index object - * @return 0 or an error code - */ -GIT_EXTERN(int) git_index_write(git_index *index); - -/** - * Find the first index of any entries which point to given - * path in the Git index. - * - * @param index an existing index object - * @param path path to search - * @return an index >= 0 if found, -1 otherwise - */ -GIT_EXTERN(int) git_index_find(git_index *index, const char *path); - -/** - * Remove all entries with equal path except last added - * - * @param index an existing index object - */ -GIT_EXTERN(void) git_index_uniq(git_index *index); - -/** - * Add or update an index entry from a file in disk - * - * The file `path` must be relative to the repository's - * working folder and must be readable. - * - * This method will fail in bare index instances. - * - * This forces the file to be added to the index, not looking - * at gitignore rules. Those rules can be evaluated through - * the git_status APIs (in status.h) before calling this. - * - * @param index an existing index object - * @param path filename to add - * @param stage stage for the entry - * @return 0 or an error code - */ -GIT_EXTERN(int) git_index_add(git_index *index, const char *path, int stage); - -/** - * Add or update an index entry from an in-memory struct - * - * A full copy (including the 'path' string) of the given - * 'source_entry' will be inserted on the index. - * - * @param index an existing index object - * @param source_entry new entry object - * @return 0 or an error code - */ -GIT_EXTERN(int) git_index_add2(git_index *index, const git_index_entry *source_entry); - -/** - * Add (append) an index entry from a file in disk - * - * A new entry will always be inserted into the index; - * if the index already contains an entry for such - * path, the old entry will **not** be replaced. - * - * The file `path` must be relative to the repository's - * working folder and must be readable. - * - * This method will fail in bare index instances. - * - * @param index an existing index object - * @param path filename to add - * @param stage stage for the entry - * @return 0 or an error code - */ -GIT_EXTERN(int) git_index_append(git_index *index, const char *path, int stage); - -/** - * Add (append) an index entry from an in-memory struct - * - * A new entry will always be inserted into the index; - * if the index already contains an entry for the path - * in the `entry` struct, the old entry will **not** be - * replaced. - * - * A full copy (including the 'path' string) of the given - * 'source_entry' will be inserted on the index. - * - * @param index an existing index object - * @param source_entry new entry object - * @return 0 or an error code - */ -GIT_EXTERN(int) git_index_append2(git_index *index, const git_index_entry *source_entry); - -/** - * Remove an entry from the index - * - * @param index an existing index object - * @param position position of the entry to remove - * @return 0 or an error code - */ -GIT_EXTERN(int) git_index_remove(git_index *index, int position); - - -/** - * Get a pointer to one of the entries in the index - * - * This entry can be modified, and the changes will be written - * back to disk on the next write() call. - * - * The entry should not be freed by the caller. - * - * @param index an existing index object - * @param n the position of the entry - * @return a pointer to the entry; NULL if out of bounds - */ -GIT_EXTERN(git_index_entry *) git_index_get(git_index *index, size_t n); - -/** - * Get the count of entries currently in the index - * - * @param index an existing index object - * @return integer of count of current entries - */ -GIT_EXTERN(unsigned int) git_index_entrycount(git_index *index); - -/** - * Get the count of unmerged entries currently in the index - * - * @param index an existing index object - * @return integer of count of current unmerged entries - */ -GIT_EXTERN(unsigned int) git_index_entrycount_unmerged(git_index *index); - -/** - * Get an unmerged entry from the index. - * - * The returned entry is read-only and should not be modified - * of freed by the caller. - * - * @param index an existing index object - * @param path path to search - * @return the unmerged entry; NULL if not found - */ -GIT_EXTERN(const git_index_entry_unmerged *) git_index_get_unmerged_bypath(git_index *index, const char *path); - -/** - * Get an unmerged entry from the index. - * - * The returned entry is read-only and should not be modified - * of freed by the caller. - * - * @param index an existing index object - * @param n the position of the entry - * @return a pointer to the unmerged entry; NULL if out of bounds - */ -GIT_EXTERN(const git_index_entry_unmerged *) git_index_get_unmerged_byindex(git_index *index, size_t n); - -/** - * Return the stage number from a git index entry - * - * This entry is calculated from the entry's flag - * attribute like this: - * - * (entry->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT - * - * @param entry The entry - * @returns the stage number - */ -GIT_EXTERN(int) git_index_entry_stage(const git_index_entry *entry); - -/** - * Read a tree into the index file with stats - * - * The current index contents will be replaced by the specified tree. The total - * node count is collected in stats. - * - * @param index an existing index object - * @param tree tree to read - * @param stats structure that receives the total node count (may be NULL) - * @return 0 or an error code - */ -GIT_EXTERN(int) git_index_read_tree(git_index *index, git_tree *tree, git_indexer_stats *stats); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/indexer.h b/include/git2/indexer.h deleted file mode 100644 index 87f48fe277c..00000000000 --- a/include/git2/indexer.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef _INCLUDE_git_indexer_h__ -#define _INCLUDE_git_indexer_h__ - -#include "common.h" -#include "oid.h" - -GIT_BEGIN_DECL - -/** - * This is passed as the first argument to the callback to allow the - * user to see the progress. - */ -typedef struct git_indexer_stats { - unsigned int total; - unsigned int processed; - unsigned int received; -} git_indexer_stats; - - -typedef struct git_indexer git_indexer; -typedef struct git_indexer_stream git_indexer_stream; - -/** - * Create a new streaming indexer instance - * - * @param out where to store the indexer instance - * @param path to the directory where the packfile should be stored - */ -GIT_EXTERN(int) git_indexer_stream_new(git_indexer_stream **out, const char *path); - -/** - * Add data to the indexer - * - * @param idx the indexer - * @param data the data to add - * @param size the size of the data - * @param stats stat storage - */ -GIT_EXTERN(int) git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t size, git_indexer_stats *stats); - -/** - * Finalize the pack and index - * - * Resolve any pending deltas and write out the index file - * - * @param idx the indexer - */ -GIT_EXTERN(int) git_indexer_stream_finalize(git_indexer_stream *idx, git_indexer_stats *stats); - -/** - * Get the packfile's hash - * - * A packfile's name is derived from the sorted hashing of all object - * names. This is only correct after the index has been finalized. - * - * @param idx the indexer instance - */ -GIT_EXTERN(const git_oid *) git_indexer_stream_hash(git_indexer_stream *idx); - -/** - * Free the indexer and its resources - * - * @param idx the indexer to free - */ -GIT_EXTERN(void) git_indexer_stream_free(git_indexer_stream *idx); - -/** - * Create a new indexer instance - * - * @param out where to store the indexer instance - * @param packname the absolute filename of the packfile to index - */ -GIT_EXTERN(int) git_indexer_new(git_indexer **out, const char *packname); - -/** - * Iterate over the objects in the packfile and extract the information - * - * Indexing a packfile can be very expensive so this function is - * expected to be run in a worker thread and the stats used to provide - * feedback the user. - * - * @param idx the indexer instance - * @param stats storage for the running state - */ -GIT_EXTERN(int) git_indexer_run(git_indexer *idx, git_indexer_stats *stats); - -/** - * Write the index file to disk. - * - * The file will be stored as pack-$hash.idx in the same directory as - * the packfile. - * - * @param idx the indexer instance - */ -GIT_EXTERN(int) git_indexer_write(git_indexer *idx); - -/** - * Get the packfile's hash - * - * A packfile's name is derived from the sorted hashing of all object - * names. This is only correct after the index has been written to disk. - * - * @param idx the indexer instance - */ -GIT_EXTERN(const git_oid *) git_indexer_hash(git_indexer *idx); - -/** - * Free the indexer and its resources - * - * @param idx the indexer to free - */ -GIT_EXTERN(void) git_indexer_free(git_indexer *idx); - -GIT_END_DECL - -#endif diff --git a/include/git2/inttypes.h b/include/git2/inttypes.h deleted file mode 100644 index ead903f78e4..00000000000 --- a/include/git2/inttypes.h +++ /dev/null @@ -1,305 +0,0 @@ -// ISO C9x compliant inttypes.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006 Alexander Chemeris -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. The name of the author may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] - -#ifndef _MSC_INTTYPES_H_ // [ -#define _MSC_INTTYPES_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#include "stdint.h" - -// 7.8 Format conversion of integer types - -typedef struct { - intmax_t quot; - intmax_t rem; -} imaxdiv_t; - -// 7.8.1 Macros for format specifiers - -#if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198 - -// The fprintf macros for signed integers are: -#define PRId8 "d" -#define PRIi8 "i" -#define PRIdLEAST8 "d" -#define PRIiLEAST8 "i" -#define PRIdFAST8 "d" -#define PRIiFAST8 "i" - -#define PRId16 "hd" -#define PRIi16 "hi" -#define PRIdLEAST16 "hd" -#define PRIiLEAST16 "hi" -#define PRIdFAST16 "hd" -#define PRIiFAST16 "hi" - -#define PRId32 "I32d" -#define PRIi32 "I32i" -#define PRIdLEAST32 "I32d" -#define PRIiLEAST32 "I32i" -#define PRIdFAST32 "I32d" -#define PRIiFAST32 "I32i" - -#define PRId64 "I64d" -#define PRIi64 "I64i" -#define PRIdLEAST64 "I64d" -#define PRIiLEAST64 "I64i" -#define PRIdFAST64 "I64d" -#define PRIiFAST64 "I64i" - -#define PRIdMAX "I64d" -#define PRIiMAX "I64i" - -#define PRIdPTR "Id" -#define PRIiPTR "Ii" - -// The fprintf macros for unsigned integers are: -#define PRIo8 "o" -#define PRIu8 "u" -#define PRIx8 "x" -#define PRIX8 "X" -#define PRIoLEAST8 "o" -#define PRIuLEAST8 "u" -#define PRIxLEAST8 "x" -#define PRIXLEAST8 "X" -#define PRIoFAST8 "o" -#define PRIuFAST8 "u" -#define PRIxFAST8 "x" -#define PRIXFAST8 "X" - -#define PRIo16 "ho" -#define PRIu16 "hu" -#define PRIx16 "hx" -#define PRIX16 "hX" -#define PRIoLEAST16 "ho" -#define PRIuLEAST16 "hu" -#define PRIxLEAST16 "hx" -#define PRIXLEAST16 "hX" -#define PRIoFAST16 "ho" -#define PRIuFAST16 "hu" -#define PRIxFAST16 "hx" -#define PRIXFAST16 "hX" - -#define PRIo32 "I32o" -#define PRIu32 "I32u" -#define PRIx32 "I32x" -#define PRIX32 "I32X" -#define PRIoLEAST32 "I32o" -#define PRIuLEAST32 "I32u" -#define PRIxLEAST32 "I32x" -#define PRIXLEAST32 "I32X" -#define PRIoFAST32 "I32o" -#define PRIuFAST32 "I32u" -#define PRIxFAST32 "I32x" -#define PRIXFAST32 "I32X" - -#define PRIo64 "I64o" -#define PRIu64 "I64u" -#define PRIx64 "I64x" -#define PRIX64 "I64X" -#define PRIoLEAST64 "I64o" -#define PRIuLEAST64 "I64u" -#define PRIxLEAST64 "I64x" -#define PRIXLEAST64 "I64X" -#define PRIoFAST64 "I64o" -#define PRIuFAST64 "I64u" -#define PRIxFAST64 "I64x" -#define PRIXFAST64 "I64X" - -#define PRIoMAX "I64o" -#define PRIuMAX "I64u" -#define PRIxMAX "I64x" -#define PRIXMAX "I64X" - -#define PRIoPTR "Io" -#define PRIuPTR "Iu" -#define PRIxPTR "Ix" -#define PRIXPTR "IX" - -// The fscanf macros for signed integers are: -#define SCNd8 "d" -#define SCNi8 "i" -#define SCNdLEAST8 "d" -#define SCNiLEAST8 "i" -#define SCNdFAST8 "d" -#define SCNiFAST8 "i" - -#define SCNd16 "hd" -#define SCNi16 "hi" -#define SCNdLEAST16 "hd" -#define SCNiLEAST16 "hi" -#define SCNdFAST16 "hd" -#define SCNiFAST16 "hi" - -#define SCNd32 "ld" -#define SCNi32 "li" -#define SCNdLEAST32 "ld" -#define SCNiLEAST32 "li" -#define SCNdFAST32 "ld" -#define SCNiFAST32 "li" - -#define SCNd64 "I64d" -#define SCNi64 "I64i" -#define SCNdLEAST64 "I64d" -#define SCNiLEAST64 "I64i" -#define SCNdFAST64 "I64d" -#define SCNiFAST64 "I64i" - -#define SCNdMAX "I64d" -#define SCNiMAX "I64i" - -#ifdef _WIN64 // [ -# define SCNdPTR "I64d" -# define SCNiPTR "I64i" -#else // _WIN64 ][ -# define SCNdPTR "ld" -# define SCNiPTR "li" -#endif // _WIN64 ] - -// The fscanf macros for unsigned integers are: -#define SCNo8 "o" -#define SCNu8 "u" -#define SCNx8 "x" -#define SCNX8 "X" -#define SCNoLEAST8 "o" -#define SCNuLEAST8 "u" -#define SCNxLEAST8 "x" -#define SCNXLEAST8 "X" -#define SCNoFAST8 "o" -#define SCNuFAST8 "u" -#define SCNxFAST8 "x" -#define SCNXFAST8 "X" - -#define SCNo16 "ho" -#define SCNu16 "hu" -#define SCNx16 "hx" -#define SCNX16 "hX" -#define SCNoLEAST16 "ho" -#define SCNuLEAST16 "hu" -#define SCNxLEAST16 "hx" -#define SCNXLEAST16 "hX" -#define SCNoFAST16 "ho" -#define SCNuFAST16 "hu" -#define SCNxFAST16 "hx" -#define SCNXFAST16 "hX" - -#define SCNo32 "lo" -#define SCNu32 "lu" -#define SCNx32 "lx" -#define SCNX32 "lX" -#define SCNoLEAST32 "lo" -#define SCNuLEAST32 "lu" -#define SCNxLEAST32 "lx" -#define SCNXLEAST32 "lX" -#define SCNoFAST32 "lo" -#define SCNuFAST32 "lu" -#define SCNxFAST32 "lx" -#define SCNXFAST32 "lX" - -#define SCNo64 "I64o" -#define SCNu64 "I64u" -#define SCNx64 "I64x" -#define SCNX64 "I64X" -#define SCNoLEAST64 "I64o" -#define SCNuLEAST64 "I64u" -#define SCNxLEAST64 "I64x" -#define SCNXLEAST64 "I64X" -#define SCNoFAST64 "I64o" -#define SCNuFAST64 "I64u" -#define SCNxFAST64 "I64x" -#define SCNXFAST64 "I64X" - -#define SCNoMAX "I64o" -#define SCNuMAX "I64u" -#define SCNxMAX "I64x" -#define SCNXMAX "I64X" - -#ifdef _WIN64 // [ -# define SCNoPTR "I64o" -# define SCNuPTR "I64u" -# define SCNxPTR "I64x" -# define SCNXPTR "I64X" -#else // _WIN64 ][ -# define SCNoPTR "lo" -# define SCNuPTR "lu" -# define SCNxPTR "lx" -# define SCNXPTR "lX" -#endif // _WIN64 ] - -#endif // __STDC_FORMAT_MACROS ] - -// 7.8.2 Functions for greatest-width integer types - -// 7.8.2.1 The imaxabs function -#define imaxabs _abs64 - -// 7.8.2.2 The imaxdiv function - -// This is modified version of div() function from Microsoft's div.c found -// in %MSVC.NET%\crt\src\div.c -#ifdef STATIC_IMAXDIV // [ -static -#else // STATIC_IMAXDIV ][ -_inline -#endif // STATIC_IMAXDIV ] -imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom) -{ - imaxdiv_t result; - - result.quot = numer / denom; - result.rem = numer % denom; - - if (numer < 0 && result.rem > 0) { - // did division wrong; must fix up - ++result.quot; - result.rem -= denom; - } - - return result; -} - -// 7.8.2.3 The strtoimax and strtoumax functions -#define strtoimax _strtoi64 -#define strtoumax _strtoui64 - -// 7.8.2.4 The wcstoimax and wcstoumax functions -#define wcstoimax _wcstoi64 -#define wcstoumax _wcstoui64 - - -#endif // _MSC_INTTYPES_H_ ] diff --git a/include/git2/merge.h b/include/git2/merge.h deleted file mode 100644 index 37b1c787d41..00000000000 --- a/include/git2/merge.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_merge_h__ -#define INCLUDE_git_merge_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" - -/** - * @file git2/merge.h - * @brief Git merge-base routines - * @defgroup git_revwalk Git merge-base routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Find a merge base between two commits - * - * @param out the OID of a merge base between 'one' and 'two' - * @param repo the repository where the commits exist - * @param one one of the commits - * @param two the other commit - */ -GIT_EXTERN(int) git_merge_base(git_oid *out, git_repository *repo, const git_oid *one, const git_oid *two); - -/** - * Find a merge base given a list of commits - * - * @param out the OID of a merge base considering all the commits - * @param repo the repository where the commits exist - * @param input_array oids of the commits - * @param length The number of commits in the provided `input_array` - */ -GIT_EXTERN(int) git_merge_base_many(git_oid *out, git_repository *repo, const git_oid input_array[], size_t length); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/message.h b/include/git2/message.h deleted file mode 100644 index b42cb76777f..00000000000 --- a/include/git2/message.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_message_h__ -#define INCLUDE_git_message_h__ - -#include "common.h" - -/** - * @file git2/message.h - * @brief Git message management routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Clean up message from excess whitespace and make sure that the last line - * ends with a '\n'. - * - * Optionally, can remove lines starting with a "#". - * - * @param message_out The user allocated buffer which will be filled with - * the cleaned up message. Pass NULL if you just want to get the size of the - * prettified message as the output value. - * - * @param size The size of the allocated buffer message_out. - * - * @param message The message to be prettified. - * - * @param strip_comments 1 to remove lines starting with a "#", 0 otherwise. - * - * @return -1 on error, else number of characters in prettified message - * including the trailing NUL byte - */ -GIT_EXTERN(int) git_message_prettify(char *message_out, size_t buffer_size, const char *message, int strip_comments); - -/** @} */ -GIT_END_DECL -#endif /* INCLUDE_git_message_h__ */ diff --git a/include/git2/net.h b/include/git2/net.h deleted file mode 100644 index c2301b6f14b..00000000000 --- a/include/git2/net.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_net_h__ -#define INCLUDE_net_h__ - -#include "common.h" -#include "oid.h" -#include "types.h" - -/** - * @file git2/net.h - * @brief Git networking declarations - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -#define GIT_DEFAULT_PORT "9418" - -/* - * We need this because we need to know whether we should call - * git-upload-pack or git-receive-pack on the remote end when get_refs - * gets called. - */ - -#define GIT_DIR_FETCH 0 -#define GIT_DIR_PUSH 1 - - -/** - * Remote head description, given out on `ls` calls. - */ -struct git_remote_head { - int local:1; /* available locally */ - git_oid oid; - git_oid loid; - char *name; -}; - -/** - * Callback for listing the remote heads - */ -typedef int (*git_headlist_cb)(git_remote_head *, void *); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/notes.h b/include/git2/notes.h deleted file mode 100644 index af480a40818..00000000000 --- a/include/git2/notes.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_note_h__ -#define INCLUDE_git_note_h__ - -#include "oid.h" - -/** - * @file git2/notes.h - * @brief Git notes management routines - * @defgroup git_note Git notes management routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Read the note for an object - * - * The note must be freed manually by the user. - * - * @param note pointer to the read note; NULL in case of error - * @param repo repository where to look up the note - * @param notes_ref canonical name of the reference to use (optional); - * defaults to "refs/notes/commits" - * @param oid OID of the git object to read the note from - * - * @return 0 or an error code - */ -GIT_EXTERN(int) git_note_read(git_note **note, git_repository *repo, - const char *notes_ref, const git_oid *oid); - -/** - * Get the note message - * - * @param note - * @return the note message - */ -GIT_EXTERN(const char *) git_note_message(git_note *note); - - -/** - * Get the note object OID - * - * @param note - * @return the note object OID - */ -GIT_EXTERN(const git_oid *) git_note_oid(git_note *note); - -/** - * Add a note for an object - * - * @param out pointer to store the OID (optional); NULL in case of error - * @param repo repository where to store the note - * @param author signature of the notes commit author - * @param committer signature of the notes commit committer - * @param notes_ref canonical name of the reference to use (optional); - * defaults to "refs/notes/commits" - * @param oid OID of the git object to decorate - * @param note Content of the note to add for object oid - * - * @return 0 or an error code - */ -GIT_EXTERN(int) git_note_create(git_oid *out, git_repository *repo, - git_signature *author, git_signature *committer, - const char *notes_ref, const git_oid *oid, - const char *note); - - -/** - * Remove the note for an object - * - * @param repo repository where the note lives - * @param notes_ref canonical name of the reference to use (optional); - * defaults to "refs/notes/commits" - * @param author signature of the notes commit author - * @param committer signature of the notes commit committer - * @param oid OID of the git object to remove the note from - * - * @return 0 or an error code - */ -GIT_EXTERN(int) git_note_remove(git_repository *repo, const char *notes_ref, - git_signature *author, git_signature *committer, - const git_oid *oid); - -/** - * Free a git_note object - * - * @param note git_note object - */ -GIT_EXTERN(void) git_note_free(git_note *note); - -/** - * Get the default notes reference for a repository - * - * @param out Pointer to the default notes reference - * @param repo The Git repository - * - * @return 0 or an error code - */ -GIT_EXTERN(int) git_note_default_ref(const char **out, git_repository *repo); - -/** - * Basic components of a note - * - * - Oid of the blob containing the message - * - Oid of the git object being annotated - */ -typedef struct { - git_oid blob_oid; - git_oid annotated_object_oid; -} git_note_data; - -/** - * Loop over all the notes within a specified namespace - * and issue a callback for each one. - * - * @param repo Repository where to find the notes. - * - * @param notes_ref Reference to read from (optional); defaults to - * "refs/notes/commits". - * - * @param note_cb Callback to invoke per found annotation. Return non-zero - * to stop looping. - * - * @param payload Extra parameter to callback function. - * - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_note_foreach( - git_repository *repo, - const char *notes_ref, - int (*note_cb)(git_note_data *note_data, void *payload), - void *payload -); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/object.h b/include/git2/object.h deleted file mode 100644 index fd6ae95c142..00000000000 --- a/include/git2/object.h +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_object_h__ -#define INCLUDE_git_object_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" - -/** - * @file git2/object.h - * @brief Git revision object management routines - * @defgroup git_object Git revision object management routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Lookup a reference to one of the objects in a repository. - * - * The generated reference is owned by the repository and - * should be closed with the `git_object_free` method - * instead of free'd manually. - * - * The 'type' parameter must match the type of the object - * in the odb; the method will fail otherwise. - * The special value 'GIT_OBJ_ANY' may be passed to let - * the method guess the object's type. - * - * @param object pointer to the looked-up object - * @param repo the repository to look up the object - * @param id the unique identifier for the object - * @param type the type of the object - * @return a reference to the object - */ -GIT_EXTERN(int) git_object_lookup( - git_object **object, - git_repository *repo, - const git_oid *id, - git_otype type); - -/** - * Lookup a reference to one of the objects in a repository, - * given a prefix of its identifier (short id). - * - * The object obtained will be so that its identifier - * matches the first 'len' hexadecimal characters - * (packets of 4 bits) of the given 'id'. - * 'len' must be at least GIT_OID_MINPREFIXLEN, and - * long enough to identify a unique object matching - * the prefix; otherwise the method will fail. - * - * The generated reference is owned by the repository and - * should be closed with the `git_object_free` method - * instead of free'd manually. - * - * The 'type' parameter must match the type of the object - * in the odb; the method will fail otherwise. - * The special value 'GIT_OBJ_ANY' may be passed to let - * the method guess the object's type. - * - * @param object_out pointer where to store the looked-up object - * @param repo the repository to look up the object - * @param id a short identifier for the object - * @param len the length of the short identifier - * @param type the type of the object - * @return 0 or an error code - */ -GIT_EXTERN(int) git_object_lookup_prefix( - git_object **object_out, - git_repository *repo, - const git_oid *id, - size_t len, - git_otype type); - -/** - * Get the id (SHA1) of a repository object - * - * @param obj the repository object - * @return the SHA1 id - */ -GIT_EXTERN(const git_oid *) git_object_id(const git_object *obj); - -/** - * Get the object type of an object - * - * @param obj the repository object - * @return the object's type - */ -GIT_EXTERN(git_otype) git_object_type(const git_object *obj); - -/** - * Get the repository that owns this object - * - * Freeing or calling `git_repository_close` on the - * returned pointer will invalidate the actual object. - * - * Any other operation may be run on the repository without - * affecting the object. - * - * @param obj the object - * @return the repository who owns this object - */ -GIT_EXTERN(git_repository *) git_object_owner(const git_object *obj); - -/** - * Close an open object - * - * This method instructs the library to close an existing - * object; note that git_objects are owned and cached by the repository - * so the object may or may not be freed after this library call, - * depending on how aggressive is the caching mechanism used - * by the repository. - * - * IMPORTANT: - * It *is* necessary to call this method when you stop using - * an object. Failure to do so will cause a memory leak. - * - * @param object the object to close - */ -GIT_EXTERN(void) git_object_free(git_object *object); - -/** - * Convert an object type to it's string representation. - * - * The result is a pointer to a string in static memory and - * should not be free()'ed. - * - * @param type object type to convert. - * @return the corresponding string representation. - */ -GIT_EXTERN(const char *) git_object_type2string(git_otype type); - -/** - * Convert a string object type representation to it's git_otype. - * - * @param str the string to convert. - * @return the corresponding git_otype. - */ -GIT_EXTERN(git_otype) git_object_string2type(const char *str); - -/** - * Determine if the given git_otype is a valid loose object type. - * - * @param type object type to test. - * @return true if the type represents a valid loose object type, - * false otherwise. - */ -GIT_EXTERN(int) git_object_typeisloose(git_otype type); - -/** - * Get the size in bytes for the structure which - * acts as an in-memory representation of any given - * object type. - * - * For all the core types, this would the equivalent - * of calling `sizeof(git_commit)` if the core types - * were not opaque on the external API. - * - * @param type object type to get its size - * @return size in bytes of the object - */ -GIT_EXTERN(size_t) git_object__size(git_otype type); - -/** - * Recursively peel an object until an object of the specified type is met. - * - * The retrieved `peeled` object is owned by the repository and should be - * closed with the `git_object_free` method. - * - * If you pass `GIT_OBJ_ANY` as the target type, then the object will be - * peeled until the type changes (e.g. a tag will be chased until the - * referenced object is no longer a tag). - * - * @param peeled Pointer to the peeled git_object - * @param object The object to be processed - * @param target_type The type of the requested object - * @return 0 or an error code - */ -GIT_EXTERN(int) git_object_peel( - git_object **peeled, - git_object *object, - git_otype target_type); - -/** @} */ -GIT_END_DECL - -#endif diff --git a/include/git2/odb.h b/include/git2/odb.h deleted file mode 100644 index c6e73571b27..00000000000 --- a/include/git2/odb.h +++ /dev/null @@ -1,348 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_odb_h__ -#define INCLUDE_git_odb_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" -#include "odb_backend.h" - -/** - * @file git2/odb.h - * @brief Git object database routines - * @defgroup git_odb Git object database routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Create a new object database with no backends. - * - * Before the ODB can be used for read/writing, a custom database - * backend must be manually added using `git_odb_add_backend()` - * - * @param out location to store the database pointer, if opened. - * Set to NULL if the open failed. - * @return 0 or an error code - */ -GIT_EXTERN(int) git_odb_new(git_odb **out); - -/** - * Create a new object database and automatically add - * the two default backends: - * - * - git_odb_backend_loose: read and write loose object files - * from disk, assuming `objects_dir` as the Objects folder - * - * - git_odb_backend_pack: read objects from packfiles, - * assuming `objects_dir` as the Objects folder which - * contains a 'pack/' folder with the corresponding data - * - * @param out location to store the database pointer, if opened. - * Set to NULL if the open failed. - * @param objects_dir path of the backends' "objects" directory. - * @return 0 or an error code - */ -GIT_EXTERN(int) git_odb_open(git_odb **out, const char *objects_dir); - -/** - * Add a custom backend to an existing Object DB - * - * The backends are checked in relative ordering, based on the - * value of the `priority` parameter. - * - * Read for more information. - * - * @param odb database to add the backend to - * @param backend pointer to a git_odb_backend instance - * @param priority Value for ordering the backends queue - * @return 0 on success; error code otherwise - */ -GIT_EXTERN(int) git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int priority); - -/** - * Add a custom backend to an existing Object DB; this - * backend will work as an alternate. - * - * Alternate backends are always checked for objects *after* - * all the main backends have been exhausted. - * - * The backends are checked in relative ordering, based on the - * value of the `priority` parameter. - * - * Writing is disabled on alternate backends. - * - * Read for more information. - * - * @param odb database to add the backend to - * @param backend pointer to a git_odb_backend instance - * @param priority Value for ordering the backends queue - * @return 0 on success; error code otherwise - */ -GIT_EXTERN(int) git_odb_add_alternate(git_odb *odb, git_odb_backend *backend, int priority); - -/** - * Close an open object database. - * - * @param db database pointer to close. If NULL no action is taken. - */ -GIT_EXTERN(void) git_odb_free(git_odb *db); - -/** - * Read an object from the database. - * - * This method queries all available ODB backends - * trying to read the given OID. - * - * The returned object is reference counted and - * internally cached, so it should be closed - * by the user once it's no longer in use. - * - * @param out pointer where to store the read object - * @param db database to search for the object in. - * @param id identity of the object to read. - * @return - * - 0 if the object was read; - * - GIT_ENOTFOUND if the object is not in the database. - */ -GIT_EXTERN(int) git_odb_read(git_odb_object **out, git_odb *db, const git_oid *id); - -/** - * Read an object from the database, given a prefix - * of its identifier. - * - * This method queries all available ODB backends - * trying to match the 'len' first hexadecimal - * characters of the 'short_id'. - * The remaining (GIT_OID_HEXSZ-len)*4 bits of - * 'short_id' must be 0s. - * 'len' must be at least GIT_OID_MINPREFIXLEN, - * and the prefix must be long enough to identify - * a unique object in all the backends; the - * method will fail otherwise. - * - * The returned object is reference counted and - * internally cached, so it should be closed - * by the user once it's no longer in use. - * - * @param out pointer where to store the read object - * @param db database to search for the object in. - * @param short_id a prefix of the id of the object to read. - * @param len the length of the prefix - * @return 0 if the object was read; - * GIT_ENOTFOUND if the object is not in the database. - * GIT_EAMBIGUOUS if the prefix is ambiguous (several objects match the prefix) - */ -GIT_EXTERN(int) git_odb_read_prefix(git_odb_object **out, git_odb *db, const git_oid *short_id, size_t len); - -/** - * Read the header of an object from the database, without - * reading its full contents. - * - * The header includes the length and the type of an object. - * - * Note that most backends do not support reading only the header - * of an object, so the whole object will be read and then the - * header will be returned. - * - * @param len_p pointer where to store the length - * @param type_p pointer where to store the type - * @param db database to search for the object in. - * @param id identity of the object to read. - * @return - * - 0 if the object was read; - * - GIT_ENOTFOUND if the object is not in the database. - */ -GIT_EXTERN(int) git_odb_read_header(size_t *len_p, git_otype *type_p, git_odb *db, const git_oid *id); - -/** - * Determine if the given object can be found in the object database. - * - * @param db database to be searched for the given object. - * @param id the object to search for. - * @return - * - 1, if the object was found - * - 0, otherwise - */ -GIT_EXTERN(int) git_odb_exists(git_odb *db, const git_oid *id); - -/** - * List all objects available in the database - * - * The callback will be called for each object available in the - * database. Note that the objects are likely to be returned in the index - * order, which would make accessing the objects in that order inefficient. - * Return a non-zero value from the callback to stop looping. - * - * @param db database to use - * @param cb the callback to call for each object - * @param data data to pass to the callback - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_odb_foreach(git_odb *db, int (*cb)(git_oid *oid, void *data), void *data); - -/** - * Write an object directly into the ODB - * - * This method writes a full object straight into the ODB. - * For most cases, it is preferred to write objects through a write - * stream, which is both faster and less memory intensive, specially - * for big objects. - * - * This method is provided for compatibility with custom backends - * which are not able to support streaming writes - * - * @param oid pointer to store the OID result of the write - * @param odb object database where to store the object - * @param data buffer with the data to store - * @param len size of the buffer - * @param type type of the data to store - * @return 0 or an error code - */ -GIT_EXTERN(int) git_odb_write(git_oid *oid, git_odb *odb, const void *data, size_t len, git_otype type); - -/** - * Open a stream to write an object into the ODB - * - * The type and final length of the object must be specified - * when opening the stream. - * - * The returned stream will be of type `GIT_STREAM_WRONLY` and - * will have the following methods: - * - * - stream->write: write `n` bytes into the stream - * - stream->finalize_write: close the stream and store the object in - * the odb - * - stream->free: free the stream - * - * The streaming write won't be effective until `stream->finalize_write` - * is called and returns without an error - * - * The stream must always be free'd or will leak memory. - * - * @see git_odb_stream - * - * @param stream pointer where to store the stream - * @param db object database where the stream will write - * @param size final size of the object that will be written - * @param type type of the object that will be written - * @return 0 if the stream was created; error code otherwise - */ -GIT_EXTERN(int) git_odb_open_wstream(git_odb_stream **stream, git_odb *db, size_t size, git_otype type); - -/** - * Open a stream to read an object from the ODB - * - * Note that most backends do *not* support streaming reads - * because they store their objects as compressed/delta'ed blobs. - * - * It's recommended to use `git_odb_read` instead, which is - * assured to work on all backends. - * - * The returned stream will be of type `GIT_STREAM_RDONLY` and - * will have the following methods: - * - * - stream->read: read `n` bytes from the stream - * - stream->free: free the stream - * - * The stream must always be free'd or will leak memory. - * - * @see git_odb_stream - * - * @param stream pointer where to store the stream - * @param db object database where the stream will read from - * @param oid oid of the object the stream will read from - * @return 0 if the stream was created; error code otherwise - */ -GIT_EXTERN(int) git_odb_open_rstream(git_odb_stream **stream, git_odb *db, const git_oid *oid); - -/** - * Determine the object-ID (sha1 hash) of a data buffer - * - * The resulting SHA-1 OID will be the identifier for the data - * buffer as if the data buffer it were to written to the ODB. - * - * @param id the resulting object-ID. - * @param data data to hash - * @param len size of the data - * @param type of the data to hash - * @return 0 or an error code - */ -GIT_EXTERN(int) git_odb_hash(git_oid *id, const void *data, size_t len, git_otype type); - -/** - * Read a file from disk and fill a git_oid with the object id - * that the file would have if it were written to the Object - * Database as an object of the given type (w/o applying filters). - * Similar functionality to git.git's `git hash-object` without - * the `-w` flag, however, with the --no-filters flag. - * If you need filters, see git_repository_hashfile. - * - * @param out oid structure the result is written into. - * @param path file to read and determine object id for - * @param type the type of the object that will be hashed - * @return 0 or an error code - */ -GIT_EXTERN(int) git_odb_hashfile(git_oid *out, const char *path, git_otype type); - -/** - * Close an ODB object - * - * This method must always be called once a `git_odb_object` is no - * longer needed, otherwise memory will leak. - * - * @param object object to close - */ -GIT_EXTERN(void) git_odb_object_free(git_odb_object *object); - -/** - * Return the OID of an ODB object - * - * This is the OID from which the object was read from - * - * @param object the object - * @return a pointer to the OID - */ -GIT_EXTERN(const git_oid *) git_odb_object_id(git_odb_object *object); - -/** - * Return the data of an ODB object - * - * This is the uncompressed, raw data as read from the ODB, - * without the leading header. - * - * This pointer is owned by the object and shall not be free'd. - * - * @param object the object - * @return a pointer to the data - */ -GIT_EXTERN(const void *) git_odb_object_data(git_odb_object *object); - -/** - * Return the size of an ODB object - * - * This is the real size of the `data` buffer, not the - * actual size of the object. - * - * @param object the object - * @return the size - */ -GIT_EXTERN(size_t) git_odb_object_size(git_odb_object *object); - -/** - * Return the type of an ODB object - * - * @param object the object - * @return the type - */ -GIT_EXTERN(git_otype) git_odb_object_type(git_odb_object *object); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/odb_backend.h b/include/git2/odb_backend.h deleted file mode 100644 index cb806978782..00000000000 --- a/include/git2/odb_backend.h +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_odb_backend_h__ -#define INCLUDE_git_odb_backend_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" - -/** - * @file git2/backend.h - * @brief Git custom backend functions - * @defgroup git_backend Git custom backend API - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -struct git_odb_stream; - -/** An instance for a custom backend */ -struct git_odb_backend { - git_odb *odb; - - /* read and read_prefix each return to libgit2 a buffer which - * will be freed later. The buffer should be allocated using - * the function git_odb_backend_malloc to ensure that it can - * be safely freed later. */ - int (* read)( - void **, size_t *, git_otype *, - struct git_odb_backend *, - const git_oid *); - - /* To find a unique object given a prefix - * of its oid. - * The oid given must be so that the - * remaining (GIT_OID_HEXSZ - len)*4 bits - * are 0s. - */ - int (* read_prefix)( - git_oid *, - void **, size_t *, git_otype *, - struct git_odb_backend *, - const git_oid *, - size_t); - - int (* read_header)( - size_t *, git_otype *, - struct git_odb_backend *, - const git_oid *); - - int (* write)( - git_oid *, - struct git_odb_backend *, - const void *, - size_t, - git_otype); - - int (* writestream)( - struct git_odb_stream **, - struct git_odb_backend *, - size_t, - git_otype); - - int (* readstream)( - struct git_odb_stream **, - struct git_odb_backend *, - const git_oid *); - - int (* exists)( - struct git_odb_backend *, - const git_oid *); - - int (*foreach)( - struct git_odb_backend *, - int (*cb)(git_oid *oid, void *data), - void *data - ); - - void (* free)(struct git_odb_backend *); -}; - -/** Streaming mode */ -enum { - GIT_STREAM_RDONLY = (1 << 1), - GIT_STREAM_WRONLY = (1 << 2), - GIT_STREAM_RW = (GIT_STREAM_RDONLY | GIT_STREAM_WRONLY), -}; - -/** A stream to read/write from a backend */ -struct git_odb_stream { - struct git_odb_backend *backend; - int mode; - - int (*read)(struct git_odb_stream *stream, char *buffer, size_t len); - int (*write)(struct git_odb_stream *stream, const char *buffer, size_t len); - int (*finalize_write)(git_oid *oid_p, struct git_odb_stream *stream); - void (*free)(struct git_odb_stream *stream); -}; - -GIT_EXTERN(int) git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir); -GIT_EXTERN(int) git_odb_backend_loose(git_odb_backend **backend_out, const char *objects_dir, int compression_level, int do_fsync); -GIT_EXTERN(int) git_odb_backend_one_pack(git_odb_backend **backend_out, const char *index_file); - -GIT_EXTERN(void *) git_odb_backend_malloc(git_odb_backend *backend, size_t len); - -GIT_END_DECL - -#endif diff --git a/include/git2/oid.h b/include/git2/oid.h deleted file mode 100644 index 9e54a9f963e..00000000000 --- a/include/git2/oid.h +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_oid_h__ -#define INCLUDE_git_oid_h__ - -#include "common.h" -#include "types.h" - -/** - * @file git2/oid.h - * @brief Git object id routines - * @defgroup git_oid Git object id routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** Size (in bytes) of a raw/binary oid */ -#define GIT_OID_RAWSZ 20 - -/** Size (in bytes) of a hex formatted oid */ -#define GIT_OID_HEXSZ (GIT_OID_RAWSZ * 2) - -/** Minimum length (in number of hex characters, - * i.e. packets of 4 bits) of an oid prefix */ -#define GIT_OID_MINPREFIXLEN 4 - -/** Unique identity of any object (commit, tree, blob, tag). */ -typedef struct _git_oid git_oid; -struct _git_oid { - /** raw binary formatted id */ - unsigned char id[GIT_OID_RAWSZ]; -}; - -/** - * Parse a hex formatted object id into a git_oid. - * - * @param out oid structure the result is written into. - * @param str input hex string; must be pointing at the start of - * the hex sequence and have at least the number of bytes - * needed for an oid encoded in hex (40 bytes). - * @return 0 or an error code - */ -GIT_EXTERN(int) git_oid_fromstr(git_oid *out, const char *str); - -/** - * Parse N characters of a hex formatted object id into a git_oid - * - * If N is odd, N-1 characters will be parsed instead. - * The remaining space in the git_oid will be set to zero. - * - * @param out oid structure the result is written into. - * @param str input hex string of at least size `length` - * @param length length of the input string - * @return 0 or an error code - */ -GIT_EXTERN(int) git_oid_fromstrn(git_oid *out, const char *str, size_t length); - -/** - * Copy an already raw oid into a git_oid structure. - * - * @param out oid structure the result is written into. - * @param raw the raw input bytes to be copied. - */ -GIT_EXTERN(void) git_oid_fromraw(git_oid *out, const unsigned char *raw); - -/** - * Format a git_oid into a hex string. - * - * @param str output hex string; must be pointing at the start of - * the hex sequence and have at least the number of bytes - * needed for an oid encoded in hex (40 bytes). Only the - * oid digits are written; a '\\0' terminator must be added - * by the caller if it is required. - * @param oid oid structure to format. - */ -GIT_EXTERN(void) git_oid_fmt(char *str, const git_oid *oid); - -/** - * Format a git_oid into a loose-object path string. - * - * The resulting string is "aa/...", where "aa" is the first two - * hex digits of the oid and "..." is the remaining 38 digits. - * - * @param str output hex string; must be pointing at the start of - * the hex sequence and have at least the number of bytes - * needed for an oid encoded in hex (41 bytes). Only the - * oid digits are written; a '\\0' terminator must be added - * by the caller if it is required. - * @param oid oid structure to format. - */ -GIT_EXTERN(void) git_oid_pathfmt(char *str, const git_oid *oid); - -/** - * Format a git_oid into a newly allocated c-string. - * - * @param oid the oid structure to format - * @return the c-string; NULL if memory is exhausted. Caller must - * deallocate the string with git__free(). - */ -GIT_EXTERN(char *) git_oid_allocfmt(const git_oid *oid); - -/** - * Format a git_oid into a buffer as a hex format c-string. - * - * If the buffer is smaller than GIT_OID_HEXSZ+1, then the resulting - * oid c-string will be truncated to n-1 characters. If there are - * any input parameter errors (out == NULL, n == 0, oid == NULL), - * then a pointer to an empty string is returned, so that the return - * value can always be printed. - * - * @param out the buffer into which the oid string is output. - * @param n the size of the out buffer. - * @param oid the oid structure to format. - * @return the out buffer pointer, assuming no input parameter - * errors, otherwise a pointer to an empty string. - */ -GIT_EXTERN(char *) git_oid_tostr(char *out, size_t n, const git_oid *oid); - -/** - * Copy an oid from one structure to another. - * - * @param out oid structure the result is written into. - * @param src oid structure to copy from. - */ -GIT_EXTERN(void) git_oid_cpy(git_oid *out, const git_oid *src); - -/** - * Compare two oid structures. - * - * @param a first oid structure. - * @param b second oid structure. - * @return <0, 0, >0 if a < b, a == b, a > b. - */ -GIT_INLINE(int) git_oid_cmp(const git_oid *a, const git_oid *b) -{ - const unsigned char *sha1 = a->id; - const unsigned char *sha2 = b->id; - int i; - - for (i = 0; i < GIT_OID_RAWSZ; i++, sha1++, sha2++) { - if (*sha1 != *sha2) - return *sha1 - *sha2; - } - - return 0; -} - -/** - * Compare two oid structures for equality - * - * @param a first oid structure. - * @param b second oid structure. - * @return true if equal, false otherwise - */ -GIT_INLINE(int) git_oid_equal(const git_oid *a, const git_oid *b) -{ - return !git_oid_cmp(a, b); -} - -/** - * Compare the first 'len' hexadecimal characters (packets of 4 bits) - * of two oid structures. - * - * @param a first oid structure. - * @param b second oid structure. - * @param len the number of hex chars to compare - * @return 0 in case of a match - */ -GIT_EXTERN(int) git_oid_ncmp(const git_oid *a, const git_oid *b, size_t len); - -/** - * Check if an oid equals an hex formatted object id. - * - * @param a oid structure. - * @param str input hex string of an object id. - * @return GIT_ENOTOID if str is not a valid hex string, - * 0 in case of a match, GIT_ERROR otherwise. - */ -GIT_EXTERN(int) git_oid_streq(const git_oid *a, const char *str); - -/** - * Check is an oid is all zeros. - * - * @return 1 if all zeros, 0 otherwise. - */ -GIT_EXTERN(int) git_oid_iszero(const git_oid *a); - -/** - * OID Shortener object - */ -typedef struct git_oid_shorten git_oid_shorten; - -/** - * Create a new OID shortener. - * - * The OID shortener is used to process a list of OIDs - * in text form and return the shortest length that would - * uniquely identify all of them. - * - * E.g. look at the result of `git log --abbrev`. - * - * @param min_length The minimal length for all identifiers, - * which will be used even if shorter OIDs would still - * be unique. - * @return a `git_oid_shorten` instance, NULL if OOM - */ -GIT_EXTERN(git_oid_shorten *) git_oid_shorten_new(size_t min_length); - -/** - * Add a new OID to set of shortened OIDs and calculate - * the minimal length to uniquely identify all the OIDs in - * the set. - * - * The OID is expected to be a 40-char hexadecimal string. - * The OID is owned by the user and will not be modified - * or freed. - * - * For performance reasons, there is a hard-limit of how many - * OIDs can be added to a single set (around ~22000, assuming - * a mostly randomized distribution), which should be enough - * for any kind of program, and keeps the algorithm fast and - * memory-efficient. - * - * Attempting to add more than those OIDs will result in a - * GIT_ENOMEM error - * - * @param os a `git_oid_shorten` instance - * @param text_oid an OID in text form - * @return the minimal length to uniquely identify all OIDs - * added so far to the set; or an error code (<0) if an - * error occurs. - */ -GIT_EXTERN(int) git_oid_shorten_add(git_oid_shorten *os, const char *text_oid); - -/** - * Free an OID shortener instance - * - * @param os a `git_oid_shorten` instance - */ -GIT_EXTERN(void) git_oid_shorten_free(git_oid_shorten *os); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/reflog.h b/include/git2/reflog.h deleted file mode 100644 index 447915ef8f6..00000000000 --- a/include/git2/reflog.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_reflog_h__ -#define INCLUDE_git_reflog_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" - -/** - * @file git2/reflog.h - * @brief Git reflog management routines - * @defgroup git_reflog Git reflog management routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Read the reflog for the given reference - * - * If there is no reflog file for the given - * reference yet, an empty reflog object will - * be returned. - * - * The reflog must be freed manually by using - * git_reflog_free(). - * - * @param reflog pointer to reflog - * @param ref reference to read the reflog for - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reflog_read(git_reflog **reflog, git_reference *ref); - -/** - * Write an existing in-memory reflog object back to disk - * using an atomic file lock. - * - * @param reflog an existing reflog object - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reflog_write(git_reflog *reflog); - -/** - * Add a new entry to the reflog. - * - * `msg` is optional and can be NULL. - * - * @param reflog an existing reflog object - * @param new_oid the OID the reference is now pointing to - * @param committer the signature of the committer - * @param msg the reflog message - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reflog_append(git_reflog *reflog, const git_oid *new_oid, const git_signature *committer, const char *msg); - -/** - * Rename the reflog for the given reference - * - * The reflog to be renamed is expected to already exist - * - * @param ref the reference - * @param new_name the new name of the reference - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reflog_rename(git_reference *ref, const char *new_name); - -/** - * Delete the reflog for the given reference - * - * @param ref the reference - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reflog_delete(git_reference *ref); - -/** - * Get the number of log entries in a reflog - * - * @param reflog the previously loaded reflog - * @return the number of log entries - */ -GIT_EXTERN(unsigned int) git_reflog_entrycount(git_reflog *reflog); - -/** - * Lookup an entry by its index - * - * @param reflog a previously loaded reflog - * @param idx the position to lookup - * @return the entry; NULL if not found - */ -GIT_EXTERN(const git_reflog_entry *) git_reflog_entry_byindex(git_reflog *reflog, size_t idx); - -/** - * Remove an entry from the reflog by its index - * - * To ensure there's no gap in the log history, set the `rewrite_previosu_entry` to 1. - * When deleting entry `n`, member old_oid of entry `n-1` (if any) will be updated with - * the value of memeber new_oid of entry `n+1`. - * - * @param reflog a previously loaded reflog. - * - * @param idx the position of the entry to remove. - * - * @param rewrite_previous_entry 1 to rewrite the history; 0 otherwise. - * - * @return 0 on success or an error code. - */ -GIT_EXTERN(int) git_reflog_drop( - git_reflog *reflog, - unsigned int idx, - int rewrite_previous_entry); - -/** - * Get the old oid - * - * @param entry a reflog entry - * @return the old oid - */ -GIT_EXTERN(const git_oid *) git_reflog_entry_oidold(const git_reflog_entry *entry); - -/** - * Get the new oid - * - * @param entry a reflog entry - * @return the new oid at this time - */ -GIT_EXTERN(const git_oid *) git_reflog_entry_oidnew(const git_reflog_entry *entry); - -/** - * Get the committer of this entry - * - * @param entry a reflog entry - * @return the committer - */ -GIT_EXTERN(git_signature *) git_reflog_entry_committer(const git_reflog_entry *entry); - -/** - * Get the log msg - * - * @param entry a reflog entry - * @return the log msg - */ -GIT_EXTERN(char *) git_reflog_entry_msg(const git_reflog_entry *entry); - -/** - * Free the reflog - * - * @param reflog reflog to free - */ -GIT_EXTERN(void) git_reflog_free(git_reflog *reflog); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/refs.h b/include/git2/refs.h deleted file mode 100644 index 73b32a9e2b2..00000000000 --- a/include/git2/refs.h +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_refs_h__ -#define INCLUDE_git_refs_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" - -/** - * @file git2/refs.h - * @brief Git reference management routines - * @defgroup git_reference Git reference management routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Lookup a reference by its name in a repository. - * - * The generated reference must be freed by the user. - * - * @param reference_out pointer to the looked-up reference - * @param repo the repository to look up the reference - * @param name the long name for the reference (e.g. HEAD, ref/heads/master, refs/tags/v0.1.0, ...) - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reference_lookup(git_reference **reference_out, git_repository *repo, const char *name); - -/** - * Lookup a reference by name and resolve immediately to OID. - * - * @param oid Pointer to oid to be filled in - * @param repo The repository in which to look up the reference - * @param name The long name for the reference - * @return 0 on success, -1 if name could not be resolved - */ -GIT_EXTERN(int) git_reference_name_to_oid( - git_oid *out, git_repository *repo, const char *name); - -/** - * Create a new symbolic reference. - * - * The reference will be created in the repository and written - * to the disk. - * - * The generated reference must be freed by the user. - * - * If `force` is true and there already exists a reference - * with the same name, it will be overwritten. - * - * @param ref_out Pointer to the newly created reference - * @param repo Repository where that reference will live - * @param name The name of the reference - * @param target The target of the reference - * @param force Overwrite existing references - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reference_create_symbolic(git_reference **ref_out, git_repository *repo, const char *name, const char *target, int force); - -/** - * Create a new object id reference. - * - * The reference will be created in the repository and written - * to the disk. - * - * The generated reference must be freed by the user. - * - * If `force` is true and there already exists a reference - * with the same name, it will be overwritten. - * - * @param ref_out Pointer to the newly created reference - * @param repo Repository where that reference will live - * @param name The name of the reference - * @param id The object id pointed to by the reference. - * @param force Overwrite existing references - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reference_create_oid(git_reference **ref_out, git_repository *repo, const char *name, const git_oid *id, int force); - -/** - * Get the OID pointed to by a reference. - * - * Only available if the reference is direct (i.e. not symbolic) - * - * @param ref The reference - * @return a pointer to the oid if available, NULL otherwise - */ -GIT_EXTERN(const git_oid *) git_reference_oid(git_reference *ref); - -/** - * Get full name to the reference pointed by this reference - * - * Only available if the reference is symbolic - * - * @param ref The reference - * @return a pointer to the name if available, NULL otherwise - */ -GIT_EXTERN(const char *) git_reference_target(git_reference *ref); - -/** - * Get the type of a reference - * - * Either direct (GIT_REF_OID) or symbolic (GIT_REF_SYMBOLIC) - * - * @param ref The reference - * @return the type - */ -GIT_EXTERN(git_ref_t) git_reference_type(git_reference *ref); - -/** - * Get the full name of a reference - * - * @param ref The reference - * @return the full name for the ref - */ -GIT_EXTERN(const char *) git_reference_name(git_reference *ref); - -/** - * Resolve a symbolic reference - * - * This method iteratively peels a symbolic reference - * until it resolves to a direct reference to an OID. - * - * The peeled reference is returned in the `resolved_ref` - * argument, and must be freed manually once it's no longer - * needed. - * - * If a direct reference is passed as an argument, - * a copy of that reference is returned. This copy must - * be manually freed too. - * - * @param resolved_ref Pointer to the peeled reference - * @param ref The reference - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reference_resolve(git_reference **resolved_ref, git_reference *ref); - -/** - * Get the repository where a reference resides - * - * @param ref The reference - * @return a pointer to the repo - */ -GIT_EXTERN(git_repository *) git_reference_owner(git_reference *ref); - -/** - * Set the symbolic target of a reference. - * - * The reference must be a symbolic reference, otherwise - * this method will fail. - * - * The reference will be automatically updated in - * memory and on disk. - * - * @param ref The reference - * @param target The new target for the reference - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reference_set_target(git_reference *ref, const char *target); - -/** - * Set the OID target of a reference. - * - * The reference must be a direct reference, otherwise - * this method will fail. - * - * The reference will be automatically updated in - * memory and on disk. - * - * @param ref The reference - * @param id The new target OID for the reference - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reference_set_oid(git_reference *ref, const git_oid *id); - -/** - * Rename an existing reference - * - * This method works for both direct and symbolic references. - * The new name will be checked for validity and may be - * modified into a normalized form. - * - * The given git_reference will be updated in place. - * - * The reference will be immediately renamed in-memory - * and on disk. - * - * If the `force` flag is not enabled, and there's already - * a reference with the given name, the renaming will fail. - * - * IMPORTANT: - * The user needs to write a proper reflog entry if the - * reflog is enabled for the repository. We only rename - * the reflog if it exists. - * - * @param ref The reference to rename - * @param new_name The new name for the reference - * @param force Overwrite an existing reference - * @return 0 or an error code - * - */ -GIT_EXTERN(int) git_reference_rename(git_reference *ref, const char *new_name, int force); - -/** - * Delete an existing reference - * - * This method works for both direct and symbolic references. - * - * The reference will be immediately removed on disk and from - * memory. The given reference pointer will no longer be valid. - * - * @param ref The reference to remove - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reference_delete(git_reference *ref); - -/** - * Pack all the loose references in the repository - * - * This method will load into the cache all the loose - * references on the repository and update the - * `packed-refs` file with them. - * - * Once the `packed-refs` file has been written properly, - * the loose references will be removed from disk. - * - * @param repo Repository where the loose refs will be packed - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reference_packall(git_repository *repo); - -/** - * Fill a list with all the references that can be found - * in a repository. - * - * The listed references may be filtered by type, or using - * a bitwise OR of several types. Use the magic value - * `GIT_REF_LISTALL` to obtain all references, including - * packed ones. - * - * The string array will be filled with the names of all - * references; these values are owned by the user and - * should be free'd manually when no longer needed, using - * `git_strarray_free`. - * - * @param array Pointer to a git_strarray structure where - * the reference names will be stored - * @param repo Repository where to find the refs - * @param list_flags Filtering flags for the reference - * listing. - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reference_list(git_strarray *array, git_repository *repo, unsigned int list_flags); - -/** - * Perform an operation on each reference in the repository - * - * The processed references may be filtered by type, or using - * a bitwise OR of several types. Use the magic value - * `GIT_REF_LISTALL` to obtain all references, including - * packed ones. - * - * The `callback` function will be called for each of the references - * in the repository, and will receive the name of the reference and - * the `payload` value passed to this method. Returning a non-zero - * value from the callback will terminate the iteration. - * - * @param repo Repository where to find the refs - * @param list_flags Filtering flags for the reference - * listing. - * @param callback Function which will be called for every listed ref - * @param payload Additional data to pass to the callback - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_reference_foreach(git_repository *repo, unsigned int list_flags, int (*callback)(const char *, void *), void *payload); - -/** - * Check if a reference has been loaded from a packfile - * - * @param ref A git reference - * @return 0 in case it's not packed; 1 otherwise - */ -GIT_EXTERN(int) git_reference_is_packed(git_reference *ref); - -/** - * Reload a reference from disk - * - * Reference pointers may become outdated if the Git - * repository is accessed simultaneously by other clients - * while the library is open. - * - * This method forces a reload of the reference from disk, - * to ensure that the provided information is still - * reliable. - * - * If the reload fails (e.g. the reference no longer exists - * on disk, or has become corrupted), an error code will be - * returned and the reference pointer will be invalidated. - * - * @param ref The reference to reload - * @return 0 on success, or an error code - */ -GIT_EXTERN(int) git_reference_reload(git_reference *ref); - -/** - * Free the given reference - * - * @param ref git_reference - */ -GIT_EXTERN(void) git_reference_free(git_reference *ref); - -/** - * Compare two references. - * - * @param ref1 The first git_reference - * @param ref2 The second git_reference - * @return 0 if the same, else a stable but meaningless ordering. - */ -GIT_EXTERN(int) git_reference_cmp(git_reference *ref1, git_reference *ref2); - -/** - * Loop over all the references and issue a callback for each one - * which name matches the given glob pattern. - * - * The processed references may be filtered by type, or using - * a bitwise OR of several types. Use the magic value - * `GIT_REF_LISTALL` to obtain all references, including - * packed ones. - * - * @param repo Repository where to find the references. - * - * @param glob Glob pattern references should match. - * - * @param list_flags Filtering flags for the reference - * listing. - * - * @param callback Callback to invoke per found reference. - * - * @param payload Extra parameter to callback function. - * - * @return 0 or an error code. - */ -GIT_EXTERN(int) git_reference_foreach_glob( - git_repository *repo, - const char *glob, - unsigned int list_flags, - int (*callback)( - const char *reference_name, - void *payload), - void *payload -); - -/** - * Check if a reflog exists for the specified reference. - * - * @param ref A git reference - * - * @return 0 when no reflog can be found, 1 when it exists; - * otherwise an error code. - */ -GIT_EXTERN(int) git_reference_has_log(git_reference *ref); - -/** - * Check if a reference is a local branch. - * - * @param ref A git reference - * - * @return 1 when the reference lives in the refs/heads - * namespace; 0 otherwise. - */ -GIT_EXTERN(int) git_reference_is_branch(git_reference *ref); - -/** - * Check if a reference is a remote tracking branch - * - * @param ref A git reference - * - * @return 1 when the reference lives in the refs/remotes - * namespace; 0 otherwise. - */ -GIT_EXTERN(int) git_reference_is_remote(git_reference *ref); - -enum { - GIT_REF_FORMAT_NORMAL = 0, - - /** - * Control whether one-level refnames are accepted - * (i.e., refnames that do not contain multiple /-separated - * components) - */ - GIT_REF_FORMAT_ALLOW_ONELEVEL = (1 << 0), - - /** - * Interpret the provided name as a reference pattern for a - * refspec (as used with remote repositories). If this option - * is enabled, the name is allowed to contain a single * () - * in place of a one full pathname component - * (e.g., foo//bar but not foo/bar). - */ - GIT_REF_FORMAT_REFSPEC_PATTERN = (1 << 1), -}; - -/** - * Normalize the reference name by removing any leading - * slash (/) characters and collapsing runs of adjacent slashes - * between name components into a single slash. - * - * Once normalized, if the reference name is valid, it will be - * returned in the user allocated buffer. - * - * TODO: Implement handling of GIT_REF_FORMAT_REFSPEC_PATTERN - * - * @param buffer_out The user allocated buffer where the - * normalized name will be stored. - * - * @param buffer_size buffer_out size - * - * @param name name to be checked. - * - * @param flags Flags to determine the options to be applied while - * checking the validatity of the name. - * - * @return 0 or an error code. - */ -GIT_EXTERN(int) git_reference_normalize_name( - char *buffer_out, - size_t buffer_size, - const char *name, - unsigned int flags); - -/** - * Recursively peel an reference until an object of the - * specified type is met. - * - * The retrieved `peeled` object is owned by the repository - * and should be closed with the `git_object_free` method. - * - * If you pass `GIT_OBJ_ANY` as the target type, then the object - * will be peeled until a non-tag object is met. - * - * @param peeled Pointer to the peeled git_object - * @param ref The reference to be processed - * @param target_type The type of the requested object - * @return 0 or an error code - */ -GIT_EXTERN(int) git_reference_peel( - git_object **out, - git_reference *ref, - git_otype type); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/refspec.h b/include/git2/refspec.h deleted file mode 100644 index 9e84aad99b0..00000000000 --- a/include/git2/refspec.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_refspec_h__ -#define INCLUDE_git_refspec_h__ - -#include "common.h" -#include "types.h" - -/** - * @file git2/refspec.h - * @brief Git refspec attributes - * @defgroup git_refspec Git refspec attributes - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Parse a refspec string and create a refspec object - * - * @param refspec pointer to the refspec structure to be used - * @param str the refspec as a string - */ -GIT_EXTERN(int) git_refspec_parse(git_refspec *refspec, const char *str); - -/** - * Get the source specifier - * - * @param refspec the refspec - * @return the refspec's source specifier - */ -GIT_EXTERN(const char *) git_refspec_src(const git_refspec *refspec); - -/** - * Get the destination specifier - * - * @param refspec the refspec - * @return the refspec's destination specifier - */ -GIT_EXTERN(const char *) git_refspec_dst(const git_refspec *refspec); - -/** - * Get the force update setting - * - * @param refspec the refspec - * @return 1 if force update has been set, 0 otherwise - */ -GIT_EXTERN(int) git_refspec_force(const git_refspec *refspec); - -/** - * Check if a refspec's source descriptor matches a reference - * - * @param refspec the refspec - * @param refname the name of the reference to check - * @return 1 if the refspec matches, 0 otherwise - */ -GIT_EXTERN(int) git_refspec_src_matches(const git_refspec *refspec, const char *refname); - -/** - * Transform a reference to its target following the refspec's rules - * - * @param out where to store the target name - * @param outlen the size ouf the `out` buffer - * @param spec the refspec - * @param name the name of the reference to transform - * @return 0, GIT_EBUFS or another error - */ -GIT_EXTERN(int) git_refspec_transform(char *out, size_t outlen, const git_refspec *spec, const char *name); - -GIT_END_DECL - -#endif diff --git a/include/git2/remote.h b/include/git2/remote.h deleted file mode 100644 index a3913af5bca..00000000000 --- a/include/git2/remote.h +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_remote_h__ -#define INCLUDE_git_remote_h__ - -#include "common.h" -#include "repository.h" -#include "refspec.h" -#include "net.h" -#include "indexer.h" - -/** - * @file git2/remote.h - * @brief Git remote management functions - * @defgroup git_remote remote management functions - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/* - * TODO: This functions still need to be implemented: - * - _listcb/_foreach - * - _add - * - _rename - * - _del (needs support from config) - */ - -/** - * Create a remote in memory - * - * Create a remote with the default refspecs in memory. You can use - * this when you have a URL instead of a remote's name. - * - * @param out pointer to the new remote object - * @param repo the associated repository - * @param name the remote's name - * @param url the remote repository's URL - * @param fetch the fetch refspec to use for this remote - * @return 0 or an error code - */ -GIT_EXTERN(int) git_remote_new(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch); - -/** - * Get the information for a particular remote - * - * @param out pointer to the new remote object - * @param cfg the repository's configuration - * @param name the remote's name - * @return 0 or an error code - */ -GIT_EXTERN(int) git_remote_load(git_remote **out, git_repository *repo, const char *name); - -/** - * Save a remote to its repository's configuration - * - * @param remote the remote to save to config - * @return 0 or an error code - */ -GIT_EXTERN(int) git_remote_save(const git_remote *remote); - -/** - * Get the remote's name - * - * @param remote the remote - * @return a pointer to the name - */ -GIT_EXTERN(const char *) git_remote_name(git_remote *remote); - -/** - * Get the remote's url - * - * @param remote the remote - * @return a pointer to the url - */ -GIT_EXTERN(const char *) git_remote_url(git_remote *remote); - -/** - * Get the remote's url for pushing - * - * @param remote the remote - * @return a pointer to the url or NULL if no special url for pushing is set - */ -GIT_EXTERN(const char *) git_remote_pushurl(git_remote *remote); - -/** - * Set the remote's url - * - * Existing connections will not be updated. - * - * @param remote the remote - * @param url the url to set - * @return 0 or an error value - */ -GIT_EXTERN(int) git_remote_set_url(git_remote *remote, const char* url); - -/** - * Set the remote's url for pushing - * - * Existing connections will not be updated. - * - * @param remote the remote - * @param url the url to set or NULL to clear the pushurl - * @return 0 or an error value - */ -GIT_EXTERN(int) git_remote_set_pushurl(git_remote *remote, const char* url); - -/** - * Set the remote's fetch refspec - * - * @param remote the remote - * @apram spec the new fetch refspec - * @return 0 or an error value - */ -GIT_EXTERN(int) git_remote_set_fetchspec(git_remote *remote, const char *spec); - -/** - * Get the fetch refspec - * - * @param remote the remote - * @return a pointer to the fetch refspec or NULL if it doesn't exist - */ -GIT_EXTERN(const git_refspec *) git_remote_fetchspec(git_remote *remote); - -/** - * Set the remote's push refspec - * - * @param remote the remote - * @param spec the new push refspec - * @return 0 or an error value - */ -GIT_EXTERN(int) git_remote_set_pushspec(git_remote *remote, const char *spec); - -/** - * Get the push refspec - * - * @param remote the remote - * @return a pointer to the push refspec or NULL if it doesn't exist - */ - -GIT_EXTERN(const git_refspec *) git_remote_pushspec(git_remote *remote); - -/** - * Open a connection to a remote - * - * The transport is selected based on the URL. The direction argument - * is due to a limitation of the git protocol (over TCP or SSH) which - * starts up a specific binary which can only do the one or the other. - * - * @param remote the remote to connect to - * @param direction whether you want to receive or send data - * @return 0 or an error code - */ -GIT_EXTERN(int) git_remote_connect(git_remote *remote, int direction); - -/** - * Get a list of refs at the remote - * - * The remote (or more exactly its transport) must be connected. The - * memory belongs to the remote. - * - * If you a return a non-zero value from the callback, this will stop - * looping over the refs. - * - * @param refs where to store the refs - * @param remote the remote - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_remote_ls(git_remote *remote, git_headlist_cb list_cb, void *payload); - -/** - * Download the packfile - * - * Negotiate what objects should be downloaded and download the - * packfile with those objects. The packfile is downloaded with a - * temporary filename, as it's final name is not known yet. If there - * was no packfile needed (all the objects were available locally), - * filename will be NULL and the function will return success. - * - * @param remote the remote to download from - * @param filename where to store the temporary filename - * @return 0 or an error code - */ -GIT_EXTERN(int) git_remote_download(git_remote *remote, git_off_t *bytes, git_indexer_stats *stats); - -/** - * Check whether the remote is connected - * - * Check whether the remote's underlying transport is connected to the - * remote host. - * - * @return 1 if it's connected, 0 otherwise. - */ -GIT_EXTERN(int) git_remote_connected(git_remote *remote); - -/** - * Disconnect from the remote - * - * Close the connection to the remote and free the underlying - * transport. - * - * @param remote the remote to disconnect from - */ -GIT_EXTERN(void) git_remote_disconnect(git_remote *remote); - -/** - * Free the memory associated with a remote - * - * This also disconnects from the remote, if the connection - * has not been closed yet (using git_remote_disconnect). - * - * @param remote the remote to free - */ -GIT_EXTERN(void) git_remote_free(git_remote *remote); - -/** - * Update the tips to the new state - * - * @param remote the remote to update - * @param cb callback to run on each ref update. 'a' is the old value, 'b' is then new value - */ -GIT_EXTERN(int) git_remote_update_tips(git_remote *remote); - -/** - * Return whether a string is a valid remote URL - * - * @param url the url to check - * @param 1 if the url is valid, 0 otherwise - */ -GIT_EXTERN(int) git_remote_valid_url(const char *url); - -/** - * Return whether the passed URL is supported by this version of the library. - * - * @param url the url to check - * @return 1 if the url is supported, 0 otherwise -*/ -GIT_EXTERN(int) git_remote_supported_url(const char* url); - -/** - * Get a list of the configured remotes for a repo - * - * The string array must be freed by the user. - * - * @param remotes_list a string array with the names of the remotes - * @param repo the repository to query - * @return 0 or an error code - */ -GIT_EXTERN(int) git_remote_list(git_strarray *remotes_list, git_repository *repo); - -/** - * Add a remote with the default fetch refspec to the repository's configuration - * - * @param out the resulting remote - * @param repo the repository in which to create the remote - * @param name the remote's name - * @param url the remote's url - */ -GIT_EXTERN(int) git_remote_add(git_remote **out, git_repository *repo, const char *name, const char *url); - -/** - * Choose whether to check the server's certificate (applies to HTTPS only) - * - * @param remote the remote to configure - * @param check whether to check the server's certificate (defaults to yes) - */ - -GIT_EXTERN(void) git_remote_check_cert(git_remote *remote, int check); - -/** - * Argument to the completion callback which tells it which operation - * finished. - */ -typedef enum git_remote_completion_type { - GIT_REMOTE_COMPLETION_DOWNLOAD, - GIT_REMOTE_COMPLETION_INDEXING, - GIT_REMOTE_COMPLETION_ERROR, -} git_remote_completion_type; - -/** - * The callback settings structure - * - * Set the calbacks to be called by the remote. - */ -struct git_remote_callbacks { - void (*progress)(const char *str, int len, void *data); - int (*completion)(git_remote_completion_type type, void *data); - int (*update_tips)(const char *refname, const git_oid *a, const git_oid *b, void *data); - void *data; -}; - -/** - * Set the callbacks for a remote - * - * Note that the remote keeps its own copy of the data and you need to - * call this function again if you want to change the callbacks. - * - * @param remote the remote to configure - * @param callbacks a pointer to the user's callback settings - */ -GIT_EXTERN(void) git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callbacks); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/repository.h b/include/git2/repository.h deleted file mode 100644 index 025a0a95dec..00000000000 --- a/include/git2/repository.h +++ /dev/null @@ -1,572 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_repository_h__ -#define INCLUDE_git_repository_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" - -/** - * @file git2/repository.h - * @brief Git repository management routines - * @defgroup git_repository Git repository management routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Open a git repository. - * - * The 'path' argument must point to either a git repository - * folder, or an existing work dir. - * - * The method will automatically detect if 'path' is a normal - * or bare repository or fail is 'path' is neither. - * - * @param repository pointer to the repo which will be opened - * @param path the path to the repository - * @return 0 or an error code - */ -GIT_EXTERN(int) git_repository_open(git_repository **repository, const char *path); - -/** - * Create a "fake" repository to wrap an object database - * - * Create a repository object to wrap an object database to be used - * with the API when all you have is an object database. This doesn't - * have any paths associated with it, so use with care. - * - * @param repository pointer to the repo - * @param odb the object database to wrap - * @return 0 or an error code - */ -GIT_EXTERN(int) git_repository_wrap_odb(git_repository **repository, git_odb *odb); - -/** - * Look for a git repository and copy its path in the given buffer. - * The lookup start from base_path and walk across parent directories - * if nothing has been found. The lookup ends when the first repository - * is found, or when reaching a directory referenced in ceiling_dirs - * or when the filesystem changes (in case across_fs is true). - * - * The method will automatically detect if the repository is bare - * (if there is a repository). - * - * @param repository_path The user allocated buffer which will - * contain the found path. - * - * @param size repository_path size - * - * @param start_path The base path where the lookup starts. - * - * @param across_fs If true, then the lookup will not stop when a - * filesystem device change is detected while exploring parent directories. - * - * @param ceiling_dirs A GIT_PATH_LIST_SEPARATOR separated list of - * absolute symbolic link free paths. The lookup will stop when any - * of this paths is reached. Note that the lookup always performs on - * start_path no matter start_path appears in ceiling_dirs ceiling_dirs - * might be NULL (which is equivalent to an empty string) - * - * @return 0 or an error code - */ -GIT_EXTERN(int) git_repository_discover( - char *repository_path, - size_t size, - const char *start_path, - int across_fs, - const char *ceiling_dirs); - -/** - * Option flags for `git_repository_open_ext`. - * - * * GIT_REPOSITORY_OPEN_NO_SEARCH - Only open the repository if it can be - * immediately found in the start_path. Do not walk up from the - * start_path looking at parent directories. - * * GIT_REPOSITORY_OPEN_CROSS_FS - Unless this flag is set, open will not - * continue searching across filesystem boundaries (i.e. when `st_dev` - * changes from the `stat` system call). (E.g. Searching in a user's home - * directory "/home/user/source/" will not return "/.git/" as the found - * repo if "/" is a different filesystem than "/home".) - */ -enum { - GIT_REPOSITORY_OPEN_NO_SEARCH = (1 << 0), - GIT_REPOSITORY_OPEN_CROSS_FS = (1 << 1), -}; - -/** - * Find and open a repository with extended controls. - * - * @param repo_out Pointer to the repo which will be opened. This can - * actually be NULL if you only want to use the error code to - * see if a repo at this path could be opened. - * @param start_path Path to open as git repository. If the flags - * permit "searching", then this can be a path to a subdirectory - * inside the working directory of the repository. - * @param flags A combination of the GIT_REPOSITORY_OPEN flags above. - * @param ceiling_dirs A GIT_PATH_LIST_SEPARATOR delimited list of path - * prefixes at which the search for a containing repository should - * terminate. - * @return 0 on success, GIT_ENOTFOUND if no repository could be found, - * or -1 if there was a repository but open failed for some reason - * (such as repo corruption or system errors). - */ -GIT_EXTERN(int) git_repository_open_ext( - git_repository **repo, - const char *start_path, - uint32_t flags, - const char *ceiling_dirs); - -/** - * Free a previously allocated repository - * - * Note that after a repository is free'd, all the objects it has spawned - * will still exist until they are manually closed by the user - * with `git_object_free`, but accessing any of the attributes of - * an object without a backing repository will result in undefined - * behavior - * - * @param repo repository handle to close. If NULL nothing occurs. - */ -GIT_EXTERN(void) git_repository_free(git_repository *repo); - -/** - * Creates a new Git repository in the given folder. - * - * TODO: - * - Reinit the repository - * - * @param repo_out pointer to the repo which will be created or reinitialized - * @param path the path to the repository - * @param is_bare if true, a Git repository without a working directory is - * created at the pointed path. If false, provided path will be - * considered as the working directory into which the .git directory - * will be created. - * - * @return 0 or an error code - */ -GIT_EXTERN(int) git_repository_init( - git_repository **repo_out, - const char *path, - unsigned is_bare); - -/** - * Option flags for `git_repository_init_ext`. - * - * These flags configure extra behaviors to `git_repository_init_ext`. - * In every case, the default behavior is the zero value (i.e. flag is - * not set). Just OR the flag values together for the `flags` parameter - * when initializing a new repo. Details of individual values are: - * - * * BARE - Create a bare repository with no working directory. - * * NO_REINIT - Return an EEXISTS error if the repo_path appears to - * already be an git repository. - * * NO_DOTGIT_DIR - Normally a "/.git/" will be appended to the repo - * path for non-bare repos (if it is not already there), but - * passing this flag prevents that behavior. - * * MKDIR - Make the repo_path (and workdir_path) as needed. Init is - * always willing to create the ".git" directory even without this - * flag. This flag tells init to create the trailing component of - * the repo and workdir paths as needed. - * * MKPATH - Recursively make all components of the repo and workdir - * paths as necessary. - * * EXTERNAL_TEMPLATE - libgit2 normally uses internal templates to - * initialize a new repo. This flags enables external templates, - * looking the "template_path" from the options if set, or the - * `init.templatedir` global config if not, or falling back on - * "/usr/share/git-core/templates" if it exists. - */ -enum { - GIT_REPOSITORY_INIT_BARE = (1u << 0), - GIT_REPOSITORY_INIT_NO_REINIT = (1u << 1), - GIT_REPOSITORY_INIT_NO_DOTGIT_DIR = (1u << 2), - GIT_REPOSITORY_INIT_MKDIR = (1u << 3), - GIT_REPOSITORY_INIT_MKPATH = (1u << 4), - GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE = (1u << 5), -}; - -/** - * Mode options for `git_repository_init_ext`. - * - * Set the mode field of the `git_repository_init_options` structure - * either to the custom mode that you would like, or to one of the - * following modes: - * - * * SHARED_UMASK - Use permissions configured by umask - the default. - * * SHARED_GROUP - Use "--shared=group" behavior, chmod'ing the new repo - * to be group writable and "g+sx" for sticky group assignment. - * * SHARED_ALL - Use "--shared=all" behavior, adding world readability. - * * Anything else - Set to custom value. - */ -enum { - GIT_REPOSITORY_INIT_SHARED_UMASK = 0, - GIT_REPOSITORY_INIT_SHARED_GROUP = 0002775, - GIT_REPOSITORY_INIT_SHARED_ALL = 0002777, -}; - -/** - * Extended options structure for `git_repository_init_ext`. - * - * This contains extra options for `git_repository_init_ext` that enable - * additional initialization features. The fields are: - * - * * flags - Combination of GIT_REPOSITORY_INIT flags above. - * * mode - Set to one of the standard GIT_REPOSITORY_INIT_SHARED_... - * constants above, or to a custom value that you would like. - * * workdir_path - The path to the working dir or NULL for default (i.e. - * repo_path parent on non-bare repos). IF THIS IS RELATIVE PATH, - * IT WILL BE EVALUATED RELATIVE TO THE REPO_PATH. If this is not - * the "natural" working directory, a .git gitlink file will be - * created here linking to the repo_path. - * * description - If set, this will be used to initialize the "description" - * file in the repository, instead of using the template content. - * * template_path - When GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE is set, - * this contains the path to use for the template directory. If - * this is NULL, the config or default directory options will be - * used instead. - * * initial_head - The name of the head to point HEAD at. If NULL, then - * this will be treated as "master" and the HEAD ref will be set - * to "refs/heads/master". If this begins with "refs/" it will be - * used verbatim; otherwise "refs/heads/" will be prefixed. - * * origin_url - If this is non-NULL, then after the rest of the - * repository initialization is completed, an "origin" remote - * will be added pointing to this URL. - */ -typedef struct { - uint32_t flags; - uint32_t mode; - const char *workdir_path; - const char *description; - const char *template_path; - const char *initial_head; - const char *origin_url; -} git_repository_init_options; - -/** - * Create a new Git repository in the given folder with extended controls. - * - * This will initialize a new git repository (creating the repo_path - * if requested by flags) and working directory as needed. It will - * auto-detect the case sensitivity of the file system and if the - * file system supports file mode bits correctly. - * - * @param repo_out Pointer to the repo which will be created or reinitialized. - * @param repo_path The path to the repository. - * @param opts Pointer to git_repository_init_options struct. - * @return 0 or an error code on failure. - */ -GIT_EXTERN(int) git_repository_init_ext( - git_repository **repo_out, - const char *repo_path, - git_repository_init_options *opts); - -/** - * Retrieve and resolve the reference pointed at by HEAD. - * - * @param head_out pointer to the reference which will be retrieved - * @param repo a repository object - * - * @return 0 on success; error code otherwise - */ -GIT_EXTERN(int) git_repository_head(git_reference **head_out, git_repository *repo); - -/** - * Check if a repository's HEAD is detached - * - * A repository's HEAD is detached when it points directly to a commit - * instead of a branch. - * - * @param repo Repo to test - * @return 1 if HEAD is detached, 0 if it's not; error code if there - * was an error. - */ -GIT_EXTERN(int) git_repository_head_detached(git_repository *repo); - -/** - * Check if the current branch is an orphan - * - * An orphan branch is one named from HEAD but which doesn't exist in - * the refs namespace, because it doesn't have any commit to point to. - * - * @param repo Repo to test - * @return 1 if the current branch is an orphan, 0 if it's not; error - * code if there was an error - */ -GIT_EXTERN(int) git_repository_head_orphan(git_repository *repo); - -/** - * Check if a repository is empty - * - * An empty repository has just been initialized and contains - * no commits. - * - * @param repo Repo to test - * @return 1 if the repository is empty, 0 if it isn't, error code - * if the repository is corrupted - */ -GIT_EXTERN(int) git_repository_is_empty(git_repository *repo); - -/** - * Get the path of this repository - * - * This is the path of the `.git` folder for normal repositories, - * or of the repository itself for bare repositories. - * - * @param repo A repository object - * @return the path to the repository - */ -GIT_EXTERN(const char *) git_repository_path(git_repository *repo); - -/** - * Get the path of the working directory for this repository - * - * If the repository is bare, this function will always return - * NULL. - * - * @param repo A repository object - * @return the path to the working dir, if it exists - */ -GIT_EXTERN(const char *) git_repository_workdir(git_repository *repo); - -/** - * Set the path to the working directory for this repository - * - * The working directory doesn't need to be the same one - * that contains the `.git` folder for this repository. - * - * If this repository is bare, setting its working directory - * will turn it into a normal repository, capable of performing - * all the common workdir operations (checkout, status, index - * manipulation, etc). - * - * @param repo A repository object - * @param workdir The path to a working directory - * @param update_gitlink Create/update gitlink in workdir and set config - * "core.worktree" (if workdir is not the parent of the .git directory) - * @return 0, or an error code - */ -GIT_EXTERN(int) git_repository_set_workdir( - git_repository *repo, const char *workdir, int update_gitlink); - -/** - * Check if a repository is bare - * - * @param repo Repo to test - * @return 1 if the repository is bare, 0 otherwise. - */ -GIT_EXTERN(int) git_repository_is_bare(git_repository *repo); - -/** - * Get the configuration file for this repository. - * - * If a configuration file has not been set, the default - * config set for the repository will be returned, including - * global and system configurations (if they are available). - * - * The configuration file must be freed once it's no longer - * being used by the user. - * - * @param out Pointer to store the loaded config file - * @param repo A repository object - * @return 0, or an error code - */ -GIT_EXTERN(int) git_repository_config(git_config **out, git_repository *repo); - -/** - * Set the configuration file for this repository - * - * This configuration file will be used for all configuration - * queries involving this repository. - * - * The repository will keep a reference to the config file; - * the user must still free the config after setting it - * to the repository, or it will leak. - * - * @param repo A repository object - * @param config A Config object - */ -GIT_EXTERN(void) git_repository_set_config(git_repository *repo, git_config *config); - -/** - * Get the Object Database for this repository. - * - * If a custom ODB has not been set, the default - * database for the repository will be returned (the one - * located in `.git/objects`). - * - * The ODB must be freed once it's no longer being used by - * the user. - * - * @param out Pointer to store the loaded ODB - * @param repo A repository object - * @return 0, or an error code - */ -GIT_EXTERN(int) git_repository_odb(git_odb **out, git_repository *repo); - -/** - * Set the Object Database for this repository - * - * The ODB will be used for all object-related operations - * involving this repository. - * - * The repository will keep a reference to the ODB; the user - * must still free the ODB object after setting it to the - * repository, or it will leak. - * - * @param repo A repository object - * @param odb An ODB object - */ -GIT_EXTERN(void) git_repository_set_odb(git_repository *repo, git_odb *odb); - -/** - * Get the Index file for this repository. - * - * If a custom index has not been set, the default - * index for the repository will be returned (the one - * located in `.git/index`). - * - * The index must be freed once it's no longer being used by - * the user. - * - * @param out Pointer to store the loaded index - * @param repo A repository object - * @return 0, or an error code - */ -GIT_EXTERN(int) git_repository_index(git_index **out, git_repository *repo); - -/** - * Set the index file for this repository - * - * This index will be used for all index-related operations - * involving this repository. - * - * The repository will keep a reference to the index file; - * the user must still free the index after setting it - * to the repository, or it will leak. - * - * @param repo A repository object - * @param index An index object - */ -GIT_EXTERN(void) git_repository_set_index(git_repository *repo, git_index *index); - -/** - * Retrieve git's prepared message - * - * Operations such as git revert/cherry-pick/merge with the -n option - * stop just short of creating a commit with the changes and save - * their prepared message in .git/MERGE_MSG so the next git-commit - * execution can present it to the user for them to amend if they - * wish. - * - * Use this function to get the contents of this file. Don't forget to - * remove the file after you create the commit. - * - * @param buffer Buffer to write data into or NULL to just read required size - * @param len Length of buffer in bytes - * @param repo Repository to read prepared message from - * @return Bytes written to buffer, GIT_ENOTFOUND if no message, or -1 on error - */ -GIT_EXTERN(int) git_repository_message(char *buffer, size_t len, git_repository *repo); - -/** - * Remove git's prepared message. - * - * Remove the message that `git_repository_message` retrieves. - */ -GIT_EXTERN(int) git_repository_message_remove(git_repository *repo); - -/** - * Calculate hash of file using repository filtering rules. - * - * If you simply want to calculate the hash of a file on disk with no filters, - * you can just use the `git_odb_hashfile()` API. However, if you want to - * hash a file in the repository and you want to apply filtering rules (e.g. - * crlf filters) before generating the SHA, then use this function. - * - * @param out Output value of calculated SHA - * @param repo Repository pointer - * @param path Path to file on disk whose contents should be hashed. If the - * repository is not NULL, this can be a relative path. - * @param type The object type to hash as (e.g. GIT_OBJ_BLOB) - * @param as_path The path to use to look up filtering rules. If this is - * NULL, then the `path` parameter will be used instead. If - * this is passed as the empty string, then no filters will be - * applied when calculating the hash. - */ -GIT_EXTERN(int) git_repository_hashfile( - git_oid *out, - git_repository *repo, - const char *path, - git_otype type, - const char *as_path); - -/** - * Make the repository HEAD point to the specified reference. - * - * If the provided reference points to a Tree or a Blob, the HEAD is - * unaltered and -1 is returned. - * - * If the provided reference points to a branch, the HEAD will point - * to that branch, staying attached, or become attached if it isn't yet. - * If the branch doesn't exist yet, no error will be return. The HEAD - * will then be attached to an unborn branch. - * - * Otherwise, the HEAD will be detached and will directly point to - * the Commit. - * - * @param repo Repository pointer - * @param refname Canonical name of the reference the HEAD should point at - * @return 0 on success, or an error code - */ -GIT_EXTERN(int) git_repository_set_head( - git_repository* repo, - const char* refname); - -/** - * Make the repository HEAD directly point to the Commit. - * - * If the provided committish cannot be found in the repository, the HEAD - * is unaltered and GIT_ENOTFOUND is returned. - * - * If the provided commitish cannot be peeled into a commit, the HEAD - * is unaltered and -1 is returned. - * - * Otherwise, the HEAD will eventually be detached and will directly point to - * the peeled Commit. - * - * @param repo Repository pointer - * @param commitish Object id of the Commit the HEAD should point to - * @return 0 on success, or an error code - */ -GIT_EXTERN(int) git_repository_set_head_detached( - git_repository* repo, - const git_oid* commitish); - -/** - * Detach the HEAD. - * - * If the HEAD is already detached and points to a Commit, 0 is returned. - * - * If the HEAD is already detached and points to a Tag, the HEAD is - * updated into making it point to the peeled Commit, and 0 is returned. - * - * If the HEAD is already detached and points to a non commitish, the HEAD is - * unaletered, and -1 is returned. - * - * Otherwise, the HEAD will be detached and point to the peeled Commit. - * - * @param repo Repository pointer - * @return 0 on success, or an error code - */ -GIT_EXTERN(int) git_repository_detach_head( - git_repository* repo); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/reset.h b/include/git2/reset.h deleted file mode 100644 index cdcfb76710c..00000000000 --- a/include/git2/reset.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_reset_h__ -#define INCLUDE_git_reset_h__ - -/** - * @file git2/reset.h - * @brief Git reset management routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Sets the current head to the specified commit oid and optionally - * resets the index and working tree to match. - * - * When specifying a Soft kind of reset, the head will be moved to the commit. - * - * Specifying a Mixed kind of reset will trigger a Soft reset and the index will - * be replaced with the content of the commit tree. - * - * Specifying a Hard kind of reset will trigger a Mixed reset and the working - * directory will be replaced with the content of the index. - * - * TODO: Implement remaining kinds of resets. - * - * @param repo Repository where to perform the reset operation. - * - * @param target Object to which the Head should be moved to. This object - * must belong to the given `repo` and can either be a git_commit or a - * git_tag. When a git_tag is being passed, it should be dereferencable - * to a git_commit which oid will be used as the target of the branch. - * - * @param reset_type Kind of reset operation to perform. - * - * @return GIT_SUCCESS or an error code - */ -GIT_EXTERN(int) git_reset(git_repository *repo, git_object *target, git_reset_type reset_type); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/revparse.h b/include/git2/revparse.h deleted file mode 100644 index 4567027e516..00000000000 --- a/include/git2/revparse.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_revparse_h__ -#define INCLUDE_git_revparse_h__ - -#include "common.h" -#include "types.h" - - -/** - * @file git2/revparse.h - * @brief Git revision parsing routines - * @defgroup git_revparse Git revision parsing routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Find an object, as specified by a revision string. See `man gitrevisions`, or the documentation - * for `git rev-parse` for information on the syntax accepted. - * - * @param out pointer to output object - * @param repo the repository to search in - * @param spec the textual specification for an object - * @return on success, GIT_ERROR otherwise (use git_error_last for information about the error) - */ -GIT_EXTERN(int) git_revparse_single(git_object **out, git_repository *repo, const char *spec); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/revwalk.h b/include/git2/revwalk.h deleted file mode 100644 index 0a85a4c6082..00000000000 --- a/include/git2/revwalk.h +++ /dev/null @@ -1,237 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_revwalk_h__ -#define INCLUDE_git_revwalk_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" - -/** - * @file git2/revwalk.h - * @brief Git revision traversal routines - * @defgroup git_revwalk Git revision traversal routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Sort the repository contents in no particular ordering; - * this sorting is arbitrary, implementation-specific - * and subject to change at any time. - * This is the default sorting for new walkers. - */ -#define GIT_SORT_NONE (0) - -/** - * Sort the repository contents in topological order - * (parents before children); this sorting mode - * can be combined with time sorting. - */ -#define GIT_SORT_TOPOLOGICAL (1 << 0) - -/** - * Sort the repository contents by commit time; - * this sorting mode can be combined with - * topological sorting. - */ -#define GIT_SORT_TIME (1 << 1) - -/** - * Iterate through the repository contents in reverse - * order; this sorting mode can be combined with - * any of the above. - */ -#define GIT_SORT_REVERSE (1 << 2) - -/** - * Allocate a new revision walker to iterate through a repo. - * - * This revision walker uses a custom memory pool and an internal - * commit cache, so it is relatively expensive to allocate. - * - * For maximum performance, this revision walker should be - * reused for different walks. - * - * This revision walker is *not* thread safe: it may only be - * used to walk a repository on a single thread; however, - * it is possible to have several revision walkers in - * several different threads walking the same repository. - * - * @param walker pointer to the new revision walker - * @param repo the repo to walk through - * @return 0 or an error code - */ -GIT_EXTERN(int) git_revwalk_new(git_revwalk **walker, git_repository *repo); - -/** - * Reset the revision walker for reuse. - * - * This will clear all the pushed and hidden commits, and - * leave the walker in a blank state (just like at - * creation) ready to receive new commit pushes and - * start a new walk. - * - * The revision walk is automatically reset when a walk - * is over. - * - * @param walker handle to reset. - */ -GIT_EXTERN(void) git_revwalk_reset(git_revwalk *walker); - -/** - * Mark a commit to start traversal from. - * - * The given OID must belong to a commit on the walked - * repository. - * - * The given commit will be used as one of the roots - * when starting the revision walk. At least one commit - * must be pushed the repository before a walk can - * be started. - * - * @param walk the walker being used for the traversal. - * @param oid the oid of the commit to start from. - * @return 0 or an error code - */ -GIT_EXTERN(int) git_revwalk_push(git_revwalk *walk, const git_oid *oid); - -/** - * Push matching references - * - * The OIDs pointed to by the references that match the given glob - * pattern will be pushed to the revision walker. - * - * A leading 'refs/' is implied if not present as well as a trailing - * '/ *' if the glob lacks '?', '*' or '['. - * - * @param walk the walker being used for the traversal - * @param glob the glob pattern references should match - * @return 0 or an error code - */ -GIT_EXTERN(int) git_revwalk_push_glob(git_revwalk *walk, const char *glob); - -/** - * Push the repository's HEAD - * - * @param walk the walker being used for the traversal - * @return 0 or an error code - */ -GIT_EXTERN(int) git_revwalk_push_head(git_revwalk *walk); - -/** - * Mark a commit (and its ancestors) uninteresting for the output. - * - * The given OID must belong to a commit on the walked - * repository. - * - * The resolved commit and all its parents will be hidden from the - * output on the revision walk. - * - * @param walk the walker being used for the traversal. - * @param oid the oid of commit that will be ignored during the traversal - * @return 0 or an error code - */ -GIT_EXTERN(int) git_revwalk_hide(git_revwalk *walk, const git_oid *oid); - -/** - * Hide matching references. - * - * The OIDs pointed to by the references that match the given glob - * pattern and their ancestors will be hidden from the output on the - * revision walk. - * - * A leading 'refs/' is implied if not present as well as a trailing - * '/ *' if the glob lacks '?', '*' or '['. - * - * @param walk the walker being used for the traversal - * @param glob the glob pattern references should match - * @return 0 or an error code - */ -GIT_EXTERN(int) git_revwalk_hide_glob(git_revwalk *walk, const char *glob); - -/** - * Hide the repository's HEAD - * - * @param walk the walker being used for the traversal - * @return 0 or an error code - */ -GIT_EXTERN(int) git_revwalk_hide_head(git_revwalk *walk); - -/** - * Push the OID pointed to by a reference - * - * The reference must point to a commit. - * - * @param walk the walker being used for the traversal - * @param refname the reference to push - * @return 0 or an error code - */ -GIT_EXTERN(int) git_revwalk_push_ref(git_revwalk *walk, const char *refname); - -/** - * Hide the OID pointed to by a reference - * - * The reference must point to a commit. - * - * @param walk the walker being used for the traversal - * @param refname the reference to hide - * @return 0 or an error code - */ -GIT_EXTERN(int) git_revwalk_hide_ref(git_revwalk *walk, const char *refname); - -/** - * Get the next commit from the revision walk. - * - * The initial call to this method is *not* blocking when - * iterating through a repo with a time-sorting mode. - * - * Iterating with Topological or inverted modes makes the initial - * call blocking to preprocess the commit list, but this block should be - * mostly unnoticeable on most repositories (topological preprocessing - * times at 0.3s on the git.git repo). - * - * The revision walker is reset when the walk is over. - * - * @param oid Pointer where to store the oid of the next commit - * @param walk the walker to pop the commit from. - * @return 0 if the next commit was found; - * GIT_ITEROVER if there are no commits left to iterate - */ -GIT_EXTERN(int) git_revwalk_next(git_oid *oid, git_revwalk *walk); - -/** - * Change the sorting mode when iterating through the - * repository's contents. - * - * Changing the sorting mode resets the walker. - * - * @param walk the walker being used for the traversal. - * @param sort_mode combination of GIT_SORT_XXX flags - */ -GIT_EXTERN(void) git_revwalk_sorting(git_revwalk *walk, unsigned int sort_mode); - -/** - * Free a revision walker previously allocated. - * - * @param walk traversal handle to close. If NULL nothing occurs. - */ -GIT_EXTERN(void) git_revwalk_free(git_revwalk *walk); - -/** - * Return the repository on which this walker - * is operating. - * - * @param walk the revision walker - * @return the repository being walked - */ -GIT_EXTERN(git_repository *) git_revwalk_repository(git_revwalk *walk); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/signature.h b/include/git2/signature.h deleted file mode 100644 index cdbe678795c..00000000000 --- a/include/git2/signature.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_signature_h__ -#define INCLUDE_git_signature_h__ - -#include "common.h" -#include "types.h" - -/** - * @file git2/signature.h - * @brief Git signature creation - * @defgroup git_signature Git signature creation - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Create a new action signature. The signature must be freed - * manually or using git_signature_free - * - * Note: angle brackets ('<' and '>') characters are not allowed - * to be used in either the `name` or the `email` parameter. - * - * @param sig_out new signature, in case of error NULL - * @param name name of the person - * @param email email of the person - * @param time time when the action happened - * @param offset timezone offset in minutes for the time - * @return 0 or an error code - */ -GIT_EXTERN(int) git_signature_new(git_signature **sig_out, const char *name, const char *email, git_time_t time, int offset); - -/** - * Create a new action signature with a timestamp of 'now'. The - * signature must be freed manually or using git_signature_free - * - * @param sig_out new signature, in case of error NULL - * @param name name of the person - * @param email email of the person - * @return 0 or an error code - */ -GIT_EXTERN(int) git_signature_now(git_signature **sig_out, const char *name, const char *email); - - -/** - * Create a copy of an existing signature. - * - * All internal strings are also duplicated. - * @param sig signature to duplicated - * @return a copy of sig, NULL on out of memory - */ -GIT_EXTERN(git_signature *) git_signature_dup(const git_signature *sig); - -/** - * Free an existing signature - * - * @param sig signature to free - */ -GIT_EXTERN(void) git_signature_free(git_signature *sig); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/status.h b/include/git2/status.h deleted file mode 100644 index cc94d768022..00000000000 --- a/include/git2/status.h +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_status_h__ -#define INCLUDE_git_status_h__ - -#include "common.h" -#include "types.h" - -/** - * @file git2/status.h - * @brief Git file status routines - * @defgroup git_status Git file status routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -enum { - GIT_STATUS_CURRENT = 0, - - GIT_STATUS_INDEX_NEW = (1 << 0), - GIT_STATUS_INDEX_MODIFIED = (1 << 1), - GIT_STATUS_INDEX_DELETED = (1 << 2), - - GIT_STATUS_WT_NEW = (1 << 3), - GIT_STATUS_WT_MODIFIED = (1 << 4), - GIT_STATUS_WT_DELETED = (1 << 5), - - GIT_STATUS_IGNORED = (1 << 6), -}; - -/** - * Gather file statuses and run a callback for each one. - * - * The callback is passed the path of the file, the status and the data - * pointer passed to this function. If the callback returns something other - * than 0, this function will stop looping and return GIT_EUSER. - * - * @param repo a repository object - * @param callback the function to call on each file - * @return 0 on success, GIT_EUSER on non-zero callback, or error code - */ -GIT_EXTERN(int) git_status_foreach( - git_repository *repo, - int (*callback)(const char *, unsigned int, void *), - void *payload); - -/** - * Select the files on which to report status. - * - * - GIT_STATUS_SHOW_INDEX_AND_WORKDIR is the default. This is the - * rough equivalent of `git status --porcelain` where each file - * will receive a callback indicating its status in the index and - * in the workdir. - * - GIT_STATUS_SHOW_INDEX_ONLY will only make callbacks for index - * side of status. The status of the index contents relative to - * the HEAD will be given. - * - GIT_STATUS_SHOW_WORKDIR_ONLY will only make callbacks for the - * workdir side of status, reporting the status of workdir content - * relative to the index. - * - GIT_STATUS_SHOW_INDEX_THEN_WORKDIR behaves like index-only - * followed by workdir-only, causing two callbacks to be issued - * per file (first index then workdir). This is slightly more - * efficient than making separate calls. This makes it easier to - * emulate the output of a plain `git status`. - */ -typedef enum { - GIT_STATUS_SHOW_INDEX_AND_WORKDIR = 0, - GIT_STATUS_SHOW_INDEX_ONLY = 1, - GIT_STATUS_SHOW_WORKDIR_ONLY = 2, - GIT_STATUS_SHOW_INDEX_THEN_WORKDIR = 3, -} git_status_show_t; - -/** - * Flags to control status callbacks - * - * - GIT_STATUS_OPT_INCLUDE_UNTRACKED says that callbacks should - * be made on untracked files. These will only be made if the - * workdir files are included in the status "show" option. - * - GIT_STATUS_OPT_INCLUDE_IGNORED says that ignored files should - * get callbacks. Again, these callbacks will only be made if - * the workdir files are included in the status "show" option. - * Right now, there is no option to include all files in - * directories that are ignored completely. - * - GIT_STATUS_OPT_INCLUDE_UNMODIFIED indicates that callback - * should be made even on unmodified files. - * - GIT_STATUS_OPT_EXCLUDE_SUBMODULES indicates that directories - * which appear to be submodules should just be skipped over. - * - GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS indicates that the - * contents of untracked directories should be included in the - * status. Normally if an entire directory is new, then just - * the top-level directory will be included (with a trailing - * slash on the entry name). Given this flag, the directory - * itself will not be included, but all the files in it will. - * - GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH indicates that the given - * path will be treated as a literal path, and not as a pathspec. - */ - -enum { - GIT_STATUS_OPT_INCLUDE_UNTRACKED = (1 << 0), - GIT_STATUS_OPT_INCLUDE_IGNORED = (1 << 1), - GIT_STATUS_OPT_INCLUDE_UNMODIFIED = (1 << 2), - GIT_STATUS_OPT_EXCLUDE_SUBMODULES = (1 << 3), - GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS = (1 << 4), - GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH = (1 << 5), -}; - -/** - * Options to control how callbacks will be made by - * `git_status_foreach_ext()`. - */ -typedef struct { - git_status_show_t show; - unsigned int flags; - git_strarray pathspec; -} git_status_options; - -/** - * Gather file status information and run callbacks as requested. - */ -GIT_EXTERN(int) git_status_foreach_ext( - git_repository *repo, - const git_status_options *opts, - int (*callback)(const char *, unsigned int, void *), - void *payload); - -/** - * Get file status for a single file - * - * @param status_flags the status value - * @param repo a repository object - * @param path the file to retrieve status for, rooted at the repo's workdir - * @return GIT_EINVALIDPATH when `path` points at a folder, GIT_ENOTFOUND when - * the file doesn't exist in any of HEAD, the index or the worktree, - * 0 otherwise - */ -GIT_EXTERN(int) git_status_file( - unsigned int *status_flags, - git_repository *repo, - const char *path); - -/** - * Test if the ignore rules apply to a given file. - * - * This function simply checks the ignore rules to see if they would apply - * to the given file. Unlike git_status_file(), this indicates if the file - * would be ignored regardless of whether the file is already in the index - * or in the repository. - * - * @param ignored boolean returning 0 if the file is not ignored, 1 if it is - * @param repo a repository object - * @param path the file to check ignores for, rooted at the repo's workdir. - * @return 0 if ignore rules could be processed for the file (regardless - * of whether it exists or not), or an error < 0 if they could not. - */ -GIT_EXTERN(int) git_status_should_ignore( - int *ignored, - git_repository *repo, - const char *path); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/stdint.h b/include/git2/stdint.h deleted file mode 100644 index c66fbb817c0..00000000000 --- a/include/git2/stdint.h +++ /dev/null @@ -1,247 +0,0 @@ -// ISO C9x compliant stdint.h for Microsoft Visual Studio -// Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124 -// -// Copyright (c) 2006-2008 Alexander Chemeris -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// 1. Redistributions of source code must retain the above copyright notice, -// this list of conditions and the following disclaimer. -// -// 2. Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// -// 3. The name of the author may be used to endorse or promote products -// derived from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef _MSC_VER // [ -#error "Use this header only with Microsoft Visual C++ compilers!" -#endif // _MSC_VER ] - -#ifndef _MSC_STDINT_H_ // [ -#define _MSC_STDINT_H_ - -#if _MSC_VER > 1000 -#pragma once -#endif - -#include - -// For Visual Studio 6 in C++ mode and for many Visual Studio versions when -// compiling for ARM we should wrap include with 'extern "C++" {}' -// or compiler give many errors like this: -// error C2733: second C linkage of overloaded function 'wmemchr' not allowed -#ifdef __cplusplus -extern "C" { -#endif -# include -#ifdef __cplusplus -} -#endif - -// Define _W64 macros to mark types changing their size, like intptr_t. -#ifndef _W64 -# if !defined(__midl) && (defined(_X86_) || defined(_M_IX86)) && _MSC_VER >= 1300 -# define _W64 __w64 -# else -# define _W64 -# endif -#endif - - -// 7.18.1 Integer types - -// 7.18.1.1 Exact-width integer types - -// Visual Studio 6 and Embedded Visual C++ 4 doesn't -// realize that, e.g. char has the same size as __int8 -// so we give up on __intX for them. -#if (_MSC_VER < 1300) - typedef signed char int8_t; - typedef signed short int16_t; - typedef signed int int32_t; - typedef unsigned char uint8_t; - typedef unsigned short uint16_t; - typedef unsigned int uint32_t; -#else - typedef signed __int8 int8_t; - typedef signed __int16 int16_t; - typedef signed __int32 int32_t; - typedef unsigned __int8 uint8_t; - typedef unsigned __int16 uint16_t; - typedef unsigned __int32 uint32_t; -#endif -typedef signed __int64 int64_t; -typedef unsigned __int64 uint64_t; - - -// 7.18.1.2 Minimum-width integer types -typedef int8_t int_least8_t; -typedef int16_t int_least16_t; -typedef int32_t int_least32_t; -typedef int64_t int_least64_t; -typedef uint8_t uint_least8_t; -typedef uint16_t uint_least16_t; -typedef uint32_t uint_least32_t; -typedef uint64_t uint_least64_t; - -// 7.18.1.3 Fastest minimum-width integer types -typedef int8_t int_fast8_t; -typedef int16_t int_fast16_t; -typedef int32_t int_fast32_t; -typedef int64_t int_fast64_t; -typedef uint8_t uint_fast8_t; -typedef uint16_t uint_fast16_t; -typedef uint32_t uint_fast32_t; -typedef uint64_t uint_fast64_t; - -// 7.18.1.4 Integer types capable of holding object pointers -#ifdef _WIN64 // [ - typedef signed __int64 intptr_t; - typedef unsigned __int64 uintptr_t; -#else // _WIN64 ][ - typedef _W64 signed int intptr_t; - typedef _W64 unsigned int uintptr_t; -#endif // _WIN64 ] - -// 7.18.1.5 Greatest-width integer types -typedef int64_t intmax_t; -typedef uint64_t uintmax_t; - - -// 7.18.2 Limits of specified-width integer types - -#if !defined(__cplusplus) || defined(__STDC_LIMIT_MACROS) // [ See footnote 220 at page 257 and footnote 221 at page 259 - -// 7.18.2.1 Limits of exact-width integer types -#define INT8_MIN ((int8_t)_I8_MIN) -#define INT8_MAX _I8_MAX -#define INT16_MIN ((int16_t)_I16_MIN) -#define INT16_MAX _I16_MAX -#define INT32_MIN ((int32_t)_I32_MIN) -#define INT32_MAX _I32_MAX -#define INT64_MIN ((int64_t)_I64_MIN) -#define INT64_MAX _I64_MAX -#define UINT8_MAX _UI8_MAX -#define UINT16_MAX _UI16_MAX -#define UINT32_MAX _UI32_MAX -#define UINT64_MAX _UI64_MAX - -// 7.18.2.2 Limits of minimum-width integer types -#define INT_LEAST8_MIN INT8_MIN -#define INT_LEAST8_MAX INT8_MAX -#define INT_LEAST16_MIN INT16_MIN -#define INT_LEAST16_MAX INT16_MAX -#define INT_LEAST32_MIN INT32_MIN -#define INT_LEAST32_MAX INT32_MAX -#define INT_LEAST64_MIN INT64_MIN -#define INT_LEAST64_MAX INT64_MAX -#define UINT_LEAST8_MAX UINT8_MAX -#define UINT_LEAST16_MAX UINT16_MAX -#define UINT_LEAST32_MAX UINT32_MAX -#define UINT_LEAST64_MAX UINT64_MAX - -// 7.18.2.3 Limits of fastest minimum-width integer types -#define INT_FAST8_MIN INT8_MIN -#define INT_FAST8_MAX INT8_MAX -#define INT_FAST16_MIN INT16_MIN -#define INT_FAST16_MAX INT16_MAX -#define INT_FAST32_MIN INT32_MIN -#define INT_FAST32_MAX INT32_MAX -#define INT_FAST64_MIN INT64_MIN -#define INT_FAST64_MAX INT64_MAX -#define UINT_FAST8_MAX UINT8_MAX -#define UINT_FAST16_MAX UINT16_MAX -#define UINT_FAST32_MAX UINT32_MAX -#define UINT_FAST64_MAX UINT64_MAX - -// 7.18.2.4 Limits of integer types capable of holding object pointers -#ifdef _WIN64 // [ -# define INTPTR_MIN INT64_MIN -# define INTPTR_MAX INT64_MAX -# define UINTPTR_MAX UINT64_MAX -#else // _WIN64 ][ -# define INTPTR_MIN INT32_MIN -# define INTPTR_MAX INT32_MAX -# define UINTPTR_MAX UINT32_MAX -#endif // _WIN64 ] - -// 7.18.2.5 Limits of greatest-width integer types -#define INTMAX_MIN INT64_MIN -#define INTMAX_MAX INT64_MAX -#define UINTMAX_MAX UINT64_MAX - -// 7.18.3 Limits of other integer types - -#ifdef _WIN64 // [ -# define PTRDIFF_MIN _I64_MIN -# define PTRDIFF_MAX _I64_MAX -#else // _WIN64 ][ -# define PTRDIFF_MIN _I32_MIN -# define PTRDIFF_MAX _I32_MAX -#endif // _WIN64 ] - -#define SIG_ATOMIC_MIN INT_MIN -#define SIG_ATOMIC_MAX INT_MAX - -#ifndef SIZE_MAX // [ -# ifdef _WIN64 // [ -# define SIZE_MAX _UI64_MAX -# else // _WIN64 ][ -# define SIZE_MAX _UI32_MAX -# endif // _WIN64 ] -#endif // SIZE_MAX ] - -// WCHAR_MIN and WCHAR_MAX are also defined in -#ifndef WCHAR_MIN // [ -# define WCHAR_MIN 0 -#endif // WCHAR_MIN ] -#ifndef WCHAR_MAX // [ -# define WCHAR_MAX _UI16_MAX -#endif // WCHAR_MAX ] - -#define WINT_MIN 0 -#define WINT_MAX _UI16_MAX - -#endif // __STDC_LIMIT_MACROS ] - - -// 7.18.4 Limits of other integer types - -#if !defined(__cplusplus) || defined(__STDC_CONSTANT_MACROS) // [ See footnote 224 at page 260 - -// 7.18.4.1 Macros for minimum-width integer constants - -#define INT8_C(val) val##i8 -#define INT16_C(val) val##i16 -#define INT32_C(val) val##i32 -#define INT64_C(val) val##i64 - -#define UINT8_C(val) val##ui8 -#define UINT16_C(val) val##ui16 -#define UINT32_C(val) val##ui32 -#define UINT64_C(val) val##ui64 - -// 7.18.4.2 Macros for greatest-width integer constants -#define INTMAX_C INT64_C -#define UINTMAX_C UINT64_C - -#endif // __STDC_CONSTANT_MACROS ] - - -#endif // _MSC_STDINT_H_ ] diff --git a/include/git2/submodule.h b/include/git2/submodule.h deleted file mode 100644 index 28057d26f6e..00000000000 --- a/include/git2/submodule.h +++ /dev/null @@ -1,502 +0,0 @@ -/* - * Copyright (C) 2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_submodule_h__ -#define INCLUDE_git_submodule_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" - -/** - * @file git2/submodule.h - * @brief Git submodule management utilities - * @defgroup git_submodule Git submodule management routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Opaque structure representing a submodule. - * - * Submodule support in libgit2 builds a list of known submodules and keeps - * it in the repository. The list is built from the .gitmodules file, the - * .git/config file, the index, and the HEAD tree. Items in the working - * directory that look like submodules (i.e. a git repo) but are not - * mentioned in those places won't be tracked. - */ -typedef struct git_submodule git_submodule; - -/** - * Values that could be specified for the update rule of a submodule. - * - * Use the DEFAULT value if you have altered the update value via - * `git_submodule_set_update()` and wish to reset to the original default. - */ -typedef enum { - GIT_SUBMODULE_UPDATE_DEFAULT = -1, - GIT_SUBMODULE_UPDATE_CHECKOUT = 0, - GIT_SUBMODULE_UPDATE_REBASE = 1, - GIT_SUBMODULE_UPDATE_MERGE = 2, - GIT_SUBMODULE_UPDATE_NONE = 3 -} git_submodule_update_t; - -/** - * Values that could be specified for how closely to examine the - * working directory when getting submodule status. - * - * Use the DEFUALT value if you have altered the ignore value via - * `git_submodule_set_ignore()` and wish to reset to the original value. - */ -typedef enum { - GIT_SUBMODULE_IGNORE_DEFAULT = -1, /* reset to default */ - GIT_SUBMODULE_IGNORE_NONE = 0, /* any change or untracked == dirty */ - GIT_SUBMODULE_IGNORE_UNTRACKED = 1, /* dirty if tracked files change */ - GIT_SUBMODULE_IGNORE_DIRTY = 2, /* only dirty if HEAD moved */ - GIT_SUBMODULE_IGNORE_ALL = 3 /* never dirty */ -} git_submodule_ignore_t; - -/** - * Return codes for submodule status. - * - * A combination of these flags will be returned to describe the status of a - * submodule. Depending on the "ignore" property of the submodule, some of - * the flags may never be returned because they indicate changes that are - * supposed to be ignored. - * - * Submodule info is contained in 4 places: the HEAD tree, the index, config - * files (both .git/config and .gitmodules), and the working directory. Any - * or all of those places might be missing information about the submodule - * depending on what state the repo is in. We consider all four places to - * build the combination of status flags. - * - * There are four values that are not really status, but give basic info - * about what sources of submodule data are available. These will be - * returned even if ignore is set to "ALL". - * - * * IN_HEAD - superproject head contains submodule - * * IN_INDEX - superproject index contains submodule - * * IN_CONFIG - superproject gitmodules has submodule - * * IN_WD - superproject workdir has submodule - * - * The following values will be returned so long as ignore is not "ALL". - * - * * INDEX_ADDED - in index, not in head - * * INDEX_DELETED - in head, not in index - * * INDEX_MODIFIED - index and head don't match - * * WD_UNINITIALIZED - workdir contains empty directory - * * WD_ADDED - in workdir, not index - * * WD_DELETED - in index, not workdir - * * WD_MODIFIED - index and workdir head don't match - * - * The following can only be returned if ignore is "NONE" or "UNTRACKED". - * - * * WD_INDEX_MODIFIED - submodule workdir index is dirty - * * WD_WD_MODIFIED - submodule workdir has modified files - * - * Lastly, the following will only be returned for ignore "NONE". - * - * * WD_UNTRACKED - wd contains untracked files - */ -typedef enum { - GIT_SUBMODULE_STATUS_IN_HEAD = (1u << 0), - GIT_SUBMODULE_STATUS_IN_INDEX = (1u << 1), - GIT_SUBMODULE_STATUS_IN_CONFIG = (1u << 2), - GIT_SUBMODULE_STATUS_IN_WD = (1u << 3), - GIT_SUBMODULE_STATUS_INDEX_ADDED = (1u << 4), - GIT_SUBMODULE_STATUS_INDEX_DELETED = (1u << 5), - GIT_SUBMODULE_STATUS_INDEX_MODIFIED = (1u << 6), - GIT_SUBMODULE_STATUS_WD_UNINITIALIZED = (1u << 7), - GIT_SUBMODULE_STATUS_WD_ADDED = (1u << 8), - GIT_SUBMODULE_STATUS_WD_DELETED = (1u << 9), - GIT_SUBMODULE_STATUS_WD_MODIFIED = (1u << 10), - GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED = (1u << 11), - GIT_SUBMODULE_STATUS_WD_WD_MODIFIED = (1u << 12), - GIT_SUBMODULE_STATUS_WD_UNTRACKED = (1u << 13), -} git_submodule_status_t; - -#define GIT_SUBMODULE_STATUS_IS_UNMODIFIED(S) \ - (((S) & ~(GIT_SUBMODULE_STATUS_IN_HEAD | GIT_SUBMODULE_STATUS_IN_INDEX | \ - GIT_SUBMODULE_STATUS_IN_CONFIG | GIT_SUBMODULE_STATUS_IN_WD)) == 0) - -/** - * Lookup submodule information by name or path. - * - * Given either the submodule name or path (they are usually the same), this - * returns a structure describing the submodule. - * - * There are two expected error scenarios: - * - * - The submodule is not mentioned in the HEAD, the index, and the config, - * but does "exist" in the working directory (i.e. there is a subdirectory - * that is a valid self-contained git repo). In this case, this function - * returns GIT_EEXISTS to indicate the the submodule exists but not in a - * state where a git_submodule can be instantiated. - * - The submodule is not mentioned in the HEAD, index, or config and the - * working directory doesn't contain a value git repo at that path. - * There may or may not be anything else at that path, but nothing that - * looks like a submodule. In this case, this returns GIT_ENOTFOUND. - * - * The submodule object is owned by the containing repo and will be freed - * when the repo is freed. The caller need not free the submodule. - * - * @param submodule Pointer to submodule description object pointer.. - * @param repo The repository. - * @param name The name of the submodule. Trailing slashes will be ignored. - * @return 0 on success, GIT_ENOTFOUND if submodule does not exist, - * GIT_EEXISTS if submodule exists in working directory only, -1 on - * other errors. - */ -GIT_EXTERN(int) git_submodule_lookup( - git_submodule **submodule, - git_repository *repo, - const char *name); - -/** - * Iterate over all tracked submodules of a repository. - * - * See the note on `git_submodule` above. This iterates over the tracked - * submodules as decribed therein. - * - * If you are concerned about items in the working directory that look like - * submodules but are not tracked, the diff API will generate a diff record - * for workdir items that look like submodules but are not tracked, showing - * them as added in the workdir. Also, the status API will treat the entire - * subdirectory of a contained git repo as a single GIT_STATUS_WT_NEW item. - * - * @param repo The repository - * @param callback Function to be called with the name of each submodule. - * Return a non-zero value to terminate the iteration. - * @param payload Extra data to pass to callback - * @return 0 on success, -1 on error, or non-zero return value of callback - */ -GIT_EXTERN(int) git_submodule_foreach( - git_repository *repo, - int (*callback)(git_submodule *sm, const char *name, void *payload), - void *payload); - -/** - * Set up a new git submodule for checkout. - * - * This does "git submodule add" up to the fetch and checkout of the - * submodule contents. It preps a new submodule, creates an entry in - * .gitmodules and creates an empty initialized repository either at the - * given path in the working directory or in .git/modules with a gitlink - * from the working directory to the new repo. - * - * To fully emulate "git submodule add" call this function, then open the - * submodule repo and perform the clone step as needed. Lastly, call - * `git_submodule_add_finalize()` to wrap up adding the new submodule and - * .gitmodules to the index to be ready to commit. - * - * @param submodule The newly created submodule ready to open for clone - * @param repo Superproject repository to contain the new submodule - * @param url URL for the submodules remote - * @param path Path at which the submodule should be created - * @param use_gitlink Should workdir contain a gitlink to the repo in - * .git/modules vs. repo directly in workdir. - * @return 0 on success, GIT_EEXISTS if submodule already exists, - * -1 on other errors. - */ -GIT_EXTERN(int) git_submodule_add_setup( - git_submodule **submodule, - git_repository *repo, - const char *url, - const char *path, - int use_gitlink); - -/** - * Resolve the setup of a new git submodule. - * - * This should be called on a submodule once you have called add setup - * and done the clone of the submodule. This adds the .gitmodules file - * and the newly cloned submodule to the index to be ready to be committed - * (but doesn't actually do the commit). - * - * @param submodule The submodule to finish adding. - */ -GIT_EXTERN(int) git_submodule_add_finalize(git_submodule *submodule); - -/** - * Add current submodule HEAD commit to index of superproject. - * - * @param submodule The submodule to add to the index - * @param write_index Boolean if this should immediately write the index - * file. If you pass this as false, you will have to get the - * git_index and explicitly call `git_index_write()` on it to - * save the change. - * @return 0 on success, <0 on failure - */ -GIT_EXTERN(int) git_submodule_add_to_index( - git_submodule *submodule, - int write_index); - -/** - * Write submodule settings to .gitmodules file. - * - * This commits any in-memory changes to the submodule to the gitmodules - * file on disk. You may also be interested in `git_submodule_init()` which - * writes submodule info to ".git/config" (which is better for local changes - * to submodule settings) and/or `git_submodule_sync()` which writes - * settings about remotes to the actual submodule repository. - * - * @param submodule The submodule to write. - * @return 0 on success, <0 on failure. - */ -GIT_EXTERN(int) git_submodule_save(git_submodule *submodule); - -/** - * Get the containing repository for a submodule. - * - * This returns a pointer to the repository that contains the submodule. - * This is a just a reference to the repository that was passed to the - * original `git_submodule_lookup()` call, so if that repository has been - * freed, then this may be a dangling reference. - * - * @param submodule Pointer to submodule object - * @return Pointer to `git_repository` - */ -GIT_EXTERN(git_repository *) git_submodule_owner(git_submodule *submodule); - -/** - * Get the name of submodule. - * - * @param submodule Pointer to submodule object - * @return Pointer to the submodule name - */ -GIT_EXTERN(const char *) git_submodule_name(git_submodule *submodule); - -/** - * Get the path to the submodule. - * - * The path is almost always the same as the submodule name, but the - * two are actually not required to match. - * - * @param submodule Pointer to submodule object - * @return Pointer to the submodule path - */ -GIT_EXTERN(const char *) git_submodule_path(git_submodule *submodule); - -/** - * Get the URL for the submodule. - * - * @param submodule Pointer to submodule object - * @return Pointer to the submodule url - */ -GIT_EXTERN(const char *) git_submodule_url(git_submodule *submodule); - -/** - * Set the URL for the submodule. - * - * This sets the URL in memory for the submodule. This will be used for - * any following submodule actions while this submodule data is in memory. - * - * After calling this, you may wish to call `git_submodule_save()` to write - * the changes back to the ".gitmodules" file and `git_submodule_sync()` to - * write the changes to the checked out submodule repository. - * - * @param submodule Pointer to the submodule object - * @param url URL that should be used for the submodule - * @return 0 on success, <0 on failure - */ -GIT_EXTERN(int) git_submodule_set_url(git_submodule *submodule, const char *url); - -/** - * Get the OID for the submodule in the index. - * - * @param submodule Pointer to submodule object - * @return Pointer to git_oid or NULL if submodule is not in index. - */ -GIT_EXTERN(const git_oid *) git_submodule_index_oid(git_submodule *submodule); - -/** - * Get the OID for the submodule in the current HEAD tree. - * - * @param submodule Pointer to submodule object - * @return Pointer to git_oid or NULL if submodule is not in the HEAD. - */ -GIT_EXTERN(const git_oid *) git_submodule_head_oid(git_submodule *submodule); - -/** - * Get the OID for the submodule in the current working directory. - * - * This returns the OID that corresponds to looking up 'HEAD' in the checked - * out submodule. If there are pending changes in the index or anything - * else, this won't notice that. You should call `git_submodule_status()` - * for a more complete picture about the state of the working directory. - * - * @param submodule Pointer to submodule object - * @return Pointer to git_oid or NULL if submodule is not checked out. - */ -GIT_EXTERN(const git_oid *) git_submodule_wd_oid(git_submodule *submodule); - -/** - * Get the ignore rule for the submodule. - * - * There are four ignore values: - * - * - **GIT_SUBMODULE_IGNORE_NONE** will consider any change to the contents - * of the submodule from a clean checkout to be dirty, including the - * addition of untracked files. This is the default if unspecified. - * - **GIT_SUBMODULE_IGNORE_UNTRACKED** examines the contents of the - * working tree (i.e. call `git_status_foreach()` on the submodule) but - * UNTRACKED files will not count as making the submodule dirty. - * - **GIT_SUBMODULE_IGNORE_DIRTY** means to only check if the HEAD of the - * submodule has moved for status. This is fast since it does not need to - * scan the working tree of the submodule at all. - * - **GIT_SUBMODULE_IGNORE_ALL** means not to open the submodule repo. - * The working directory will be consider clean so long as there is a - * checked out version present. - */ -GIT_EXTERN(git_submodule_ignore_t) git_submodule_ignore( - git_submodule *submodule); - -/** - * Set the ignore rule for the submodule. - * - * This sets the ignore rule in memory for the submodule. This will be used - * for any following actions (such as `git_submodule_status()`) while the - * submodule is in memory. You should call `git_submodule_save()` if you - * want to persist the new ignore role. - * - * Calling this again with GIT_SUBMODULE_IGNORE_DEFAULT or calling - * `git_submodule_reload()` will revert the rule to the value that was in the - * original config. - * - * @return old value for ignore - */ -GIT_EXTERN(git_submodule_ignore_t) git_submodule_set_ignore( - git_submodule *submodule, - git_submodule_ignore_t ignore); - -/** - * Get the update rule for the submodule. - */ -GIT_EXTERN(git_submodule_update_t) git_submodule_update( - git_submodule *submodule); - -/** - * Set the update rule for the submodule. - * - * This sets the update rule in memory for the submodule. You should call - * `git_submodule_save()` if you want to persist the new update rule. - * - * Calling this again with GIT_SUBMODULE_UPDATE_DEFAULT or calling - * `git_submodule_reload()` will revert the rule to the value that was in the - * original config. - * - * @return old value for update - */ -GIT_EXTERN(git_submodule_update_t) git_submodule_set_update( - git_submodule *submodule, - git_submodule_update_t update); - -/** - * Read the fetchRecurseSubmodules rule for a submodule. - * - * This accesses the submodule..fetchRecurseSubmodules value for - * the submodule that controls fetching behavior for the submodule. - * - * Note that at this time, libgit2 does not honor this setting and the - * fetch functionality current ignores submodules. - * - * @return 0 if fetchRecurseSubmodules is false, 1 if true - */ -GIT_EXTERN(int) git_submodule_fetch_recurse_submodules( - git_submodule *submodule); - -/** - * Set the fetchRecurseSubmodules rule for a submodule. - * - * This sets the submodule..fetchRecurseSubmodules value for - * the submodule. You should call `git_submodule_save()` if you want - * to persist the new value. - * - * @param submodule The submodule to modify - * @param fetch_recurse_submodules Boolean value - * @return old value for fetchRecurseSubmodules - */ -GIT_EXTERN(int) git_submodule_set_fetch_recurse_submodules( - git_submodule *submodule, - int fetch_recurse_submodules); - -/** - * Copy submodule info into ".git/config" file. - * - * Just like "git submodule init", this copies information about the - * submodule into ".git/config". You can use the accessor functions - * above to alter the in-memory git_submodule object and control what - * is written to the config, overriding what is in .gitmodules. - * - * @param submodule The submodule to write into the superproject config - * @param overwrite By default, existing entries will not be overwritten, - * but setting this to true forces them to be updated. - * @return 0 on success, <0 on failure. - */ -GIT_EXTERN(int) git_submodule_init(git_submodule *submodule, int overwrite); - -/** - * Copy submodule remote info into submodule repo. - * - * This copies the information about the submodules URL into the checked out - * submodule config, acting like "git submodule sync". This is useful if - * you have altered the URL for the submodule (or it has been altered by a - * fetch of upstream changes) and you need to update your local repo. - */ -GIT_EXTERN(int) git_submodule_sync(git_submodule *submodule); - -/** - * Open the repository for a submodule. - * - * This is a newly opened repository object. The caller is responsible for - * calling `git_repository_free()` on it when done. Multiple calls to this - * function will return distinct `git_repository` objects. This will only - * work if the submodule is checked out into the working directory. - * - * @param subrepo Pointer to the submodule repo which was opened - * @param submodule Submodule to be opened - * @return 0 on success, <0 if submodule repo could not be opened. - */ -GIT_EXTERN(int) git_submodule_open( - git_repository **repo, - git_submodule *submodule); - -/** - * Reread submodule info from config, index, and HEAD. - * - * Call this to reread cached submodule information for this submodule if - * you have reason to believe that it has changed. - */ -GIT_EXTERN(int) git_submodule_reload(git_submodule *submodule); - -/** - * Reread all submodule info. - * - * Call this to reload all cached submodule information for the repo. - */ -GIT_EXTERN(int) git_submodule_reload_all(git_repository *repo); - -/** - * Get the status for a submodule. - * - * This looks at a submodule and tries to determine the status. It - * will return a combination of the `GIT_SUBMODULE_STATUS` values above. - * How deeply it examines the working directory to do this will depend - * on the `git_submodule_ignore_t` value for the submodule - which can be - * set either temporarily or permanently with `git_submodule_set_ignore()`. - * - * @param status Combination of `GIT_SUBMODULE_STATUS` flags - * @param submodule Submodule for which to get status - * @return 0 on success, <0 on error - */ -GIT_EXTERN(int) git_submodule_status( - unsigned int *status, - git_submodule *submodule); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/tag.h b/include/git2/tag.h deleted file mode 100644 index aab4b77a8e2..00000000000 --- a/include/git2/tag.h +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_tag_h__ -#define INCLUDE_git_tag_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" -#include "object.h" - -/** - * @file git2/tag.h - * @brief Git tag parsing routines - * @defgroup git_tag Git tag management - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Lookup a tag object from the repository. - * - * @param tag pointer to the looked up tag - * @param repo the repo to use when locating the tag. - * @param id identity of the tag to locate. - * @return 0 or an error code - */ -GIT_INLINE(int) git_tag_lookup(git_tag **tag, git_repository *repo, const git_oid *id) -{ - return git_object_lookup((git_object **)tag, repo, id, (git_otype)GIT_OBJ_TAG); -} - -/** - * Lookup a tag object from the repository, - * given a prefix of its identifier (short id). - * - * @see git_object_lookup_prefix - * - * @param tag pointer to the looked up tag - * @param repo the repo to use when locating the tag. - * @param id identity of the tag to locate. - * @param len the length of the short identifier - * @return 0 or an error code - */ -GIT_INLINE(int) git_tag_lookup_prefix(git_tag **tag, git_repository *repo, const git_oid *id, size_t len) -{ - return git_object_lookup_prefix((git_object **)tag, repo, id, len, (git_otype)GIT_OBJ_TAG); -} - -/** - * Close an open tag - * - * This is a wrapper around git_object_free() - * - * IMPORTANT: - * It *is* necessary to call this method when you stop - * using a tag. Failure to do so will cause a memory leak. - * - * @param tag the tag to close - */ - -GIT_INLINE(void) git_tag_free(git_tag *tag) -{ - git_object_free((git_object *) tag); -} - - -/** - * Get the id of a tag. - * - * @param tag a previously loaded tag. - * @return object identity for the tag. - */ -GIT_EXTERN(const git_oid *) git_tag_id(git_tag *tag); - -/** - * Get the tagged object of a tag - * - * This method performs a repository lookup for the - * given object and returns it - * - * @param target pointer where to store the target - * @param tag a previously loaded tag. - * @return 0 or an error code - */ -GIT_EXTERN(int) git_tag_target(git_object **target, git_tag *tag); - -/** - * Get the OID of the tagged object of a tag - * - * @param tag a previously loaded tag. - * @return pointer to the OID - */ -GIT_EXTERN(const git_oid *) git_tag_target_oid(git_tag *tag); - -/** - * Get the type of a tag's tagged object - * - * @param tag a previously loaded tag. - * @return type of the tagged object - */ -GIT_EXTERN(git_otype) git_tag_type(git_tag *tag); - -/** - * Get the name of a tag - * - * @param tag a previously loaded tag. - * @return name of the tag - */ -GIT_EXTERN(const char *) git_tag_name(git_tag *tag); - -/** - * Get the tagger (author) of a tag - * - * @param tag a previously loaded tag. - * @return reference to the tag's author - */ -GIT_EXTERN(const git_signature *) git_tag_tagger(git_tag *tag); - -/** - * Get the message of a tag - * - * @param tag a previously loaded tag. - * @return message of the tag - */ -GIT_EXTERN(const char *) git_tag_message(git_tag *tag); - - -/** - * Create a new tag in the repository from an object - * - * A new reference will also be created pointing to - * this tag object. If `force` is true and a reference - * already exists with the given name, it'll be replaced. - * - * The message will not be cleaned up. This can be achieved - * through `git_message_prettify()`. - * - * @param oid Pointer where to store the OID of the - * newly created tag. If the tag already exists, this parameter - * will be the oid of the existing tag, and the function will - * return a GIT_EEXISTS error code. - * - * @param repo Repository where to store the tag - * - * @param tag_name Name for the tag; this name is validated - * for consistency. It should also not conflict with an - * already existing tag name - * - * @param target Object to which this tag points. This object - * must belong to the given `repo`. - * - * @param tagger Signature of the tagger for this tag, and - * of the tagging time - * - * @param message Full message for this tag - * - * @param force Overwrite existing references - * - * @return 0 or an error code - * A tag object is written to the ODB, and a proper reference - * is written in the /refs/tags folder, pointing to it - */ -GIT_EXTERN(int) git_tag_create( - git_oid *oid, - git_repository *repo, - const char *tag_name, - const git_object *target, - const git_signature *tagger, - const char *message, - int force); - -/** - * Create a new tag in the repository from a buffer - * - * @param oid Pointer where to store the OID of the newly created tag - * @param repo Repository where to store the tag - * @param buffer Raw tag data - * @param force Overwrite existing tags - * @return 0 on success; error code otherwise - */ -GIT_EXTERN(int) git_tag_create_frombuffer( - git_oid *oid, - git_repository *repo, - const char *buffer, - int force); - -/** - * Create a new lightweight tag pointing at a target object - * - * A new direct reference will be created pointing to - * this target object. If `force` is true and a reference - * already exists with the given name, it'll be replaced. - * - * @param oid Pointer where to store the OID of the provided - * target object. If the tag already exists, this parameter - * will be filled with the oid of the existing pointed object - * and the function will return a GIT_EEXISTS error code. - * - * @param repo Repository where to store the lightweight tag - * - * @param tag_name Name for the tag; this name is validated - * for consistency. It should also not conflict with an - * already existing tag name - * - * @param target Object to which this tag points. This object - * must belong to the given `repo`. - * - * @param force Overwrite existing references - * - * @return 0 or an error code - * A proper reference is written in the /refs/tags folder, - * pointing to the provided target object - */ -GIT_EXTERN(int) git_tag_create_lightweight( - git_oid *oid, - git_repository *repo, - const char *tag_name, - const git_object *target, - int force); - -/** - * Delete an existing tag reference. - * - * @param repo Repository where lives the tag - * - * @param tag_name Name of the tag to be deleted; - * this name is validated for consistency. - * - * @return 0 or an error code - */ -GIT_EXTERN(int) git_tag_delete( - git_repository *repo, - const char *tag_name); - -/** - * Fill a list with all the tags in the Repository - * - * The string array will be filled with the names of the - * matching tags; these values are owned by the user and - * should be free'd manually when no longer needed, using - * `git_strarray_free`. - * - * @param tag_names Pointer to a git_strarray structure where - * the tag names will be stored - * @param repo Repository where to find the tags - * @return 0 or an error code - */ -GIT_EXTERN(int) git_tag_list( - git_strarray *tag_names, - git_repository *repo); - -/** - * Fill a list with all the tags in the Repository - * which name match a defined pattern - * - * If an empty pattern is provided, all the tags - * will be returned. - * - * The string array will be filled with the names of the - * matching tags; these values are owned by the user and - * should be free'd manually when no longer needed, using - * `git_strarray_free`. - * - * @param tag_names Pointer to a git_strarray structure where - * the tag names will be stored - * @param pattern Standard fnmatch pattern - * @param repo Repository where to find the tags - * @return 0 or an error code - */ -GIT_EXTERN(int) git_tag_list_match( - git_strarray *tag_names, - const char *pattern, - git_repository *repo); - -/** - * Recursively peel a tag until a non tag git_object - * is met - * - * The retrieved `tag_target` object is owned by the repository - * and should be closed with the `git_object_free` method. - * - * @param tag_target Pointer to the peeled git_object - * @param tag The tag to be processed - * @return 0 or an error code - */ -GIT_EXTERN(int) git_tag_peel( - git_object **tag_target, - git_tag *tag); - -/** @} */ -GIT_END_DECL -#endif diff --git a/include/git2/threads.h b/include/git2/threads.h deleted file mode 100644 index 567a104876c..00000000000 --- a/include/git2/threads.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_threads_h__ -#define INCLUDE_git_threads_h__ - -#include "common.h" - -/** - * @file git2/threads.h - * @brief Library level thread functions - * @defgroup git_thread Threading functions - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Init the threading system. - * - * If libgit2 has been built with GIT_THREADS - * on, this function must be called once before - * any other library functions. - * - * If libgit2 has been built without GIT_THREADS - * support, this function is a no-op. - */ -GIT_EXTERN(void) git_threads_init(void); - -/** - * Shutdown the threading system. - * - * If libgit2 has been built with GIT_THREADS - * on, this function must be called before shutting - * down the library. - * - * If libgit2 has been built without GIT_THREADS - * support, this function is a no-op. - */ -GIT_EXTERN(void) git_threads_shutdown(void); - -/** @} */ -GIT_END_DECL -#endif - diff --git a/include/git2/tree.h b/include/git2/tree.h deleted file mode 100644 index e5261417cd2..00000000000 --- a/include/git2/tree.h +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_tree_h__ -#define INCLUDE_git_tree_h__ - -#include "common.h" -#include "types.h" -#include "oid.h" -#include "object.h" - -/** - * @file git2/tree.h - * @brief Git tree parsing, loading routines - * @defgroup git_tree Git tree parsing, loading routines - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Lookup a tree object from the repository. - * - * @param tree pointer to the looked up tree - * @param repo the repo to use when locating the tree. - * @param id identity of the tree to locate. - * @return 0 or an error code - */ -GIT_INLINE(int) git_tree_lookup(git_tree **tree, git_repository *repo, const git_oid *id) -{ - return git_object_lookup((git_object **)tree, repo, id, GIT_OBJ_TREE); -} - -/** - * Lookup a tree object from the repository, - * given a prefix of its identifier (short id). - * - * @see git_object_lookup_prefix - * - * @param tree pointer to the looked up tree - * @param repo the repo to use when locating the tree. - * @param id identity of the tree to locate. - * @param len the length of the short identifier - * @return 0 or an error code - */ -GIT_INLINE(int) git_tree_lookup_prefix( - git_tree **tree, - git_repository *repo, - const git_oid *id, - size_t len) -{ - return git_object_lookup_prefix((git_object **)tree, repo, id, len, GIT_OBJ_TREE); -} - -/** - * Close an open tree - * - * This is a wrapper around git_object_free() - * - * IMPORTANT: - * It *is* necessary to call this method when you stop - * using a tree. Failure to do so will cause a memory leak. - * - * @param tree the tree to close - */ -GIT_INLINE(void) git_tree_free(git_tree *tree) -{ - git_object_free((git_object *) tree); -} - -/** - * Free a tree entry - * - * IMPORTANT: This function is only needed for tree - * entries owned by the user, such as the ones returned - * by `git_tree_entry_dup`. - * - * @param entry The entry to free - */ -GIT_EXTERN(void) git_tree_entry_free(git_tree_entry *entry); - -/** - * Duplicate a tree entry - * - * Create a copy of a tree entry. The returned copy is owned - * by the user, and must be freed manually with - * `git_tree_entry_free`. - * - * @param entry A tree entry to duplicate - * @return a copy of the original entry - */ -GIT_EXTERN(git_tree_entry *) git_tree_entry_dup(const git_tree_entry *entry); - -/** - * Get the id of a tree. - * - * @param tree a previously loaded tree. - * @return object identity for the tree. - */ -GIT_EXTERN(const git_oid *) git_tree_id(git_tree *tree); - -/** - * Get the number of entries listed in a tree - * - * @param tree a previously loaded tree. - * @return the number of entries in the tree - */ -GIT_EXTERN(unsigned int) git_tree_entrycount(git_tree *tree); - -/** - * Lookup a tree entry by its filename - * - * @param tree a previously loaded tree. - * @param filename the filename of the desired entry - * @return the tree entry; NULL if not found - */ -GIT_EXTERN(const git_tree_entry *) git_tree_entry_byname(git_tree *tree, const char *filename); - -/** - * Lookup a tree entry by its position in the tree - * - * @param tree a previously loaded tree. - * @param idx the position in the entry list - * @return the tree entry; NULL if not found - */ -GIT_EXTERN(const git_tree_entry *) git_tree_entry_byindex(git_tree *tree, size_t idx); - -/** - * Lookup a tree entry by SHA value. - * - * Warning: this must examine every entry in the tree, so it is not fast. - * - * @param tree a previously loaded tree. - * @param oid the sha being looked for - * @return the tree entry; NULL if not found - */ -GIT_EXTERN(const git_tree_entry *) git_tree_entry_byoid(git_tree *tree, const git_oid *oid); - -/** - * Get the UNIX file attributes of a tree entry - * - * @param entry a tree entry - * @return filemode as an integer - */ -GIT_EXTERN(git_filemode_t) git_tree_entry_filemode(const git_tree_entry *entry); - -/** - * Get the filename of a tree entry - * - * @param entry a tree entry - * @return the name of the file - */ -GIT_EXTERN(const char *) git_tree_entry_name(const git_tree_entry *entry); - -/** - * Get the id of the object pointed by the entry - * - * @param entry a tree entry - * @return the oid of the object - */ -GIT_EXTERN(const git_oid *) git_tree_entry_id(const git_tree_entry *entry); - -/** - * Get the type of the object pointed by the entry - * - * @param entry a tree entry - * @return the type of the pointed object - */ -GIT_EXTERN(git_otype) git_tree_entry_type(const git_tree_entry *entry); - -/** - * Convert a tree entry to the git_object it points too. - * - * @param object pointer to the converted object - * @param repo repository where to lookup the pointed object - * @param entry a tree entry - * @return 0 or an error code - */ -GIT_EXTERN(int) git_tree_entry_to_object( - git_object **object_out, - git_repository *repo, - const git_tree_entry *entry); - -/** - * Write a tree to the ODB from the index file - * - * This method will scan the index and write a representation - * of its current state back to disk; it recursively creates - * tree objects for each of the subtrees stored in the index, - * but only returns the OID of the root tree. This is the OID - * that can be used e.g. to create a commit. - * - * The index instance cannot be bare, and needs to be associated - * to an existing repository. - * - * @param oid Pointer where to store the written tree - * @param index Index to write - * @return 0 or an error code - */ -GIT_EXTERN(int) git_tree_create_fromindex(git_oid *oid, git_index *index); - -/** - * Create a new tree builder. - * - * The tree builder can be used to create or modify - * trees in memory and write them as tree objects to the - * database. - * - * If the `source` parameter is not NULL, the tree builder - * will be initialized with the entries of the given tree. - * - * If the `source` parameter is NULL, the tree builder will - * have no entries and will have to be filled manually. - * - * @param builder_p Pointer where to store the tree builder - * @param source Source tree to initialize the builder (optional) - * @return 0 on success; error code otherwise - */ -GIT_EXTERN(int) git_treebuilder_create(git_treebuilder **builder_p, const git_tree *source); - -/** - * Clear all the entires in the builder - * - * @param bld Builder to clear - */ -GIT_EXTERN(void) git_treebuilder_clear(git_treebuilder *bld); - -/** - * Free a tree builder - * - * This will clear all the entries and free to builder. - * Failing to free the builder after you're done using it - * will result in a memory leak - * - * @param bld Builder to free - */ -GIT_EXTERN(void) git_treebuilder_free(git_treebuilder *bld); - -/** - * Get an entry from the builder from its filename - * - * The returned entry is owned by the builder and should - * not be freed manually. - * - * @param bld Tree builder - * @param filename Name of the entry - * @return pointer to the entry; NULL if not found - */ -GIT_EXTERN(const git_tree_entry *) git_treebuilder_get(git_treebuilder *bld, const char *filename); - -/** - * Add or update an entry to the builder - * - * Insert a new entry for `filename` in the builder with the - * given attributes. - * - * if an entry named `filename` already exists, its attributes - * will be updated with the given ones. - * - * The optional pointer `entry_out` can be used to retrieve a - * pointer to the newly created/updated entry. - * - * No attempt is being made to ensure that the provided oid points - * to an existing git object in the object database, nor that the - * attributes make sense regarding the type of the pointed at object. - * - * @param entry_out Pointer to store the entry (optional) - * @param bld Tree builder - * @param filename Filename of the entry - * @param id SHA1 oid of the entry - * @param filemode Folder attributes of the entry. This parameter must - * be valued with one of the following entries: 0040000, 0100644, - * 0100755, 0120000 or 0160000. - * @return 0 or an error code - */ -GIT_EXTERN(int) git_treebuilder_insert( - const git_tree_entry **entry_out, - git_treebuilder *bld, - const char *filename, - const git_oid *id, - git_filemode_t filemode); - -/** - * Remove an entry from the builder by its filename - * - * @param bld Tree builder - * @param filename Filename of the entry to remove - */ -GIT_EXTERN(int) git_treebuilder_remove(git_treebuilder *bld, const char *filename); - -/** - * Filter the entries in the tree - * - * The `filter` callback will be called for each entry - * in the tree with a pointer to the entry and the - * provided `payload`: if the callback returns 1, the - * entry will be filtered (removed from the builder). - * - * @param bld Tree builder - * @param filter Callback to filter entries - */ -GIT_EXTERN(void) git_treebuilder_filter( - git_treebuilder *bld, - int (*filter)(const git_tree_entry *, void *), - void *payload); - -/** - * Write the contents of the tree builder as a tree object - * - * The tree builder will be written to the given `repo`, and - * it's identifying SHA1 hash will be stored in the `oid` - * pointer. - * - * @param oid Pointer where to store the written OID - * @param repo Repository where to store the object - * @param bld Tree builder to write - * @return 0 or an error code - */ -GIT_EXTERN(int) git_treebuilder_write(git_oid *oid, git_repository *repo, git_treebuilder *bld); - -/** - * Retrieve a tree entry contained in a tree or in any - * of its subtrees, given its relative path. - * - * The returned tree entry is owned by the user and must - * be freed manually with `git_tree_entry_free`. - * - * @param entry Pointer where to store the tree entry - * @param root A previously loaded tree which will be the root of the relative path - * @param subtree_path Path to the contained entry - * @return 0 on success; GIT_ENOTFOUND if the path does not exist - */ -GIT_EXTERN(int) git_tree_entry_bypath( - git_tree_entry **entry, - git_tree *root, - const char *path); - -/** Callback for the tree traversal method */ -typedef int (*git_treewalk_cb)(const char *root, const git_tree_entry *entry, void *payload); - -/** Tree traversal modes */ -enum git_treewalk_mode { - GIT_TREEWALK_PRE = 0, /* Pre-order */ - GIT_TREEWALK_POST = 1, /* Post-order */ -}; - -/** - * Traverse the entries in a tree and its subtrees in - * post or pre order - * - * The entries will be traversed in the specified order, - * children subtrees will be automatically loaded as required, - * and the `callback` will be called once per entry with - * the current (relative) root for the entry and the entry - * data itself. - * - * If the callback returns a positive value, the passed entry will be - * skipped on the traversal (in pre mode). A negative value stops the - * walk. - * - * @param tree The tree to walk - * @param callback Function to call on each tree entry - * @param mode Traversal mode (pre or post-order) - * @param payload Opaque pointer to be passed on each callback - * @return 0 or an error code - */ -GIT_EXTERN(int) git_tree_walk(git_tree *tree, git_treewalk_cb callback, int mode, void *payload); - -/** @} */ - -GIT_END_DECL -#endif diff --git a/include/git2/types.h b/include/git2/types.h deleted file mode 100644 index 26e9c57e78b..00000000000 --- a/include/git2/types.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_types_h__ -#define INCLUDE_git_types_h__ - -#include "common.h" - -/** - * @file git2/types.h - * @brief libgit2 base & compatibility types - * @ingroup Git - * @{ - */ -GIT_BEGIN_DECL - -/** - * Cross-platform compatibility types for off_t / time_t - * - * NOTE: This needs to be in a public header so that both the library - * implementation and client applications both agree on the same types. - * Otherwise we get undefined behavior. - * - * Use the "best" types that each platform provides. Currently we truncate - * these intermediate representations for compatibility with the git ABI, but - * if and when it changes to support 64 bit types, our code will naturally - * adapt. - * NOTE: These types should match those that are returned by our internal - * stat() functions, for all platforms. - */ -#include -#ifdef __amigaos4__ -#include -#endif - -#if defined(_MSC_VER) - -typedef __int64 git_off_t; -typedef __time64_t git_time_t; - -#elif defined(__MINGW32__) - -typedef off64_t git_off_t; -typedef __time64_t git_time_t; - -#elif defined(__HAIKU__) - -typedef __haiku_std_int64 git_off_t; -typedef __haiku_std_int64 git_time_t; - -#else /* POSIX */ - -/* - * Note: Can't use off_t since if a client program includes - * before us (directly or indirectly), they'll get 32 bit off_t in their client - * app, even though /we/ define _FILE_OFFSET_BITS=64. - */ -typedef int64_t git_off_t; -typedef int64_t git_time_t; - -#endif - -/** Basic type (loose or packed) of any Git object. */ -typedef enum { - GIT_OBJ_ANY = -2, /**< Object can be any of the following */ - GIT_OBJ_BAD = -1, /**< Object is invalid. */ - GIT_OBJ__EXT1 = 0, /**< Reserved for future use. */ - GIT_OBJ_COMMIT = 1, /**< A commit object. */ - GIT_OBJ_TREE = 2, /**< A tree (directory listing) object. */ - GIT_OBJ_BLOB = 3, /**< A file revision object. */ - GIT_OBJ_TAG = 4, /**< An annotated tag object. */ - GIT_OBJ__EXT2 = 5, /**< Reserved for future use. */ - GIT_OBJ_OFS_DELTA = 6, /**< A delta, base is given by an offset. */ - GIT_OBJ_REF_DELTA = 7, /**< A delta, base is given by object id. */ -} git_otype; - -/** An open object database handle. */ -typedef struct git_odb git_odb; - -/** A custom backend in an ODB */ -typedef struct git_odb_backend git_odb_backend; - -/** An object read from the ODB */ -typedef struct git_odb_object git_odb_object; - -/** A stream to read/write from the ODB */ -typedef struct git_odb_stream git_odb_stream; - -/** - * Representation of an existing git repository, - * including all its object contents - */ -typedef struct git_repository git_repository; - -/** Representation of a generic object in a repository */ -typedef struct git_object git_object; - -/** Representation of an in-progress walk through the commits in a repo */ -typedef struct git_revwalk git_revwalk; - -/** Parsed representation of a tag object. */ -typedef struct git_tag git_tag; - -/** In-memory representation of a blob object. */ -typedef struct git_blob git_blob; - -/** Parsed representation of a commit object. */ -typedef struct git_commit git_commit; - -/** Representation of each one of the entries in a tree object. */ -typedef struct git_tree_entry git_tree_entry; - -/** Representation of a tree object. */ -typedef struct git_tree git_tree; - -/** Constructor for in-memory trees */ -typedef struct git_treebuilder git_treebuilder; - -/** Memory representation of an index file. */ -typedef struct git_index git_index; - -/** Memory representation of a set of config files */ -typedef struct git_config git_config; - -/** Interface to access a configuration file */ -typedef struct git_config_file git_config_file; - -/** Representation of a reference log entry */ -typedef struct git_reflog_entry git_reflog_entry; - -/** Representation of a reference log */ -typedef struct git_reflog git_reflog; - -/** Representation of a git note */ -typedef struct git_note git_note; - -/** Time in a signature */ -typedef struct git_time { - git_time_t time; /** time in seconds from epoch */ - int offset; /** timezone offset, in minutes */ -} git_time; - -/** An action signature (e.g. for committers, taggers, etc) */ -typedef struct git_signature { - char *name; /** full name of the author */ - char *email; /** email of the author */ - git_time when; /** time when the action happened */ -} git_signature; - -/** In-memory representation of a reference. */ -typedef struct git_reference git_reference; - -/** Basic type of any Git reference. */ -typedef enum { - GIT_REF_INVALID = 0, /** Invalid reference */ - GIT_REF_OID = 1, /** A reference which points at an object id */ - GIT_REF_SYMBOLIC = 2, /** A reference which points at another reference */ - GIT_REF_PACKED = 4, - GIT_REF_HAS_PEEL = 8, - GIT_REF_LISTALL = GIT_REF_OID|GIT_REF_SYMBOLIC|GIT_REF_PACKED, -} git_ref_t; - -/** Basic type of any Git branch. */ -typedef enum { - GIT_BRANCH_LOCAL = 1, - GIT_BRANCH_REMOTE = 2, -} git_branch_t; - -/** Kinds of reset operation. */ -typedef enum { - GIT_RESET_SOFT = 1, - GIT_RESET_MIXED = 2, - GIT_RESET_HARD = 3, -} git_reset_type; - -/** Valid modes for index and tree entries. */ -typedef enum { - GIT_FILEMODE_NEW = 0000000, - GIT_FILEMODE_TREE = 0040000, - GIT_FILEMODE_BLOB = 0100644, - GIT_FILEMODE_BLOB_EXECUTABLE = 0100755, - GIT_FILEMODE_LINK = 0120000, - GIT_FILEMODE_COMMIT = 0160000, -} git_filemode_t; - -typedef struct git_refspec git_refspec; -typedef struct git_remote git_remote; - -typedef struct git_remote_head git_remote_head; -typedef struct git_remote_callbacks git_remote_callbacks; - -/** @} */ -GIT_END_DECL - -#endif diff --git a/include/git2/version.h b/include/git2/version.h deleted file mode 100644 index 8edbe323c76..00000000000 --- a/include/git2/version.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (C) 2009-2012 the libgit2 contributors - * - * This file is part of libgit2, distributed under the GNU GPL v2 with - * a Linking Exception. For full terms see the included COPYING file. - */ -#ifndef INCLUDE_git_version_h__ -#define INCLUDE_git_version_h__ - -#define LIBGIT2_VERSION "0.17.0" -#define LIBGIT2_VER_MAJOR 0 -#define LIBGIT2_VER_MINOR 17 -#define LIBGIT2_VER_REVISION 0 - -#endif diff --git a/index.html b/index.html new file mode 100644 index 00000000000..0d4540037ea --- /dev/null +++ b/index.html @@ -0,0 +1,65 @@ + + + + + API Documentation + + + + + + + + + + + + + + + + + diff --git a/js/backbone.js b/js/backbone.js new file mode 100644 index 00000000000..161b401e407 --- /dev/null +++ b/js/backbone.js @@ -0,0 +1,27 @@ +// Backbone.js 0.3.3 +// (c) 2010 Jeremy Ashkenas, DocumentCloud Inc. +// Backbone may be freely distributed under the MIT license. +// For all details and documentation: +// http://documentcloud.github.com/backbone +(function(){var e;e=typeof exports!=="undefined"?exports:this.Backbone={};e.VERSION="0.3.3";var f=this._;if(!f&&typeof require!=="undefined")f=require("underscore")._;var h=this.jQuery||this.Zepto;e.emulateHTTP=false;e.emulateJSON=false;e.Events={bind:function(a,b){this._callbacks||(this._callbacks={});(this._callbacks[a]||(this._callbacks[a]=[])).push(b);return this},unbind:function(a,b){var c;if(a){if(c=this._callbacks)if(b){c=c[a];if(!c)return this;for(var d=0,g=c.length;d/g,">").replace(/"/g, +""")},set:function(a,b){b||(b={});if(!a)return this;if(a.attributes)a=a.attributes;var c=this.attributes,d=this._escapedAttributes;if(!b.silent&&this.validate&&!this._performValidation(a,b))return false;if("id"in a)this.id=a.id;for(var g in a){var i=a[g];if(!f.isEqual(c[g],i)){c[g]=i;delete d[g];if(!b.silent){this._changed=true;this.trigger("change:"+g,this,i,b)}}}!b.silent&&this._changed&&this.change(b);return this},unset:function(a,b){b||(b={});var c={};c[a]=void 0;if(!b.silent&&this.validate&& +!this._performValidation(c,b))return false;delete this.attributes[a];delete this._escapedAttributes[a];if(!b.silent){this._changed=true;this.trigger("change:"+a,this,void 0,b);this.change(b)}return this},clear:function(a){a||(a={});var b=this.attributes,c={};for(attr in b)c[attr]=void 0;if(!a.silent&&this.validate&&!this._performValidation(c,a))return false;this.attributes={};this._escapedAttributes={};if(!a.silent){this._changed=true;for(attr in b)this.trigger("change:"+attr,this,void 0,a);this.change(a)}return this}, +fetch:function(a){a||(a={});var b=this,c=j(a.error,b,a);(this.sync||e.sync)("read",this,function(d){if(!b.set(b.parse(d),a))return false;a.success&&a.success(b,d)},c);return this},save:function(a,b){b||(b={});if(a&&!this.set(a,b))return false;var c=this,d=j(b.error,c,b),g=this.isNew()?"create":"update";(this.sync||e.sync)(g,this,function(i){if(!c.set(c.parse(i),b))return false;b.success&&b.success(c,i)},d);return this},destroy:function(a){a||(a={});var b=this,c=j(a.error,b,a);(this.sync||e.sync)("delete", +this,function(d){b.collection&&b.collection.remove(b);a.success&&a.success(b,d)},c);return this},url:function(){var a=k(this.collection);if(this.isNew())return a;return a+(a.charAt(a.length-1)=="/"?"":"/")+this.id},parse:function(a){return a},clone:function(){return new this.constructor(this)},isNew:function(){return!this.id},change:function(a){this.trigger("change",this,a);this._previousAttributes=f.clone(this.attributes);this._changed=false},hasChanged:function(a){if(a)return this._previousAttributes[a]!= +this.attributes[a];return this._changed},changedAttributes:function(a){a||(a=this.attributes);var b=this._previousAttributes,c=false,d;for(d in a)if(!f.isEqual(b[d],a[d])){c=c||{};c[d]=a[d]}return c},previous:function(a){if(!a||!this._previousAttributes)return null;return this._previousAttributes[a]},previousAttributes:function(){return f.clone(this._previousAttributes)},_performValidation:function(a,b){var c=this.validate(a);if(c){b.error?b.error(this,c):this.trigger("error",this,c,b);return false}return true}}); +e.Collection=function(a,b){b||(b={});if(b.comparator){this.comparator=b.comparator;delete b.comparator}this._boundOnModelEvent=f.bind(this._onModelEvent,this);this._reset();a&&this.refresh(a,{silent:true});this.initialize(a,b)};f.extend(e.Collection.prototype,e.Events,{model:e.Model,initialize:function(){},toJSON:function(){return this.map(function(a){return a.toJSON()})},add:function(a,b){if(f.isArray(a))for(var c=0,d=a.length;c').hide().appendTo("body")[0].contentWindow; +"onhashchange"in window&&!a?h(window).bind("hashchange",this.checkUrl):setInterval(this.checkUrl,this.interval);return this.loadUrl()},route:function(a,b){this.handlers.push({route:a,callback:b})},checkUrl:function(){var a=this.getFragment();if(a==this.fragment&&this.iframe)a=this.getFragment(this.iframe.location);if(a==this.fragment||a==decodeURIComponent(this.fragment))return false;if(this.iframe)window.location.hash=this.iframe.location.hash=a;this.loadUrl()},loadUrl:function(){var a=this.fragment= +this.getFragment();return f.any(this.handlers,function(b){if(b.route.test(a)){b.callback(a);return true}})},saveLocation:function(a){a=(a||"").replace(l,"");if(this.fragment!=a){window.location.hash=this.fragment=a;if(this.iframe&&a!=this.getFragment(this.iframe.location)){this.iframe.document.open().close();this.iframe.location.hash=a}}}});e.View=function(a){this._configure(a||{});this._ensureElement();this.delegateEvents();this.initialize(a)};var q=/^(\w+)\s*(.*)$/;f.extend(e.View.prototype,e.Events, +{tagName:"div",$:function(a){return h(a,this.el)},initialize:function(){},render:function(){return this},remove:function(){h(this.el).remove();return this},make:function(a,b,c){a=document.createElement(a);b&&h(a).attr(b);c&&h(a).html(c);return a},delegateEvents:function(a){if(a||(a=this.events)){h(this.el).unbind();for(var b in a){var c=a[b],d=b.match(q),g=d[1];d=d[2];c=f.bind(this[c],this);d===""?h(this.el).bind(g,c):h(this.el).delegate(d,g,c)}}},_configure:function(a){if(this.options)a=f.extend({}, +this.options,a);if(a.model)this.model=a.model;if(a.collection)this.collection=a.collection;if(a.el)this.el=a.el;if(a.id)this.id=a.id;if(a.className)this.className=a.className;if(a.tagName)this.tagName=a.tagName;this.options=a},_ensureElement:function(){if(!this.el){var a={};if(this.id)a.id=this.id;if(this.className)a["class"]=this.className;this.el=this.make(this.tagName,a)}}});var m=function(a,b){var c=r(this,a,b);c.extend=m;return c};e.Model.extend=e.Collection.extend=e.Controller.extend=e.View.extend= +m;var s={create:"POST",update:"PUT","delete":"DELETE",read:"GET"};e.sync=function(a,b,c,d){var g=s[a];a=a==="create"||a==="update"?JSON.stringify(b.toJSON()):null;b={url:k(b),type:g,contentType:"application/json",data:a,dataType:"json",processData:false,success:c,error:d};if(e.emulateJSON){b.contentType="application/x-www-form-urlencoded";b.processData=true;b.data=a?{model:a}:{}}if(e.emulateHTTP)if(g==="PUT"||g==="DELETE"){if(e.emulateJSON)b.data._method=g;b.type="POST";b.beforeSend=function(i){i.setRequestHeader("X-HTTP-Method-Override", +g)}}h.ajax(b)};var n=function(){},r=function(a,b,c){var d;d=b&&b.hasOwnProperty("constructor")?b.constructor:function(){return a.apply(this,arguments)};n.prototype=a.prototype;d.prototype=new n;b&&f.extend(d.prototype,b);c&&f.extend(d,c);d.prototype.constructor=d;d.__super__=a.prototype;return d},k=function(a){if(!(a&&a.url))throw Error("A 'url' property or function must be specified");return f.isFunction(a.url)?a.url():a.url},j=function(a,b,c){return function(d){a?a(b,d):b.trigger("error",b,d,c)}}})(); diff --git a/js/docurium.js b/js/docurium.js new file mode 100644 index 00000000000..b5a9cbdcb8d --- /dev/null +++ b/js/docurium.js @@ -0,0 +1,682 @@ +$(function() { + // our document model - stores the datastructure generated from docurium + var Docurium = Backbone.Model.extend({ + + defaults: {'version': 'unknown'}, + + initialize: function() { + this.loadVersions() + }, + + loadVersions: function() { + $.getJSON("project.json", function(data) { + docurium.set({'versions': data.versions, 'github': data.github, 'signatures': data.signatures, 'name': data.name, 'groups': data.groups}) + if(data.name) { + $('#site-title').text(data.name + ' API') + document.title = data.name + ' API' + } + docurium.setVersionPicker() + docurium.setVersion() + }) + }, + + setVersionPicker: function () { + vers = docurium.get('versions') + $('#version-list').empty().hide() + for(var i in vers) { + version = vers[i] + vlink = $('').attr('href', '#' + version).append(version).click( function() { + $('#version-list').hide(100) + }) + $('#version-list').append($('
  • ').append(vlink)) + } + vlink = $('').attr('href', '#' + 'p/changelog').append("Changelog").click ( function () { + $('#version-list').hide(100) + }) + $('#version-list').append($('
  • ').append(vlink)) + }, + + setVersion: function (version) { + if(!version) { + version = _.first(docurium.get('versions')) + } + if(docurium.get('version') != version) { + docurium.set({'version': version}) + $('#site-title').attr('href', '#' + version) + docurium.loadDoc() + } + }, + + loadDoc: function() { + version = this.get('version') + $.ajax({ + url: version + '.json', + context: this, + dataType: 'json', + success: function(data){ + this.set({'data': data}) + Backbone.history.start() + } + }) + }, + + collapseSection: function(data) { + $(this).next().toggle(100) + return false + }, + + showIndexPage: function() { + version = docurium.get('version') + ws.saveLocation(version) + + data = docurium.get('data') + content = $('.content') + content.empty() + + content.append($('

    ').append("Public API Functions")) + + sigHist = docurium.get('signatures') + + // Function Groups + for (var i in data['groups']) { + group = data['groups'][i] + content.append($('

    ').addClass('funcGroup').append(group[0])) + list = $('

    ').addClass('functionList') + for(var j in group[1]) { + fun = group[1][j] + link = $('').attr('href', '#' + groupLink(group[0], fun)).append(fun) + if(sigHist[fun].changes[version]) { + link.addClass('changed') + } + if(version == _.first(sigHist[fun].exists)) { + link.addClass('introd') + } + list.append(link) + if(j < group[1].length - 1) { + list.append(', ') + } + } + content.append(list) + } + }, + + getGroup: function(gname) { + var groups = docurium.get('data')['groups'] + for(var i in groups) { + if(groups[i][0] == gname) { + return groups[i] + } + } + }, + + showFun: function(gname, fname) { + group = docurium.getGroup(gname) + + fdata = docurium.get('data')['functions'] + gname = group[0] + functions = group[1] + + content = $('.content') + content.empty() + + // Show Function Name + content.append($('

    ').addClass('funcTitle').append(fname)) + if(fdata[fname]['description']) { + sub = content.append($('

    ').addClass('funcDesc').append( ' ' + fdata[fname]['description'] )) + } + + // Show Function Arguments + argtable = $('').addClass('funcTable') + args = fdata[fname]['args'] + for(var i=0; i') + row.append($('
    ').attr('valign', 'top').attr('nowrap', true).append(this.hotLink(arg.type))) + row.append($('').attr('valign', 'top').addClass('var').append(arg.name)) + row.append($('').addClass('comment').append(arg.comment)) + argtable.append(row) + } + content.append(argtable) + + // Show Function Return Value + retdiv = $('
    ').addClass('returns') + retdiv.append($('

    ').append("returns")) + rettable = $('').addClass('funcTable') + retrow = $('') + rettable.append(retrow) + retdiv.append(rettable) + + ret = fdata[fname]['return'] + retrow.append($('
    ').attr('valign', 'top').append(this.hotLink(ret.type))) + if(ret.comment) { + retrow.append($('').addClass('comment').append(ret.comment)) + } + content.append(retdiv) + + // Show Non-Parsed Function Comments + if (fdata[fname]['comments']) { + content.append($('
    ').append(fdata[fname]['comments']))
    +      }
    +
    +      // Show Function Signature
    +      ex = $('').addClass('params')
    +      ex.append(this.hotLink(fdata[fname]['return']['type'] + ' ' + fname + '(' + fdata[fname]['argline'] + ');'))
    +      example = $('
    ').addClass('example') + example.append($('

    ').append("signature")) + example.append(ex) + content.append(example) + + // Show Function History + sigs = $('
    ').addClass('signatures') + sigs.append($('

    ').append("versions")) + sigHist = docurium.get('signatures')[fname] + for(var i in sigHist.exists) { + ver = sigHist.exists[i] + link = $('').attr('href', '#' + groupLink(gname, fname, ver)).append(ver) + if(sigHist.changes[ver]) { + link.addClass('changed') + } + if(ver == docurium.get('version')) { + link.addClass('current') + } + sigs.append(link) + } + content.append(sigs) + + // Link to Function Def on GitHub + link = this.github_file(fdata[fname].file, fdata[fname].line, fdata[fname].lineto) + flink = $('').attr('target', 'github').attr('href', link).append(fdata[fname].file) + content.append($('
    ').addClass('fileLink').append("Defined in: ").append(flink)) + + // Show where this is used in the examples + if(ex = fdata[fname].examples) { + also = $('
    ').addClass('funcEx') + also.append("Used in examples: ") + for( fname in ex ) { + lines = ex[fname] + line = $('
  • ') + line.append($('').append(fname)) + for( var i in lines ) { + flink = $('').attr('href', lines[i]).append(' [' + (parseInt(i) + 1) + '] ') + line.append(flink) + } + also.append(line) + } + content.append(also) + } + + // Show other functions in this group + also = $('
    ').addClass('also') + flink = $('' + group[0] + '') + flink.click( docurium.showGroup ) + also.append("Also in ") + also.append(flink) + also.append(" group:
    ") + + for(i=0; i').attr('href', '#' + groupLink(gname, f)).append(f) + also.append(link) + also.append(', ') + } + content.append(also) + + + this.addHotlinks() + }, + + showChangeLog: function() { + content = $('.content') + content.empty() + content.append($('

    ').append("Function Changelog")) + // for every version, show which functions added, removed, changed - from HEAD down + versions = docurium.get('versions') + sigHist = docurium.get('signatures') + + lastVer = _.first(versions) + + // fill changelog struct + changelog = {} + for(var i in versions) { + version = versions[i] + changelog[version] = {'deletes': [], 'changes': [], 'adds': []} + } + + // figure out the adds, deletes and changes + for(var func in sigHist) { + lastv = _.last(sigHist[func].exists) + firstv = _.first(sigHist[func].exists) + if (func != '__attribute__') { + changelog[firstv]['adds'].push(func) + } + if(lastv && (lastv != lastVer)) { + vi = _.indexOf(versions, lastv) + delv = versions[vi - 1] + changelog[delv]['deletes'].push(func) + } + for(var v in sigHist[func].changes) { + changelog[v]['changes'].push(func) + } + } + + // display the data + for(var i in versions) { + version = versions[i] + content.append($('

    ').append(version)) + cl = $('
    ').addClass('changelog') + + console.log(version) + + for(var type in changelog[version]) { + adds = changelog[version][type] + adds.sort() + addsection = $('

    ') + for(var j in adds) { + add = adds[j] + if(type != 'deletes') { + gname = docurium.groupOf(add) + addlink = $('').attr('href', '#' + groupLink(gname, add, version)).append(add) + } else { + addlink = add + } + addsection.append($('

  • ').addClass(type).append(addlink)) + } + cl.append(addsection) + } + content.append(cl) + } + }, + + showType: function(data, manual) { + if(manual) { + id = '#typeItem' + domSafe(manual) + ref = parseInt($(id).attr('ref')) + } else { + ref = parseInt($(this).attr('ref')) + } + tdata = docurium.get('data')['types'][ref] + tname = tdata[0] + data = tdata[1] + + ws.saveLocation(typeLink(tname)) + + content = $('.content') + content.empty() + content.append($('

    ').addClass('funcTitle').append(tname).append($("").append(data.type))) + + content.append($('

    ').append(data.value)) + if(data.block) { + content.append($('

    ').append(data.block))
    +      }
    +
    +      var ret = data.used.returns
    +      if (ret.length > 0) {
    +        content.append($('

    ').append('Returns')) + } + for(var i=0; i').attr('href', '#' + groupLink(gname, ret[i])).append(ret[i]) + flink.click( docurium.showFun ) + content.append(flink) + content.append(', ') + } + + var needs = data.used.needs + if (needs.length > 0) { + content.append($('

    ').append('Argument In')) + } + for(var i=0; i').attr('href', '#' + groupLink(gname, needs[i])).append(needs[i]) + flink.click( docurium.showFun ) + content.append(flink) + content.append(', ') + } + + link = docurium.github_file(data.file, data.line, data.lineto) + flink = $('').attr('target', 'github').attr('href', link).append(data.file) + content.append($('
    ').addClass('fileLink').append("Defined in: ").append(flink)) + + return false + }, + + showGroup: function(data, manual, flink) { + if(manual) { + id = '#groupItem' + manual + ref = parseInt($(id).attr('ref')) + } else { + ref = parseInt($(this).attr('ref')) + } + group = docurium.get('data')['groups'][ref] + fdata = docurium.get('data')['functions'] + gname = group[0] + + ws.saveLocation(groupLink(gname)); + + functions = group[1] + $('.content').empty() + $('.content').append($('

    ').append(gname + ' functions')) + + table = $('').addClass('methods') + for(i=0; i') + row.append($('
    ').attr('nowrap', true).attr('valign', 'top').append(d['return']['type'].substring(0, 20))) + link = $('').attr('href', '#' + groupLink(gname, f)).append(f) + row.append($('').attr('valign', 'top').addClass('methodName').append( link )) + args = d['args'] + argtd = $('') + for(j=0; j')) + } + row.append(argtd) + table.append(row) + } + $('.content').append(table) + + for(var i=0; i').attr('href', '#' + groupLink(gname, f)).append(f) + $('.content').append($('

    ').append(link).append($('').append(argsText))) + description = fdata[f]['description'] + if(fdata[f]['comments']) + description += "\n\n" + fdata[f]['comments'] + $('.content').append($('
    ').append(description))
    +      }
    +      return false
    +    },
    +
    +    // look for structs and link them 
    +    hotLink: function(text) {
    +      types = this.get('data')['types']
    +      for(var i=0; i' + typeName + ' '
    +        text = text.replace(re, link)
    +      }
    +      return text
    +    },
    +
    +    groupOf: function (func) {
    +      return this.get('groups')[func]
    +    },
    +
    +    addHotlinks: function() {
    +      types = this.get('data')['types']
    +      for(var i=0; i')
    +      title = $('

    Functions

    ').click( this.collapseSection ) + menu.append(title) + list = $('