mirror of
https://git.proxmox.com/git/libgit2
synced 2025-06-02 23:21:25 +00:00
Merge remote-tracking branch 'source/development' into update-test
Merging main libgit2! Conflicts: CMakeLists.txt src/unix/map.c
This commit is contained in:
commit
c3f35902f3
5
.gitignore
vendored
5
.gitignore
vendored
@ -1,3 +1,6 @@
|
||||
/tests-clar/clar.h
|
||||
/tests-clar/clar_main.c
|
||||
/tests-clar/clar_main.c.rule
|
||||
/apidocs
|
||||
/trash-*.exe
|
||||
/libgit2.pc
|
||||
@ -19,6 +22,8 @@ msvc/Release/
|
||||
*.vc*proj*
|
||||
*.sdf
|
||||
*.opensdf
|
||||
*.aps
|
||||
CMake*
|
||||
*.cmake
|
||||
.DS_Store
|
||||
*~
|
||||
|
39
.travis.yml
Normal file
39
.travis.yml
Normal file
@ -0,0 +1,39 @@
|
||||
# Travis-CI Build for libgit2
|
||||
# see travis-ci.org for details
|
||||
|
||||
# As CMake is not officially supported we use erlang VMs
|
||||
language: erlang
|
||||
|
||||
# Settings to try
|
||||
env:
|
||||
- OPTIONS="-DTHREADSAFE=ON -DCMAKE_BUILD_TYPE=Release"
|
||||
- OPTIONS="-DBUILD_CLAR=ON -DBUILD_EXAMPLES=ON"
|
||||
- CC=i586-mingw32msvc-gcc OPTIONS="-DBUILD_CLAR=OFF -DWIN32=ON -DMINGW=ON"
|
||||
|
||||
# Make sure CMake is installed
|
||||
install:
|
||||
- sudo apt-get install cmake
|
||||
|
||||
# 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 .
|
||||
|
||||
# Only watch the development branch
|
||||
branches:
|
||||
only:
|
||||
- development
|
||||
|
||||
# Notify development list when needed
|
||||
notifications:
|
||||
recipients:
|
||||
- vicent@github.com
|
||||
email:
|
||||
on_success: change
|
||||
on_failure: always
|
64
AUTHORS
Normal file
64
AUTHORS
Normal file
@ -0,0 +1,64 @@
|
||||
The following people contribute or have contributed
|
||||
to the libgit2 project (sorted alphabetically):
|
||||
|
||||
Alex Budovski
|
||||
Alexei Sholik
|
||||
Andreas Ericsson
|
||||
Ankur Sethi
|
||||
Ben Noordhuis
|
||||
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
|
209
CMakeLists.txt
209
CMakeLists.txt
@ -4,7 +4,7 @@
|
||||
# > mkdir build && cd build
|
||||
# > cmake .. [-DSETTINGS=VALUE]
|
||||
# > cmake --build .
|
||||
#
|
||||
#
|
||||
# Testing:
|
||||
# > ctest -V
|
||||
#
|
||||
@ -16,7 +16,7 @@ SET(CMAKE_SYSTEM_NAME "Generic")
|
||||
PROJECT(libgit2 C)
|
||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
|
||||
|
||||
FILE(STRINGS "include/git2.h" GIT2_HEADER REGEX "^#define LIBGIT2_VERSION \"[^\"]*\"$")
|
||||
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}")
|
||||
@ -24,37 +24,26 @@ STRING(REGEX REPLACE "^.*LIBGIT2_VERSION \"[0-9]+\\.[0-9]+\\.([0-9]+).*$" "\\1"
|
||||
SET(LIBGIT2_VERSION_STRING "${LIBGIT2_VERSION_MAJOR}.${LIBGIT2_VERSION_MINOR}.${LIBGIT2_VERSION_REV}")
|
||||
|
||||
# Find required dependencies
|
||||
INCLUDE_DIRECTORIES(deps/zlib src include)
|
||||
INCLUDE_DIRECTORIES(src include deps/http-parser)
|
||||
|
||||
# Try finding openssl
|
||||
#FIND_PACKAGE(OpenSSL)
|
||||
IF (OPENSSL_CRYPTO_LIBRARIES)
|
||||
SET(SHA1_TYPE "openssl" CACHE STRING "Which SHA1 implementation to use: builtin, ppc, openssl")
|
||||
ELSEIF ()
|
||||
SET(SHA1_TYPE "ppc" CACHE STRING "Which SHA1 implementation to use: builtin, ppc")
|
||||
ENDIF ()
|
||||
FILE(GLOB SRC_HTTP deps/http-parser/*.c)
|
||||
|
||||
INCLUDE(FindPkgConfig)
|
||||
IF (NOT WIN32)
|
||||
FIND_PACKAGE(ZLIB)
|
||||
ELSE()
|
||||
# Windows doesn't understand POSIX regex on its own
|
||||
INCLUDE_DIRECTORIES(deps/regex)
|
||||
SET(SRC_REGEX deps/regex/regex.c)
|
||||
ENDIF()
|
||||
|
||||
# Show SQLite3 settings in GUI (if they won't be found out)
|
||||
SET(SQLITE3_INCLUDE_DIRS "" CACHE PATH "SQLite include directory")
|
||||
SET(SQLITE3_LIBRARIES "" CACHE FILEPATH "SQLite library")
|
||||
|
||||
# Are SQLite3 variables already set up? (poor Windows/no pkg-config/no sqlite3.pc)
|
||||
IF (SQLITE3_INCLUDE_DIRS AND SQLITE3_LIBRARIES)
|
||||
SET(SQLITE3_FOUND 1)
|
||||
ENDIF ()
|
||||
|
||||
# Try to find SQLite3 via pkg-config
|
||||
IF (PKG_CONFIG_FOUND AND NOT SQLITE3_FOUND)
|
||||
pkg_check_modules(SQLITE3 sqlite3)
|
||||
ENDIF ()
|
||||
|
||||
# Compile SQLite backend if SQLite3 is available
|
||||
IF (SQLITE3_FOUND)
|
||||
ADD_DEFINITIONS(-DGIT2_SQLITE_BACKEND)
|
||||
INCLUDE_DIRECTORIES(${SQLITE3_INCLUDE_DIRS})
|
||||
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.")
|
||||
@ -63,14 +52,52 @@ 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 (BUILD_TESTS "Build Tests" 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)
|
||||
|
||||
# Build Release by default
|
||||
# Platform specific compilation flags
|
||||
IF (MSVC)
|
||||
# Not using __stdcall with the CRT causes problems
|
||||
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 "Release" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
|
||||
SET(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE)
|
||||
ENDIF ()
|
||||
|
||||
FIND_PACKAGE(OpenSSL)
|
||||
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)
|
||||
@ -79,57 +106,107 @@ IF (THREADSAFE)
|
||||
ADD_DEFINITIONS(-DGIT_THREADS)
|
||||
ENDIF()
|
||||
|
||||
ADD_DEFINITIONS(-D_FILE_OFFSET_BITS=64)
|
||||
|
||||
# Collect sourcefiles
|
||||
FILE(GLOB SRC src/*.c src/backends/*.c)
|
||||
FILE(GLOB SRC_ZLIB deps/zlib/*.c)
|
||||
FILE(GLOB SRC_SHA1 src/block-sha1/*.c)
|
||||
FILE(GLOB SRC_PLAT src/unix/*.c)
|
||||
FILE(GLOB SRC_H include/git2/*.h)
|
||||
|
||||
# On Windows use specific platform sources
|
||||
IF (WIN32 AND NOT CYGWIN)
|
||||
ADD_DEFINITIONS(-DWIN32 -D_DEBUG -D_LIB)
|
||||
FILE(GLOB SRC_PLAT src/win32/*.c)
|
||||
ENDIF ()
|
||||
|
||||
# Specify sha1 implementation
|
||||
IF (SHA1_TYPE STREQUAL "ppc")
|
||||
ADD_DEFINITIONS(-DPPC_SHA1)
|
||||
FILE(GLOB SRC_SHA1 src/ppc/*.c)
|
||||
ELSEIF (SHA1_TYPE STREQUAL "openssl")
|
||||
ADD_DEFINITIONS(-DOPENSSL_SHA1)
|
||||
SET (SRC_SHA1)
|
||||
INCLUDE_DIRECTORIES(${OPENSSL_INCLUDE_DIR})
|
||||
SET (LIB_SHA1 ${OPENSSL_CRYPTO_LIBRARIES})
|
||||
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)
|
||||
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_PLAT} ${SRC_SHA1} ${SRC_ZLIB})
|
||||
TARGET_LINK_LIBRARIES(git2 ${LIB_SHA1} ${CMAKE_THREAD_LIBS_INIT} ${SQLITE3_LIBRARIES})
|
||||
ADD_LIBRARY(git2 ${SRC} ${SRC_ZLIB} ${SRC_HTTP} ${SRC_REGEX} ${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)
|
||||
|
||||
# Install
|
||||
INSTALL(TARGETS git2
|
||||
RUNTIME DESTINATION ${INSTALL_BIN}
|
||||
LIBRARY DESTINATION ${INSTALL_LIB}
|
||||
ARCHIVE DESTINATION ${INSTALL_LIB}
|
||||
INSTALL(TARGETS git2
|
||||
RUNTIME DESTINATION ${INSTALL_BIN}
|
||||
LIBRARY DESTINATION ${INSTALL_LIB}
|
||||
ARCHIVE DESTINATION ${INSTALL_LIB}
|
||||
)
|
||||
INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/libgit2.pc DESTINATION ${INSTALL_LIB}/pkgconfig )
|
||||
INSTALL(DIRECTORY include/git2 DESTINATION ${INSTALL_INC} )
|
||||
INSTALL(FILES include/git2.h DESTINATION ${INSTALL_INC} )
|
||||
|
||||
# Tests
|
||||
IF (BUILD_TESTS)
|
||||
SET(TEST_RESOURCES "${CMAKE_CURRENT_SOURCE_DIR}/tests/resources" CACHE PATH "Path to test resources.")
|
||||
ADD_DEFINITIONS(-DTEST_RESOURCES=\"${TEST_RESOURCES}\")
|
||||
|
||||
ENABLE_TESTING()
|
||||
INCLUDE_DIRECTORIES(tests)
|
||||
IF (BUILD_CLAR)
|
||||
|
||||
FILE(GLOB SRC_TEST tests/t??-*.c)
|
||||
FIND_PACKAGE(PythonInterp REQUIRED)
|
||||
|
||||
ADD_EXECUTABLE(libgit2_test tests/test_main.c tests/test_lib.c tests/test_helpers.c ${SRC} ${SRC_PLAT} ${SRC_SHA1} ${SRC_TEST} ${SRC_ZLIB})
|
||||
TARGET_LINK_LIBRARIES(libgit2_test ${LIB_SHA1} ${CMAKE_THREAD_LIBS_INIT} ${SQLITE3_LIBRARIES})
|
||||
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}\")
|
||||
|
||||
ADD_TEST(libgit2_test libgit2_test)
|
||||
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 (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 ()
|
||||
|
@ -49,7 +49,7 @@ 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_SUCCESS and < 0 for an error.
|
||||
int status codes are 0 for GIT_OK and < 0 for an error.
|
||||
This permits common POSIX result testing:
|
||||
|
||||
----
|
||||
@ -58,7 +58,7 @@ This permits common POSIX result testing:
|
||||
----
|
||||
|
||||
Functions returning a pointer may return NULL instead of an int
|
||||
if there is only one type of failure (ENOMEM).
|
||||
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
|
||||
|
586
COPYING
586
COPYING
@ -1,11 +1,17 @@
|
||||
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 file into combinations with other programs,
|
||||
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
|
||||
@ -71,7 +77,7 @@ 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
|
||||
|
||||
@ -126,7 +132,7 @@ above, provided that you also meet all of these conditions:
|
||||
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
|
||||
@ -184,7 +190,7 @@ 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
|
||||
@ -241,7 +247,7 @@ 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
|
||||
@ -294,7 +300,7 @@ 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
|
||||
@ -354,3 +360,571 @@ 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ı <volkan.yazici@gmail.com>
|
||||
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.
|
||||
|
||||
<one line to give the library's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
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.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1990
|
||||
Ty Coon, President of Vice
|
||||
|
||||
That's all there is to it!
|
||||
|
26
Makefile.embed
Normal file
26
Makefile.embed
Normal file
@ -0,0 +1,26 @@
|
||||
rm=rm -f
|
||||
CC=cc
|
||||
AR=ar cq
|
||||
RANLIB=ranlib
|
||||
LIBNAME=libgit2.a
|
||||
|
||||
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 -fPIC -O2 $(EXTRA_CFLAGS)
|
||||
|
||||
SRCS = $(wildcard src/*.c) $(wildcard src/transports/*.c) $(wildcard src/unix/*.c) $(wildcard src/xdiff/*.c) $(wildcard deps/http-parser/*.c) $(wildcard deps/zlib/*.c)
|
||||
OBJS = $(patsubst %.c,%.o,$(SRCS))
|
||||
|
||||
%.c.o:
|
||||
$(CC) $(CFLAGS) -c $*.c
|
||||
|
||||
all: $(LIBNAME)
|
||||
|
||||
$(LIBNAME): $(OBJS)
|
||||
$(rm) $@
|
||||
$(AR) $@ $(OBJS)
|
||||
$(RANLIB) $@
|
||||
|
||||
clean:
|
||||
$(rm) $(OBJS) $(LIBNAME)
|
160
README.md
160
README.md
@ -1,6 +1,8 @@
|
||||
libgit2 - the Git linkable library
|
||||
======================
|
||||
|
||||
[](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.
|
||||
@ -10,8 +12,9 @@ This basically means that you can link it (unmodified) with any kind of software
|
||||
release its source code.
|
||||
|
||||
* Mailing list: <libgit2@librelist.org>
|
||||
* Archives: <http://librelist.com/browser/libgit2/>
|
||||
* Website: <http://libgit2.github.com>
|
||||
* API documentation: <http://libgit2.github.com/libgit2/modules.html>
|
||||
* API documentation: <http://libgit2.github.com/libgit2>
|
||||
* Usage guide: <http://libgit2.github.com/api.html>
|
||||
|
||||
What It Can Do
|
||||
@ -20,85 +23,27 @@ What It Can Do
|
||||
libgit2 is already very usable.
|
||||
|
||||
* SHA conversions, formatting and shortening
|
||||
* object reading (loose and packed)
|
||||
* object writing (loose)
|
||||
* commit, tag, tree and blob parsing and write-back
|
||||
* abstracted ODB backend system
|
||||
* commit, tag, tree and blob parsing, editing, and write-back
|
||||
* tree traversal
|
||||
* revision walking
|
||||
* index file (staging area) manipulation
|
||||
* custom ODB backends
|
||||
* reference management (including packed references)
|
||||
* ...and more
|
||||
|
||||
|
||||
Building libgit2 - External dependencies
|
||||
========================================
|
||||
|
||||
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.
|
||||
|
||||
Additionally, the following libraries may be used as replacement for built-in functionality:
|
||||
|
||||
* LibSSL **(optional)** <http://www.openssl.org/>
|
||||
|
||||
libgit2 can be built using the SHA1 implementation of LibSSL-Crypto, instead of the built-in custom implementations. Performance wise, they are quite similar.
|
||||
|
||||
Building libgit2 - Using waf
|
||||
======================
|
||||
|
||||
Waf is a minimalist build system which only requires a Python 2.5+ interpreter to run. This is the default build system for libgit2.
|
||||
|
||||
To build libgit2 using waf, first configure the build system by running:
|
||||
|
||||
$ ./waf configure
|
||||
|
||||
Then build the library, either in its shared (libgit2.so) or static form (libgit2.a):
|
||||
|
||||
$ ./waf build-static
|
||||
$ ./waf build-shared
|
||||
|
||||
You can then run the full test suite with:
|
||||
|
||||
$ ./waf test
|
||||
|
||||
And finally you can install the library with (you may need to sudo):
|
||||
|
||||
$ sudo ./waf install
|
||||
|
||||
The waf build system for libgit2 accepts the following flags:
|
||||
|
||||
--debug
|
||||
build the library with debug symbols.
|
||||
Defaults to off.
|
||||
|
||||
--sha1=[builtin|ppc|openssl]
|
||||
use the builtin SHA1 functions, the optimized PPC versions
|
||||
or the SHA1 functions from LibCrypto (OpenSSL).
|
||||
Defaults to 'builtin'.
|
||||
|
||||
--msvc=[7.1|8.0|9.0|10.0]
|
||||
Force a specific version of the MSVC compiler, if more than
|
||||
one version is installed.
|
||||
|
||||
--arch=[ia64|x64|x86|x86_amd64|x86_ia64]
|
||||
Force a specific architecture for compilers that support it.
|
||||
|
||||
--with-sqlite
|
||||
Enable sqlite support.
|
||||
|
||||
--with-redis
|
||||
Enable redis support.
|
||||
|
||||
You can run `./waf --help` to see a full list of install options and
|
||||
targets.
|
||||
|
||||
* 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
|
||||
==============================
|
||||
|
||||
The libgit2 library can also be built using CMake 2.6+ (<http://www.cmake.org>) on all platforms.
|
||||
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+ (<http://www.cmake.org>) on all platforms.
|
||||
|
||||
On most systems you can build the library using the following commands
|
||||
|
||||
@ -113,36 +58,75 @@ 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 <http://www.cmake.org/Wiki/CMake_FAQ>.
|
||||
|
||||
The following CMake variables are declared:
|
||||
|
||||
- `INSTALL_BIN`: Where to install binaries to.
|
||||
- `INSTALL_LIB`: 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:
|
||||
|
||||
* Rugged (Ruby bindings) <https://github.com/libgit2/rugged>
|
||||
* objective-git (Objective-C bindings) <https://github.com/libgit2/objective-git>
|
||||
* pygit2 (Python bindings) <https://github.com/libgit2/pygit2>
|
||||
* libgit2sharp (.NET bindings) <https://github.com/libgit2/libgit2sharp>
|
||||
* php-git (PHP bindings) <https://github.com/libgit2/php-git>
|
||||
* luagit2 (Lua bindings) <https://github.com/libgit2/luagit2>
|
||||
* GitForDelphi (Delphi bindings) <https://github.com/libgit2/GitForDelphi>
|
||||
* node-gitteh (Node.js bindings) <https://github.com/libgit2/node-gitteh>
|
||||
* nodegit (Node.js bindings) <https://github.com/tbranyen/nodegit>
|
||||
* go-git (Go bindings) <https://github.com/str1ngs/go-git>
|
||||
* libqgit2 (C++ QT bindings) <https://projects.kde.org/projects/playground/libs/libqgit2/>
|
||||
* libgit2-ocaml (ocaml bindings) <https://github.com/burdges/libgit2-ocaml>
|
||||
* Geef (Erlang bindings) <https://github.com/schacon/geef>
|
||||
* C++
|
||||
* libqgit2, Qt bindings <https://projects.kde.org/projects/playground/libs/libqgit2/>
|
||||
* Chicken Scheme
|
||||
* chicken-git <https://wiki.call-cc.org/egg/git>
|
||||
* Delphi
|
||||
* GitForDelphi <https://github.com/libgit2/GitForDelphi>
|
||||
* Erlang
|
||||
* Geef <https://github.com/schacon/geef>
|
||||
* Go
|
||||
* go-git <https://github.com/str1ngs/go-git>
|
||||
* GObject
|
||||
* libgit2-glib <http://git.gnome.org/browse/libgit2-glib>
|
||||
* Haskell
|
||||
* hgit2 <https://github.com/norm2782/hgit2>
|
||||
* Lua
|
||||
* luagit2 <https://github.com/libgit2/luagit2>
|
||||
* .NET
|
||||
* libgit2net, low level bindings <https://github.com/txdv/libgit2net>
|
||||
* libgit2sharp <https://github.com/libgit2/libgit2sharp>
|
||||
* Node.js
|
||||
* node-gitteh <https://github.com/libgit2/node-gitteh>
|
||||
* nodegit <https://github.com/tbranyen/nodegit>
|
||||
* Objective-C
|
||||
* objective-git <https://github.com/libgit2/objective-git>
|
||||
* OCaml
|
||||
* libgit2-ocaml <https://github.com/burdges/libgit2-ocaml>
|
||||
* Parrot Virtual Machine
|
||||
* parrot-libgit2 <https://github.com/letolabs/parrot-libgit2>
|
||||
* Perl
|
||||
* git-xs-pm <https://github.com/ingydotnet/git-xs-pm>
|
||||
* PHP
|
||||
* php-git <https://github.com/libgit2/php-git>
|
||||
* Python
|
||||
* pygit2 <https://github.com/libgit2/pygit2>
|
||||
* Ruby
|
||||
* Rugged <https://github.com/libgit2/rugged>
|
||||
* Vala
|
||||
* libgit2.vapi <https://github.com/apmasell/vapis/blob/master/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
|
||||
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.
|
||||
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:
|
||||
@ -150,7 +134,7 @@ GitHub, or join us on the mailing list by sending an email to:
|
||||
libgit2@librelist.com
|
||||
|
||||
|
||||
License
|
||||
License
|
||||
==================================
|
||||
libgit2 is under GPL2 **with linking exemption**. This means you
|
||||
can link to the library with any program, commercial, open source or
|
||||
|
13
api.docurium
Normal file
13
api.docurium
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"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"]}
|
||||
}
|
||||
}
|
24
api.doxygen
24
api.doxygen
@ -1,24 +0,0 @@
|
||||
PROJECT_NAME = libgit2
|
||||
|
||||
INPUT = include/git2
|
||||
QUIET = YES
|
||||
RECURSIVE = YES
|
||||
FILE_PATTERNS = *.h
|
||||
OUTPUT_DIRECTORY = apidocs
|
||||
GENERATE_TAGFILE = apidocs/libgit2.tag
|
||||
|
||||
JAVADOC_AUTOBRIEF = YES
|
||||
MACRO_EXPANSION = YES
|
||||
EXPAND_ONLY_PREDEF = YES
|
||||
OPTIMIZE_OUTPUT_FOR_C = YES
|
||||
STRIP_CODE_COMMENTS = NO
|
||||
FULL_PATH_NAMES = NO
|
||||
CASE_SENSE_NAMES = NO
|
||||
|
||||
PREDEFINED = \
|
||||
"GIT_EXTERN(x)=x" \
|
||||
"GIT_EXTERN_TLS(x)=x" \
|
||||
"GIT_INLINE(x)=x" \
|
||||
"GIT_BEGIN_DECL=" \
|
||||
"GIT_END_DECL=" \
|
||||
DOXYGEN=
|
23
deps/http-parser/LICENSE-MIT
vendored
Normal file
23
deps/http-parser/LICENSE-MIT
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
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.
|
1778
deps/http-parser/http_parser.c
vendored
Normal file
1778
deps/http-parser/http_parser.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
267
deps/http-parser/http_parser.h
vendored
Normal file
267
deps/http-parser/http_parser.h
vendored
Normal file
@ -0,0 +1,267 @@
|
||||
/* 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 <sys/types.h>
|
||||
#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
|
7
deps/regex/config.h
vendored
Normal file
7
deps/regex/config.h
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef _REGEX_CONFIG_H_
|
||||
#define _REGEX_CONFIG_H_
|
||||
|
||||
# define GAWK
|
||||
# define NO_MBSUPPORT
|
||||
|
||||
#endif
|
3856
deps/regex/regcomp.c
vendored
Normal file
3856
deps/regex/regcomp.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
85
deps/regex/regex.c
vendored
Normal file
85
deps/regex/regex.c
vendored
Normal file
@ -0,0 +1,85 @@
|
||||
/* 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 <isamu@yamato.ibm.com>.
|
||||
|
||||
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 <stdio.h> /* for size_t */
|
||||
#endif
|
||||
|
||||
/* On some systems, limits.h sets RE_DUP_MAX to a lower value than
|
||||
GNU regex allows. Include it before <regex.h>, which correctly
|
||||
#undefs RE_DUP_MAX and sets it to the right value. */
|
||||
#include <limits.h>
|
||||
|
||||
#ifdef GAWK
|
||||
#undef alloca
|
||||
#define alloca alloca_is_bad_you_should_never_use_it
|
||||
#endif
|
||||
#include <regex.h>
|
||||
#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 <shlib-compat.h>
|
||||
# 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
|
582
deps/regex/regex.h
vendored
Normal file
582
deps/regex/regex.h
vendored
Normal file
@ -0,0 +1,582 @@
|
||||
#include <stdio.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* 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 <stddef.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
#include <sys/types.h>
|
||||
#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 \<digit> matches <digit>.
|
||||
If not set, then \<digit> 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 */
|
1744
deps/regex/regex_internal.c
vendored
Normal file
1744
deps/regex/regex_internal.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
810
deps/regex/regex_internal.h
vendored
Normal file
810
deps/regex/regex_internal.h
vendored
Normal file
@ -0,0 +1,810 @@
|
||||
/* 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 <isamu@yamato.ibm.com>.
|
||||
|
||||
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 <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined HAVE_LANGINFO_H || defined HAVE_LANGINFO_CODESET || defined _LIBC
|
||||
# include <langinfo.h>
|
||||
#endif
|
||||
#if defined HAVE_LOCALE_H || defined _LIBC
|
||||
# include <locale.h>
|
||||
#endif
|
||||
#if defined HAVE_WCHAR_H || defined _LIBC
|
||||
# include <wchar.h>
|
||||
#endif /* HAVE_WCHAR_H || _LIBC */
|
||||
#if defined HAVE_WCTYPE_H || defined _LIBC
|
||||
# include <wctype.h>
|
||||
#endif /* HAVE_WCTYPE_H || _LIBC */
|
||||
#if defined HAVE_STDBOOL_H || defined _LIBC
|
||||
# include <stdbool.h>
|
||||
#endif /* HAVE_STDBOOL_H || _LIBC */
|
||||
#if !defined(ZOS_USS)
|
||||
#if defined HAVE_STDINT_H || defined _LIBC
|
||||
# include <stdint.h>
|
||||
#endif /* HAVE_STDINT_H || _LIBC */
|
||||
#endif /* !ZOS_USS */
|
||||
#if defined _LIBC
|
||||
# include <bits/libc-lock.h>
|
||||
#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 <ctype.h>, 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 <locale/localeinfo.h>
|
||||
# include <locale/elem-hash.h>
|
||||
# include <locale/coll-lookup.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* This is for other GNU distributions with internationalized messages. */
|
||||
#if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
|
||||
# include <libintl.h>
|
||||
# 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 <malloc.h>
|
||||
# define __libc_use_alloca(n) 0
|
||||
# else
|
||||
# include <alloca.h>
|
||||
/* 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 <locale/weight.h>
|
||||
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 */
|
4369
deps/regex/regexec.c
vendored
Normal file
4369
deps/regex/regexec.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
442
deps/zlib/crc32.c
vendored
Normal file
442
deps/zlib/crc32.c
vendored
Normal file
@ -0,0 +1,442 @@
|
||||
/* 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 <rbrown64@csc.com.au> 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 <stdio.h>
|
||||
# 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 <limits.h>
|
||||
# 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);
|
||||
}
|
441
deps/zlib/crc32.h
vendored
Normal file
441
deps/zlib/crc32.h
vendored
Normal file
@ -0,0 +1,441 @@
|
||||
/* 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
|
||||
}
|
||||
};
|
3
deps/zlib/zconf.h
vendored
3
deps/zlib/zconf.h
vendored
@ -10,9 +10,6 @@
|
||||
|
||||
#include "../../src/common.h"
|
||||
|
||||
#define NO_GZIP
|
||||
#define STDC
|
||||
|
||||
/* Jeez, don't complain about non-prototype
|
||||
* forms, we didn't write zlib */
|
||||
#if defined(_MSC_VER)
|
||||
|
111
docs/error-handling.md
Normal file
111
docs/error-handling.md
Normal file
@ -0,0 +1,111 @@
|
||||
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.
|
2
examples/.gitignore
vendored
Normal file
2
examples/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
general
|
||||
showindex
|
15
examples/Makefile
Normal file
15
examples/Makefile
Normal file
@ -0,0 +1,15 @@
|
||||
.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
|
240
examples/diff.c
Normal file
240
examples/diff.c
Normal file
@ -0,0 +1,240 @@
|
||||
#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;
|
||||
}
|
||||
|
451
examples/general.c
Normal file
451
examples/general.c
Normal file
@ -0,0 +1,451 @@
|
||||
// [**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 <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][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;
|
||||
}
|
||||
|
1
examples/network/.gitignore
vendored
Normal file
1
examples/network/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
/git2
|
14
examples/network/Makefile
Normal file
14
examples/network/Makefile
Normal file
@ -0,0 +1,14 @@
|
||||
default: all
|
||||
|
||||
CC = gcc
|
||||
CFLAGS += -g
|
||||
CFLAGS += -I../../include -L../../ -lgit2 -lpthread
|
||||
|
||||
OBJECTS = \
|
||||
git2.o \
|
||||
ls-remote.o \
|
||||
fetch.o \
|
||||
index-pack.o
|
||||
|
||||
all: $(OBJECTS)
|
||||
$(CC) $(CFLAGS) -o git2 $(OBJECTS)
|
14
examples/network/common.h
Normal file
14
examples/network/common.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef __COMMON_H__
|
||||
#define __COMMON_H__
|
||||
|
||||
#include <git2.h>
|
||||
|
||||
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);
|
||||
|
||||
#endif /* __COMMON_H__ */
|
113
examples/network/fetch.c
Normal file
113
examples/network/fetch.c
Normal file
@ -0,0 +1,113 @@
|
||||
#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.
|
||||
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, update_cb) < 0)
|
||||
return -1;
|
||||
|
||||
git_remote_free(remote);
|
||||
|
||||
return 0;
|
||||
|
||||
on_error:
|
||||
git_remote_free(remote);
|
||||
return -1;
|
||||
}
|
62
examples/network/git2.c
Normal file
62
examples/network/git2.c
Normal file
@ -0,0 +1,62 @@
|
||||
#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;
|
||||
}
|
102
examples/network/index-pack.c
Normal file
102
examples/network/index-pack.c
Normal file
@ -0,0 +1,102 @@
|
||||
#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;
|
||||
}
|
76
examples/network/ls-remote.c
Normal file
76
examples/network/ls-remote.c
Normal file
@ -0,0 +1,76 @@
|
||||
#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;
|
||||
}
|
43
examples/showindex.c
Normal file
43
examples/showindex.c
Normal file
@ -0,0 +1,43 @@
|
||||
#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);
|
||||
}
|
||||
|
@ -61,6 +61,7 @@ ok Pierre Habouzit <madcoder@debian.org>
|
||||
ok Pieter de Bie <pdebie@ai.rug.nl>
|
||||
ok René Scharfe <rene.scharfe@lsrfire.ath.cx>
|
||||
ign Robert Shearman <rob@codeweavers.com> (imap-send)
|
||||
ok Sebastian Schuberth <sschuberth@gmail.com>
|
||||
ok Shawn O. Pearce <spearce@spearce.org>
|
||||
ok Steffen Prohaska <prohaska@zib.de>
|
||||
ok Sven Verdoolaege <skimo@kotnet.org>
|
||||
|
@ -1,39 +1,18 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* 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.
|
||||
* 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__
|
||||
|
||||
#define LIBGIT2_VERSION "0.12.0"
|
||||
#define LIBGIT2_VER_MAJOR 0
|
||||
#define LIBGIT2_VER_MINOR 12
|
||||
#define LIBGIT2_VER_REVISION 0
|
||||
#include "git2/version.h"
|
||||
|
||||
#include "git2/common.h"
|
||||
#include "git2/threads.h"
|
||||
#include "git2/errors.h"
|
||||
#include "git2/zlib.h"
|
||||
|
||||
#include "git2/types.h"
|
||||
|
||||
@ -43,15 +22,26 @@
|
||||
|
||||
#include "git2/repository.h"
|
||||
#include "git2/revwalk.h"
|
||||
#include "git2/merge.h"
|
||||
#include "git2/refs.h"
|
||||
#include "git2/reflog.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/refspec.h"
|
||||
#include "git2/net.h"
|
||||
#include "git2/status.h"
|
||||
#include "git2/indexer.h"
|
||||
#include "git2/submodule.h"
|
||||
#include "git2/notes.h"
|
||||
|
||||
#endif
|
||||
|
224
include/git2/attr.h
Normal file
224
include/git2/attr.h
Normal file
@ -0,0 +1,224 @@
|
||||
/*
|
||||
* 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) ((attr) == git_attr__true)
|
||||
|
||||
/**
|
||||
* 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) ((attr) == git_attr__false)
|
||||
|
||||
/**
|
||||
* 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) (!(attr) || (attr) == git_attr__unset)
|
||||
|
||||
/**
|
||||
* 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) \
|
||||
((attr) && (attr) != git_attr__unset && \
|
||||
(attr) != git_attr__true && (attr) != git_attr__false)
|
||||
|
||||
GIT_EXTERN(const char *) git_attr__true;
|
||||
GIT_EXTERN(const char *) git_attr__false;
|
||||
GIT_EXTERN(const char *) git_attr__unset;
|
||||
|
||||
/**
|
||||
* 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 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 callback The function that will be invoked on each attribute
|
||||
* and attribute value. The name parameter will be the name
|
||||
* of the attribute and the value will be the value it is
|
||||
* set to, including possibly NULL if the attribute is
|
||||
* explicitly set to UNSPECIFIED using the ! sign. This
|
||||
* 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.
|
||||
* @param payload Passed on as extra parameter to callback function.
|
||||
*/
|
||||
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
|
||||
|
@ -1,26 +1,8 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* 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.
|
||||
* 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__
|
||||
@ -45,17 +27,34 @@ GIT_BEGIN_DECL
|
||||
* @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 on success; error code otherwise
|
||||
* @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, unsigned int 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_close()
|
||||
* This is a wrapper around git_object_free()
|
||||
*
|
||||
* IMPORTANT:
|
||||
* It *is* necessary to call this method when you stop
|
||||
@ -64,9 +63,9 @@ GIT_INLINE(int) git_blob_lookup(git_blob **blob, git_repository *repo, const git
|
||||
* @param blob the blob to close
|
||||
*/
|
||||
|
||||
GIT_INLINE(void) git_blob_close(git_blob *blob)
|
||||
GIT_INLINE(void) git_blob_free(git_blob *blob)
|
||||
{
|
||||
git_object_close((git_object *) blob);
|
||||
git_object_free((git_object *) blob);
|
||||
}
|
||||
|
||||
|
||||
@ -89,7 +88,7 @@ GIT_EXTERN(const void *) git_blob_rawcontent(git_blob *blob);
|
||||
* @param blob pointer to the blob
|
||||
* @return size on bytes
|
||||
*/
|
||||
GIT_EXTERN(int) git_blob_rawsize(git_blob *blob);
|
||||
GIT_EXTERN(size_t) git_blob_rawsize(git_blob *blob);
|
||||
|
||||
/**
|
||||
* Read a file from the working folder of a repository
|
||||
@ -100,10 +99,64 @@ GIT_EXTERN(int) git_blob_rawsize(git_blob *blob);
|
||||
* this repository cannot be bare
|
||||
* @param path file from which the blob will be created,
|
||||
* relative to the repository's working dir
|
||||
* @return 0 on success; error code otherwise
|
||||
* @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
|
||||
@ -112,7 +165,7 @@ GIT_EXTERN(int) git_blob_create_fromfile(git_oid *oid, git_repository *repo, con
|
||||
* @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 on success; error code otherwise
|
||||
* @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);
|
||||
|
||||
|
122
include/git2/branch.h
Normal file
122
include/git2/branch.h
Normal file
@ -0,0 +1,122 @@
|
||||
/*
|
||||
* 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 "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.
|
||||
*
|
||||
* @param oid_out Pointer where to store the OID of the target commit.
|
||||
*
|
||||
* @param repo Repository where to store the branch.
|
||||
*
|
||||
* @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_oid *oid_out,
|
||||
git_repository *repo,
|
||||
const char *branch_name,
|
||||
const git_object *target,
|
||||
int force);
|
||||
|
||||
/**
|
||||
* Delete an existing branch reference.
|
||||
*
|
||||
* @param repo Repository where lives the branch.
|
||||
*
|
||||
* @param branch_name Name of the branch to be deleted;
|
||||
* 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 if the branch
|
||||
* doesn't exist or an error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_branch_delete(
|
||||
git_repository *repo,
|
||||
const char *branch_name,
|
||||
git_branch_t branch_type);
|
||||
|
||||
/**
|
||||
* Fill a list with all the branches in the Repository
|
||||
*
|
||||
* The string array will be filled with the names of the
|
||||
* matching branches; these values are owned by the user and
|
||||
* should be free'd manually when no longer needed, using
|
||||
* `git_strarray_free`.
|
||||
*
|
||||
* @param branch_names Pointer to a git_strarray structure
|
||||
* where the branch names will be stored.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @return 0 or an error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_branch_list(
|
||||
git_strarray *branch_names,
|
||||
git_repository *repo,
|
||||
unsigned int list_flags);
|
||||
|
||||
/**
|
||||
* Move/rename an existing branch reference.
|
||||
*
|
||||
* @param repo Repository where lives the branch.
|
||||
*
|
||||
* @param old_branch_name Current name of the branch to be moved;
|
||||
* this name is validated for consistency.
|
||||
*
|
||||
* @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, GIT_ENOTFOUND if the branch
|
||||
* doesn't exist or an error code.
|
||||
*/
|
||||
GIT_EXTERN(int) git_branch_move(
|
||||
git_repository *repo,
|
||||
const char *old_branch_name,
|
||||
const char *new_branch_name,
|
||||
int force);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
@ -1,26 +1,8 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* 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.
|
||||
* 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__
|
||||
@ -44,19 +26,37 @@ GIT_BEGIN_DECL
|
||||
*
|
||||
* @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 on success; error code otherwise
|
||||
* @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, unsigned 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_close()
|
||||
* This is a wrapper around git_object_free()
|
||||
*
|
||||
* IMPORTANT:
|
||||
* It *is* necessary to call this method when you stop
|
||||
@ -65,9 +65,9 @@ GIT_INLINE(int) git_commit_lookup(git_commit **commit, git_repository *repo, con
|
||||
* @param commit the commit to close
|
||||
*/
|
||||
|
||||
GIT_INLINE(void) git_commit_close(git_commit *commit)
|
||||
GIT_INLINE(void) git_commit_free(git_commit *commit)
|
||||
{
|
||||
git_object_close((git_object *) commit);
|
||||
git_object_free((git_object *) commit);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -79,12 +79,16 @@ GIT_INLINE(void) git_commit_close(git_commit *commit)
|
||||
GIT_EXTERN(const git_oid *) git_commit_id(git_commit *commit);
|
||||
|
||||
/**
|
||||
* Get the short (one line) message of a 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 the short message of a commit
|
||||
* @return NULL, or the encoding
|
||||
*/
|
||||
GIT_EXTERN(const char *) git_commit_message_short(git_commit *commit);
|
||||
GIT_EXTERN(const char *) git_commit_message_encoding(git_commit *commit);
|
||||
|
||||
/**
|
||||
* Get the full message of a commit.
|
||||
@ -131,7 +135,7 @@ GIT_EXTERN(const git_signature *) git_commit_author(git_commit *commit);
|
||||
*
|
||||
* @param tree_out pointer where to store the tree object
|
||||
* @param commit a previously loaded commit.
|
||||
* @return 0 on success; error code otherwise
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_commit_tree(git_tree **tree_out, git_commit *commit);
|
||||
|
||||
@ -159,7 +163,7 @@ GIT_EXTERN(unsigned int) git_commit_parentcount(git_commit *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 on success; error code otherwise
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_commit_parent(git_commit **parent, git_commit *commit, unsigned int n);
|
||||
|
||||
@ -175,8 +179,11 @@ GIT_EXTERN(int) git_commit_parent(git_commit **parent, git_commit *commit, unsig
|
||||
GIT_EXTERN(const git_oid *) git_commit_parent_oid(git_commit *commit, unsigned int n);
|
||||
|
||||
/**
|
||||
* Create a new commit in the repository
|
||||
* Create a new commit in the repository using `git_object`
|
||||
* instances as parameters.
|
||||
*
|
||||
* The message will be cleaned up from excess whitespace
|
||||
* it will be made sure that the last line ends with a '\n'.
|
||||
*
|
||||
* @param oid Pointer where to store the OID of the
|
||||
* newly created commit
|
||||
@ -187,28 +194,34 @@ GIT_EXTERN(const git_oid *) git_commit_parent_oid(git_commit *commit, unsigned i
|
||||
* 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
|
||||
* 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
|
||||
* 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_oid Object ID of the tree for this commit. Note that
|
||||
* no validation is performed on this OID. Use the _o variants of
|
||||
* this method to assure a proper tree is passed to the 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 pointers to parent OIDs for this commit.
|
||||
* Note that no validation is performed on these OIDs. Use the _o
|
||||
* variants of this method to assure that are parents for the commit
|
||||
* are proper objects.
|
||||
* @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 on success; error code otherwise
|
||||
* @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
|
||||
*/
|
||||
@ -218,39 +231,18 @@ GIT_EXTERN(int) git_commit_create(
|
||||
const char *update_ref,
|
||||
const git_signature *author,
|
||||
const git_signature *committer,
|
||||
const char *message,
|
||||
const git_oid *tree_oid,
|
||||
int parent_count,
|
||||
const git_oid *parent_oids[]);
|
||||
|
||||
/**
|
||||
* Create a new commit in the repository using `git_object`
|
||||
* instances as parameters.
|
||||
*
|
||||
* The `tree_oid` and `parent_oids` paremeters now take a instance
|
||||
* of `git_tree` and `git_commit`, respectively.
|
||||
*
|
||||
* All other parameters remain the same
|
||||
*
|
||||
* @see git_commit_create
|
||||
*/
|
||||
GIT_EXTERN(int) git_commit_create_o(
|
||||
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 `git_object`
|
||||
* instances and a variable argument list.
|
||||
* Create a new commit in the repository using a variable
|
||||
* argument list.
|
||||
*
|
||||
* The `tree_oid` paremeter now takes a instance
|
||||
* of `const git_tree *`.
|
||||
* 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
|
||||
@ -261,39 +253,15 @@ GIT_EXTERN(int) git_commit_create_o(
|
||||
*
|
||||
* @see git_commit_create
|
||||
*/
|
||||
GIT_EXTERN(int) git_commit_create_ov(
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *update_ref,
|
||||
const git_signature *author,
|
||||
const git_signature *committer,
|
||||
const char *message,
|
||||
const git_tree *tree,
|
||||
int parent_count,
|
||||
...);
|
||||
|
||||
|
||||
/**
|
||||
* Create a new commit in the repository using
|
||||
* a variable argument list.
|
||||
*
|
||||
* The parents for the commit are specified as a variable
|
||||
* list of pointers to `const git_oid *`. 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_oid *tree_oid,
|
||||
const git_tree *tree,
|
||||
int parent_count,
|
||||
...);
|
||||
|
||||
|
@ -1,67 +1,42 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* 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.
|
||||
* 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 "thread-utils.h"
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
# define GIT_BEGIN_DECL extern "C" {
|
||||
# define GIT_END_DECL }
|
||||
#ifdef _MSC_VER
|
||||
# include "inttypes.h"
|
||||
#else
|
||||
/** Start declarations in C mode */
|
||||
# define GIT_BEGIN_DECL /* empty */
|
||||
/** End declarations in C mode */
|
||||
# define GIT_END_DECL /* empty */
|
||||
# include <inttypes.h>
|
||||
#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. */
|
||||
#ifdef __GNUC__
|
||||
#if __GNUC__ >= 4
|
||||
# define GIT_EXTERN(type) extern \
|
||||
__attribute__((visibility("default"))) \
|
||||
type
|
||||
__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 public TLS symbol exported for application use. */
|
||||
#ifdef __GNUC__
|
||||
# define GIT_EXTERN_TLS(type) extern \
|
||||
__attribute__((visibility("default"))) \
|
||||
GIT_TLS \
|
||||
type
|
||||
#elif defined(_MSC_VER)
|
||||
# define GIT_EXTERN_TLS(type) __declspec(dllexport) GIT_TLS type
|
||||
#else
|
||||
# define GIT_EXTERN_TLS(type) extern GIT_TLS type
|
||||
#endif
|
||||
|
||||
/** Declare a function as always inlined. */
|
||||
#if defined(_MSC_VER)
|
||||
# define GIT_INLINE(type) static __inline type
|
||||
@ -76,6 +51,10 @@
|
||||
# define GIT_FORMAT_PRINTF(a,b) /* empty */
|
||||
#endif
|
||||
|
||||
#if (defined(_WIN32)) && !defined(__CYGWIN__)
|
||||
#define GIT_WIN32 1
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @file git2/common.h
|
||||
* @brief Git common platform definitions
|
||||
@ -86,12 +65,39 @@
|
||||
|
||||
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);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
@ -1,26 +1,8 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* 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.
|
||||
* 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__
|
||||
@ -47,56 +29,146 @@ struct git_config_file {
|
||||
/* 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 (*foreach)(struct git_config_file *, int (*fn)(const char *, void *), void *data);
|
||||
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 *, 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 configuration file
|
||||
*
|
||||
* Utility wrapper that calls `git_config_find_global`
|
||||
* and opens the located file, if it exists.
|
||||
*
|
||||
* @param out Pointer to store the config instance
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_open_global(git_config **out);
|
||||
|
||||
/**
|
||||
* Create a configuration file backend for ondisk files
|
||||
*
|
||||
* These are the normal `.gitconfig` files that Core Git
|
||||
* processes.
|
||||
* 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
|
||||
* @path where the config file is located
|
||||
* @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
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Open a configuration file
|
||||
* Add a generic config file instance to an existing config
|
||||
*
|
||||
* @param cfg_out pointer to the configuration data
|
||||
* @param path where to load the confiration from
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_open_file(git_config **cfg_out, const char *path);
|
||||
|
||||
/**
|
||||
* Open the global configuration file at $HOME/.gitconfig
|
||||
* Note that the configuration object will free the file
|
||||
* automatically.
|
||||
*
|
||||
* @param cfg pointer to the configuration
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_open_global(git_config **cfg);
|
||||
|
||||
/**
|
||||
* Add a config backend to an existing instance
|
||||
* 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).
|
||||
*
|
||||
* Note that the configuration will call the backend's ->free()
|
||||
* function.
|
||||
*
|
||||
* @param cfg the configuration to add the backend to
|
||||
* @param backend the backend to add
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* Free the configuration and its associated memory
|
||||
* 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
|
||||
*/
|
||||
@ -105,22 +177,22 @@ 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
|
||||
* @param out pointer to the variable where the value should be stored
|
||||
* @return GIT_SUCCESS on success; error code otherwise
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_get_int(git_config *cfg, const char *name, int *out);
|
||||
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
|
||||
* @param out pointer to the variable where the value should be stored
|
||||
* @return GIT_SUCCESS on success; error code otherwise
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_get_long(git_config *cfg, const char *name, long int *out);
|
||||
GIT_EXTERN(int) git_config_get_int64(int64_t *out, git_config *cfg, const char *name);
|
||||
|
||||
/**
|
||||
* Get the value of a boolean config variable.
|
||||
@ -128,12 +200,12 @@ GIT_EXTERN(int) git_config_get_long(git_config *cfg, const char *name, long int
|
||||
* 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
|
||||
* @param out pointer to the variable where the value should be stored
|
||||
* @return GIT_SUCCESS on success; error code otherwise
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_get_bool(git_config *cfg, const char *name, int *out);
|
||||
GIT_EXTERN(int) git_config_get_bool(int *out, git_config *cfg, const char *name);
|
||||
|
||||
/**
|
||||
* Get the value of a string config variable.
|
||||
@ -141,32 +213,46 @@ GIT_EXTERN(int) git_config_get_bool(git_config *cfg, const char *name, int *out)
|
||||
* 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
|
||||
* @param out pointer to the variable's value
|
||||
* @return GIT_SUCCESS on success; error code otherwise
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_get_string(git_config *cfg, const char *name, const char **out);
|
||||
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 out pointer to the variable where the value should be stored
|
||||
* @return GIT_SUCCESS on success; error code otherwise
|
||||
* @param value Integer value for the variable
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_set_int(git_config *cfg, const char *name, int value);
|
||||
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 out pointer to the variable where the value should be stored
|
||||
* @return GIT_SUCCESS on success; error code otherwise
|
||||
* @param value Long integer value for the variable
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_set_long(git_config *cfg, const char *name, long int value);
|
||||
GIT_EXTERN(int) git_config_set_int64(git_config *cfg, const char *name, int64_t value);
|
||||
|
||||
/**
|
||||
* Set the value of a boolean config variable.
|
||||
@ -174,7 +260,7 @@ GIT_EXTERN(int) git_config_set_long(git_config *cfg, const char *name, long int
|
||||
* @param cfg where to look for the variable
|
||||
* @param name the variable's name
|
||||
* @param value the value to store
|
||||
* @return GIT_SUCCESS on success; error code otherwise
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_config_set_bool(git_config *cfg, const char *name, int value);
|
||||
|
||||
@ -187,24 +273,83 @@ GIT_EXTERN(int) git_config_set_bool(git_config *cfg, const char *name, int value
|
||||
* @param cfg where to look for the variable
|
||||
* @param name the variable's name
|
||||
* @param value the string to store.
|
||||
* @return GIT_SUCCESS on success; error code otherwise
|
||||
* @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 is passed a pointer to a config variable name and the
|
||||
* data pointer passed to this function. As soon as one of the
|
||||
* callback functions returns something other than 0, this function
|
||||
* returns that value.
|
||||
* 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 returns that value.
|
||||
*
|
||||
* @param cfg where to get the variables from
|
||||
* @param callback the function to call on each variable
|
||||
* @param data the data to pass to the callback
|
||||
* @return GIT_SUCCESS or the return value of the callback which didn't return 0
|
||||
* @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(git_config *cfg, int (*callback)(const char *, void *data), void *data);
|
||||
GIT_EXTERN(int) git_config_foreach(
|
||||
git_config *cfg,
|
||||
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[3] = {
|
||||
* {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
|
||||
|
362
include/git2/diff.h
Normal file
362
include/git2/diff.h
Normal file
@ -0,0 +1,362 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
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),
|
||||
};
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @todo Most of the parameters here are not actually supported at this time.
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t flags; /**< defaults to GIT_DIFF_NORMAL */
|
||||
uint16_t context_lines; /**< defaults to 3 */
|
||||
uint16_t interhunk_lines; /**< defaults to 3 */
|
||||
char *old_prefix; /**< defaults to "a" */
|
||||
char *new_prefix; /**< defaults to "b" */
|
||||
git_strarray pathspec; /**< defaults to show all paths */
|
||||
} git_diff_options;
|
||||
|
||||
/**
|
||||
* The diff list object that contains all individual file deltas.
|
||||
*/
|
||||
typedef struct git_diff_list git_diff_list;
|
||||
|
||||
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)
|
||||
};
|
||||
|
||||
/**
|
||||
* 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;
|
||||
uint16_t mode;
|
||||
git_off_t size;
|
||||
unsigned int flags;
|
||||
} 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', /**< LF was added at end of file */
|
||||
GIT_DIFF_LINE_DEL_EOFNL = '\0', /**< LF was removed at end of file */
|
||||
/* these 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);
|
||||
|
||||
/** @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.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* @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 returns strictly the differences between the tree and the
|
||||
* files contained in the working directory, regardless of the state
|
||||
* of files in the index. There is no direct equivalent in C git.
|
||||
*
|
||||
* This is *NOT* the same as 'git diff HEAD' or 'git diff <SHA>'. Those
|
||||
* commands diff the tree, the index, and the workdir. To emulate those
|
||||
* functions, call `git_diff_index_to_tree` and `git_diff_workdir_to_index`,
|
||||
* then call `git_diff_merge` on the results.
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
* If the hunk and/or line callbacks are not NULL, then this will calculate
|
||||
* text diffs for all files it thinks are not binary. If those are both
|
||||
* NULL, then this will not bother with the text diffs, so it can be
|
||||
* efficient.
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Iterate over a diff generating text output like "git diff --name-status".
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
GIT_EXTERN(int) git_diff_print_patch(
|
||||
git_diff_list *diff,
|
||||
void *cb_data,
|
||||
git_diff_data_fn print_cb);
|
||||
|
||||
/**@}*/
|
||||
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
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
|
@ -1,26 +1,8 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* 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.
|
||||
* 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__
|
||||
@ -35,113 +17,92 @@
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
typedef enum {
|
||||
#ifdef GIT_OLD_ERRORS
|
||||
enum {
|
||||
GIT_SUCCESS = 0,
|
||||
GIT_ERROR = -1,
|
||||
|
||||
/** Input was not a properly formatted Git object id. */
|
||||
GIT_ENOTOID = -2,
|
||||
|
||||
/** Input does not exist in the scope searched. */
|
||||
GIT_ENOTFOUND = -3,
|
||||
|
||||
/** Not enough space available. */
|
||||
GIT_ENOMEM = -4,
|
||||
|
||||
/** Consult the OS error information. */
|
||||
GIT_EOSERR = -5,
|
||||
|
||||
/** The specified object is of invalid type */
|
||||
GIT_EOBJTYPE = -6,
|
||||
|
||||
/** The specified repository is invalid */
|
||||
GIT_ENOTAREPO = -7,
|
||||
|
||||
/** The object type is invalid or doesn't match */
|
||||
GIT_EINVALIDTYPE = -8,
|
||||
|
||||
/** The object cannot be written because it's missing internal data */
|
||||
GIT_EMISSINGOBJDATA = -9,
|
||||
|
||||
/** The packfile for the ODB is corrupted */
|
||||
GIT_EPACKCORRUPTED = -10,
|
||||
|
||||
/** Failed to acquire or release a file lock */
|
||||
GIT_EFLOCKFAIL = -11,
|
||||
|
||||
/** The Z library failed to inflate/deflate an object's data */
|
||||
GIT_EZLIB = -12,
|
||||
|
||||
/** The queried object is currently busy */
|
||||
GIT_EBUSY = -13,
|
||||
|
||||
/** The index file is not backed up by an existing repository */
|
||||
GIT_EBAREINDEX = -14,
|
||||
|
||||
/** The name of the reference is not valid */
|
||||
GIT_EINVALIDREFNAME = -15,
|
||||
|
||||
/** The specified reference has its data corrupted */
|
||||
GIT_EREFCORRUPTED = -16,
|
||||
|
||||
/** The specified symbolic reference is too deeply nested */
|
||||
GIT_EREFCORRUPTED = -16,
|
||||
GIT_ETOONESTEDSYMREF = -17,
|
||||
|
||||
/** The pack-refs file is either corrupted or its format is not currently supported */
|
||||
GIT_EPACKEDREFSCORRUPTED = -18,
|
||||
|
||||
/** The path is invalid */
|
||||
GIT_EINVALIDPATH = -19,
|
||||
|
||||
/** The revision walker is empty; there are no more commits left to iterate */
|
||||
GIT_EREVWALKOVER = -20,
|
||||
|
||||
/** The state of the reference is not valid */
|
||||
GIT_EINVALIDREFSTATE = -21,
|
||||
|
||||
/** This feature has not been implemented yet */
|
||||
GIT_ENOTIMPLEMENTED = -22,
|
||||
|
||||
/** A reference with this name already exists */
|
||||
GIT_EEXISTS = -23,
|
||||
|
||||
/** The given integer literal is too large to be parsed */
|
||||
GIT_EOVERFLOW = -24,
|
||||
|
||||
/** The given literal is not a valid number */
|
||||
GIT_ENOTNUM = -25,
|
||||
|
||||
/** Streaming error */
|
||||
GIT_ESTREAM = -26,
|
||||
|
||||
/** invalid arguments to function */
|
||||
GIT_EINVALIDARGS = -27,
|
||||
|
||||
/** The specified object has its data corrupted */
|
||||
GIT_EOBJCORRUPTED = -28,
|
||||
GIT_EAMBIGUOUS = -29,
|
||||
GIT_EPASSTHROUGH = -30,
|
||||
GIT_ENOMATCH = -31,
|
||||
GIT_ESHORTBUFFER = -32,
|
||||
};
|
||||
#endif
|
||||
|
||||
/** The given short oid is ambiguous */
|
||||
GIT_EAMBIGUOUSOIDPREFIX = -29,
|
||||
/** Generic return codes */
|
||||
enum {
|
||||
GIT_OK = 0,
|
||||
GIT_ERROR = -1,
|
||||
GIT_ENOTFOUND = -3,
|
||||
GIT_EEXISTS = -4,
|
||||
GIT_EAMBIGUOUS = -5,
|
||||
GIT_EBUFS = -6,
|
||||
|
||||
GIT_PASSTHROUGH = -30,
|
||||
GIT_REVWALKOVER = -31,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
char *message;
|
||||
int klass;
|
||||
} git_error;
|
||||
|
||||
/**
|
||||
* Return a detailed error string with the latest error
|
||||
* that occurred in the library.
|
||||
* @return a string explaining the error
|
||||
*/
|
||||
GIT_EXTERN(const char *) git_lasterror(void);
|
||||
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,
|
||||
} git_error_t;
|
||||
|
||||
/**
|
||||
* strerror() for the Git library
|
||||
* Return the last `git_error` object that was generated for the
|
||||
* current thread or NULL if no error has occurred.
|
||||
*
|
||||
* Get a string description for a given error code.
|
||||
* NOTE: This method will be eventually deprecated in favor
|
||||
* of the new `git_lasterror`.
|
||||
*
|
||||
* @param num The error code to explain
|
||||
* @return a string explaining the error code
|
||||
* @return A git_error object.
|
||||
*/
|
||||
GIT_EXTERN(const char *) git_strerror(int num);
|
||||
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
|
||||
|
@ -1,26 +1,8 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* 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.
|
||||
* 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__
|
||||
@ -38,10 +20,10 @@
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
#define GIT_IDXENTRY_NAMEMASK (0x0fff)
|
||||
#define GIT_IDXENTRY_NAMEMASK (0x0fff)
|
||||
#define GIT_IDXENTRY_STAGEMASK (0x3000)
|
||||
#define GIT_IDXENTRY_EXTENDED (0x4000)
|
||||
#define GIT_IDXENTRY_VALID (0x8000)
|
||||
#define GIT_IDXENTRY_EXTENDED (0x4000)
|
||||
#define GIT_IDXENTRY_VALID (0x8000)
|
||||
#define GIT_IDXENTRY_STAGESHIFT 12
|
||||
|
||||
/*
|
||||
@ -51,26 +33,26 @@ GIT_BEGIN_DECL
|
||||
*
|
||||
* 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_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_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_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)
|
||||
#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_EXTENDED2 (1 << 15)
|
||||
|
||||
#define GIT_IDXENTRY_EXTENDED_FLAGS (GIT_IDXENTRY_INTENT_TO_ADD | GIT_IDXENTRY_SKIP_WORKTREE)
|
||||
|
||||
@ -98,14 +80,14 @@ typedef struct git_index_entry {
|
||||
unsigned short flags;
|
||||
unsigned short flags_extended;
|
||||
|
||||
const char *path;
|
||||
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];
|
||||
const char *path;
|
||||
char *path;
|
||||
} git_index_entry_unmerged;
|
||||
|
||||
/**
|
||||
@ -124,7 +106,7 @@ typedef struct git_index_entry_unmerged {
|
||||
*
|
||||
* @param index the pointer for the new index
|
||||
* @param index_path the path to the index file in disk
|
||||
* @return 0 on success; error code otherwise
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_open(git_index **index, const char *index_path);
|
||||
|
||||
@ -149,7 +131,7 @@ GIT_EXTERN(void) git_index_free(git_index *index);
|
||||
* by reading from the hard disk.
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @return 0 on success, otherwise an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_read(git_index *index);
|
||||
|
||||
@ -158,7 +140,7 @@ GIT_EXTERN(int) git_index_read(git_index *index);
|
||||
* using an atomic file lock.
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @return 0 on success, otherwise an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_write(git_index *index);
|
||||
|
||||
@ -172,6 +154,13 @@ GIT_EXTERN(int) git_index_write(git_index *index);
|
||||
*/
|
||||
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
|
||||
*
|
||||
@ -180,10 +169,14 @@ GIT_EXTERN(int) git_index_find(git_index *index, const char *path);
|
||||
*
|
||||
* 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 on success, otherwise an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_add(git_index *index, const char *path, int stage);
|
||||
|
||||
@ -195,7 +188,7 @@ GIT_EXTERN(int) git_index_add(git_index *index, const char *path, int stage);
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param source_entry new entry object
|
||||
* @return 0 on success, otherwise an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_add2(git_index *index, const git_index_entry *source_entry);
|
||||
|
||||
@ -214,7 +207,7 @@ GIT_EXTERN(int) git_index_add2(git_index *index, const git_index_entry *source_e
|
||||
* @param index an existing index object
|
||||
* @param path filename to add
|
||||
* @param stage stage for the entry
|
||||
* @return 0 on success, otherwise an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_append(git_index *index, const char *path, int stage);
|
||||
|
||||
@ -231,7 +224,7 @@ GIT_EXTERN(int) git_index_append(git_index *index, const char *path, int stage);
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param source_entry new entry object
|
||||
* @return 0 on success, otherwise an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_append2(git_index *index, const git_index_entry *source_entry);
|
||||
|
||||
@ -240,7 +233,7 @@ GIT_EXTERN(int) git_index_append2(git_index *index, const git_index_entry *sourc
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param position position of the entry to remove
|
||||
* @return 0 on success, otherwise an error code
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_remove(git_index *index, int position);
|
||||
|
||||
@ -257,7 +250,7 @@ GIT_EXTERN(int) git_index_remove(git_index *index, int position);
|
||||
* @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, int n);
|
||||
GIT_EXTERN(git_index_entry *) git_index_get(git_index *index, unsigned int n);
|
||||
|
||||
/**
|
||||
* Get the count of entries currently in the index
|
||||
@ -285,12 +278,24 @@ GIT_EXTERN(unsigned int) git_index_entrycount_unmerged(git_index *index);
|
||||
* @param path path to search
|
||||
* @return the unmerged entry; NULL if not found
|
||||
*/
|
||||
GIT_EXTERN(const git_index_entry_unmerged *) git_index_get_unmerged(git_index *index, const char *path);
|
||||
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, unsigned int n);
|
||||
|
||||
/**
|
||||
* Return the stage number from a git index entry
|
||||
*
|
||||
* This entry is calculated from the entrie's flag
|
||||
* This entry is calculated from the entry's flag
|
||||
* attribute like this:
|
||||
*
|
||||
* (entry->flags & GIT_IDXENTRY_STAGEMASK) >> GIT_IDXENTRY_STAGESHIFT
|
||||
@ -300,6 +305,17 @@ GIT_EXTERN(const git_index_entry_unmerged *) git_index_get_unmerged(git_index *i
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_entry_stage(const git_index_entry *entry);
|
||||
|
||||
/**
|
||||
* Read a tree into the index file
|
||||
*
|
||||
* The current index contents will be replaced by the specified tree.
|
||||
*
|
||||
* @param index an existing index object
|
||||
* @param tree tree to read
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_index_read_tree(git_index *index, git_tree *tree);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
||||
|
121
include/git2/indexer.h
Normal file
121
include/git2/indexer.h
Normal file
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* 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;
|
||||
} 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 gitdir (metadata directory)
|
||||
*/
|
||||
GIT_EXTERN(int) git_indexer_stream_new(git_indexer_stream **out, const char *gitdir);
|
||||
|
||||
/**
|
||||
* 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
|
305
include/git2/inttypes.h
Normal file
305
include/git2/inttypes.h
Normal file
@ -0,0 +1,305 @@
|
||||
// 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_ ]
|
35
include/git2/merge.h
Normal file
35
include/git2/merge.h
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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, git_oid *one, git_oid *two);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
51
include/git2/net.h
Normal file
51
include/git2/net.h
Normal file
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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
|
139
include/git2/notes.h
Normal file
139
include/git2/notes.h
Normal file
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* 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 the note; NULL in case of error
|
||||
* @param repo the Git repository
|
||||
* @param notes_ref OID reference to use (optional); defaults to "refs/notes/commits"
|
||||
* @param oid OID of the object
|
||||
*
|
||||
* @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 oid pointer to store the OID (optional); NULL in case of error
|
||||
* @param repo the Git repository
|
||||
* @param author signature of the notes commit author
|
||||
* @param committer signature of the notes commit committer
|
||||
* @param notes_ref OID reference to update (optional); defaults to "refs/notes/commits"
|
||||
* @param oid The OID of the object
|
||||
* @param oid 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 the Git repository
|
||||
* @param notes_ref OID 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 the oid which note's to be removed
|
||||
*
|
||||
* @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 OID reference to read from (optional); defaults to "refs/notes/commits".
|
||||
*
|
||||
* @param note_cb Callback to invoke per found annotation.
|
||||
*
|
||||
* @param payload Extra parameter to callback function.
|
||||
*
|
||||
* @return 0 or an 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
|
@ -1,26 +1,8 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* 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.
|
||||
* 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__
|
||||
@ -39,10 +21,10 @@
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Lookup a reference to one of the objects in a repostory.
|
||||
* 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_close` method
|
||||
* should be closed with the `git_object_free` method
|
||||
* instead of free'd manually.
|
||||
*
|
||||
* The 'type' parameter must match the type of the object
|
||||
@ -63,7 +45,7 @@ GIT_EXTERN(int) git_object_lookup(
|
||||
git_otype type);
|
||||
|
||||
/**
|
||||
* Lookup a reference to one of the objects in a repostory,
|
||||
* 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
|
||||
@ -74,7 +56,7 @@ GIT_EXTERN(int) git_object_lookup(
|
||||
* the prefix; otherwise the method will fail.
|
||||
*
|
||||
* The generated reference is owned by the repository and
|
||||
* should be closed with the `git_object_close` method
|
||||
* should be closed with the `git_object_free` method
|
||||
* instead of free'd manually.
|
||||
*
|
||||
* The 'type' parameter must match the type of the object
|
||||
@ -82,12 +64,12 @@ GIT_EXTERN(int) git_object_lookup(
|
||||
* 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 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 a reference to the object
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_object_lookup_prefix(
|
||||
git_object **object_out,
|
||||
@ -132,7 +114,7 @@ GIT_EXTERN(git_repository *) git_object_owner(const git_object *obj);
|
||||
* 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 agressive is the caching mechanism used
|
||||
* depending on how aggressive is the caching mechanism used
|
||||
* by the repository.
|
||||
*
|
||||
* IMPORTANT:
|
||||
@ -141,7 +123,7 @@ GIT_EXTERN(git_repository *) git_object_owner(const git_object *obj);
|
||||
*
|
||||
* @param object the object to close
|
||||
*/
|
||||
GIT_EXTERN(void) git_object_close(git_object *object);
|
||||
GIT_EXTERN(void) git_object_free(git_object *object);
|
||||
|
||||
/**
|
||||
* Convert an object type to it's string representation.
|
||||
|
@ -1,26 +1,8 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* 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.
|
||||
* 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__
|
||||
@ -46,9 +28,8 @@ GIT_BEGIN_DECL
|
||||
* 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 GIT_SUCCESS if the database was created; otherwise an error
|
||||
* code describing why the open was not possible.
|
||||
* Set to NULL if the open failed.
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_odb_new(git_odb **out);
|
||||
|
||||
@ -64,21 +45,24 @@ GIT_EXTERN(int) git_odb_new(git_odb **out);
|
||||
* 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.
|
||||
* Set to NULL if the open failed.
|
||||
* @param objects_dir path of the backends' "objects" directory.
|
||||
* @return GIT_SUCCESS if the database opened; otherwise an error
|
||||
* code describing why the open was not possible.
|
||||
* @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 <odb_backends.h> for more information.
|
||||
*
|
||||
* @param odb database to add the backend to
|
||||
* @paramm backend pointer to a git_odb_backend instance
|
||||
* @return 0 on sucess; error code otherwise
|
||||
* @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);
|
||||
|
||||
@ -89,22 +73,26 @@ GIT_EXTERN(int) git_odb_add_backend(git_odb *odb, git_odb_backend *backend, int
|
||||
* 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 <odb_backends.h> for more information.
|
||||
*
|
||||
* @param odb database to add the backend to
|
||||
* @paramm backend pointer to a git_odb_backend instance
|
||||
* @return 0 on sucess; error code otherwise
|
||||
* @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.
|
||||
* @param db database pointer to close. If NULL no action is taken.
|
||||
*/
|
||||
GIT_EXTERN(void) git_odb_close(git_odb *db);
|
||||
GIT_EXTERN(void) git_odb_free(git_odb *db);
|
||||
|
||||
/**
|
||||
* Read an object from the database.
|
||||
@ -120,7 +108,7 @@ GIT_EXTERN(void) git_odb_close(git_odb *db);
|
||||
* @param db database to search for the object in.
|
||||
* @param id identity of the object to read.
|
||||
* @return
|
||||
* - GIT_SUCCESS if the object was read;
|
||||
* - 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);
|
||||
@ -143,16 +131,13 @@ GIT_EXTERN(int) git_odb_read(git_odb_object **out, git_odb *db, const git_oid *i
|
||||
* internally cached, so it should be closed
|
||||
* by the user once it's no longer in use.
|
||||
*
|
||||
* @param out_oid the oid of the unique object matching
|
||||
* the short id
|
||||
* @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
|
||||
* - GIT_SUCCESS 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)
|
||||
* @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, unsigned int len);
|
||||
|
||||
@ -171,7 +156,7 @@ GIT_EXTERN(int) git_odb_read_prefix(git_odb_object **out, git_odb *db, const git
|
||||
* @param db database to search for the object in.
|
||||
* @param id identity of the object to read.
|
||||
* @return
|
||||
* - GIT_SUCCESS if the object was read;
|
||||
* - 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);
|
||||
@ -200,10 +185,10 @@ GIT_EXTERN(int) git_odb_exists(git_odb *db, const git_oid *id);
|
||||
*
|
||||
* @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 storr
|
||||
* @param data buffer with the data to store
|
||||
* @param len size of the buffer
|
||||
* @param type type of the data to store
|
||||
* @return 0 on success; error code otherwise
|
||||
* @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);
|
||||
|
||||
@ -215,12 +200,12 @@ GIT_EXTERN(int) git_odb_write(git_oid *oid, git_odb *odb, const void *data, size
|
||||
*
|
||||
* 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
|
||||
*
|
||||
@ -247,7 +232,7 @@ GIT_EXTERN(int) git_odb_open_wstream(git_odb_stream **stream, git_odb *db, size_
|
||||
*
|
||||
* 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
|
||||
*
|
||||
@ -265,17 +250,30 @@ GIT_EXTERN(int) git_odb_open_rstream(git_odb_stream **stream, git_odb *db, const
|
||||
/**
|
||||
* Determine the object-ID (sha1 hash) of a data buffer
|
||||
*
|
||||
* The resulting SHA-1 OID will the itentifier for the data
|
||||
* 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 on success; error code otherwise
|
||||
* @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. Similar functionality
|
||||
* to git.git's `git hash-object` without the `-w` flag.
|
||||
*
|
||||
* @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
|
||||
*
|
||||
@ -284,7 +282,7 @@ GIT_EXTERN(int) git_odb_hash(git_oid *id, const void *data, size_t len, git_otyp
|
||||
*
|
||||
* @param object object to close
|
||||
*/
|
||||
GIT_EXTERN(void) git_odb_object_close(git_odb_object *object);
|
||||
GIT_EXTERN(void) git_odb_object_free(git_odb_object *object);
|
||||
|
||||
/**
|
||||
* Return the OID of an ODB object
|
||||
|
@ -1,26 +1,8 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* 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.
|
||||
* 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__
|
||||
@ -92,6 +74,13 @@ struct git_odb_backend {
|
||||
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;
|
||||
@ -103,17 +92,8 @@ struct git_odb_stream {
|
||||
void (*free)(struct git_odb_stream *stream);
|
||||
};
|
||||
|
||||
/** Streaming mode */
|
||||
typedef enum {
|
||||
GIT_STREAM_RDONLY = (1 << 1),
|
||||
GIT_STREAM_WRONLY = (1 << 2),
|
||||
GIT_STREAM_RW = (GIT_STREAM_RDONLY | GIT_STREAM_WRONLY),
|
||||
} git_odb_streammode;
|
||||
|
||||
|
||||
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);
|
||||
GIT_EXTERN(int) git_odb_backend_sqlite(git_odb_backend **backend_out, const char *sqlite_db);
|
||||
GIT_EXTERN(int) git_odb_backend_loose(git_odb_backend **backend_out, const char *objects_dir, int compression_level, int do_fsync);
|
||||
|
||||
GIT_END_DECL
|
||||
|
||||
|
@ -1,26 +1,8 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* 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.
|
||||
* 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__
|
||||
@ -48,65 +30,83 @@ GIT_BEGIN_DECL
|
||||
#define GIT_OID_MINPREFIXLEN 4
|
||||
|
||||
/** Unique identity of any object (commit, tree, blob, tag). */
|
||||
typedef struct {
|
||||
typedef struct _git_oid git_oid;
|
||||
struct _git_oid {
|
||||
/** raw binary formatted id */
|
||||
unsigned char id[GIT_OID_RAWSZ];
|
||||
} git_oid;
|
||||
};
|
||||
|
||||
/**
|
||||
* 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 GIT_SUCCESS if valid; GIT_ENOTOID on failure.
|
||||
* 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_mkstr(git_oid *out, const char *str);
|
||||
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_mkraw(git_oid *out, const unsigned char *raw);
|
||||
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.
|
||||
* 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.
|
||||
* <p>
|
||||
*
|
||||
* The resulting string is "aa/...", where "aa" is the first two
|
||||
* hex digitis of the oid and "..." is the remaining 38 digits.
|
||||
* 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.
|
||||
* 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 gid_oid into a newly allocated c-string.
|
||||
* 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 free().
|
||||
* @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.
|
||||
* <p>
|
||||
*
|
||||
* 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),
|
||||
@ -117,12 +117,13 @@ GIT_EXTERN(char *) git_oid_allocfmt(const git_oid *oid);
|
||||
* @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.
|
||||
* errors, otherwise a pointer to an empty string.
|
||||
*/
|
||||
GIT_EXTERN(char *) git_oid_to_string(char *out, size_t n, const git_oid *oid);
|
||||
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.
|
||||
*/
|
||||
@ -130,6 +131,7 @@ 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.
|
||||
@ -139,12 +141,28 @@ GIT_EXTERN(int) git_oid_cmp(const git_oid *a, const git_oid *b);
|
||||
/**
|
||||
* Compare the first 'len' hexadecimal characters (packets of 4 bits)
|
||||
* of two oid structures.
|
||||
* @param len the number of hex chars to compare
|
||||
*
|
||||
* @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) gid_oid_match(unsigned int len, git_oid *a, git_oid *b);
|
||||
GIT_EXTERN(int) git_oid_ncmp(const git_oid *a, const git_oid *b, unsigned int 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.
|
||||
*/
|
||||
GIT_EXTERN(int) git_oid_iszero(const git_oid *a);
|
||||
|
||||
/**
|
||||
* OID Shortener object
|
||||
@ -165,7 +183,7 @@ typedef struct git_oid_shorten git_oid_shorten;
|
||||
* be unique.
|
||||
* @return a `git_oid_shorten` instance, NULL if OOM
|
||||
*/
|
||||
git_oid_shorten *git_oid_shorten_new(size_t min_length);
|
||||
GIT_EXTERN(git_oid_shorten *) git_oid_shorten_new(size_t min_length);
|
||||
|
||||
/**
|
||||
* Add a new OID to set of shortened OIDs and calculate
|
||||
@ -191,14 +209,14 @@ git_oid_shorten *git_oid_shorten_new(size_t min_length);
|
||||
* added so far to the set; or an error code (<0) if an
|
||||
* error occurs.
|
||||
*/
|
||||
int git_oid_shorten_add(git_oid_shorten *os, const char *text_oid);
|
||||
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
|
||||
*/
|
||||
void git_oid_shorten_free(git_oid_shorten *os);
|
||||
GIT_EXTERN(void) git_oid_shorten_free(git_oid_shorten *os);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
128
include/git2/reflog.h
Normal file
128
include/git2/reflog.h
Normal file
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* 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 a new reflog for the given reference
|
||||
*
|
||||
* If there is no reflog file for the given
|
||||
* reference yet, it will be created.
|
||||
*
|
||||
* `oid_old` may be NULL in case it's a new reference.
|
||||
*
|
||||
* `msg` is optional and can be NULL.
|
||||
*
|
||||
* @param ref the changed reference
|
||||
* @param oid_old the OID the reference was 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_write(git_reference *ref, const git_oid *oid_old, const git_signature *committer, const char *msg);
|
||||
|
||||
/**
|
||||
* Rename the reflog for the given reference
|
||||
*
|
||||
* @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, unsigned int idx);
|
||||
|
||||
/**
|
||||
* 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
|
@ -1,26 +1,8 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* 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.
|
||||
* 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__
|
||||
@ -41,53 +23,45 @@ GIT_BEGIN_DECL
|
||||
/**
|
||||
* Lookup a reference by its name in a repository.
|
||||
*
|
||||
* The generated reference is owned by the repository and
|
||||
* should not be freed by the user.
|
||||
* 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 on success; error code otherwise
|
||||
* @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.
|
||||
*
|
||||
* This reference is owned by the repository and shall not
|
||||
* be free'd by the user.
|
||||
* 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
|
||||
* @return 0 on success; error code otherwise
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* Create a new symbolic reference, overwriting an existing one with
|
||||
* the same name, if it exists.
|
||||
*
|
||||
* If the new reference isn't a symbolic one, any pointers to the old
|
||||
* reference become invalid.
|
||||
*
|
||||
* The reference will be created in the repository and written
|
||||
* to the disk.
|
||||
*
|
||||
* This reference is owned by the repository and shall not
|
||||
* be free'd by the user.
|
||||
*
|
||||
* @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
|
||||
* @return 0 on success; error code otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_create_symbolic_f(git_reference **ref_out, git_repository *repo, const char *name, const char *target);
|
||||
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.
|
||||
@ -95,41 +69,23 @@ GIT_EXTERN(int) git_reference_create_symbolic_f(git_reference **ref_out, git_rep
|
||||
* The reference will be created in the repository and written
|
||||
* to the disk.
|
||||
*
|
||||
* This reference is owned by the repository and shall not
|
||||
* be free'd by the user.
|
||||
* 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.
|
||||
* @return 0 on success; error code otherwise
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* Create a new object id reference, overwriting an existing one with
|
||||
* the same name, if it exists.
|
||||
*
|
||||
* If the new reference isn't an object id one, any pointers to the
|
||||
* old reference become invalid.
|
||||
*
|
||||
* The reference will be created in the repository and written
|
||||
* to the disk.
|
||||
*
|
||||
* This reference is owned by the repository and shall not
|
||||
* be free'd by the user.
|
||||
*
|
||||
* @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.
|
||||
* @return 0 on success; error code otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_create_oid_f(git_reference **ref_out, git_repository *repo, const char *name, const git_oid *id);
|
||||
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
|
||||
@ -139,7 +95,7 @@ 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
|
||||
@ -155,7 +111,7 @@ GIT_EXTERN(const char *) git_reference_target(git_reference *ref);
|
||||
* @param ref The reference
|
||||
* @return the type
|
||||
*/
|
||||
GIT_EXTERN(git_rtype) git_reference_type(git_reference *ref);
|
||||
GIT_EXTERN(git_ref_t) git_reference_type(git_reference *ref);
|
||||
|
||||
/**
|
||||
* Get the full name of a reference
|
||||
@ -166,17 +122,22 @@ GIT_EXTERN(git_rtype) git_reference_type(git_reference *ref);
|
||||
GIT_EXTERN(const char *) git_reference_name(git_reference *ref);
|
||||
|
||||
/**
|
||||
* Resolve a symbolic reference
|
||||
* Resolve a symbolic reference
|
||||
*
|
||||
* Thie method iteratively peels 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,
|
||||
* that reference is returned immediately
|
||||
* 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 on success; error code otherwise
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_resolve(git_reference **resolved_ref, git_reference *ref);
|
||||
|
||||
@ -199,7 +160,7 @@ GIT_EXTERN(git_repository *) git_reference_owner(git_reference *ref);
|
||||
*
|
||||
* @param ref The reference
|
||||
* @param target The new target for the reference
|
||||
* @return 0 on success; error code otherwise
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_set_target(git_reference *ref, const char *target);
|
||||
|
||||
@ -213,8 +174,8 @@ GIT_EXTERN(int) git_reference_set_target(git_reference *ref, const char *target)
|
||||
* memory and on disk.
|
||||
*
|
||||
* @param ref The reference
|
||||
* @param target The new target OID for the reference
|
||||
* @return 0 on success; error code otherwise
|
||||
* @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);
|
||||
|
||||
@ -225,25 +186,26 @@ GIT_EXTERN(int) git_reference_set_oid(git_reference *ref, const git_oid *id);
|
||||
* The new name will be checked for validity and may be
|
||||
* modified into a normalized form.
|
||||
*
|
||||
* The refernece will be immediately renamed in-memory
|
||||
* The given git_reference will be updated in place.
|
||||
*
|
||||
* The reference will be immediately renamed in-memory
|
||||
* and on disk.
|
||||
*
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_rename(git_reference *ref, const char *new_name);
|
||||
|
||||
/**
|
||||
* Rename an existing reference, overwriting an existing one with the
|
||||
* same name, if it exists.
|
||||
* If the `force` flag is not enabled, and there's already
|
||||
* a reference with the given name, the renaming will fail.
|
||||
*
|
||||
* 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.
|
||||
* 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.
|
||||
*
|
||||
* The refernece will be immediately renamed in-memory
|
||||
* and on disk.
|
||||
* @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_f(git_reference *ref, const char *new_name);
|
||||
GIT_EXTERN(int) git_reference_rename(git_reference *ref, const char *new_name, int force);
|
||||
|
||||
/**
|
||||
* Delete an existing reference
|
||||
@ -253,6 +215,8 @@ GIT_EXTERN(int) git_reference_rename_f(git_reference *ref, const char *new_name)
|
||||
* 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);
|
||||
|
||||
@ -260,17 +224,14 @@ 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
|
||||
* 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.
|
||||
*
|
||||
* WARNING: calling this method may invalidate any existing
|
||||
* references previously loaded on the cache.
|
||||
*
|
||||
* @param repo Repository where the loose refs will be packed
|
||||
* @return 0 on success; error code otherwise
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_packall(git_repository *repo);
|
||||
|
||||
@ -293,16 +254,15 @@ GIT_EXTERN(int) git_reference_packall(git_repository *repo);
|
||||
* @param repo Repository where to find the refs
|
||||
* @param list_flags Filtering flags for the reference
|
||||
* listing.
|
||||
* @return 0 on success; error code otherwise
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_listall(git_strarray *array, git_repository *repo, unsigned int list_flags);
|
||||
GIT_EXTERN(int) git_reference_list(git_strarray *array, git_repository *repo, unsigned int list_flags);
|
||||
|
||||
|
||||
/**
|
||||
* List all the references in the repository, calling a custom
|
||||
* callback for each one.
|
||||
* Perform an operation on each reference in the repository
|
||||
*
|
||||
* The listed references may be filtered by type, or using
|
||||
* 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.
|
||||
@ -316,9 +276,53 @@ GIT_EXTERN(int) git_reference_listall(git_strarray *array, git_repository *repo,
|
||||
* 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; error code otherwise
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_reference_listcb(git_repository *repo, unsigned int list_flags, int (*callback)(const char *, void *), void *payload);
|
||||
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);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
68
include/git2/refspec.h
Normal file
68
include/git2/refspec.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
/**
|
||||
* 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
|
243
include/git2/remote.h
Normal file
243
include/git2/remote.h
Normal file
@ -0,0 +1,243 @@
|
||||
/*
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* @param refs where to store the refs
|
||||
* @param remote the remote
|
||||
* @return 0 or an 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, int (*cb)(const char *refname, const git_oid *a, const git_oid *b));
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
@ -1,26 +1,8 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* 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.
|
||||
* 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__
|
||||
@ -41,131 +23,73 @@ GIT_BEGIN_DECL
|
||||
/**
|
||||
* Open a git repository.
|
||||
*
|
||||
* The 'path' argument must point to an existing git repository
|
||||
* folder, e.g.
|
||||
* The 'path' argument must point to either a git repository
|
||||
* folder, or an existing work dir.
|
||||
*
|
||||
* /path/to/my_repo/.git/ (normal repository)
|
||||
* objects/
|
||||
* index
|
||||
* HEAD
|
||||
*
|
||||
* /path/to/bare_repo/ (bare repository)
|
||||
* objects/
|
||||
* index
|
||||
* HEAD
|
||||
*
|
||||
* The method will automatically detect if 'path' is a normal
|
||||
* or bare repository or fail is 'path' is neither.
|
||||
* 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 on success; error code otherwise
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_open(git_repository **repository, const char *path);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
enum {
|
||||
GIT_REPOSITORY_OPEN_NO_SEARCH = (1 << 0),
|
||||
GIT_REPOSITORY_OPEN_CROSS_FS = (1 << 1),
|
||||
};
|
||||
|
||||
/**
|
||||
* Open a git repository by manually specifying all its paths
|
||||
*
|
||||
* @param repository pointer to the repo which will be opened
|
||||
*
|
||||
* @param git_dir The full path to the repository folder
|
||||
* e.g. a '.git' folder for live repos, any folder for bare
|
||||
* Equivalent to $GIT_DIR.
|
||||
* Cannot be NULL.
|
||||
*
|
||||
* @param git_object_directory The full path to the ODB folder.
|
||||
* the folder where all the loose and packed objects are stored
|
||||
* Equivalent to $GIT_OBJECT_DIRECTORY.
|
||||
* If NULL, "$GIT_DIR/objects/" is assumed.
|
||||
*
|
||||
* @param git_index_file The full path to the index (dircache) file
|
||||
* Equivalent to $GIT_INDEX_FILE.
|
||||
* If NULL, "$GIT_DIR/index" is assumed.
|
||||
*
|
||||
* @param git_work_tree The full path to the working tree of the repository,
|
||||
* if the repository is not bare.
|
||||
* Equivalent to $GIT_WORK_TREE.
|
||||
* If NULL, the repository is assumed to be bare.
|
||||
*
|
||||
* @return 0 on success; error code otherwise
|
||||
* Find and open a repository with extended controls.
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_open2(git_repository **repository,
|
||||
const char *git_dir,
|
||||
const char *git_object_directory,
|
||||
const char *git_index_file,
|
||||
const char *git_work_tree);
|
||||
|
||||
|
||||
/**
|
||||
* Open a git repository by manually specifying its paths and
|
||||
* the object database it will use.
|
||||
*
|
||||
* @param repository pointer to the repo which will be opened
|
||||
*
|
||||
* @param git_dir The full path to the repository folder
|
||||
* e.g. a '.git' folder for live repos, any folder for bare
|
||||
* Equivalent to $GIT_DIR.
|
||||
* Cannot be NULL.
|
||||
*
|
||||
* @param object_database A pointer to a git_odb created & initialized
|
||||
* by the user (e.g. with custom backends). This object database
|
||||
* will be owned by the repository and will be automatically free'd.
|
||||
* It should not be manually free'd by the user, or this
|
||||
* git_repository object will become invalid.
|
||||
*
|
||||
* @param git_index_file The full path to the index (dircache) file
|
||||
* Equivalent to $GIT_INDEX_FILE.
|
||||
* If NULL, "$GIT_DIR/index" is assumed.
|
||||
*
|
||||
* @param git_work_tree The full path to the working tree of the repository,
|
||||
* if the repository is not bare.
|
||||
* Equivalent to $GIT_WORK_TREE.
|
||||
* If NULL, the repository is assumed to be bare.
|
||||
*
|
||||
* @return 0 on success; error code otherwise
|
||||
*/
|
||||
|
||||
GIT_EXTERN(int) git_repository_open3(git_repository **repository,
|
||||
const char *git_dir,
|
||||
git_odb *object_database,
|
||||
const char *git_index_file,
|
||||
const char *git_work_tree);
|
||||
|
||||
/**
|
||||
* Get the object database behind a Git repository
|
||||
*
|
||||
* @param repo a repository object
|
||||
* @return a pointer to the object db
|
||||
*/
|
||||
GIT_EXTERN(git_odb *) git_repository_database(git_repository *repo);
|
||||
|
||||
/**
|
||||
* Open the Index file of a Git repository
|
||||
*
|
||||
* This returns a new and unique `git_index` object representing the
|
||||
* active index for the repository.
|
||||
*
|
||||
* This method may be called more than once (e.g. on different threads).
|
||||
*
|
||||
* Each returned `git_index` object is independent and suffers no race
|
||||
* conditions: synchronization is done at the FS level.
|
||||
*
|
||||
* Each returned `git_index` object must be manually freed by the user,
|
||||
* using `git_index_free`.
|
||||
*
|
||||
* @param index Pointer where to store the index
|
||||
* @param repo a repository object
|
||||
* @return 0 on success; error code if the index could not be opened
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_index(git_index **index, git_repository *repo);
|
||||
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_close`, but accessing any of the attributes of
|
||||
* with `git_object_free`, but accessing any of the attributes of
|
||||
* an object without a backing repository will result in undefined
|
||||
* behavior
|
||||
*
|
||||
@ -178,17 +102,50 @@ GIT_EXTERN(void) git_repository_free(git_repository *repo);
|
||||
*
|
||||
* TODO:
|
||||
* - Reinit the repository
|
||||
* - Create config files
|
||||
*
|
||||
* @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
|
||||
* @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);
|
||||
|
||||
/**
|
||||
* 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_init(git_repository **repo_out, const char *path, unsigned is_bare);
|
||||
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
|
||||
@ -203,31 +160,145 @@ GIT_EXTERN(int) git_repository_init(git_repository **repo_out, const char *path,
|
||||
GIT_EXTERN(int) git_repository_is_empty(git_repository *repo);
|
||||
|
||||
/**
|
||||
* Get the normalized path to the git repository.
|
||||
* Get the path of this repository
|
||||
*
|
||||
* @param repo a repository object
|
||||
* @return absolute path to the git directory
|
||||
* 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 normalized path to the working directory of the repository.
|
||||
* Get the path of the working directory for this repository
|
||||
*
|
||||
* If the repository is bare, there is no working directory and NULL we be returned.
|
||||
* If the repository is bare, this function will always return
|
||||
* NULL.
|
||||
*
|
||||
* @param repo a repository object
|
||||
* @return NULL if the repository is bare; absolute path to the working directory otherwise.
|
||||
* @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
|
||||
* @return 0, or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_repository_set_workdir(git_repository *repo, const char *workdir);
|
||||
|
||||
/**
|
||||
* Check if a repository is bare
|
||||
*
|
||||
* @param repo Repo to test
|
||||
* @return 1 if the repository is empty, 0 otherwise.
|
||||
* @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);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
||||
|
@ -1,26 +1,8 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* 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.
|
||||
* 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__
|
||||
@ -44,28 +26,28 @@ GIT_BEGIN_DECL
|
||||
* and subject to change at any time.
|
||||
* This is the default sorting for new walkers.
|
||||
*/
|
||||
#define GIT_SORT_NONE (0)
|
||||
#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)
|
||||
#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)
|
||||
#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)
|
||||
#define GIT_SORT_REVERSE (1 << 2)
|
||||
|
||||
/**
|
||||
* Allocate a new revision walker to iterate through a repo.
|
||||
@ -83,7 +65,7 @@ GIT_BEGIN_DECL
|
||||
*
|
||||
* @param walker pointer to the new revision walker
|
||||
* @param repo the repo to walk through
|
||||
* @return 0 on success; error code otherwise
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_revwalk_new(git_revwalk **walker, git_repository *repo);
|
||||
|
||||
@ -113,12 +95,34 @@ GIT_EXTERN(void) git_revwalk_reset(git_revwalk *walker);
|
||||
* must be pushed the repository before a walk can
|
||||
* be started.
|
||||
*
|
||||
* @param walker the walker being used for the traversal.
|
||||
* @param walk the walker being used for the traversal.
|
||||
* @param oid the oid of the commit to start from.
|
||||
* @return 0 on success; error code otherwise
|
||||
* @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 it 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.
|
||||
@ -129,12 +133,58 @@ GIT_EXTERN(int) git_revwalk_push(git_revwalk *walk, const git_oid *oid);
|
||||
* The resolved commit and all its parents will be hidden from the
|
||||
* output on the revision walk.
|
||||
*
|
||||
* @param walker the walker being used for the traversal.
|
||||
* @param commit the commit that will be ignored during the traversal
|
||||
* @return 0 on success; error code otherwise
|
||||
* @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 it 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.
|
||||
*
|
||||
@ -150,8 +200,8 @@ GIT_EXTERN(int) git_revwalk_hide(git_revwalk *walk, const git_oid *oid);
|
||||
*
|
||||
* @param oid Pointer where to store the oid of the next commit
|
||||
* @param walk the walker to pop the commit from.
|
||||
* @return GIT_SUCCESS if the next commit was found;
|
||||
* GIT_EREVWALKOVER if there are no commits left to iterate
|
||||
* @return 0 if the next commit was found;
|
||||
* GIT_REVWALKOVER if there are no commits left to iterate
|
||||
*/
|
||||
GIT_EXTERN(int) git_revwalk_next(git_oid *oid, git_revwalk *walk);
|
||||
|
||||
@ -169,7 +219,7 @@ 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.
|
||||
* @param walk traversal handle to close. If NULL nothing occurs.
|
||||
*/
|
||||
GIT_EXTERN(void) git_revwalk_free(git_revwalk *walk);
|
||||
|
||||
|
@ -1,26 +1,8 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* 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.
|
||||
* 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__
|
||||
@ -41,23 +23,25 @@ GIT_BEGIN_DECL
|
||||
* Create a new action signature. 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 mail email 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 the new sig, NULL on out of memory
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(git_signature *) git_signature_new(const char *name, const char *email, git_time_t time, int offset);
|
||||
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 the new sig, NULL on out of memory
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(git_signature *) git_signature_now(const char *name, const char *email);
|
||||
GIT_EXTERN(int) git_signature_now(git_signature **sig_out, const char *name, const char *email);
|
||||
|
||||
|
||||
/**
|
||||
|
164
include/git2/status.h
Normal file
164
include/git2/status.h
Normal file
@ -0,0 +1,164 @@
|
||||
/*
|
||||
* 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 return that value.
|
||||
*
|
||||
* @param repo a repository object
|
||||
* @param callback the function to call on each file
|
||||
* @return 0 on success or the return value of the callback that was non-zero
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
|
||||
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_SUBMODULED = (1 << 3),
|
||||
GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS = (1 << 4),
|
||||
};
|
||||
|
||||
/**
|
||||
* 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
|
247
include/git2/stdint.h
Normal file
247
include/git2/stdint.h
Normal file
@ -0,0 +1,247 @@
|
||||
// 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 <limits.h>
|
||||
|
||||
// For Visual Studio 6 in C++ mode and for many Visual Studio versions when
|
||||
// compiling for ARM we should wrap <wchar.h> 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 <wchar.h>
|
||||
#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 <wchar.h>
|
||||
#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_ ]
|
103
include/git2/submodule.h
Normal file
103
include/git2/submodule.h
Normal file
@ -0,0 +1,103 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
typedef enum {
|
||||
GIT_SUBMODULE_UPDATE_CHECKOUT = 0,
|
||||
GIT_SUBMODULE_UPDATE_REBASE = 1,
|
||||
GIT_SUBMODULE_UPDATE_MERGE = 2
|
||||
} git_submodule_update_t;
|
||||
|
||||
typedef enum {
|
||||
GIT_SUBMODULE_IGNORE_ALL = 0, /* never dirty */
|
||||
GIT_SUBMODULE_IGNORE_DIRTY = 1, /* only dirty if HEAD moved */
|
||||
GIT_SUBMODULE_IGNORE_UNTRACKED = 2, /* dirty if tracked files change */
|
||||
GIT_SUBMODULE_IGNORE_NONE = 3 /* any change or untracked == dirty */
|
||||
} git_submodule_ignore_t;
|
||||
|
||||
/**
|
||||
* Description of submodule
|
||||
*
|
||||
* This record describes a submodule found in a repository. There
|
||||
* should be an entry for every submodule found in the HEAD and for
|
||||
* every submodule described in .gitmodules. The fields are as follows:
|
||||
*
|
||||
* - `name` is the name of the submodule from .gitmodules.
|
||||
* - `path` is the path to the submodule from the repo working directory.
|
||||
* It is almost always the same as `name`.
|
||||
* - `url` is the url for the submodule.
|
||||
* - `oid` is the HEAD SHA1 for the submodule.
|
||||
* - `update` is a value from above - see gitmodules(5) update.
|
||||
* - `ignore` is a value from above - see gitmodules(5) ignore.
|
||||
* - `fetch_recurse` is 0 or 1 - see gitmodules(5) fetchRecurseSubmodules.
|
||||
* - `refcount` is for internal use.
|
||||
*
|
||||
* If the submodule has been added to .gitmodules but not yet git added,
|
||||
* then the `oid` will be zero. If the submodule has been deleted, but
|
||||
* the delete has not been committed yet, then the `oid` will be set, but
|
||||
* the `url` will be NULL.
|
||||
*/
|
||||
typedef struct {
|
||||
char *name;
|
||||
char *path;
|
||||
char *url;
|
||||
git_oid oid; /* sha1 of submodule HEAD ref or zero if not committed */
|
||||
git_submodule_update_t update;
|
||||
git_submodule_ignore_t ignore;
|
||||
int fetch_recurse;
|
||||
int refcount;
|
||||
} git_submodule;
|
||||
|
||||
/**
|
||||
* Iterate over all submodules of a repository.
|
||||
*
|
||||
* @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)(const char *name, void *payload),
|
||||
void *payload);
|
||||
|
||||
/**
|
||||
* 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. If the submodule
|
||||
* does not exist, this will return GIT_ENOTFOUND and set the submodule
|
||||
* pointer to NULL.
|
||||
*
|
||||
* @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, -1 on error
|
||||
*/
|
||||
GIT_EXTERN(int) git_submodule_lookup(
|
||||
git_submodule **submodule,
|
||||
git_repository *repo,
|
||||
const char *name);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
@ -1,26 +1,8 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* 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.
|
||||
* 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__
|
||||
@ -45,17 +27,34 @@ GIT_BEGIN_DECL
|
||||
* @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 on success; error code otherwise
|
||||
* @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, unsigned int 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_close()
|
||||
* This is a wrapper around git_object_free()
|
||||
*
|
||||
* IMPORTANT:
|
||||
* It *is* necessary to call this method when you stop
|
||||
@ -64,9 +63,9 @@ GIT_INLINE(int) git_tag_lookup(git_tag **tag, git_repository *repo, const git_oi
|
||||
* @param tag the tag to close
|
||||
*/
|
||||
|
||||
GIT_INLINE(void) git_tag_close(git_tag *tag)
|
||||
GIT_INLINE(void) git_tag_free(git_tag *tag)
|
||||
{
|
||||
git_object_close((git_object *) tag);
|
||||
git_object_free((git_object *) tag);
|
||||
}
|
||||
|
||||
|
||||
@ -86,9 +85,9 @@ GIT_EXTERN(const git_oid *) git_tag_id(git_tag *tag);
|
||||
*
|
||||
* @param target pointer where to store the target
|
||||
* @param tag a previously loaded tag.
|
||||
* @return 0 on success; error code otherwise
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_tag_target(git_object **target, git_tag *t);
|
||||
GIT_EXTERN(int) git_tag_target(git_object **target, git_tag *tag);
|
||||
|
||||
/**
|
||||
* Get the OID of the tagged object of a tag
|
||||
@ -96,7 +95,7 @@ GIT_EXTERN(int) git_tag_target(git_object **target, git_tag *t);
|
||||
* @param tag a previously loaded tag.
|
||||
* @return pointer to the OID
|
||||
*/
|
||||
GIT_EXTERN(const git_oid *) git_tag_target_oid(git_tag *t);
|
||||
GIT_EXTERN(const git_oid *) git_tag_target_oid(git_tag *tag);
|
||||
|
||||
/**
|
||||
* Get the type of a tag's tagged object
|
||||
@ -104,7 +103,7 @@ GIT_EXTERN(const git_oid *) git_tag_target_oid(git_tag *t);
|
||||
* @param tag a previously loaded tag.
|
||||
* @return type of the tagged object
|
||||
*/
|
||||
GIT_EXTERN(git_otype) git_tag_type(git_tag *t);
|
||||
GIT_EXTERN(git_otype) git_tag_type(git_tag *tag);
|
||||
|
||||
/**
|
||||
* Get the name of a tag
|
||||
@ -112,7 +111,7 @@ GIT_EXTERN(git_otype) git_tag_type(git_tag *t);
|
||||
* @param tag a previously loaded tag.
|
||||
* @return name of the tag
|
||||
*/
|
||||
GIT_EXTERN(const char *) git_tag_name(git_tag *t);
|
||||
GIT_EXTERN(const char *) git_tag_name(git_tag *tag);
|
||||
|
||||
/**
|
||||
* Get the tagger (author) of a tag
|
||||
@ -120,7 +119,7 @@ GIT_EXTERN(const char *) git_tag_name(git_tag *t);
|
||||
* @param tag a previously loaded tag.
|
||||
* @return reference to the tag's author
|
||||
*/
|
||||
GIT_EXTERN(const git_signature *) git_tag_tagger(git_tag *t);
|
||||
GIT_EXTERN(const git_signature *) git_tag_tagger(git_tag *tag);
|
||||
|
||||
/**
|
||||
* Get the message of a tag
|
||||
@ -128,138 +127,101 @@ GIT_EXTERN(const git_signature *) git_tag_tagger(git_tag *t);
|
||||
* @param tag a previously loaded tag.
|
||||
* @return message of the tag
|
||||
*/
|
||||
GIT_EXTERN(const char *) git_tag_message(git_tag *t);
|
||||
GIT_EXTERN(const char *) git_tag_message(git_tag *tag);
|
||||
|
||||
|
||||
/**
|
||||
* Create a new tag in the repository from an OID
|
||||
* 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 be cleaned up from excess whitespace
|
||||
* it will be made sure that the last line ends with a '\n'.
|
||||
*
|
||||
* @param oid Pointer where to store the OID of the
|
||||
* newly created tag
|
||||
* 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
|
||||
* for consistency. It should also not conflict with an
|
||||
* already existing tag name
|
||||
*
|
||||
* @param target OID to which this tag points; note that no
|
||||
* validation is done on this OID. Use the _o version of this
|
||||
* method to assure a proper object is being tagged
|
||||
*
|
||||
* @param target_type Type of the tagged OID; note that no
|
||||
* validation is performed here either
|
||||
* @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
|
||||
* of the tagging time
|
||||
*
|
||||
* @param message Full message for this tag
|
||||
*
|
||||
* @return 0 on success; error code otherwise.
|
||||
* @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_oid *target,
|
||||
git_otype target_type,
|
||||
const git_signature *tagger,
|
||||
const char *message);
|
||||
|
||||
|
||||
/**
|
||||
* Create a new tag in the repository from an existing
|
||||
* `git_object` instance
|
||||
*
|
||||
* This method replaces the `target` and `target_type`
|
||||
* paremeters of `git_tag_create` by a single instance
|
||||
* of a `const git_object *`, which is assured to be
|
||||
* a proper object in the ODB and hence will create
|
||||
* a valid tag
|
||||
*
|
||||
* @see git_tag_create
|
||||
*/
|
||||
GIT_EXTERN(int) git_tag_create_o(
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *tag_name,
|
||||
const git_object *target,
|
||||
const git_signature *tagger,
|
||||
const char *message);
|
||||
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);
|
||||
const char *buffer,
|
||||
int force);
|
||||
|
||||
/**
|
||||
* Create a new tag in the repository from an OID
|
||||
* and overwrite an already existing tag reference, if any.
|
||||
* Create a new lightweight tag pointing at a target object
|
||||
*
|
||||
* @param oid Pointer where to store the OID of the
|
||||
* newly created tag
|
||||
* 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 repo Repository where to store the tag
|
||||
* @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.
|
||||
* for consistency. It should also not conflict with an
|
||||
* already existing tag name
|
||||
*
|
||||
* @param target OID to which this tag points; note that no
|
||||
* validation is done on this OID. Use the _fo version of this
|
||||
* method to assure a proper object is being tagged
|
||||
* @param target Object to which this tag points. This object
|
||||
* must belong to the given `repo`.
|
||||
*
|
||||
* @param target_type Type of the tagged OID; note that no
|
||||
* validation is performed here either
|
||||
* @param force Overwrite existing references
|
||||
*
|
||||
* @param tagger Signature of the tagger for this tag, and
|
||||
* of the tagging time
|
||||
*
|
||||
* @param message Full message for this tag
|
||||
*
|
||||
* @return 0 on success; error code otherwise.
|
||||
* A tag object is written to the ODB, and a proper reference
|
||||
* is written in the /refs/tags folder, pointing to it
|
||||
* @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_f(
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *tag_name,
|
||||
const git_oid *target,
|
||||
git_otype target_type,
|
||||
const git_signature *tagger,
|
||||
const char *message);
|
||||
|
||||
/**
|
||||
* Create a new tag in the repository from an existing
|
||||
* `git_object` instance and overwrite an already existing
|
||||
* tag reference, if any.
|
||||
*
|
||||
* This method replaces the `target` and `target_type`
|
||||
* paremeters of `git_tag_create_f` by a single instance
|
||||
* of a `const git_object *`, which is assured to be
|
||||
* a proper object in the ODB and hence will create
|
||||
* a valid tag
|
||||
*
|
||||
* @see git_tag_create_f
|
||||
*/
|
||||
GIT_EXTERN(int) git_tag_create_fo(
|
||||
GIT_EXTERN(int) git_tag_create_lightweight(
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *tag_name,
|
||||
const git_object *target,
|
||||
const git_signature *tagger,
|
||||
const char *message);
|
||||
int force);
|
||||
|
||||
/**
|
||||
* Delete an existing tag reference.
|
||||
@ -269,7 +231,7 @@ GIT_EXTERN(int) git_tag_create_fo(
|
||||
* @param tag_name Name of the tag to be deleted;
|
||||
* this name is validated for consistency.
|
||||
*
|
||||
* @return 0 on success; error code otherwise.
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_tag_delete(
|
||||
git_repository *repo,
|
||||
@ -283,15 +245,53 @@ GIT_EXTERN(int) git_tag_delete(
|
||||
* should be free'd manually when no longer needed, using
|
||||
* `git_strarray_free`.
|
||||
*
|
||||
* @param array Pointer to a git_strarray structure where
|
||||
* @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 on success; error code otherwise
|
||||
* @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
|
||||
|
@ -1,71 +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.
|
||||
*/
|
||||
#ifndef INCLUDE_git_thread_utils_h__
|
||||
#define INCLUDE_git_thread_utils_h__
|
||||
|
||||
/*
|
||||
* How TLS works is compiler+platform dependant
|
||||
* Sources: http://en.wikipedia.org/wiki/Thread-Specific_Storage
|
||||
* http://predef.sourceforge.net/precomp.html
|
||||
*/
|
||||
|
||||
#define GIT_HAS_TLS 1
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
# undef GIT_TLS
|
||||
# define GIT_TLS
|
||||
|
||||
#elif defined(__GNUC__) || \
|
||||
defined(__SUNPRO_C) || \
|
||||
defined(__SUNPRO_CC) || \
|
||||
defined(__xlc__) || \
|
||||
defined(__xlC__)
|
||||
# define GIT_TLS __thread
|
||||
|
||||
#elif defined(__INTEL_COMPILER)
|
||||
# if defined(_WIN32) || defined(_WIN32_CE)
|
||||
# define GIT_TLS __declspec(thread)
|
||||
# else
|
||||
# define GIT_TLS __thread
|
||||
# endif
|
||||
|
||||
#elif defined(_WIN32) || \
|
||||
defined(_WIN32_CE) || \
|
||||
defined(__BORLANDC__)
|
||||
# define GIT_TLS __declspec(thread)
|
||||
|
||||
#else
|
||||
# undef GIT_HAS_TLS
|
||||
# define GIT_TLS /* nothing: tls vars are thread-global */
|
||||
#endif
|
||||
|
||||
/* sparse and cygwin don't grok thread-local variables */
|
||||
#if defined(__CHECKER__) || defined(__CYGWIN__)
|
||||
# undef GIT_HAS_TLS
|
||||
# undef GIT_TLS
|
||||
# define GIT_TLS
|
||||
#endif
|
||||
|
||||
#endif /* INCLUDE_git_thread_utils_h__ */
|
48
include/git2/threads.h
Normal file
48
include/git2/threads.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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
|
||||
|
@ -1,26 +1,8 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* 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.
|
||||
* 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__
|
||||
@ -45,17 +27,34 @@ GIT_BEGIN_DECL
|
||||
* @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 on success; error code otherwise
|
||||
* @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, unsigned int 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_close()
|
||||
* This is a wrapper around git_object_free()
|
||||
*
|
||||
* IMPORTANT:
|
||||
* It *is* necessary to call this method when you stop
|
||||
@ -64,9 +63,9 @@ GIT_INLINE(int) git_tree_lookup(git_tree **tree, git_repository *repo, const git
|
||||
* @param tree the tree to close
|
||||
*/
|
||||
|
||||
GIT_INLINE(void) git_tree_close(git_tree *tree)
|
||||
GIT_INLINE(void) git_tree_free(git_tree *tree)
|
||||
{
|
||||
git_object_close((git_object *) tree);
|
||||
git_object_free((git_object *) tree);
|
||||
}
|
||||
|
||||
|
||||
@ -84,7 +83,7 @@ GIT_EXTERN(const git_oid *) git_tree_id(git_tree *tree);
|
||||
* @param tree a previously loaded tree.
|
||||
* @return the number of entries in the tree
|
||||
*/
|
||||
GIT_EXTERN(size_t) git_tree_entrycount(git_tree *tree);
|
||||
GIT_EXTERN(unsigned int) git_tree_entrycount(git_tree *tree);
|
||||
|
||||
/**
|
||||
* Lookup a tree entry by its filename
|
||||
@ -102,7 +101,7 @@ GIT_EXTERN(const git_tree_entry *) git_tree_entry_byname(git_tree *tree, const c
|
||||
* @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, int idx);
|
||||
GIT_EXTERN(const git_tree_entry *) git_tree_entry_byindex(git_tree *tree, unsigned int idx);
|
||||
|
||||
/**
|
||||
* Get the UNIX file attributes of a tree entry
|
||||
@ -128,15 +127,23 @@ GIT_EXTERN(const char *) git_tree_entry_name(const git_tree_entry *entry);
|
||||
*/
|
||||
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 on success; error code otherwise
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_tree_entry_2object(git_object **object_out, git_repository *repo, const git_tree_entry *entry);
|
||||
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
|
||||
@ -152,7 +159,7 @@ GIT_EXTERN(int) git_tree_entry_2object(git_object **object_out, git_repository *
|
||||
*
|
||||
* @param oid Pointer where to store the written tree
|
||||
* @param index Index to write
|
||||
* @return 0 on success; error code otherwise
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_tree_create_fromindex(git_oid *oid, git_index *index);
|
||||
|
||||
@ -165,13 +172,13 @@ GIT_EXTERN(int) git_tree_create_fromindex(git_oid *oid, git_index *index);
|
||||
*
|
||||
* 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 sucess; error code otherwise
|
||||
* @return 0 on success; error code otherwise
|
||||
*/
|
||||
GIT_EXTERN(int) git_treebuilder_create(git_treebuilder **builder_p, const git_tree *source);
|
||||
|
||||
@ -222,7 +229,7 @@ GIT_EXTERN(const git_tree_entry *) git_treebuilder_get(git_treebuilder *bld, con
|
||||
* @param filename Filename of the entry
|
||||
* @param id SHA1 oid of the entry
|
||||
* @param attributes Folder attributes of the entry
|
||||
* @return 0 on success; error code otherwise
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_treebuilder_insert(git_tree_entry **entry_out, git_treebuilder *bld, const char *filename, const git_oid *id, unsigned int attributes);
|
||||
|
||||
@ -257,10 +264,55 @@ GIT_EXTERN(void) git_treebuilder_filter(git_treebuilder *bld, int (*filter)(cons
|
||||
* @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 on success; error code otherwise
|
||||
* @return 0 or an error code
|
||||
*/
|
||||
GIT_EXTERN(int) git_treebuilder_write(git_oid *oid, git_repository *repo, git_treebuilder *bld);
|
||||
|
||||
/**
|
||||
* Retrieve a subtree contained in a tree, given its
|
||||
* relative path.
|
||||
*
|
||||
* The returned tree is owned by the repository and
|
||||
* should be closed with the `git_object_free` method.
|
||||
*
|
||||
* @param subtree Pointer where to store the subtree
|
||||
* @param root A previously loaded tree which will be the root of the relative path
|
||||
* @param subtree_path Path to the contained subtree
|
||||
* @return 0 on success; GIT_ENOTFOUND if the path does not lead to a subtree
|
||||
*/
|
||||
GIT_EXTERN(int) git_tree_get_subtree(git_tree **subtree, git_tree *root, const char *subtree_path);
|
||||
|
||||
/** Callback for the tree traversal method */
|
||||
typedef int (*git_treewalk_cb)(const char *root, 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 negative value, the passed entry
|
||||
* will be skipped on the traversal.
|
||||
*
|
||||
* @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
|
||||
|
@ -1,30 +1,14 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* 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.
|
||||
* 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
|
||||
@ -55,16 +39,21 @@ GIT_BEGIN_DECL
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
typedef __int64 git_off_t;
|
||||
typedef __time64_t git_time_t;
|
||||
typedef __time64_t git_time_t;
|
||||
|
||||
#elif defined(__MINGW32__)
|
||||
|
||||
typedef off64_t git_off_t;
|
||||
typedef __time64_t git_time_t;
|
||||
|
||||
#else /* POSIX */
|
||||
#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 <sys/types.h>
|
||||
* before us (directly or indirectly), they'll get 32 bit off_t in their client
|
||||
* app, even though /we/ define _FILE_OFFSET_BITS=64.
|
||||
@ -77,15 +66,15 @@ typedef int64_t git_time_t;
|
||||
/** 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_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. */
|
||||
@ -139,6 +128,15 @@ 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 */
|
||||
@ -163,7 +161,18 @@ typedef enum {
|
||||
GIT_REF_PACKED = 4,
|
||||
GIT_REF_HAS_PEEL = 8,
|
||||
GIT_REF_LISTALL = GIT_REF_OID|GIT_REF_SYMBOLIC|GIT_REF_PACKED,
|
||||
} git_rtype;
|
||||
} git_ref_t;
|
||||
|
||||
/** Basic type of any Git branch. */
|
||||
typedef enum {
|
||||
GIT_BRANCH_LOCAL = 1,
|
||||
GIT_BRANCH_REMOTE = 2,
|
||||
} git_branch_t;
|
||||
|
||||
typedef struct git_refspec git_refspec;
|
||||
typedef struct git_remote git_remote;
|
||||
|
||||
typedef struct git_remote_head git_remote_head;
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
|
15
include/git2/version.h
Normal file
15
include/git2/version.h
Normal file
@ -0,0 +1,15 @@
|
||||
/*
|
||||
* 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
|
59
include/git2/windows.h
Normal file
59
include/git2/windows.h
Normal file
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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_windows_h__
|
||||
#define INCLUDE_git_windows_h__
|
||||
|
||||
#include "common.h"
|
||||
|
||||
/**
|
||||
* @file git2/windows.h
|
||||
* @brief Windows-specific functions
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
/**
|
||||
* Set the active codepage for Windows syscalls
|
||||
*
|
||||
* All syscalls performed by the library will assume
|
||||
* this codepage when converting paths and strings
|
||||
* to use by the Windows kernel.
|
||||
*
|
||||
* The default value of UTF-8 will work automatically
|
||||
* with most Git repositories created on Unix systems.
|
||||
*
|
||||
* This settings needs only be changed when working
|
||||
* with repositories that contain paths in specific,
|
||||
* non-UTF codepages.
|
||||
*
|
||||
* A full list of all available codepage identifiers may
|
||||
* be found at:
|
||||
*
|
||||
* http://msdn.microsoft.com/en-us/library/windows/desktop/dd317756(v=vs.85).aspx
|
||||
*
|
||||
* @param codepage numeric codepage identifier
|
||||
*/
|
||||
GIT_EXTERN(void) gitwin_set_codepage(unsigned int codepage);
|
||||
|
||||
/**
|
||||
* Return the active codepage for Windows syscalls
|
||||
*
|
||||
* @return numeric codepage identifier
|
||||
*/
|
||||
GIT_EXTERN(unsigned int) gitwin_get_codepage(void);
|
||||
|
||||
/**
|
||||
* Set the active Windows codepage to UTF-8 (this is
|
||||
* the default value)
|
||||
*/
|
||||
GIT_EXTERN(void) gitwin_set_utf8(void);
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
||||
|
@ -1,58 +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.
|
||||
*/
|
||||
#ifndef INCLUDE_git_zlib_h__
|
||||
#define INCLUDE_git_zlib_h__
|
||||
|
||||
#include <zlib.h>
|
||||
|
||||
/**
|
||||
* @file git2/zlib.h
|
||||
* @brief Git data compression routines
|
||||
* @defgroup git_zlib Git data compression routines
|
||||
* @ingroup Git
|
||||
* @{
|
||||
*/
|
||||
GIT_BEGIN_DECL
|
||||
|
||||
#if defined(NO_DEFLATE_BOUND) || ZLIB_VERNUM < 0x1200
|
||||
/**
|
||||
* deflateBound returns an upper bound on the compressed size.
|
||||
*
|
||||
* This is a stub function used when zlib does not supply the
|
||||
* deflateBound() implementation itself.
|
||||
*
|
||||
* @param stream the stream pointer.
|
||||
* @param s total length of the source data (in bytes).
|
||||
* @return maximum length of the compressed data.
|
||||
*/
|
||||
GIT_INLINE(size_t) deflateBound(z_streamp stream, size_t s)
|
||||
{
|
||||
return (s + ((s + 7) >> 3) + ((s + 63) >> 6) + 11);
|
||||
}
|
||||
#endif
|
||||
|
||||
/** @} */
|
||||
GIT_END_DECL
|
||||
#endif
|
@ -1,11 +1,9 @@
|
||||
prefix=@prefix@
|
||||
exec_prefix=${prefix}
|
||||
libdir=@libdir@
|
||||
includedir=${prefix}/include
|
||||
libdir=@CMAKE_INSTALL_PREFIX@/@INSTALL_LIB@
|
||||
includedir=@CMAKE_INSTALL_PREFIX@/@INSTALL_INC@
|
||||
|
||||
Name: libgit2
|
||||
Description: The git library, take 2
|
||||
Version: @version@
|
||||
Version: @LIBGIT2_VERSION_STRING@
|
||||
Requires: libcrypto
|
||||
Libs: -L${libdir} -lgit2 -lz -lcrypto
|
||||
Cflags: -I${includedir}
|
||||
|
6
packaging/rpm/README
Normal file
6
packaging/rpm/README
Normal file
@ -0,0 +1,6 @@
|
||||
To build RPM pakcages for Fedora, follow these steps:
|
||||
cp packaging/rpm/libgit2.spec ~/rpmbuild/SPECS
|
||||
cd ~/rpmbuild/SOURCES
|
||||
wget https://github.com/downloads/libgit2/libgit2/libgit2-0.16.0.tar.gz
|
||||
cd ~/rpmbuild/SPECS
|
||||
rpmbuild -ba libgit2.spec
|
106
packaging/rpm/libgit2.spec
Normal file
106
packaging/rpm/libgit2.spec
Normal file
@ -0,0 +1,106 @@
|
||||
#
|
||||
# spec file for package libgit2
|
||||
#
|
||||
# Copyright (c) 2012 Saleem Ansari <tuxdna@gmail.com>
|
||||
# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
||||
# Copyright (c) 2011, Sascha Peilicke <saschpe@gmx.de>
|
||||
#
|
||||
# All modifications and additions to the file contributed by third parties
|
||||
# remain the property of their copyright owners, unless otherwise agreed
|
||||
# upon. The license for this file, and modifications and additions to the
|
||||
# file, is the same license as for the pristine package itself (unless the
|
||||
# license for the pristine package is not an Open Source License, in which
|
||||
# case the license is the MIT License). An "Open Source License" is a
|
||||
# license that conforms to the Open Source Definition (Version 1.9)
|
||||
# published by the Open Source Initiative.
|
||||
|
||||
# Please submit bugfixes or comments via http://bugs.opensuse.org/
|
||||
#
|
||||
Name: libgit2
|
||||
Version: 0.16.0
|
||||
Release: 1
|
||||
Summary: C git library
|
||||
License: GPL-2.0 with linking
|
||||
Group: Development/Libraries/C and C++
|
||||
Url: http://libgit2.github.com/
|
||||
Source0: https://github.com/downloads/libgit2/libgit2/libgit2-0.16.0.tar.gz
|
||||
BuildRequires: cmake
|
||||
BuildRequires: pkgconfig
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
%if 0%{?fedora} || 0%{?rhel_version} || 0%{?centos_version}
|
||||
BuildRequires: openssl-devel
|
||||
%else
|
||||
BuildRequires: libopenssl-devel
|
||||
%endif
|
||||
|
||||
%description
|
||||
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.
|
||||
|
||||
%package -n %{name}-0
|
||||
Summary: C git library
|
||||
Group: System/Libraries
|
||||
|
||||
%description -n %{name}-0
|
||||
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.
|
||||
|
||||
%package devel
|
||||
Summary: C git library
|
||||
Group: Development/Libraries/C and C++
|
||||
Requires: %{name}-0 >= %{version}
|
||||
|
||||
%description devel
|
||||
This package contains all necessary include files and libraries needed
|
||||
to compile and develop applications that use libgit2.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
|
||||
%build
|
||||
cmake . \
|
||||
-DCMAKE_C_FLAGS:STRING="%{optflags}" \
|
||||
-DCMAKE_INSTALL_PREFIX:PATH=%{_prefix} \
|
||||
-DINSTALL_LIB:PATH=%{_libdir}
|
||||
make %{?_smp_mflags}
|
||||
|
||||
%install
|
||||
%make_install
|
||||
|
||||
%post -n %{name}-0 -p /sbin/ldconfig
|
||||
%postun -n %{name}-0 -p /sbin/ldconfig
|
||||
|
||||
%files -n %{name}-0
|
||||
%defattr (-,root,root)
|
||||
%doc AUTHORS COPYING README.md
|
||||
%{_libdir}/%{name}.so.*
|
||||
|
||||
%files devel
|
||||
%defattr (-,root,root)
|
||||
%doc CONVENTIONS examples
|
||||
%{_libdir}/%{name}.so
|
||||
%{_includedir}/git2*
|
||||
%{_libdir}/pkgconfig/libgit2.pc
|
||||
|
||||
%changelog
|
||||
* Tue Mar 04 2012 tuxdna@gmail.com
|
||||
- Update to version 0.16.0
|
||||
* Tue Jan 31 2012 jengelh@medozas.de
|
||||
- Provide pkgconfig symbols
|
||||
* Thu Oct 27 2011 saschpe@suse.de
|
||||
- Change license to 'GPL-2.0 with linking', fixes bnc#726789
|
||||
* Wed Oct 26 2011 saschpe@suse.de
|
||||
- Update to version 0.15.0:
|
||||
* Upstream doesn't provide changes
|
||||
- Removed outdated %%clean section
|
||||
* Tue Jan 18 2011 saschpe@gmx.de
|
||||
- Proper Requires for devel package
|
||||
* Tue Jan 18 2011 saschpe@gmx.de
|
||||
- Set BuildRequires to "openssl-devel" also for RHEL and CentOS
|
||||
* Tue Jan 18 2011 saschpe@gmx.de
|
||||
- Initial commit (0.0.1)
|
||||
- Added patch to fix shared library soname
|
677
src/attr.c
Normal file
677
src/attr.c
Normal file
@ -0,0 +1,677 @@
|
||||
#include "repository.h"
|
||||
#include "fileops.h"
|
||||
#include "config.h"
|
||||
#include <ctype.h>
|
||||
|
||||
GIT__USE_STRMAP;
|
||||
|
||||
static int collect_attr_files(
|
||||
git_repository *repo,
|
||||
uint32_t flags,
|
||||
const char *path,
|
||||
git_vector *files);
|
||||
|
||||
|
||||
int git_attr_get(
|
||||
const char **value,
|
||||
git_repository *repo,
|
||||
uint32_t flags,
|
||||
const char *pathname,
|
||||
const char *name)
|
||||
{
|
||||
int error;
|
||||
git_attr_path path;
|
||||
git_vector files = GIT_VECTOR_INIT;
|
||||
unsigned int i, j;
|
||||
git_attr_file *file;
|
||||
git_attr_name attr;
|
||||
git_attr_rule *rule;
|
||||
|
||||
*value = NULL;
|
||||
|
||||
if (git_attr_path__init(&path, pathname, git_repository_workdir(repo)) < 0)
|
||||
return -1;
|
||||
|
||||
if ((error = collect_attr_files(repo, flags, pathname, &files)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
attr.name = name;
|
||||
attr.name_hash = git_attr_file__name_hash(name);
|
||||
|
||||
git_vector_foreach(&files, i, file) {
|
||||
|
||||
git_attr_file__foreach_matching_rule(file, &path, j, rule) {
|
||||
int pos = git_vector_bsearch(&rule->assigns, &attr);
|
||||
if (pos >= 0) {
|
||||
*value = ((git_attr_assignment *)git_vector_get(
|
||||
&rule->assigns, pos))->value;
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
git_vector_free(&files);
|
||||
git_attr_path__free(&path);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
git_attr_name name;
|
||||
git_attr_assignment *found;
|
||||
} attr_get_many_info;
|
||||
|
||||
int git_attr_get_many(
|
||||
const char **values,
|
||||
git_repository *repo,
|
||||
uint32_t flags,
|
||||
const char *pathname,
|
||||
size_t num_attr,
|
||||
const char **names)
|
||||
{
|
||||
int error;
|
||||
git_attr_path path;
|
||||
git_vector files = GIT_VECTOR_INIT;
|
||||
unsigned int i, j, k;
|
||||
git_attr_file *file;
|
||||
git_attr_rule *rule;
|
||||
attr_get_many_info *info = NULL;
|
||||
size_t num_found = 0;
|
||||
|
||||
memset((void *)values, 0, sizeof(const char *) * num_attr);
|
||||
|
||||
if (git_attr_path__init(&path, pathname, git_repository_workdir(repo)) < 0)
|
||||
return -1;
|
||||
|
||||
if ((error = collect_attr_files(repo, flags, pathname, &files)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
info = git__calloc(num_attr, sizeof(attr_get_many_info));
|
||||
GITERR_CHECK_ALLOC(info);
|
||||
|
||||
git_vector_foreach(&files, i, file) {
|
||||
|
||||
git_attr_file__foreach_matching_rule(file, &path, j, rule) {
|
||||
|
||||
for (k = 0; k < num_attr; k++) {
|
||||
int pos;
|
||||
|
||||
if (info[k].found != NULL) /* already found assignment */
|
||||
continue;
|
||||
|
||||
if (!info[k].name.name) {
|
||||
info[k].name.name = names[k];
|
||||
info[k].name.name_hash = git_attr_file__name_hash(names[k]);
|
||||
}
|
||||
|
||||
pos = git_vector_bsearch(&rule->assigns, &info[k].name);
|
||||
if (pos >= 0) {
|
||||
info[k].found = (git_attr_assignment *)
|
||||
git_vector_get(&rule->assigns, pos);
|
||||
values[k] = info[k].found->value;
|
||||
|
||||
if (++num_found == num_attr)
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
git_vector_free(&files);
|
||||
git_attr_path__free(&path);
|
||||
git__free(info);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int git_attr_foreach(
|
||||
git_repository *repo,
|
||||
uint32_t flags,
|
||||
const char *pathname,
|
||||
int (*callback)(const char *name, const char *value, void *payload),
|
||||
void *payload)
|
||||
{
|
||||
int error;
|
||||
git_attr_path path;
|
||||
git_vector files = GIT_VECTOR_INIT;
|
||||
unsigned int i, j, k;
|
||||
git_attr_file *file;
|
||||
git_attr_rule *rule;
|
||||
git_attr_assignment *assign;
|
||||
git_strmap *seen = NULL;
|
||||
|
||||
if (git_attr_path__init(&path, pathname, git_repository_workdir(repo)) < 0)
|
||||
return -1;
|
||||
|
||||
if ((error = collect_attr_files(repo, flags, pathname, &files)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
seen = git_strmap_alloc();
|
||||
GITERR_CHECK_ALLOC(seen);
|
||||
|
||||
git_vector_foreach(&files, i, file) {
|
||||
|
||||
git_attr_file__foreach_matching_rule(file, &path, j, rule) {
|
||||
|
||||
git_vector_foreach(&rule->assigns, k, assign) {
|
||||
/* skip if higher priority assignment was already seen */
|
||||
if (git_strmap_exists(seen, assign->name))
|
||||
continue;
|
||||
|
||||
git_strmap_insert(seen, assign->name, assign, error);
|
||||
if (error >= 0)
|
||||
error = callback(assign->name, assign->value, payload);
|
||||
|
||||
if (error != 0)
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
git_strmap_free(seen);
|
||||
git_vector_free(&files);
|
||||
git_attr_path__free(&path);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int git_attr_add_macro(
|
||||
git_repository *repo,
|
||||
const char *name,
|
||||
const char *values)
|
||||
{
|
||||
int error;
|
||||
git_attr_rule *macro = NULL;
|
||||
git_pool *pool;
|
||||
|
||||
if (git_attr_cache__init(repo) < 0)
|
||||
return -1;
|
||||
|
||||
macro = git__calloc(1, sizeof(git_attr_rule));
|
||||
GITERR_CHECK_ALLOC(macro);
|
||||
|
||||
pool = &git_repository_attr_cache(repo)->pool;
|
||||
|
||||
macro->match.pattern = git_pool_strdup(pool, name);
|
||||
GITERR_CHECK_ALLOC(macro->match.pattern);
|
||||
|
||||
macro->match.length = strlen(macro->match.pattern);
|
||||
macro->match.flags = GIT_ATTR_FNMATCH_MACRO;
|
||||
|
||||
error = git_attr_assignment__parse(repo, pool, ¯o->assigns, &values);
|
||||
|
||||
if (!error)
|
||||
error = git_attr_cache__insert_macro(repo, macro);
|
||||
|
||||
if (error < 0)
|
||||
git_attr_rule__free(macro);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
bool git_attr_cache__is_cached(
|
||||
git_repository *repo, git_attr_file_source source, const char *path)
|
||||
{
|
||||
git_buf cache_key = GIT_BUF_INIT;
|
||||
git_strmap *files = git_repository_attr_cache(repo)->files;
|
||||
const char *workdir = git_repository_workdir(repo);
|
||||
bool rval;
|
||||
|
||||
if (workdir && git__prefixcmp(path, workdir) == 0)
|
||||
path += strlen(workdir);
|
||||
if (git_buf_printf(&cache_key, "%d#%s", (int)source, path) < 0)
|
||||
return false;
|
||||
|
||||
rval = git_strmap_exists(files, git_buf_cstr(&cache_key));
|
||||
|
||||
git_buf_free(&cache_key);
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
static int load_attr_file(
|
||||
const char **data,
|
||||
git_attr_file_stat_sig *sig,
|
||||
const char *filename)
|
||||
{
|
||||
int error;
|
||||
git_buf content = GIT_BUF_INIT;
|
||||
struct stat st;
|
||||
|
||||
if (p_stat(filename, &st) < 0)
|
||||
return GIT_ENOTFOUND;
|
||||
|
||||
if (sig != NULL &&
|
||||
(git_time_t)st.st_mtime == sig->seconds &&
|
||||
(git_off_t)st.st_size == sig->size &&
|
||||
(unsigned int)st.st_ino == sig->ino)
|
||||
return GIT_ENOTFOUND;
|
||||
|
||||
error = git_futils_readbuffer_updated(&content, filename, NULL, NULL);
|
||||
if (error < 0)
|
||||
return error;
|
||||
|
||||
if (sig != NULL) {
|
||||
sig->seconds = (git_time_t)st.st_mtime;
|
||||
sig->size = (git_off_t)st.st_size;
|
||||
sig->ino = (unsigned int)st.st_ino;
|
||||
}
|
||||
|
||||
*data = git_buf_detach(&content);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int load_attr_blob_from_index(
|
||||
const char **content,
|
||||
git_blob **blob,
|
||||
git_repository *repo,
|
||||
const git_oid *old_oid,
|
||||
const char *relfile)
|
||||
{
|
||||
int error;
|
||||
git_index *index;
|
||||
git_index_entry *entry;
|
||||
|
||||
if ((error = git_repository_index__weakptr(&index, repo)) < 0 ||
|
||||
(error = git_index_find(index, relfile)) < 0)
|
||||
return error;
|
||||
|
||||
entry = git_index_get(index, error);
|
||||
|
||||
if (old_oid && git_oid_cmp(old_oid, &entry->oid) == 0)
|
||||
return GIT_ENOTFOUND;
|
||||
|
||||
if ((error = git_blob_lookup(blob, repo, &entry->oid)) < 0)
|
||||
return error;
|
||||
|
||||
*content = git_blob_rawcontent(*blob);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int load_attr_from_cache(
|
||||
git_attr_file **file,
|
||||
git_attr_cache *cache,
|
||||
git_attr_file_source source,
|
||||
const char *relative_path)
|
||||
{
|
||||
git_buf cache_key = GIT_BUF_INIT;
|
||||
khiter_t cache_pos;
|
||||
|
||||
*file = NULL;
|
||||
|
||||
if (!cache || !cache->files)
|
||||
return 0;
|
||||
|
||||
if (git_buf_printf(&cache_key, "%d#%s", (int)source, relative_path) < 0)
|
||||
return -1;
|
||||
|
||||
cache_pos = git_strmap_lookup_index(cache->files, cache_key.ptr);
|
||||
|
||||
git_buf_free(&cache_key);
|
||||
|
||||
if (git_strmap_valid_index(cache->files, cache_pos))
|
||||
*file = git_strmap_value_at(cache->files, cache_pos);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_attr_cache__internal_file(
|
||||
git_repository *repo,
|
||||
const char *filename,
|
||||
git_attr_file **file)
|
||||
{
|
||||
int error = 0;
|
||||
git_attr_cache *cache = git_repository_attr_cache(repo);
|
||||
khiter_t cache_pos = git_strmap_lookup_index(cache->files, filename);
|
||||
|
||||
if (git_strmap_valid_index(cache->files, cache_pos)) {
|
||||
*file = git_strmap_value_at(cache->files, cache_pos);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (git_attr_file__new(file, 0, filename, &cache->pool) < 0)
|
||||
return -1;
|
||||
|
||||
git_strmap_insert(cache->files, (*file)->key + 2, *file, error);
|
||||
if (error > 0)
|
||||
error = 0;
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_attr_cache__push_file(
|
||||
git_repository *repo,
|
||||
const char *base,
|
||||
const char *filename,
|
||||
git_attr_file_source source,
|
||||
git_attr_file_parser parse,
|
||||
git_vector *stack)
|
||||
{
|
||||
int error = 0;
|
||||
git_buf path = GIT_BUF_INIT;
|
||||
const char *workdir = git_repository_workdir(repo);
|
||||
const char *relfile, *content = NULL;
|
||||
git_attr_cache *cache = git_repository_attr_cache(repo);
|
||||
git_attr_file *file = NULL;
|
||||
git_blob *blob = NULL;
|
||||
git_attr_file_stat_sig st;
|
||||
|
||||
assert(filename && stack);
|
||||
|
||||
/* join base and path as needed */
|
||||
if (base != NULL && git_path_root(filename) < 0) {
|
||||
if (git_buf_joinpath(&path, base, filename) < 0)
|
||||
return -1;
|
||||
filename = path.ptr;
|
||||
}
|
||||
|
||||
relfile = filename;
|
||||
if (workdir && git__prefixcmp(relfile, workdir) == 0)
|
||||
relfile += strlen(workdir);
|
||||
|
||||
/* check cache */
|
||||
if (load_attr_from_cache(&file, cache, source, relfile) < 0)
|
||||
return -1;
|
||||
|
||||
/* if not in cache, load data, parse, and cache */
|
||||
|
||||
if (source == GIT_ATTR_FILE_FROM_FILE) {
|
||||
if (file)
|
||||
memcpy(&st, &file->cache_data.st, sizeof(st));
|
||||
else
|
||||
memset(&st, 0, sizeof(st));
|
||||
|
||||
error = load_attr_file(&content, &st, filename);
|
||||
} else {
|
||||
error = load_attr_blob_from_index(&content, &blob,
|
||||
repo, file ? &file->cache_data.oid : NULL, relfile);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
/* not finding a file is not an error for this function */
|
||||
if (error == GIT_ENOTFOUND) {
|
||||
giterr_clear();
|
||||
error = 0;
|
||||
}
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* if we got here, we have to parse and/or reparse the file */
|
||||
if (file)
|
||||
git_attr_file__clear_rules(file);
|
||||
else {
|
||||
error = git_attr_file__new(&file, source, relfile, &cache->pool);
|
||||
if (error < 0)
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (parse && (error = parse(repo, content, file)) < 0)
|
||||
goto finish;
|
||||
|
||||
git_strmap_insert(cache->files, file->key, file, error);
|
||||
if (error > 0)
|
||||
error = 0;
|
||||
|
||||
/* remember "cache buster" file signature */
|
||||
if (blob)
|
||||
git_oid_cpy(&file->cache_data.oid, git_object_id((git_object *)blob));
|
||||
else
|
||||
memcpy(&file->cache_data.st, &st, sizeof(st));
|
||||
|
||||
finish:
|
||||
/* push file onto vector if we found one*/
|
||||
if (!error && file != NULL)
|
||||
error = git_vector_insert(stack, file);
|
||||
|
||||
if (error != 0)
|
||||
git_attr_file__free(file);
|
||||
|
||||
if (blob)
|
||||
git_blob_free(blob);
|
||||
else
|
||||
git__free((void *)content);
|
||||
|
||||
git_buf_free(&path);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
#define push_attr_file(R,S,B,F) \
|
||||
git_attr_cache__push_file((R),(B),(F),GIT_ATTR_FILE_FROM_FILE,git_attr_file__parse_buffer,(S))
|
||||
|
||||
typedef struct {
|
||||
git_repository *repo;
|
||||
uint32_t flags;
|
||||
const char *workdir;
|
||||
git_index *index;
|
||||
git_vector *files;
|
||||
} attr_walk_up_info;
|
||||
|
||||
int git_attr_cache__decide_sources(
|
||||
uint32_t flags, bool has_wd, bool has_index, git_attr_file_source *srcs)
|
||||
{
|
||||
int count = 0;
|
||||
|
||||
switch (flags & 0x03) {
|
||||
case GIT_ATTR_CHECK_FILE_THEN_INDEX:
|
||||
if (has_wd)
|
||||
srcs[count++] = GIT_ATTR_FILE_FROM_FILE;
|
||||
if (has_index)
|
||||
srcs[count++] = GIT_ATTR_FILE_FROM_INDEX;
|
||||
break;
|
||||
case GIT_ATTR_CHECK_INDEX_THEN_FILE:
|
||||
if (has_index)
|
||||
srcs[count++] = GIT_ATTR_FILE_FROM_INDEX;
|
||||
if (has_wd)
|
||||
srcs[count++] = GIT_ATTR_FILE_FROM_FILE;
|
||||
break;
|
||||
case GIT_ATTR_CHECK_INDEX_ONLY:
|
||||
if (has_index)
|
||||
srcs[count++] = GIT_ATTR_FILE_FROM_INDEX;
|
||||
break;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int push_one_attr(void *ref, git_buf *path)
|
||||
{
|
||||
int error = 0, n_src, i;
|
||||
attr_walk_up_info *info = (attr_walk_up_info *)ref;
|
||||
git_attr_file_source src[2];
|
||||
|
||||
n_src = git_attr_cache__decide_sources(
|
||||
info->flags, info->workdir != NULL, info->index != NULL, src);
|
||||
|
||||
for (i = 0; !error && i < n_src; ++i)
|
||||
error = git_attr_cache__push_file(
|
||||
info->repo, path->ptr, GIT_ATTR_FILE, src[i],
|
||||
git_attr_file__parse_buffer, info->files);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int collect_attr_files(
|
||||
git_repository *repo,
|
||||
uint32_t flags,
|
||||
const char *path,
|
||||
git_vector *files)
|
||||
{
|
||||
int error;
|
||||
git_buf dir = GIT_BUF_INIT;
|
||||
const char *workdir = git_repository_workdir(repo);
|
||||
attr_walk_up_info info;
|
||||
|
||||
if (git_attr_cache__init(repo) < 0 ||
|
||||
git_vector_init(files, 4, NULL) < 0)
|
||||
return -1;
|
||||
|
||||
/* Resolve path in a non-bare repo */
|
||||
if (workdir != NULL)
|
||||
error = git_path_find_dir(&dir, path, workdir);
|
||||
else
|
||||
error = git_path_dirname_r(&dir, path);
|
||||
if (error < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* in precendence order highest to lowest:
|
||||
* - $GIT_DIR/info/attributes
|
||||
* - path components with .gitattributes
|
||||
* - config core.attributesfile
|
||||
* - $GIT_PREFIX/etc/gitattributes
|
||||
*/
|
||||
|
||||
error = push_attr_file(
|
||||
repo, files, git_repository_path(repo), GIT_ATTR_FILE_INREPO);
|
||||
if (error < 0)
|
||||
goto cleanup;
|
||||
|
||||
info.repo = repo;
|
||||
info.flags = flags;
|
||||
info.workdir = workdir;
|
||||
if (git_repository_index__weakptr(&info.index, repo) < 0)
|
||||
giterr_clear(); /* no error even if there is no index */
|
||||
info.files = files;
|
||||
|
||||
error = git_path_walk_up(&dir, workdir, push_one_attr, &info);
|
||||
if (error < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (git_repository_attr_cache(repo)->cfg_attr_file != NULL) {
|
||||
error = push_attr_file(
|
||||
repo, files, NULL, git_repository_attr_cache(repo)->cfg_attr_file);
|
||||
if (error < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if ((flags & GIT_ATTR_CHECK_NO_SYSTEM) == 0) {
|
||||
error = git_futils_find_system_file(&dir, GIT_ATTR_FILE_SYSTEM);
|
||||
if (!error)
|
||||
error = push_attr_file(repo, files, NULL, dir.ptr);
|
||||
else if (error == GIT_ENOTFOUND)
|
||||
error = 0;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (error < 0)
|
||||
git_vector_free(files);
|
||||
git_buf_free(&dir);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
int git_attr_cache__init(git_repository *repo)
|
||||
{
|
||||
int ret;
|
||||
git_attr_cache *cache = git_repository_attr_cache(repo);
|
||||
git_config *cfg;
|
||||
|
||||
if (cache->initialized)
|
||||
return 0;
|
||||
|
||||
/* cache config settings for attributes and ignores */
|
||||
if (git_repository_config__weakptr(&cfg, repo) < 0)
|
||||
return -1;
|
||||
|
||||
ret = git_config_get_string(&cache->cfg_attr_file, cfg, GIT_ATTR_CONFIG);
|
||||
if (ret < 0 && ret != GIT_ENOTFOUND)
|
||||
return ret;
|
||||
|
||||
ret = git_config_get_string(&cache->cfg_excl_file, cfg, GIT_IGNORE_CONFIG);
|
||||
if (ret < 0 && ret != GIT_ENOTFOUND)
|
||||
return ret;
|
||||
|
||||
giterr_clear();
|
||||
|
||||
/* allocate hashtable for attribute and ignore file contents */
|
||||
if (cache->files == NULL) {
|
||||
cache->files = git_strmap_alloc();
|
||||
GITERR_CHECK_ALLOC(cache->files);
|
||||
}
|
||||
|
||||
/* allocate hashtable for attribute macros */
|
||||
if (cache->macros == NULL) {
|
||||
cache->macros = git_strmap_alloc();
|
||||
GITERR_CHECK_ALLOC(cache->macros);
|
||||
}
|
||||
|
||||
/* allocate string pool */
|
||||
if (git_pool_init(&cache->pool, 1, 0) < 0)
|
||||
return -1;
|
||||
|
||||
cache->initialized = 1;
|
||||
|
||||
/* insert default macros */
|
||||
return git_attr_add_macro(repo, "binary", "-diff -crlf -text");
|
||||
}
|
||||
|
||||
void git_attr_cache_flush(
|
||||
git_repository *repo)
|
||||
{
|
||||
git_attr_cache *cache;
|
||||
|
||||
if (!repo)
|
||||
return;
|
||||
|
||||
cache = git_repository_attr_cache(repo);
|
||||
|
||||
if (cache->files != NULL) {
|
||||
git_attr_file *file;
|
||||
|
||||
git_strmap_foreach_value(cache->files, file, {
|
||||
git_attr_file__free(file);
|
||||
});
|
||||
|
||||
git_strmap_free(cache->files);
|
||||
}
|
||||
|
||||
if (cache->macros != NULL) {
|
||||
git_attr_rule *rule;
|
||||
|
||||
git_strmap_foreach_value(cache->macros, rule, {
|
||||
git_attr_rule__free(rule);
|
||||
});
|
||||
|
||||
git_strmap_free(cache->macros);
|
||||
}
|
||||
|
||||
git_pool_clear(&cache->pool);
|
||||
|
||||
cache->initialized = 0;
|
||||
}
|
||||
|
||||
int git_attr_cache__insert_macro(git_repository *repo, git_attr_rule *macro)
|
||||
{
|
||||
git_strmap *macros = git_repository_attr_cache(repo)->macros;
|
||||
int error;
|
||||
|
||||
/* TODO: generate warning log if (macro->assigns.length == 0) */
|
||||
if (macro->assigns.length == 0)
|
||||
return 0;
|
||||
|
||||
git_strmap_insert(macros, macro->match.pattern, macro, error);
|
||||
return (error < 0) ? -1 : 0;
|
||||
}
|
||||
|
||||
git_attr_rule *git_attr_cache__lookup_macro(
|
||||
git_repository *repo, const char *name)
|
||||
{
|
||||
git_strmap *macros = git_repository_attr_cache(repo)->macros;
|
||||
khiter_t pos;
|
||||
|
||||
pos = git_strmap_lookup_index(macros, name);
|
||||
|
||||
if (!git_strmap_valid_index(macros, pos))
|
||||
return NULL;
|
||||
|
||||
return (git_attr_rule *)git_strmap_value_at(macros, pos);
|
||||
}
|
||||
|
56
src/attr.h
Normal file
56
src/attr.h
Normal file
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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_attr_h__
|
||||
#define INCLUDE_attr_h__
|
||||
|
||||
#include "attr_file.h"
|
||||
#include "strmap.h"
|
||||
|
||||
#define GIT_ATTR_CONFIG "core.attributesfile"
|
||||
#define GIT_IGNORE_CONFIG "core.excludesfile"
|
||||
|
||||
typedef struct {
|
||||
int initialized;
|
||||
git_pool pool;
|
||||
git_strmap *files; /* hash path to git_attr_file of rules */
|
||||
git_strmap *macros; /* hash name to vector<git_attr_assignment> */
|
||||
const char *cfg_attr_file; /* cached value of core.attributesfile */
|
||||
const char *cfg_excl_file; /* cached value of core.excludesfile */
|
||||
} git_attr_cache;
|
||||
|
||||
typedef int (*git_attr_file_parser)(
|
||||
git_repository *, const char *, git_attr_file *);
|
||||
|
||||
extern int git_attr_cache__init(git_repository *repo);
|
||||
|
||||
extern int git_attr_cache__insert_macro(
|
||||
git_repository *repo, git_attr_rule *macro);
|
||||
|
||||
extern git_attr_rule *git_attr_cache__lookup_macro(
|
||||
git_repository *repo, const char *name);
|
||||
|
||||
extern int git_attr_cache__push_file(
|
||||
git_repository *repo,
|
||||
const char *base,
|
||||
const char *filename,
|
||||
git_attr_file_source source,
|
||||
git_attr_file_parser parse,
|
||||
git_vector *stack);
|
||||
|
||||
extern int git_attr_cache__internal_file(
|
||||
git_repository *repo,
|
||||
const char *key,
|
||||
git_attr_file **file_ptr);
|
||||
|
||||
/* returns true if path is in cache */
|
||||
extern bool git_attr_cache__is_cached(
|
||||
git_repository *repo, git_attr_file_source source, const char *path);
|
||||
|
||||
extern int git_attr_cache__decide_sources(
|
||||
uint32_t flags, bool has_wd, bool has_index, git_attr_file_source *srcs);
|
||||
|
||||
#endif
|
609
src/attr_file.c
Normal file
609
src/attr_file.c
Normal file
@ -0,0 +1,609 @@
|
||||
#include "common.h"
|
||||
#include "repository.h"
|
||||
#include "filebuf.h"
|
||||
#include "git2/blob.h"
|
||||
#include "git2/tree.h"
|
||||
#include <ctype.h>
|
||||
|
||||
const char *git_attr__true = "[internal]__TRUE__";
|
||||
const char *git_attr__false = "[internal]__FALSE__";
|
||||
const char *git_attr__unset = "[internal]__UNSET__";
|
||||
|
||||
static int sort_by_hash_and_name(const void *a_raw, const void *b_raw);
|
||||
static void git_attr_rule__clear(git_attr_rule *rule);
|
||||
|
||||
int git_attr_file__new(
|
||||
git_attr_file **attrs_ptr,
|
||||
git_attr_file_source from,
|
||||
const char *path,
|
||||
git_pool *pool)
|
||||
{
|
||||
git_attr_file *attrs = NULL;
|
||||
|
||||
attrs = git__calloc(1, sizeof(git_attr_file));
|
||||
GITERR_CHECK_ALLOC(attrs);
|
||||
|
||||
if (pool)
|
||||
attrs->pool = pool;
|
||||
else {
|
||||
attrs->pool = git__calloc(1, sizeof(git_pool));
|
||||
if (!attrs->pool || git_pool_init(attrs->pool, 1, 0) < 0)
|
||||
goto fail;
|
||||
attrs->pool_is_allocated = true;
|
||||
}
|
||||
|
||||
if (path) {
|
||||
size_t len = strlen(path);
|
||||
|
||||
attrs->key = git_pool_malloc(attrs->pool, (uint32_t)len + 3);
|
||||
GITERR_CHECK_ALLOC(attrs->key);
|
||||
|
||||
attrs->key[0] = '0' + from;
|
||||
attrs->key[1] = '#';
|
||||
memcpy(&attrs->key[2], path, len);
|
||||
attrs->key[len + 2] = '\0';
|
||||
}
|
||||
|
||||
if (git_vector_init(&attrs->rules, 4, NULL) < 0)
|
||||
goto fail;
|
||||
|
||||
*attrs_ptr = attrs;
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
git_attr_file__free(attrs);
|
||||
attrs_ptr = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int git_attr_file__parse_buffer(
|
||||
git_repository *repo, const char *buffer, git_attr_file *attrs)
|
||||
{
|
||||
int error = 0;
|
||||
const char *scan = NULL;
|
||||
char *context = NULL;
|
||||
git_attr_rule *rule = NULL;
|
||||
|
||||
assert(buffer && attrs);
|
||||
|
||||
scan = buffer;
|
||||
|
||||
/* if subdir file path, convert context for file paths */
|
||||
if (attrs->key && git__suffixcmp(attrs->key, "/" GIT_ATTR_FILE) == 0) {
|
||||
context = attrs->key + 2;
|
||||
context[strlen(context) - strlen(GIT_ATTR_FILE)] = '\0';
|
||||
}
|
||||
|
||||
while (!error && *scan) {
|
||||
/* allocate rule if needed */
|
||||
if (!rule && !(rule = git__calloc(1, sizeof(git_attr_rule)))) {
|
||||
error = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* parse the next "pattern attr attr attr" line */
|
||||
if (!(error = git_attr_fnmatch__parse(
|
||||
&rule->match, attrs->pool, context, &scan)) &&
|
||||
!(error = git_attr_assignment__parse(
|
||||
repo, attrs->pool, &rule->assigns, &scan)))
|
||||
{
|
||||
if (rule->match.flags & GIT_ATTR_FNMATCH_MACRO)
|
||||
/* should generate error/warning if this is coming from any
|
||||
* file other than .gitattributes at repo root.
|
||||
*/
|
||||
error = git_attr_cache__insert_macro(repo, rule);
|
||||
else
|
||||
error = git_vector_insert(&attrs->rules, rule);
|
||||
}
|
||||
|
||||
/* if the rule wasn't a pattern, on to the next */
|
||||
if (error < 0) {
|
||||
git_attr_rule__clear(rule); /* reset rule contents */
|
||||
if (error == GIT_ENOTFOUND)
|
||||
error = 0;
|
||||
} else {
|
||||
rule = NULL; /* vector now "owns" the rule */
|
||||
}
|
||||
}
|
||||
|
||||
git_attr_rule__free(rule);
|
||||
|
||||
/* restore file path used for context */
|
||||
if (context)
|
||||
context[strlen(context)] = '.'; /* first char of GIT_ATTR_FILE */
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_attr_file__new_and_load(
|
||||
git_attr_file **attrs_ptr,
|
||||
const char *path)
|
||||
{
|
||||
int error;
|
||||
git_buf content = GIT_BUF_INIT;
|
||||
|
||||
if ((error = git_attr_file__new(attrs_ptr, 0, path, NULL)) < 0)
|
||||
return error;
|
||||
|
||||
if (!(error = git_futils_readbuffer(&content, path)))
|
||||
error = git_attr_file__parse_buffer(
|
||||
NULL, git_buf_cstr(&content), *attrs_ptr);
|
||||
|
||||
git_buf_free(&content);
|
||||
|
||||
if (error) {
|
||||
git_attr_file__free(*attrs_ptr);
|
||||
*attrs_ptr = NULL;
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
void git_attr_file__clear_rules(git_attr_file *file)
|
||||
{
|
||||
unsigned int i;
|
||||
git_attr_rule *rule;
|
||||
|
||||
git_vector_foreach(&file->rules, i, rule)
|
||||
git_attr_rule__free(rule);
|
||||
|
||||
git_vector_free(&file->rules);
|
||||
}
|
||||
|
||||
void git_attr_file__free(git_attr_file *file)
|
||||
{
|
||||
if (!file)
|
||||
return;
|
||||
|
||||
git_attr_file__clear_rules(file);
|
||||
|
||||
if (file->pool_is_allocated) {
|
||||
git_pool_clear(file->pool);
|
||||
git__free(file->pool);
|
||||
}
|
||||
file->pool = NULL;
|
||||
|
||||
git__free(file);
|
||||
}
|
||||
|
||||
uint32_t git_attr_file__name_hash(const char *name)
|
||||
{
|
||||
uint32_t h = 5381;
|
||||
int c;
|
||||
assert(name);
|
||||
while ((c = (int)*name++) != 0)
|
||||
h = ((h << 5) + h) + c;
|
||||
return h;
|
||||
}
|
||||
|
||||
|
||||
int git_attr_file__lookup_one(
|
||||
git_attr_file *file,
|
||||
const git_attr_path *path,
|
||||
const char *attr,
|
||||
const char **value)
|
||||
{
|
||||
unsigned int i;
|
||||
git_attr_name name;
|
||||
git_attr_rule *rule;
|
||||
|
||||
*value = NULL;
|
||||
|
||||
name.name = attr;
|
||||
name.name_hash = git_attr_file__name_hash(attr);
|
||||
|
||||
git_attr_file__foreach_matching_rule(file, path, i, rule) {
|
||||
int pos = git_vector_bsearch(&rule->assigns, &name);
|
||||
|
||||
if (pos >= 0) {
|
||||
*value = ((git_attr_assignment *)
|
||||
git_vector_get(&rule->assigns, pos))->value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
bool git_attr_fnmatch__match(
|
||||
git_attr_fnmatch *match,
|
||||
const git_attr_path *path)
|
||||
{
|
||||
int fnm;
|
||||
|
||||
if (match->flags & GIT_ATTR_FNMATCH_DIRECTORY && !path->is_dir)
|
||||
return false;
|
||||
|
||||
if (match->flags & GIT_ATTR_FNMATCH_FULLPATH)
|
||||
fnm = p_fnmatch(match->pattern, path->path, FNM_PATHNAME);
|
||||
else if (path->is_dir)
|
||||
fnm = p_fnmatch(match->pattern, path->basename, FNM_LEADING_DIR);
|
||||
else
|
||||
fnm = p_fnmatch(match->pattern, path->basename, 0);
|
||||
|
||||
return (fnm == FNM_NOMATCH) ? false : true;
|
||||
}
|
||||
|
||||
bool git_attr_rule__match(
|
||||
git_attr_rule *rule,
|
||||
const git_attr_path *path)
|
||||
{
|
||||
bool matched = git_attr_fnmatch__match(&rule->match, path);
|
||||
|
||||
if (rule->match.flags & GIT_ATTR_FNMATCH_NEGATIVE)
|
||||
matched = !matched;
|
||||
|
||||
return matched;
|
||||
}
|
||||
|
||||
|
||||
git_attr_assignment *git_attr_rule__lookup_assignment(
|
||||
git_attr_rule *rule, const char *name)
|
||||
{
|
||||
int pos;
|
||||
git_attr_name key;
|
||||
key.name = name;
|
||||
key.name_hash = git_attr_file__name_hash(name);
|
||||
|
||||
pos = git_vector_bsearch(&rule->assigns, &key);
|
||||
|
||||
return (pos >= 0) ? git_vector_get(&rule->assigns, pos) : NULL;
|
||||
}
|
||||
|
||||
int git_attr_path__init(
|
||||
git_attr_path *info, const char *path, const char *base)
|
||||
{
|
||||
/* build full path as best we can */
|
||||
git_buf_init(&info->full, 0);
|
||||
|
||||
if (base != NULL && git_path_root(path) < 0) {
|
||||
if (git_buf_joinpath(&info->full, base, path) < 0)
|
||||
return -1;
|
||||
info->path = info->full.ptr + strlen(base);
|
||||
} else {
|
||||
if (git_buf_sets(&info->full, path) < 0)
|
||||
return -1;
|
||||
info->path = info->full.ptr;
|
||||
}
|
||||
|
||||
/* remove trailing slashes */
|
||||
while (info->full.size > 0) {
|
||||
if (info->full.ptr[info->full.size - 1] != '/')
|
||||
break;
|
||||
info->full.size--;
|
||||
}
|
||||
info->full.ptr[info->full.size] = '\0';
|
||||
|
||||
/* skip leading slashes in path */
|
||||
while (*info->path == '/')
|
||||
info->path++;
|
||||
|
||||
/* find trailing basename component */
|
||||
info->basename = strrchr(info->path, '/');
|
||||
if (info->basename)
|
||||
info->basename++;
|
||||
if (!info->basename || !*info->basename)
|
||||
info->basename = info->path;
|
||||
|
||||
info->is_dir = (int)git_path_isdir(info->full.ptr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void git_attr_path__free(git_attr_path *info)
|
||||
{
|
||||
git_buf_free(&info->full);
|
||||
info->path = NULL;
|
||||
info->basename = NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* From gitattributes(5):
|
||||
*
|
||||
* Patterns have the following format:
|
||||
*
|
||||
* - A blank line matches no files, so it can serve as a separator for
|
||||
* readability.
|
||||
*
|
||||
* - A line starting with # serves as a comment.
|
||||
*
|
||||
* - An optional prefix ! which negates the pattern; any matching file
|
||||
* excluded by a previous pattern will become included again. If a negated
|
||||
* pattern matches, this will override lower precedence patterns sources.
|
||||
*
|
||||
* - If the pattern ends with a slash, it is removed for the purpose of the
|
||||
* following description, but it would only find a match with a directory. In
|
||||
* other words, foo/ will match a directory foo and paths underneath it, but
|
||||
* will not match a regular file or a symbolic link foo (this is consistent
|
||||
* with the way how pathspec works in general in git).
|
||||
*
|
||||
* - If the pattern does not contain a slash /, git treats it as a shell glob
|
||||
* pattern and checks for a match against the pathname without leading
|
||||
* directories.
|
||||
*
|
||||
* - Otherwise, git treats the pattern as a shell glob suitable for consumption
|
||||
* by fnmatch(3) with the FNM_PATHNAME flag: wildcards in the pattern will
|
||||
* not match a / in the pathname. For example, "Documentation/\*.html" matches
|
||||
* "Documentation/git.html" but not "Documentation/ppc/ppc.html". A leading
|
||||
* slash matches the beginning of the pathname; for example, "/\*.c" matches
|
||||
* "cat-file.c" but not "mozilla-sha1/sha1.c".
|
||||
*/
|
||||
|
||||
/*
|
||||
* This will return 0 if the spec was filled out,
|
||||
* GIT_ENOTFOUND if the fnmatch does not require matching, or
|
||||
* another error code there was an actual problem.
|
||||
*/
|
||||
int git_attr_fnmatch__parse(
|
||||
git_attr_fnmatch *spec,
|
||||
git_pool *pool,
|
||||
const char *source,
|
||||
const char **base)
|
||||
{
|
||||
const char *pattern, *scan;
|
||||
int slash_count, allow_space;
|
||||
|
||||
assert(spec && base && *base);
|
||||
|
||||
spec->flags = (spec->flags & GIT_ATTR_FNMATCH_ALLOWSPACE);
|
||||
allow_space = (spec->flags != 0);
|
||||
|
||||
pattern = *base;
|
||||
|
||||
while (git__isspace(*pattern)) pattern++;
|
||||
if (!*pattern || *pattern == '#') {
|
||||
*base = git__next_line(pattern);
|
||||
return GIT_ENOTFOUND;
|
||||
}
|
||||
|
||||
if (*pattern == '[') {
|
||||
if (strncmp(pattern, "[attr]", 6) == 0) {
|
||||
spec->flags = spec->flags | GIT_ATTR_FNMATCH_MACRO;
|
||||
pattern += 6;
|
||||
}
|
||||
/* else a character range like [a-e]* which is accepted */
|
||||
}
|
||||
|
||||
if (*pattern == '!') {
|
||||
spec->flags = spec->flags | GIT_ATTR_FNMATCH_NEGATIVE;
|
||||
pattern++;
|
||||
}
|
||||
|
||||
slash_count = 0;
|
||||
for (scan = pattern; *scan != '\0'; ++scan) {
|
||||
/* scan until (non-escaped) white space */
|
||||
if (git__isspace(*scan) && *(scan - 1) != '\\') {
|
||||
if (!allow_space || (*scan != ' ' && *scan != '\t'))
|
||||
break;
|
||||
}
|
||||
|
||||
if (*scan == '/') {
|
||||
spec->flags = spec->flags | GIT_ATTR_FNMATCH_FULLPATH;
|
||||
slash_count++;
|
||||
if (pattern == scan)
|
||||
pattern++;
|
||||
}
|
||||
/* remember if we see an unescaped wildcard in pattern */
|
||||
else if (git__iswildcard(*scan) &&
|
||||
(scan == pattern || (*(scan - 1) != '\\')))
|
||||
spec->flags = spec->flags | GIT_ATTR_FNMATCH_HASWILD;
|
||||
}
|
||||
|
||||
*base = scan;
|
||||
|
||||
spec->length = scan - pattern;
|
||||
|
||||
if (pattern[spec->length - 1] == '/') {
|
||||
spec->length--;
|
||||
spec->flags = spec->flags | GIT_ATTR_FNMATCH_DIRECTORY;
|
||||
if (--slash_count <= 0)
|
||||
spec->flags = spec->flags & ~GIT_ATTR_FNMATCH_FULLPATH;
|
||||
}
|
||||
|
||||
if ((spec->flags & GIT_ATTR_FNMATCH_FULLPATH) != 0 &&
|
||||
source != NULL && git_path_root(pattern) < 0)
|
||||
{
|
||||
size_t sourcelen = strlen(source);
|
||||
/* given an unrooted fullpath match from a file inside a repo,
|
||||
* prefix the pattern with the relative directory of the source file
|
||||
*/
|
||||
spec->pattern = git_pool_malloc(
|
||||
pool, (uint32_t)(sourcelen + spec->length + 1));
|
||||
if (spec->pattern) {
|
||||
memcpy(spec->pattern, source, sourcelen);
|
||||
memcpy(spec->pattern + sourcelen, pattern, spec->length);
|
||||
spec->length += sourcelen;
|
||||
spec->pattern[spec->length] = '\0';
|
||||
}
|
||||
} else {
|
||||
spec->pattern = git_pool_strndup(pool, pattern, spec->length);
|
||||
}
|
||||
|
||||
if (!spec->pattern) {
|
||||
*base = git__next_line(pattern);
|
||||
return -1;
|
||||
} else {
|
||||
/* strip '\' that might have be used for internal whitespace */
|
||||
char *to = spec->pattern;
|
||||
for (scan = spec->pattern; *scan; to++, scan++) {
|
||||
if (*scan == '\\')
|
||||
scan++; /* skip '\' but include next char */
|
||||
if (to != scan)
|
||||
*to = *scan;
|
||||
}
|
||||
if (to != scan) {
|
||||
*to = '\0';
|
||||
spec->length = (to - spec->pattern);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sort_by_hash_and_name(const void *a_raw, const void *b_raw)
|
||||
{
|
||||
const git_attr_name *a = a_raw;
|
||||
const git_attr_name *b = b_raw;
|
||||
|
||||
if (b->name_hash < a->name_hash)
|
||||
return 1;
|
||||
else if (b->name_hash > a->name_hash)
|
||||
return -1;
|
||||
else
|
||||
return strcmp(b->name, a->name);
|
||||
}
|
||||
|
||||
static void git_attr_assignment__free(git_attr_assignment *assign)
|
||||
{
|
||||
/* name and value are stored in a git_pool associated with the
|
||||
* git_attr_file, so they do not need to be freed here
|
||||
*/
|
||||
assign->name = NULL;
|
||||
assign->value = NULL;
|
||||
git__free(assign);
|
||||
}
|
||||
|
||||
static int merge_assignments(void **old_raw, void *new_raw)
|
||||
{
|
||||
git_attr_assignment **old = (git_attr_assignment **)old_raw;
|
||||
git_attr_assignment *new = (git_attr_assignment *)new_raw;
|
||||
|
||||
GIT_REFCOUNT_DEC(*old, git_attr_assignment__free);
|
||||
*old = new;
|
||||
return GIT_EEXISTS;
|
||||
}
|
||||
|
||||
int git_attr_assignment__parse(
|
||||
git_repository *repo,
|
||||
git_pool *pool,
|
||||
git_vector *assigns,
|
||||
const char **base)
|
||||
{
|
||||
int error;
|
||||
const char *scan = *base;
|
||||
git_attr_assignment *assign = NULL;
|
||||
|
||||
assert(assigns && !assigns->length);
|
||||
|
||||
assigns->_cmp = sort_by_hash_and_name;
|
||||
|
||||
while (*scan && *scan != '\n') {
|
||||
const char *name_start, *value_start;
|
||||
|
||||
/* skip leading blanks */
|
||||
while (git__isspace(*scan) && *scan != '\n') scan++;
|
||||
|
||||
/* allocate assign if needed */
|
||||
if (!assign) {
|
||||
assign = git__calloc(1, sizeof(git_attr_assignment));
|
||||
GITERR_CHECK_ALLOC(assign);
|
||||
GIT_REFCOUNT_INC(assign);
|
||||
}
|
||||
|
||||
assign->name_hash = 5381;
|
||||
assign->value = git_attr__true;
|
||||
|
||||
/* look for magic name prefixes */
|
||||
if (*scan == '-') {
|
||||
assign->value = git_attr__false;
|
||||
scan++;
|
||||
} else if (*scan == '!') {
|
||||
assign->value = git_attr__unset; /* explicit unspecified state */
|
||||
scan++;
|
||||
} else if (*scan == '#') /* comment rest of line */
|
||||
break;
|
||||
|
||||
/* find the name */
|
||||
name_start = scan;
|
||||
while (*scan && !git__isspace(*scan) && *scan != '=') {
|
||||
assign->name_hash =
|
||||
((assign->name_hash << 5) + assign->name_hash) + *scan;
|
||||
scan++;
|
||||
}
|
||||
if (scan == name_start) {
|
||||
/* must have found lone prefix (" - ") or leading = ("=foo")
|
||||
* or end of buffer -- advance until whitespace and continue
|
||||
*/
|
||||
while (*scan && !git__isspace(*scan)) scan++;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* allocate permanent storage for name */
|
||||
assign->name = git_pool_strndup(pool, name_start, scan - name_start);
|
||||
GITERR_CHECK_ALLOC(assign->name);
|
||||
|
||||
/* if there is an equals sign, find the value */
|
||||
if (*scan == '=') {
|
||||
for (value_start = ++scan; *scan && !git__isspace(*scan); ++scan);
|
||||
|
||||
/* if we found a value, allocate permanent storage for it */
|
||||
if (scan > value_start) {
|
||||
assign->value = git_pool_strndup(pool, value_start, scan - value_start);
|
||||
GITERR_CHECK_ALLOC(assign->value);
|
||||
}
|
||||
}
|
||||
|
||||
/* expand macros (if given a repo with a macro cache) */
|
||||
if (repo != NULL && assign->value == git_attr__true) {
|
||||
git_attr_rule *macro =
|
||||
git_attr_cache__lookup_macro(repo, assign->name);
|
||||
|
||||
if (macro != NULL) {
|
||||
unsigned int i;
|
||||
git_attr_assignment *massign;
|
||||
|
||||
git_vector_foreach(¯o->assigns, i, massign) {
|
||||
GIT_REFCOUNT_INC(massign);
|
||||
|
||||
error = git_vector_insert_sorted(
|
||||
assigns, massign, &merge_assignments);
|
||||
if (error < 0 && error != GIT_EEXISTS)
|
||||
return error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* insert allocated assign into vector */
|
||||
error = git_vector_insert_sorted(assigns, assign, &merge_assignments);
|
||||
if (error < 0 && error != GIT_EEXISTS)
|
||||
return error;
|
||||
|
||||
/* clear assign since it is now "owned" by the vector */
|
||||
assign = NULL;
|
||||
}
|
||||
|
||||
if (assign != NULL)
|
||||
git_attr_assignment__free(assign);
|
||||
|
||||
*base = git__next_line(scan);
|
||||
|
||||
return (assigns->length == 0) ? GIT_ENOTFOUND : 0;
|
||||
}
|
||||
|
||||
static void git_attr_rule__clear(git_attr_rule *rule)
|
||||
{
|
||||
unsigned int i;
|
||||
git_attr_assignment *assign;
|
||||
|
||||
if (!rule)
|
||||
return;
|
||||
|
||||
if (!(rule->match.flags & GIT_ATTR_FNMATCH_IGNORE)) {
|
||||
git_vector_foreach(&rule->assigns, i, assign)
|
||||
GIT_REFCOUNT_DEC(assign, git_attr_assignment__free);
|
||||
git_vector_free(&rule->assigns);
|
||||
}
|
||||
|
||||
/* match.pattern is stored in a git_pool, so no need to free */
|
||||
rule->match.pattern = NULL;
|
||||
rule->match.length = 0;
|
||||
}
|
||||
|
||||
void git_attr_rule__free(git_attr_rule *rule)
|
||||
{
|
||||
git_attr_rule__clear(rule);
|
||||
git__free(rule);
|
||||
}
|
||||
|
145
src/attr_file.h
Normal file
145
src/attr_file.h
Normal file
@ -0,0 +1,145 @@
|
||||
/*
|
||||
* 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_attr_file_h__
|
||||
#define INCLUDE_attr_file_h__
|
||||
|
||||
#include "git2/attr.h"
|
||||
#include "vector.h"
|
||||
#include "pool.h"
|
||||
#include "buffer.h"
|
||||
|
||||
#define GIT_ATTR_FILE ".gitattributes"
|
||||
#define GIT_ATTR_FILE_INREPO "info/attributes"
|
||||
#define GIT_ATTR_FILE_SYSTEM "gitattributes"
|
||||
|
||||
#define GIT_ATTR_FNMATCH_NEGATIVE (1U << 0)
|
||||
#define GIT_ATTR_FNMATCH_DIRECTORY (1U << 1)
|
||||
#define GIT_ATTR_FNMATCH_FULLPATH (1U << 2)
|
||||
#define GIT_ATTR_FNMATCH_MACRO (1U << 3)
|
||||
#define GIT_ATTR_FNMATCH_IGNORE (1U << 4)
|
||||
#define GIT_ATTR_FNMATCH_HASWILD (1U << 5)
|
||||
#define GIT_ATTR_FNMATCH_ALLOWSPACE (1U << 6)
|
||||
|
||||
typedef struct {
|
||||
char *pattern;
|
||||
size_t length;
|
||||
unsigned int flags;
|
||||
} git_attr_fnmatch;
|
||||
|
||||
typedef struct {
|
||||
git_attr_fnmatch match;
|
||||
git_vector assigns; /* vector of <git_attr_assignment*> */
|
||||
} git_attr_rule;
|
||||
|
||||
typedef struct {
|
||||
git_refcount unused;
|
||||
const char *name;
|
||||
uint32_t name_hash;
|
||||
} git_attr_name;
|
||||
|
||||
typedef struct {
|
||||
git_refcount rc; /* for macros */
|
||||
char *name;
|
||||
uint32_t name_hash;
|
||||
const char *value;
|
||||
} git_attr_assignment;
|
||||
|
||||
typedef struct {
|
||||
git_time_t seconds;
|
||||
git_off_t size;
|
||||
unsigned int ino;
|
||||
} git_attr_file_stat_sig;
|
||||
|
||||
typedef struct {
|
||||
char *key; /* cache "source#path" this was loaded from */
|
||||
git_vector rules; /* vector of <rule*> or <fnmatch*> */
|
||||
git_pool *pool;
|
||||
bool pool_is_allocated;
|
||||
union {
|
||||
git_oid oid;
|
||||
git_attr_file_stat_sig st;
|
||||
} cache_data;
|
||||
} git_attr_file;
|
||||
|
||||
typedef struct {
|
||||
git_buf full;
|
||||
const char *path;
|
||||
const char *basename;
|
||||
int is_dir;
|
||||
} git_attr_path;
|
||||
|
||||
typedef enum {
|
||||
GIT_ATTR_FILE_FROM_FILE = 0,
|
||||
GIT_ATTR_FILE_FROM_INDEX = 1
|
||||
} git_attr_file_source;
|
||||
|
||||
/*
|
||||
* git_attr_file API
|
||||
*/
|
||||
|
||||
extern int git_attr_file__new(
|
||||
git_attr_file **attrs_ptr, git_attr_file_source src, const char *path, git_pool *pool);
|
||||
|
||||
extern int git_attr_file__new_and_load(
|
||||
git_attr_file **attrs_ptr, const char *path);
|
||||
|
||||
extern void git_attr_file__free(git_attr_file *file);
|
||||
|
||||
extern void git_attr_file__clear_rules(git_attr_file *file);
|
||||
|
||||
extern int git_attr_file__parse_buffer(
|
||||
git_repository *repo, const char *buf, git_attr_file *file);
|
||||
|
||||
extern int git_attr_file__lookup_one(
|
||||
git_attr_file *file,
|
||||
const git_attr_path *path,
|
||||
const char *attr,
|
||||
const char **value);
|
||||
|
||||
/* loop over rules in file from bottom to top */
|
||||
#define git_attr_file__foreach_matching_rule(file, path, iter, rule) \
|
||||
git_vector_rforeach(&(file)->rules, (iter), (rule)) \
|
||||
if (git_attr_rule__match((rule), (path)))
|
||||
|
||||
extern uint32_t git_attr_file__name_hash(const char *name);
|
||||
|
||||
|
||||
/*
|
||||
* other utilities
|
||||
*/
|
||||
|
||||
extern int git_attr_fnmatch__parse(
|
||||
git_attr_fnmatch *spec,
|
||||
git_pool *pool,
|
||||
const char *source,
|
||||
const char **base);
|
||||
|
||||
extern bool git_attr_fnmatch__match(
|
||||
git_attr_fnmatch *rule,
|
||||
const git_attr_path *path);
|
||||
|
||||
extern void git_attr_rule__free(git_attr_rule *rule);
|
||||
|
||||
extern bool git_attr_rule__match(
|
||||
git_attr_rule *rule,
|
||||
const git_attr_path *path);
|
||||
|
||||
extern git_attr_assignment *git_attr_rule__lookup_assignment(
|
||||
git_attr_rule *rule, const char *name);
|
||||
|
||||
extern int git_attr_path__init(
|
||||
git_attr_path *info, const char *path, const char *base);
|
||||
|
||||
extern void git_attr_path__free(git_attr_path *info);
|
||||
|
||||
extern int git_attr_assignment__parse(
|
||||
git_repository *repo, /* needed to expand macros */
|
||||
git_pool *pool,
|
||||
git_vector *assigns,
|
||||
const char **scan);
|
||||
|
||||
#endif
|
@ -1,217 +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.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "git2/object.h"
|
||||
#include "hash.h"
|
||||
#include "odb.h"
|
||||
|
||||
#include "git2/odb_backend.h"
|
||||
|
||||
#ifdef GIT2_HIREDIS_BACKEND
|
||||
|
||||
#include <hiredis/hiredis.h>
|
||||
|
||||
typedef struct {
|
||||
git_odb_backend parent;
|
||||
|
||||
redisContext *db;
|
||||
} hiredis_backend;
|
||||
|
||||
int hiredis_backend__read_header(size_t *len_p, git_otype *type_p, git_odb_backend *_backend, const git_oid *oid) {
|
||||
hiredis_backend *backend;
|
||||
int error;
|
||||
redisReply *reply;
|
||||
|
||||
assert(len_p && type_p && _backend && oid);
|
||||
|
||||
backend = (hiredis_backend *) _backend;
|
||||
error = GIT_ERROR;
|
||||
|
||||
reply = redisCommand(backend->db, "HMGET %b %s %s", oid->id, GIT_OID_RAWSZ,
|
||||
"type", "size");
|
||||
|
||||
if (reply && reply->type == REDIS_REPLY_ARRAY) {
|
||||
if (reply->element[0]->type != REDIS_REPLY_NIL &&
|
||||
reply->element[0]->type != REDIS_REPLY_NIL) {
|
||||
*type_p = (git_otype) atoi(reply->element[0]->str);
|
||||
*len_p = (size_t) atoi(reply->element[1]->str);
|
||||
error = GIT_SUCCESS;
|
||||
} else {
|
||||
error = GIT_ENOTFOUND;
|
||||
}
|
||||
} else {
|
||||
error = GIT_ERROR;
|
||||
}
|
||||
|
||||
freeReplyObject(reply);
|
||||
return error == GIT_SUCCESS ? GIT_SUCCESS : git__rethrow(error, "Failed to read header");
|
||||
}
|
||||
|
||||
int hiredis_backend__read(void **data_p, size_t *len_p, git_otype *type_p, git_odb_backend *_backend, const git_oid *oid) {
|
||||
hiredis_backend *backend;
|
||||
int error;
|
||||
redisReply *reply;
|
||||
|
||||
assert(data_p && len_p && type_p && _backend && oid);
|
||||
|
||||
backend = (hiredis_backend *) _backend;
|
||||
error = GIT_ERROR;
|
||||
|
||||
reply = redisCommand(backend->db, "HMGET %b %s %s %s", oid->id, GIT_OID_RAWSZ,
|
||||
"type", "size", "data");
|
||||
|
||||
if (reply && reply->type == REDIS_REPLY_ARRAY) {
|
||||
if (reply->element[0]->type != REDIS_REPLY_NIL &&
|
||||
reply->element[1]->type != REDIS_REPLY_NIL &&
|
||||
reply->element[2]->type != REDIS_REPLY_NIL) {
|
||||
*type_p = (git_otype) atoi(reply->element[0]->str);
|
||||
*len_p = (size_t) atoi(reply->element[1]->str);
|
||||
*data_p = git__malloc(*len_p);
|
||||
if (*data_p == NULL) {
|
||||
error = GIT_ENOMEM;
|
||||
} else {
|
||||
memcpy(*data_p, reply->element[2]->str, *len_p);
|
||||
error = GIT_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
error = GIT_ENOTFOUND;
|
||||
}
|
||||
} else {
|
||||
error = GIT_ERROR;
|
||||
}
|
||||
|
||||
freeReplyObject(reply);
|
||||
return error == GIT_SUCCESS ? GIT_SUCCESS : git__rethrow(error, "Failed to read backend");
|
||||
}
|
||||
|
||||
int hiredis_backend__read_prefix(git_oid *out_oid, void **data_p, size_t *len_p, git_otype *type_p, git_odb_backend *_backend,
|
||||
const git_oid *short_oid, unsigned int len) {
|
||||
if (len >= GIT_OID_HEXSZ) {
|
||||
/* Just match the full identifier */
|
||||
int error = hiredis_backend__read(data_p, len_p, type_p, backend, short_oid);
|
||||
if (error == GIT_SUCCESS)
|
||||
git_oid_cpy(out_oid, short_oid);
|
||||
|
||||
return error;
|
||||
} else if (len < GIT_OID_HEXSZ) {
|
||||
/* TODO */
|
||||
return git__throw(GIT_ENOTIMPLEMENTED, "Hiredis backend cannot search objects from short oid");
|
||||
}
|
||||
}
|
||||
|
||||
int hiredis_backend__exists(git_odb_backend *_backend, const git_oid *oid) {
|
||||
hiredis_backend *backend;
|
||||
int found;
|
||||
redisReply *reply;
|
||||
|
||||
assert(_backend && oid);
|
||||
|
||||
backend = (hiredis_backend *) _backend;
|
||||
found = 0;
|
||||
|
||||
reply = redisCommand(backend->db, "exists %b", oid->id, GIT_OID_RAWSZ);
|
||||
if (reply && reply->type != REDIS_REPLY_NIL && reply->type != REDIS_REPLY_ERROR)
|
||||
found = 1;
|
||||
|
||||
|
||||
freeReplyObject(reply);
|
||||
return found;
|
||||
}
|
||||
|
||||
int hiredis_backend__write(git_oid *id, git_odb_backend *_backend, const void *data, size_t len, git_otype type) {
|
||||
hiredis_backend *backend;
|
||||
int error;
|
||||
redisReply *reply;
|
||||
|
||||
assert(id && _backend && data);
|
||||
|
||||
backend = (hiredis_backend *) _backend;
|
||||
error = GIT_ERROR;
|
||||
|
||||
if ((error = git_odb_hash(id, data, len, type)) < 0)
|
||||
return git__rethrow(error, "Failed to write backend");
|
||||
|
||||
reply = redisCommand(backend->db, "HMSET %b "
|
||||
"type %d "
|
||||
"size %d "
|
||||
"data %b ", id->id, GIT_OID_RAWSZ,
|
||||
(int) type, len, data, len);
|
||||
|
||||
error = (reply == NULL || reply->type == REDIS_REPLY_ERROR) ? GIT_ERROR : GIT_SUCCESS;
|
||||
|
||||
freeReplyObject(reply);
|
||||
return error == GIT_SUCCESS ? GIT_SUCCESS : git__rethrow(error, "Failed to write backend");
|
||||
}
|
||||
|
||||
void hiredis_backend__free(git_odb_backend *_backend) {
|
||||
hiredis_backend *backend;
|
||||
assert(_backend);
|
||||
backend = (hiredis_backend *) _backend;
|
||||
|
||||
redisFree(backend->db);
|
||||
|
||||
free(backend);
|
||||
}
|
||||
|
||||
int git_odb_backend_hiredis(git_odb_backend **backend_out, const char *host, int port) {
|
||||
hiredis_backend *backend;
|
||||
|
||||
backend = git__calloc(1, sizeof (hiredis_backend));
|
||||
if (backend == NULL)
|
||||
return GIT_ENOMEM;
|
||||
|
||||
|
||||
backend->db = redisConnect(host, port);
|
||||
if (backend->db->err)
|
||||
goto cleanup;
|
||||
|
||||
backend->parent.read = &hiredis_backend__read;
|
||||
backend->parent.read_prefix = &hiredis_backend__read_prefix;
|
||||
backend->parent.read_header = &hiredis_backend__read_header;
|
||||
backend->parent.write = &hiredis_backend__write;
|
||||
backend->parent.exists = &hiredis_backend__exists;
|
||||
backend->parent.free = &hiredis_backend__free;
|
||||
|
||||
*backend_out = (git_odb_backend *) backend;
|
||||
|
||||
return GIT_SUCCESS;
|
||||
cleanup:
|
||||
free(backend);
|
||||
return git__throw(GIT_ERROR, "Failed to get ODB backend");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int git_odb_backend_hiredis(git_odb_backend ** GIT_UNUSED(backend_out),
|
||||
const char *GIT_UNUSED(host), int GIT_UNUSED(port)) {
|
||||
GIT_UNUSED_ARG(backend_out);
|
||||
GIT_UNUSED_ARG(host);
|
||||
GIT_UNUSED_ARG(port);
|
||||
return git__throw(GIT_ENOTIMPLEMENTED, "Failed to get ODB backend. Feature not yet implemented");
|
||||
}
|
||||
|
||||
|
||||
#endif /* HAVE_HIREDIS */
|
@ -1,296 +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.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "git2/object.h"
|
||||
#include "hash.h"
|
||||
#include "odb.h"
|
||||
|
||||
#include "git2/odb_backend.h"
|
||||
|
||||
#ifdef GIT2_SQLITE_BACKEND
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
#define GIT2_TABLE_NAME "git2_odb"
|
||||
|
||||
typedef struct {
|
||||
git_odb_backend parent;
|
||||
sqlite3 *db;
|
||||
sqlite3_stmt *st_read;
|
||||
sqlite3_stmt *st_write;
|
||||
sqlite3_stmt *st_read_header;
|
||||
} sqlite_backend;
|
||||
|
||||
int sqlite_backend__read_header(size_t *len_p, git_otype *type_p, git_odb_backend *_backend, const git_oid *oid)
|
||||
{
|
||||
sqlite_backend *backend;
|
||||
int error;
|
||||
|
||||
assert(len_p && type_p && _backend && oid);
|
||||
|
||||
backend = (sqlite_backend *)_backend;
|
||||
error = GIT_ERROR;
|
||||
|
||||
if (sqlite3_bind_text(backend->st_read_header, 1, (char *)oid->id, 20, SQLITE_TRANSIENT) == SQLITE_OK) {
|
||||
if (sqlite3_step(backend->st_read_header) == SQLITE_ROW) {
|
||||
*type_p = (git_otype)sqlite3_column_int(backend->st_read_header, 0);
|
||||
*len_p = (size_t)sqlite3_column_int(backend->st_read_header, 1);
|
||||
assert(sqlite3_step(backend->st_read_header) == SQLITE_DONE);
|
||||
error = GIT_SUCCESS;
|
||||
} else {
|
||||
error = GIT_ENOTFOUND;
|
||||
}
|
||||
}
|
||||
|
||||
sqlite3_reset(backend->st_read_header);
|
||||
return error == GIT_SUCCESS ? GIT_SUCCESS : git__rethrow(error, "SQLite backend: Failed to read header");
|
||||
}
|
||||
|
||||
|
||||
int sqlite_backend__read(void **data_p, size_t *len_p, git_otype *type_p, git_odb_backend *_backend, const git_oid *oid)
|
||||
{
|
||||
sqlite_backend *backend;
|
||||
int error;
|
||||
|
||||
assert(data_p && len_p && type_p && _backend && oid);
|
||||
|
||||
backend = (sqlite_backend *)_backend;
|
||||
error = GIT_ERROR;
|
||||
|
||||
if (sqlite3_bind_text(backend->st_read, 1, (char *)oid->id, 20, SQLITE_TRANSIENT) == SQLITE_OK) {
|
||||
if (sqlite3_step(backend->st_read) == SQLITE_ROW) {
|
||||
*type_p = (git_otype)sqlite3_column_int(backend->st_read, 0);
|
||||
*len_p = (size_t)sqlite3_column_int(backend->st_read, 1);
|
||||
*data_p = git__malloc(*len_p);
|
||||
|
||||
if (*data_p == NULL) {
|
||||
error = GIT_ENOMEM;
|
||||
} else {
|
||||
memcpy(*data_p, sqlite3_column_blob(backend->st_read, 2), *len_p);
|
||||
error = GIT_SUCCESS;
|
||||
}
|
||||
|
||||
assert(sqlite3_step(backend->st_read) == SQLITE_DONE);
|
||||
} else {
|
||||
error = GIT_ENOTFOUND;
|
||||
}
|
||||
}
|
||||
|
||||
sqlite3_reset(backend->st_read);
|
||||
return error == GIT_SUCCESS ? GIT_SUCCESS : git__rethrow(error, "SQLite backend: Failed to read");
|
||||
}
|
||||
|
||||
int sqlite_backend__read_prefix(git_oid *out_oid, void **data_p, size_t *len_p, git_otype *type_p, git_odb_backend *_backend,
|
||||
const git_oid *short_oid, unsigned int len) {
|
||||
if (len >= GIT_OID_HEXSZ) {
|
||||
/* Just match the full identifier */
|
||||
int error = sqlite_backend__read(data_p, len_p, type_p, _backend, short_oid);
|
||||
if (error == GIT_SUCCESS)
|
||||
git_oid_cpy(out_oid, short_oid);
|
||||
|
||||
return error;
|
||||
} else if (len < GIT_OID_HEXSZ) {
|
||||
/* TODO */
|
||||
return git__throw(GIT_ENOTIMPLEMENTED, "Sqlite backend cannot search objects from short oid");
|
||||
}
|
||||
}
|
||||
|
||||
int sqlite_backend__exists(git_odb_backend *_backend, const git_oid *oid)
|
||||
{
|
||||
sqlite_backend *backend;
|
||||
int found;
|
||||
|
||||
assert(_backend && oid);
|
||||
|
||||
backend = (sqlite_backend *)_backend;
|
||||
found = 0;
|
||||
|
||||
if (sqlite3_bind_text(backend->st_read_header, 1, (char *)oid->id, 20, SQLITE_TRANSIENT) == SQLITE_OK) {
|
||||
if (sqlite3_step(backend->st_read_header) == SQLITE_ROW) {
|
||||
found = 1;
|
||||
assert(sqlite3_step(backend->st_read_header) == SQLITE_DONE);
|
||||
}
|
||||
}
|
||||
|
||||
sqlite3_reset(backend->st_read_header);
|
||||
return found;
|
||||
}
|
||||
|
||||
|
||||
int sqlite_backend__write(git_oid *id, git_odb_backend *_backend, const void *data, size_t len, git_otype type)
|
||||
{
|
||||
int error;
|
||||
sqlite_backend *backend;
|
||||
|
||||
assert(id && _backend && data);
|
||||
|
||||
backend = (sqlite_backend *)_backend;
|
||||
|
||||
if ((error = git_odb_hash(id, data, len, type)) < 0)
|
||||
return git__rethrow(error, "SQLite backend: Failed to write");
|
||||
|
||||
error = SQLITE_ERROR;
|
||||
|
||||
if (sqlite3_bind_text(backend->st_write, 1, (char *)id->id, 20, SQLITE_TRANSIENT) == SQLITE_OK &&
|
||||
sqlite3_bind_int(backend->st_write, 2, (int)type) == SQLITE_OK &&
|
||||
sqlite3_bind_int(backend->st_write, 3, len) == SQLITE_OK &&
|
||||
sqlite3_bind_blob(backend->st_write, 4, data, len, SQLITE_TRANSIENT) == SQLITE_OK) {
|
||||
error = sqlite3_step(backend->st_write);
|
||||
}
|
||||
|
||||
sqlite3_reset(backend->st_write);
|
||||
return (error == SQLITE_DONE) ? GIT_SUCCESS : git__throw(GIT_ERROR, "SQLite backend: Failed to write");
|
||||
}
|
||||
|
||||
|
||||
void sqlite_backend__free(git_odb_backend *_backend)
|
||||
{
|
||||
sqlite_backend *backend;
|
||||
assert(_backend);
|
||||
backend = (sqlite_backend *)_backend;
|
||||
|
||||
sqlite3_finalize(backend->st_read);
|
||||
sqlite3_finalize(backend->st_read_header);
|
||||
sqlite3_finalize(backend->st_write);
|
||||
sqlite3_close(backend->db);
|
||||
|
||||
free(backend);
|
||||
}
|
||||
|
||||
static int create_table(sqlite3 *db)
|
||||
{
|
||||
static const char *sql_creat =
|
||||
"CREATE TABLE '" GIT2_TABLE_NAME "' ("
|
||||
"'oid' CHARACTER(20) PRIMARY KEY NOT NULL,"
|
||||
"'type' INTEGER NOT NULL,"
|
||||
"'size' INTEGER NOT NULL,"
|
||||
"'data' BLOB);";
|
||||
|
||||
if (sqlite3_exec(db, sql_creat, NULL, NULL, NULL) != SQLITE_OK)
|
||||
return git__throw(GIT_ERROR, "SQLite backend: Failed to create table");
|
||||
|
||||
return GIT_SUCCESS;
|
||||
}
|
||||
|
||||
static int init_db(sqlite3 *db)
|
||||
{
|
||||
static const char *sql_check =
|
||||
"SELECT name FROM sqlite_master WHERE type='table' AND name='" GIT2_TABLE_NAME "';";
|
||||
|
||||
sqlite3_stmt *st_check;
|
||||
int error;
|
||||
|
||||
if (sqlite3_prepare_v2(db, sql_check, -1, &st_check, NULL) != SQLITE_OK)
|
||||
return git__throw(GIT_ERROR, "SQLite backend: Failed to initialize database");
|
||||
|
||||
switch (sqlite3_step(st_check)) {
|
||||
case SQLITE_DONE:
|
||||
/* the table was not found */
|
||||
error = create_table(db);
|
||||
break;
|
||||
|
||||
case SQLITE_ROW:
|
||||
/* the table was found */
|
||||
error = GIT_SUCCESS;
|
||||
break;
|
||||
|
||||
default:
|
||||
error = GIT_ERROR;
|
||||
break;
|
||||
}
|
||||
|
||||
sqlite3_finalize(st_check);
|
||||
return error == GIT_SUCCESS ? GIT_SUCCESS : git__rethrow(error, "SQLite backend: Failed to initialize database");
|
||||
}
|
||||
|
||||
static int init_statements(sqlite_backend *backend)
|
||||
{
|
||||
static const char *sql_read =
|
||||
"SELECT type, size, data FROM '" GIT2_TABLE_NAME "' WHERE oid = ?;";
|
||||
|
||||
static const char *sql_read_header =
|
||||
"SELECT type, size FROM '" GIT2_TABLE_NAME "' WHERE oid = ?;";
|
||||
|
||||
static const char *sql_write =
|
||||
"INSERT OR IGNORE INTO '" GIT2_TABLE_NAME "' VALUES (?, ?, ?, ?);";
|
||||
|
||||
if (sqlite3_prepare_v2(backend->db, sql_read, -1, &backend->st_read, NULL) != SQLITE_OK)
|
||||
return git__throw(GIT_ERROR, "SQLite backend: Failed to initialize statements");
|
||||
|
||||
if (sqlite3_prepare_v2(backend->db, sql_read_header, -1, &backend->st_read_header, NULL) != SQLITE_OK)
|
||||
return git__throw(GIT_ERROR, "SQLite backend: Failed to initialize statements");
|
||||
|
||||
if (sqlite3_prepare_v2(backend->db, sql_write, -1, &backend->st_write, NULL) != SQLITE_OK)
|
||||
return git__throw(GIT_ERROR, "SQLite backend: Failed to initialize statements");
|
||||
|
||||
return GIT_SUCCESS;
|
||||
}
|
||||
|
||||
int git_odb_backend_sqlite(git_odb_backend **backend_out, const char *sqlite_db)
|
||||
{
|
||||
sqlite_backend *backend;
|
||||
int error;
|
||||
|
||||
backend = git__calloc(1, sizeof(sqlite_backend));
|
||||
if (backend == NULL)
|
||||
return GIT_ENOMEM;
|
||||
|
||||
if (sqlite3_open(sqlite_db, &backend->db) != SQLITE_OK)
|
||||
goto cleanup;
|
||||
|
||||
error = init_db(backend->db);
|
||||
if (error < 0)
|
||||
goto cleanup;
|
||||
|
||||
error = init_statements(backend);
|
||||
if (error < 0)
|
||||
goto cleanup;
|
||||
|
||||
backend->parent.read = &sqlite_backend__read;
|
||||
backend->parent.read_prefix = &sqlite_backend__read_prefix;
|
||||
backend->parent.read_header = &sqlite_backend__read_header;
|
||||
backend->parent.write = &sqlite_backend__write;
|
||||
backend->parent.exists = &sqlite_backend__exists;
|
||||
backend->parent.free = &sqlite_backend__free;
|
||||
|
||||
*backend_out = (git_odb_backend *)backend;
|
||||
return GIT_SUCCESS;
|
||||
|
||||
cleanup:
|
||||
sqlite_backend__free((git_odb_backend *)backend);
|
||||
return git__throw(GIT_ERROR, "SQLite backend: Failed to get ODB backend");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
int git_odb_backend_sqlite(git_odb_backend **GIT_UNUSED(backend_out), const char *GIT_UNUSED(sqlite_db))
|
||||
{
|
||||
GIT_UNUSED_ARG(backend_out);
|
||||
GIT_UNUSED_ARG(sqlite_db);
|
||||
return git__throw(GIT_ENOTIMPLEMENTED, "SQLite backend: Failed to get ODB backend. Operation not yet implemented");
|
||||
}
|
||||
|
||||
#endif /* HAVE_SQLITE3 */
|
309
src/blob.c
309
src/blob.c
@ -1,26 +1,8 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* 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.
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
|
||||
#include "git2/common.h"
|
||||
@ -29,6 +11,7 @@
|
||||
|
||||
#include "common.h"
|
||||
#include "blob.h"
|
||||
#include "filter.h"
|
||||
|
||||
const void *git_blob_rawcontent(git_blob *blob)
|
||||
{
|
||||
@ -36,16 +19,22 @@ const void *git_blob_rawcontent(git_blob *blob)
|
||||
return blob->odb_object->raw.data;
|
||||
}
|
||||
|
||||
int git_blob_rawsize(git_blob *blob)
|
||||
size_t git_blob_rawsize(git_blob *blob)
|
||||
{
|
||||
assert(blob);
|
||||
return blob->odb_object->raw.len;
|
||||
}
|
||||
|
||||
int git_blob__getbuf(git_buf *buffer, git_blob *blob)
|
||||
{
|
||||
return git_buf_set(
|
||||
buffer, blob->odb_object->raw.data, blob->odb_object->raw.len);
|
||||
}
|
||||
|
||||
void git_blob__free(git_blob *blob)
|
||||
{
|
||||
git_odb_object_close(blob->odb_object);
|
||||
free(blob);
|
||||
git_odb_object_free(blob->odb_object);
|
||||
git__free(blob);
|
||||
}
|
||||
|
||||
int git_blob__parse(git_blob *blob, git_odb_object *odb_obj)
|
||||
@ -53,79 +42,247 @@ int git_blob__parse(git_blob *blob, git_odb_object *odb_obj)
|
||||
assert(blob);
|
||||
git_cached_obj_incref((git_cached_obj *)odb_obj);
|
||||
blob->odb_object = odb_obj;
|
||||
return GIT_SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_blob_create_frombuffer(git_oid *oid, git_repository *repo, const void *buffer, size_t len)
|
||||
{
|
||||
int error;
|
||||
git_odb *odb;
|
||||
git_odb_stream *stream;
|
||||
|
||||
if ((error = git_odb_open_wstream(&stream, repo->db, len, GIT_OBJ_BLOB)) < GIT_SUCCESS)
|
||||
return git__rethrow(error, "Failed to create blob");
|
||||
|
||||
if ((error = stream->write(stream, buffer, len)) < GIT_SUCCESS) {
|
||||
stream->free(stream);
|
||||
if ((error = git_repository_odb__weakptr(&odb, repo)) < 0 ||
|
||||
(error = git_odb_open_wstream(&stream, odb, len, GIT_OBJ_BLOB)) < 0)
|
||||
return error;
|
||||
|
||||
if ((error = stream->write(stream, buffer, len)) == 0)
|
||||
error = stream->finalize_write(oid, stream);
|
||||
|
||||
stream->free(stream);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int write_file_stream(
|
||||
git_oid *oid, git_odb *odb, const char *path, git_off_t file_size)
|
||||
{
|
||||
int fd, error;
|
||||
char buffer[4096];
|
||||
git_odb_stream *stream = NULL;
|
||||
|
||||
if ((error = git_odb_open_wstream(
|
||||
&stream, odb, (size_t)file_size, GIT_OBJ_BLOB)) < 0)
|
||||
return error;
|
||||
|
||||
if ((fd = git_futils_open_ro(path)) < 0) {
|
||||
stream->free(stream);
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = stream->finalize_write(oid, stream);
|
||||
while (!error && file_size > 0) {
|
||||
ssize_t read_len = p_read(fd, buffer, sizeof(buffer));
|
||||
|
||||
if (read_len < 0) {
|
||||
giterr_set(
|
||||
GITERR_OS, "Failed to create blob. Can't read whole file");
|
||||
error = -1;
|
||||
}
|
||||
else if (!(error = stream->write(stream, buffer, read_len)))
|
||||
file_size -= read_len;
|
||||
}
|
||||
|
||||
p_close(fd);
|
||||
|
||||
if (!error)
|
||||
error = stream->finalize_write(oid, stream);
|
||||
|
||||
stream->free(stream);
|
||||
return error;
|
||||
}
|
||||
|
||||
if (error < GIT_SUCCESS)
|
||||
return git__rethrow(error, "Failed to create blob");
|
||||
static int write_file_filtered(
|
||||
git_oid *oid,
|
||||
git_odb *odb,
|
||||
const char *full_path,
|
||||
git_vector *filters)
|
||||
{
|
||||
int error;
|
||||
git_buf source = GIT_BUF_INIT;
|
||||
git_buf dest = GIT_BUF_INIT;
|
||||
|
||||
return GIT_SUCCESS;
|
||||
if ((error = git_futils_readbuffer(&source, full_path)) < 0)
|
||||
return error;
|
||||
|
||||
error = git_filters_apply(&dest, &source, filters);
|
||||
|
||||
/* Free the source as soon as possible. This can be big in memory,
|
||||
* and we don't want to ODB write to choke */
|
||||
git_buf_free(&source);
|
||||
|
||||
/* Write the file to disk if it was properly filtered */
|
||||
if (!error)
|
||||
error = git_odb_write(oid, odb, dest.ptr, dest.size, GIT_OBJ_BLOB);
|
||||
|
||||
git_buf_free(&dest);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int write_symlink(
|
||||
git_oid *oid, git_odb *odb, const char *path, size_t link_size)
|
||||
{
|
||||
char *link_data;
|
||||
ssize_t read_len;
|
||||
int error;
|
||||
|
||||
link_data = git__malloc(link_size);
|
||||
GITERR_CHECK_ALLOC(link_data);
|
||||
|
||||
read_len = p_readlink(path, link_data, link_size);
|
||||
if (read_len != (ssize_t)link_size) {
|
||||
giterr_set(GITERR_OS, "Failed to create blob. Can't read symlink '%s'", path);
|
||||
git__free(link_data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
error = git_odb_write(oid, odb, (void *)link_data, link_size, GIT_OBJ_BLOB);
|
||||
git__free(link_data);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int blob_create_internal(git_oid *oid, git_repository *repo, const char *content_path, const char *hint_path, bool try_load_filters)
|
||||
{
|
||||
int error;
|
||||
struct stat st;
|
||||
git_odb *odb = NULL;
|
||||
git_off_t size;
|
||||
|
||||
assert(hint_path || !try_load_filters);
|
||||
|
||||
if ((error = git_path_lstat(content_path, &st)) < 0 || (error = git_repository_odb__weakptr(&odb, repo)) < 0)
|
||||
return error;
|
||||
|
||||
size = st.st_size;
|
||||
|
||||
if (S_ISLNK(st.st_mode)) {
|
||||
error = write_symlink(oid, odb, content_path, (size_t)size);
|
||||
} else {
|
||||
git_vector write_filters = GIT_VECTOR_INIT;
|
||||
int filter_count = 0;
|
||||
|
||||
if (try_load_filters) {
|
||||
/* Load the filters for writing this file to the ODB */
|
||||
filter_count = git_filters_load(
|
||||
&write_filters, repo, hint_path, GIT_FILTER_TO_ODB);
|
||||
}
|
||||
|
||||
if (filter_count < 0) {
|
||||
/* Negative value means there was a critical error */
|
||||
error = filter_count;
|
||||
} else if (filter_count == 0) {
|
||||
/* No filters need to be applied to the document: we can stream
|
||||
* directly from disk */
|
||||
error = write_file_stream(oid, odb, content_path, size);
|
||||
} else {
|
||||
/* We need to apply one or more filters */
|
||||
error = write_file_filtered(oid, odb, content_path, &write_filters);
|
||||
}
|
||||
|
||||
git_filters_free(&write_filters);
|
||||
|
||||
/*
|
||||
* TODO: eventually support streaming filtered files, for files
|
||||
* which are bigger than a given threshold. This is not a priority
|
||||
* because applying a filter in streaming mode changes the final
|
||||
* size of the blob, and without knowing its final size, the blob
|
||||
* cannot be written in stream mode to the ODB.
|
||||
*
|
||||
* The plan is to do streaming writes to a tempfile on disk and then
|
||||
* opening streaming that file to the ODB, using
|
||||
* `write_file_stream`.
|
||||
*
|
||||
* CAREFULLY DESIGNED APIS YO
|
||||
*/
|
||||
}
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_blob_create_fromfile(git_oid *oid, git_repository *repo, const char *path)
|
||||
{
|
||||
int error, fd;
|
||||
char full_path[GIT_PATH_MAX];
|
||||
char buffer[2048];
|
||||
git_off_t size;
|
||||
git_odb_stream *stream;
|
||||
git_buf full_path = GIT_BUF_INIT;
|
||||
const char *workdir;
|
||||
int error;
|
||||
|
||||
if (repo->path_workdir == NULL)
|
||||
return git__throw(GIT_ENOTFOUND, "Failed to create blob. (No working directory found)");
|
||||
workdir = git_repository_workdir(repo);
|
||||
assert(workdir); /* error to call this on bare repo */
|
||||
|
||||
git__joinpath(full_path, repo->path_workdir, path);
|
||||
|
||||
if ((fd = gitfo_open(full_path, O_RDONLY)) < 0)
|
||||
return git__throw(GIT_ENOTFOUND, "Failed to create blob. Could not open '%s'", full_path);
|
||||
|
||||
if ((size = gitfo_size(fd)) < 0 || !git__is_sizet(size)) {
|
||||
gitfo_close(fd);
|
||||
return git__throw(GIT_EOSERR, "Failed to create blob. '%s' appears to be corrupted", full_path);
|
||||
if (git_buf_joinpath(&full_path, workdir, path) < 0) {
|
||||
git_buf_free(&full_path);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((error = git_odb_open_wstream(&stream, repo->db, (size_t)size, GIT_OBJ_BLOB)) < GIT_SUCCESS) {
|
||||
gitfo_close(fd);
|
||||
return git__rethrow(error, "Failed to create blob");
|
||||
}
|
||||
error = blob_create_internal(oid, repo, git_buf_cstr(&full_path), git_buf_cstr(&full_path), true);
|
||||
|
||||
while (size > 0) {
|
||||
ssize_t read_len;
|
||||
|
||||
read_len = read(fd, buffer, sizeof(buffer));
|
||||
|
||||
if (read_len < 0) {
|
||||
gitfo_close(fd);
|
||||
stream->free(stream);
|
||||
return git__throw(GIT_EOSERR, "Failed to create blob. Can't read full file");
|
||||
}
|
||||
|
||||
stream->write(stream, buffer, read_len);
|
||||
size -= read_len;
|
||||
}
|
||||
|
||||
error = stream->finalize_write(oid, stream);
|
||||
stream->free(stream);
|
||||
gitfo_close(fd);
|
||||
|
||||
if (error < GIT_SUCCESS)
|
||||
return git__rethrow(error, "Failed to create blob");
|
||||
|
||||
return GIT_SUCCESS;
|
||||
git_buf_free(&full_path);
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_blob_create_fromdisk(git_oid *oid, git_repository *repo, const char *path)
|
||||
{
|
||||
int error;
|
||||
git_buf full_path = GIT_BUF_INIT;
|
||||
|
||||
if ((error = git_path_prettify(&full_path, path, NULL)) < 0) {
|
||||
git_buf_free(&full_path);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = blob_create_internal(oid, repo, git_buf_cstr(&full_path), git_buf_cstr(&full_path), true);
|
||||
|
||||
git_buf_free(&full_path);
|
||||
return error;
|
||||
}
|
||||
|
||||
#define BUFFER_SIZE 4096
|
||||
|
||||
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)
|
||||
{
|
||||
int error = -1, read_bytes;
|
||||
char *content = NULL;
|
||||
git_filebuf file = GIT_FILEBUF_INIT;
|
||||
|
||||
content = git__malloc(BUFFER_SIZE);
|
||||
GITERR_CHECK_ALLOC(content);
|
||||
|
||||
if (git_filebuf_open(&file, hintpath == NULL ? "streamed" : hintpath, GIT_FILEBUF_TEMPORARY) < 0)
|
||||
goto cleanup;
|
||||
|
||||
while (1) {
|
||||
read_bytes = source_cb(content, BUFFER_SIZE, payload);
|
||||
|
||||
assert(read_bytes <= BUFFER_SIZE);
|
||||
|
||||
if (read_bytes <= 0)
|
||||
break;
|
||||
|
||||
if (git_filebuf_write(&file, content, read_bytes) < 0)
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (read_bytes < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (git_filebuf_flush(&file) < 0)
|
||||
goto cleanup;
|
||||
|
||||
error = blob_create_internal(oid, repo, file.path_lock, hintpath, hintpath != NULL);
|
||||
|
||||
cleanup:
|
||||
git_filebuf_cleanup(&file);
|
||||
git__free(content);
|
||||
return error;
|
||||
}
|
||||
|
@ -1,3 +1,9 @@
|
||||
/*
|
||||
* 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_blob_h__
|
||||
#define INCLUDE_blob_h__
|
||||
|
||||
@ -13,5 +19,6 @@ struct git_blob {
|
||||
|
||||
void git_blob__free(git_blob *blob);
|
||||
int git_blob__parse(git_blob *blob, git_odb_object *obj);
|
||||
int git_blob__getbuf(git_buf *buffer, git_blob *blob);
|
||||
|
||||
#endif
|
||||
|
208
src/branch.c
Normal file
208
src/branch.c
Normal file
@ -0,0 +1,208 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "commit.h"
|
||||
#include "branch.h"
|
||||
#include "tag.h"
|
||||
|
||||
static int retrieve_branch_reference(
|
||||
git_reference **branch_reference_out,
|
||||
git_repository *repo,
|
||||
const char *branch_name,
|
||||
int is_remote)
|
||||
{
|
||||
git_reference *branch;
|
||||
int error = -1;
|
||||
char *prefix;
|
||||
git_buf ref_name = GIT_BUF_INIT;
|
||||
|
||||
*branch_reference_out = NULL;
|
||||
|
||||
prefix = is_remote ? GIT_REFS_REMOTES_DIR : GIT_REFS_HEADS_DIR;
|
||||
|
||||
if (git_buf_joinpath(&ref_name, prefix, branch_name) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if ((error = git_reference_lookup(&branch, repo, ref_name.ptr)) < 0) {
|
||||
giterr_set(GITERR_REFERENCE,
|
||||
"Cannot locate %s branch '%s'.", is_remote ? "remote-tracking" : "local", branch_name);
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
*branch_reference_out = branch;
|
||||
|
||||
cleanup:
|
||||
git_buf_free(&ref_name);
|
||||
return error;
|
||||
}
|
||||
|
||||
static int create_error_invalid(const char *msg)
|
||||
{
|
||||
giterr_set(GITERR_INVALID, "Cannot create branch - %s", msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int git_branch_create(
|
||||
git_oid *oid_out,
|
||||
git_repository *repo,
|
||||
const char *branch_name,
|
||||
const git_object *target,
|
||||
int force)
|
||||
{
|
||||
git_otype target_type = GIT_OBJ_BAD;
|
||||
git_object *commit = NULL;
|
||||
git_reference *branch = NULL;
|
||||
git_buf canonical_branch_name = GIT_BUF_INIT;
|
||||
int error = -1;
|
||||
|
||||
assert(repo && branch_name && target && oid_out);
|
||||
|
||||
if (git_object_owner(target) != repo)
|
||||
return create_error_invalid("The given target does not belong to this repository");
|
||||
|
||||
target_type = git_object_type(target);
|
||||
|
||||
switch (target_type)
|
||||
{
|
||||
case GIT_OBJ_TAG:
|
||||
if (git_tag_peel(&commit, (git_tag *)target) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (git_object_type(commit) != GIT_OBJ_COMMIT) {
|
||||
create_error_invalid("The given target does not resolve to a commit");
|
||||
goto cleanup;
|
||||
}
|
||||
break;
|
||||
|
||||
case GIT_OBJ_COMMIT:
|
||||
commit = (git_object *)target;
|
||||
break;
|
||||
|
||||
default:
|
||||
return create_error_invalid("Only git_tag and git_commit objects are valid targets.");
|
||||
}
|
||||
|
||||
if (git_buf_joinpath(&canonical_branch_name, GIT_REFS_HEADS_DIR, branch_name) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if (git_reference_create_oid(&branch, repo, git_buf_cstr(&canonical_branch_name), git_object_id(commit), force) < 0)
|
||||
goto cleanup;
|
||||
|
||||
git_oid_cpy(oid_out, git_reference_oid(branch));
|
||||
error = 0;
|
||||
|
||||
cleanup:
|
||||
if (target_type == GIT_OBJ_TAG)
|
||||
git_object_free(commit);
|
||||
|
||||
git_reference_free(branch);
|
||||
git_buf_free(&canonical_branch_name);
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_branch_delete(git_repository *repo, const char *branch_name, git_branch_t branch_type)
|
||||
{
|
||||
git_reference *branch = NULL;
|
||||
git_reference *head = NULL;
|
||||
int error;
|
||||
|
||||
assert((branch_type == GIT_BRANCH_LOCAL) || (branch_type == GIT_BRANCH_REMOTE));
|
||||
|
||||
if ((error = retrieve_branch_reference(&branch, repo, branch_name, branch_type == GIT_BRANCH_REMOTE)) < 0)
|
||||
return error;
|
||||
|
||||
if (git_reference_lookup(&head, repo, GIT_HEAD_FILE) < 0) {
|
||||
giterr_set(GITERR_REFERENCE, "Cannot locate HEAD.");
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
if ((git_reference_type(head) == GIT_REF_SYMBOLIC)
|
||||
&& (strcmp(git_reference_target(head), git_reference_name(branch)) == 0)) {
|
||||
giterr_set(GITERR_REFERENCE,
|
||||
"Cannot delete branch '%s' as it is the current HEAD of the repository.", branch_name);
|
||||
goto on_error;
|
||||
}
|
||||
|
||||
if (git_reference_delete(branch) < 0)
|
||||
goto on_error;
|
||||
|
||||
git_reference_free(head);
|
||||
return 0;
|
||||
|
||||
on_error:
|
||||
git_reference_free(head);
|
||||
git_reference_free(branch);
|
||||
return -1;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
git_vector *branchlist;
|
||||
unsigned int branch_type;
|
||||
} branch_filter_data;
|
||||
|
||||
static int branch_list_cb(const char *branch_name, void *payload)
|
||||
{
|
||||
branch_filter_data *filter = (branch_filter_data *)payload;
|
||||
|
||||
if ((filter->branch_type & GIT_BRANCH_LOCAL && git__prefixcmp(branch_name, GIT_REFS_HEADS_DIR) == 0)
|
||||
|| (filter->branch_type & GIT_BRANCH_REMOTE && git__prefixcmp(branch_name, GIT_REFS_REMOTES_DIR) == 0))
|
||||
return git_vector_insert(filter->branchlist, git__strdup(branch_name));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_branch_list(git_strarray *branch_names, git_repository *repo, unsigned int list_flags)
|
||||
{
|
||||
int error;
|
||||
branch_filter_data filter;
|
||||
git_vector branchlist;
|
||||
|
||||
assert(branch_names && repo);
|
||||
|
||||
if (git_vector_init(&branchlist, 8, NULL) < 0)
|
||||
return -1;
|
||||
|
||||
filter.branchlist = &branchlist;
|
||||
filter.branch_type = list_flags;
|
||||
|
||||
error = git_reference_foreach(repo, GIT_REF_LISTALL, &branch_list_cb, (void *)&filter);
|
||||
if (error < 0) {
|
||||
git_vector_free(&branchlist);
|
||||
return -1;
|
||||
}
|
||||
|
||||
branch_names->strings = (char **)branchlist.contents;
|
||||
branch_names->count = branchlist.length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_branch_move(git_repository *repo, const char *old_branch_name, const char *new_branch_name, int force)
|
||||
{
|
||||
git_reference *reference = NULL;
|
||||
git_buf old_reference_name = GIT_BUF_INIT, new_reference_name = GIT_BUF_INIT;
|
||||
int error = 0;
|
||||
|
||||
if ((error = git_buf_joinpath(&old_reference_name, GIT_REFS_HEADS_DIR, old_branch_name)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
/* We need to be able to return GIT_ENOTFOUND */
|
||||
if ((error = git_reference_lookup(&reference, repo, git_buf_cstr(&old_reference_name))) < 0)
|
||||
goto cleanup;
|
||||
|
||||
if ((error = git_buf_joinpath(&new_reference_name, GIT_REFS_HEADS_DIR, new_branch_name)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
error = git_reference_rename(reference, git_buf_cstr(&new_reference_name), force);
|
||||
|
||||
cleanup:
|
||||
git_reference_free(reference);
|
||||
git_buf_free(&old_reference_name);
|
||||
git_buf_free(&new_reference_name);
|
||||
|
||||
return error;
|
||||
}
|
17
src/branch.h
Normal file
17
src/branch.h
Normal file
@ -0,0 +1,17 @@
|
||||
/*
|
||||
* 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_branch_h__
|
||||
#define INCLUDE_branch_h__
|
||||
|
||||
#include "git2/branch.h"
|
||||
|
||||
struct git_branch {
|
||||
char *remote; /* TODO: Make this a git_remote */
|
||||
char *merge;
|
||||
};
|
||||
|
||||
#endif
|
12
src/bswap.h
12
src/bswap.h
@ -1,8 +1,8 @@
|
||||
/*
|
||||
* Let's make sure we always have a sane definition for ntohl()/htonl().
|
||||
* Some libraries define those as a function call, just to perform byte
|
||||
* shifting, bringing significant overhead to what should be a simple
|
||||
* operation.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
@ -14,8 +14,8 @@
|
||||
GIT_INLINE(uint32_t) default_swab32(uint32_t val)
|
||||
{
|
||||
return (((val & 0xff000000) >> 24) |
|
||||
((val & 0x00ff0000) >> 8) |
|
||||
((val & 0x0000ff00) << 8) |
|
||||
((val & 0x00ff0000) >> 8) |
|
||||
((val & 0x0000ff00) << 8) |
|
||||
((val & 0x000000ff) << 24));
|
||||
}
|
||||
|
||||
|
461
src/buffer.c
Normal file
461
src/buffer.c
Normal file
@ -0,0 +1,461 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#include "buffer.h"
|
||||
#include "posix.h"
|
||||
#include <stdarg.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/* Used as default value for git_buf->ptr so that people can always
|
||||
* assume ptr is non-NULL and zero terminated even for new git_bufs.
|
||||
*/
|
||||
char git_buf__initbuf[1];
|
||||
|
||||
char git_buf__oom[1];
|
||||
|
||||
#define ENSURE_SIZE(b, d) \
|
||||
if ((d) > buf->asize && git_buf_grow(b, (d)) < 0)\
|
||||
return -1;
|
||||
|
||||
|
||||
void git_buf_init(git_buf *buf, size_t initial_size)
|
||||
{
|
||||
buf->asize = 0;
|
||||
buf->size = 0;
|
||||
buf->ptr = git_buf__initbuf;
|
||||
|
||||
if (initial_size)
|
||||
git_buf_grow(buf, initial_size);
|
||||
}
|
||||
|
||||
int git_buf_grow(git_buf *buf, size_t target_size)
|
||||
{
|
||||
int error = git_buf_try_grow(buf, target_size);
|
||||
if (error != 0)
|
||||
buf->ptr = git_buf__oom;
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_buf_try_grow(git_buf *buf, size_t target_size)
|
||||
{
|
||||
char *new_ptr;
|
||||
size_t new_size;
|
||||
|
||||
if (buf->ptr == git_buf__oom)
|
||||
return -1;
|
||||
|
||||
if (target_size <= buf->asize)
|
||||
return 0;
|
||||
|
||||
if (buf->asize == 0) {
|
||||
new_size = target_size;
|
||||
new_ptr = NULL;
|
||||
} else {
|
||||
new_size = buf->asize;
|
||||
new_ptr = buf->ptr;
|
||||
}
|
||||
|
||||
/* grow the buffer size by 1.5, until it's big enough
|
||||
* to fit our target size */
|
||||
while (new_size < target_size)
|
||||
new_size = (new_size << 1) - (new_size >> 1);
|
||||
|
||||
/* round allocation up to multiple of 8 */
|
||||
new_size = (new_size + 7) & ~7;
|
||||
|
||||
new_ptr = git__realloc(new_ptr, new_size);
|
||||
if (!new_ptr)
|
||||
return -1;
|
||||
|
||||
buf->asize = new_size;
|
||||
buf->ptr = new_ptr;
|
||||
|
||||
/* truncate the existing buffer size if necessary */
|
||||
if (buf->size >= buf->asize)
|
||||
buf->size = buf->asize - 1;
|
||||
buf->ptr[buf->size] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void git_buf_free(git_buf *buf)
|
||||
{
|
||||
if (!buf) return;
|
||||
|
||||
if (buf->ptr != git_buf__initbuf && buf->ptr != git_buf__oom)
|
||||
git__free(buf->ptr);
|
||||
|
||||
git_buf_init(buf, 0);
|
||||
}
|
||||
|
||||
void git_buf_clear(git_buf *buf)
|
||||
{
|
||||
buf->size = 0;
|
||||
if (buf->asize > 0)
|
||||
buf->ptr[0] = '\0';
|
||||
}
|
||||
|
||||
int git_buf_set(git_buf *buf, const char *data, size_t len)
|
||||
{
|
||||
if (len == 0 || data == NULL) {
|
||||
git_buf_clear(buf);
|
||||
} else {
|
||||
if (data != buf->ptr) {
|
||||
ENSURE_SIZE(buf, len + 1);
|
||||
memmove(buf->ptr, data, len);
|
||||
}
|
||||
buf->size = len;
|
||||
buf->ptr[buf->size] = '\0';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_buf_sets(git_buf *buf, const char *string)
|
||||
{
|
||||
return git_buf_set(buf, string, string ? strlen(string) : 0);
|
||||
}
|
||||
|
||||
int git_buf_putc(git_buf *buf, char c)
|
||||
{
|
||||
ENSURE_SIZE(buf, buf->size + 2);
|
||||
buf->ptr[buf->size++] = c;
|
||||
buf->ptr[buf->size] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_buf_put(git_buf *buf, const char *data, size_t len)
|
||||
{
|
||||
ENSURE_SIZE(buf, buf->size + len + 1);
|
||||
memmove(buf->ptr + buf->size, data, len);
|
||||
buf->size += len;
|
||||
buf->ptr[buf->size] = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_buf_puts(git_buf *buf, const char *string)
|
||||
{
|
||||
assert(string);
|
||||
return git_buf_put(buf, string, strlen(string));
|
||||
}
|
||||
|
||||
int git_buf_vprintf(git_buf *buf, const char *format, va_list ap)
|
||||
{
|
||||
int len;
|
||||
|
||||
ENSURE_SIZE(buf, buf->size + (strlen(format) * 2));
|
||||
|
||||
while (1) {
|
||||
va_list args;
|
||||
va_copy(args, ap);
|
||||
|
||||
len = p_vsnprintf(
|
||||
buf->ptr + buf->size,
|
||||
buf->asize - buf->size,
|
||||
format, args
|
||||
);
|
||||
|
||||
if (len < 0) {
|
||||
git__free(buf->ptr);
|
||||
buf->ptr = git_buf__oom;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((size_t)len + 1 <= buf->asize - buf->size) {
|
||||
buf->size += len;
|
||||
break;
|
||||
}
|
||||
|
||||
ENSURE_SIZE(buf, buf->size + len + 1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_buf_printf(git_buf *buf, const char *format, ...)
|
||||
{
|
||||
int r;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
r = git_buf_vprintf(buf, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void git_buf_copy_cstr(char *data, size_t datasize, const git_buf *buf)
|
||||
{
|
||||
size_t copylen;
|
||||
|
||||
assert(data && datasize && buf);
|
||||
|
||||
data[0] = '\0';
|
||||
|
||||
if (buf->size == 0 || buf->asize <= 0)
|
||||
return;
|
||||
|
||||
copylen = buf->size;
|
||||
if (copylen > datasize - 1)
|
||||
copylen = datasize - 1;
|
||||
memmove(data, buf->ptr, copylen);
|
||||
data[copylen] = '\0';
|
||||
}
|
||||
|
||||
void git_buf_consume(git_buf *buf, const char *end)
|
||||
{
|
||||
if (end > buf->ptr && end <= buf->ptr + buf->size) {
|
||||
size_t consumed = end - buf->ptr;
|
||||
memmove(buf->ptr, end, buf->size - consumed);
|
||||
buf->size -= consumed;
|
||||
buf->ptr[buf->size] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void git_buf_truncate(git_buf *buf, size_t len)
|
||||
{
|
||||
if (len < buf->size) {
|
||||
buf->size = len;
|
||||
buf->ptr[buf->size] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
void git_buf_rtruncate_at_char(git_buf *buf, char separator)
|
||||
{
|
||||
ssize_t idx = git_buf_rfind_next(buf, separator);
|
||||
git_buf_truncate(buf, idx < 0 ? 0 : (size_t)idx);
|
||||
}
|
||||
|
||||
void git_buf_swap(git_buf *buf_a, git_buf *buf_b)
|
||||
{
|
||||
git_buf t = *buf_a;
|
||||
*buf_a = *buf_b;
|
||||
*buf_b = t;
|
||||
}
|
||||
|
||||
char *git_buf_detach(git_buf *buf)
|
||||
{
|
||||
char *data = buf->ptr;
|
||||
|
||||
if (buf->asize == 0 || buf->ptr == git_buf__oom)
|
||||
return NULL;
|
||||
|
||||
git_buf_init(buf, 0);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void git_buf_attach(git_buf *buf, char *ptr, size_t asize)
|
||||
{
|
||||
git_buf_free(buf);
|
||||
|
||||
if (ptr) {
|
||||
buf->ptr = ptr;
|
||||
buf->size = strlen(ptr);
|
||||
if (asize)
|
||||
buf->asize = (asize < buf->size) ? buf->size + 1 : asize;
|
||||
else /* pass 0 to fall back on strlen + 1 */
|
||||
buf->asize = buf->size + 1;
|
||||
} else {
|
||||
git_buf_grow(buf, asize);
|
||||
}
|
||||
}
|
||||
|
||||
int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int i;
|
||||
size_t total_size = 0, original_size = buf->size;
|
||||
char *out, *original = buf->ptr;
|
||||
|
||||
if (buf->size > 0 && buf->ptr[buf->size - 1] != separator)
|
||||
++total_size; /* space for initial separator */
|
||||
|
||||
/* Make two passes to avoid multiple reallocation */
|
||||
|
||||
va_start(ap, nbuf);
|
||||
for (i = 0; i < nbuf; ++i) {
|
||||
const char* segment;
|
||||
size_t segment_len;
|
||||
|
||||
segment = va_arg(ap, const char *);
|
||||
if (!segment)
|
||||
continue;
|
||||
|
||||
segment_len = strlen(segment);
|
||||
total_size += segment_len;
|
||||
if (segment_len == 0 || segment[segment_len - 1] != separator)
|
||||
++total_size; /* space for separator */
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
/* expand buffer if needed */
|
||||
if (total_size == 0)
|
||||
return 0;
|
||||
if (git_buf_grow(buf, buf->size + total_size + 1) < 0)
|
||||
return -1;
|
||||
|
||||
out = buf->ptr + buf->size;
|
||||
|
||||
/* append separator to existing buf if needed */
|
||||
if (buf->size > 0 && out[-1] != separator)
|
||||
*out++ = separator;
|
||||
|
||||
va_start(ap, nbuf);
|
||||
for (i = 0; i < nbuf; ++i) {
|
||||
const char* segment;
|
||||
size_t segment_len;
|
||||
|
||||
segment = va_arg(ap, const char *);
|
||||
if (!segment)
|
||||
continue;
|
||||
|
||||
/* deal with join that references buffer's original content */
|
||||
if (segment >= original && segment < original + original_size) {
|
||||
size_t offset = (segment - original);
|
||||
segment = buf->ptr + offset;
|
||||
segment_len = original_size - offset;
|
||||
} else {
|
||||
segment_len = strlen(segment);
|
||||
}
|
||||
|
||||
/* skip leading separators */
|
||||
if (out > buf->ptr && out[-1] == separator)
|
||||
while (segment_len > 0 && *segment == separator) {
|
||||
segment++;
|
||||
segment_len--;
|
||||
}
|
||||
|
||||
/* copy over next buffer */
|
||||
if (segment_len > 0) {
|
||||
memmove(out, segment, segment_len);
|
||||
out += segment_len;
|
||||
}
|
||||
|
||||
/* append trailing separator (except for last item) */
|
||||
if (i < nbuf - 1 && out > buf->ptr && out[-1] != separator)
|
||||
*out++ = separator;
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
/* set size based on num characters actually written */
|
||||
buf->size = out - buf->ptr;
|
||||
buf->ptr[buf->size] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_buf_join(
|
||||
git_buf *buf,
|
||||
char separator,
|
||||
const char *str_a,
|
||||
const char *str_b)
|
||||
{
|
||||
size_t strlen_a = str_a ? strlen(str_a) : 0;
|
||||
size_t strlen_b = strlen(str_b);
|
||||
int need_sep = 0;
|
||||
ssize_t offset_a = -1;
|
||||
|
||||
/* not safe to have str_b point internally to the buffer */
|
||||
assert(str_b < buf->ptr || str_b > buf->ptr + buf->size);
|
||||
|
||||
/* figure out if we need to insert a separator */
|
||||
if (separator && strlen_a) {
|
||||
while (*str_b == separator) { str_b++; strlen_b--; }
|
||||
if (str_a[strlen_a - 1] != separator)
|
||||
need_sep = 1;
|
||||
}
|
||||
|
||||
/* str_a could be part of the buffer */
|
||||
if (str_a >= buf->ptr && str_a < buf->ptr + buf->size)
|
||||
offset_a = str_a - buf->ptr;
|
||||
|
||||
if (git_buf_grow(buf, strlen_a + strlen_b + need_sep + 1) < 0)
|
||||
return -1;
|
||||
|
||||
/* fix up internal pointers */
|
||||
if (offset_a >= 0)
|
||||
str_a = buf->ptr + offset_a;
|
||||
|
||||
/* do the actual copying */
|
||||
if (offset_a != 0)
|
||||
memmove(buf->ptr, str_a, strlen_a);
|
||||
if (need_sep)
|
||||
buf->ptr[strlen_a] = separator;
|
||||
memcpy(buf->ptr + strlen_a + need_sep, str_b, strlen_b);
|
||||
|
||||
buf->size = strlen_a + strlen_b + need_sep;
|
||||
buf->ptr[buf->size] = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void git_buf_rtrim(git_buf *buf)
|
||||
{
|
||||
while (buf->size > 0) {
|
||||
if (!git__isspace(buf->ptr[buf->size - 1]))
|
||||
break;
|
||||
|
||||
buf->size--;
|
||||
}
|
||||
|
||||
buf->ptr[buf->size] = '\0';
|
||||
}
|
||||
|
||||
int git_buf_cmp(const git_buf *a, const git_buf *b)
|
||||
{
|
||||
int result = memcmp(a->ptr, b->ptr, min(a->size, b->size));
|
||||
return (result != 0) ? result :
|
||||
(a->size < b->size) ? -1 : (a->size > b->size) ? 1 : 0;
|
||||
}
|
||||
|
||||
int git_buf_common_prefix(git_buf *buf, const git_strarray *strings)
|
||||
{
|
||||
size_t i;
|
||||
const char *str, *pfx;
|
||||
|
||||
git_buf_clear(buf);
|
||||
|
||||
if (!strings || !strings->count)
|
||||
return 0;
|
||||
|
||||
/* initialize common prefix to first string */
|
||||
if (git_buf_sets(buf, strings->strings[0]) < 0)
|
||||
return -1;
|
||||
|
||||
/* go through the rest of the strings, truncating to shared prefix */
|
||||
for (i = 1; i < strings->count; ++i) {
|
||||
|
||||
for (str = strings->strings[i], pfx = buf->ptr;
|
||||
*str && *str == *pfx; str++, pfx++)
|
||||
/* scanning */;
|
||||
|
||||
git_buf_truncate(buf, pfx - buf->ptr);
|
||||
|
||||
if (!buf->size)
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool git_buf_is_binary(const git_buf *buf)
|
||||
{
|
||||
size_t i;
|
||||
int printable = 0, nonprintable = 0;
|
||||
|
||||
for (i = 0; i < buf->size; i++) {
|
||||
unsigned char c = buf->ptr[i];
|
||||
if (c > 0x1F && c < 0x7F)
|
||||
printable++;
|
||||
else if (c == '\0')
|
||||
return true;
|
||||
else if (!git__isspace(c))
|
||||
nonprintable++;
|
||||
}
|
||||
|
||||
return ((printable >> 7) < nonprintable);
|
||||
}
|
||||
|
135
src/buffer.h
Normal file
135
src/buffer.h
Normal file
@ -0,0 +1,135 @@
|
||||
/*
|
||||
* 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_buffer_h__
|
||||
#define INCLUDE_buffer_h__
|
||||
|
||||
#include "common.h"
|
||||
#include <stdarg.h>
|
||||
|
||||
typedef struct {
|
||||
char *ptr;
|
||||
size_t asize, size;
|
||||
} git_buf;
|
||||
|
||||
extern char git_buf__initbuf[];
|
||||
extern char git_buf__oom[];
|
||||
|
||||
#define GIT_BUF_INIT { git_buf__initbuf, 0, 0 }
|
||||
|
||||
/**
|
||||
* Initialize a git_buf structure.
|
||||
*
|
||||
* For the cases where GIT_BUF_INIT cannot be used to do static
|
||||
* initialization.
|
||||
*/
|
||||
void git_buf_init(git_buf *buf, size_t initial_size);
|
||||
|
||||
/**
|
||||
* Grow the buffer to hold at least `target_size` bytes.
|
||||
*
|
||||
* If the allocation fails, this will return an error and the buffer
|
||||
* will be marked as invalid for future operations. The existing
|
||||
* contents of the buffer will be preserved however.
|
||||
* @return 0 on success or -1 on failure
|
||||
*/
|
||||
int git_buf_grow(git_buf *buf, size_t target_size);
|
||||
|
||||
/**
|
||||
* Attempt to grow the buffer to hold at least `target_size` bytes.
|
||||
*
|
||||
* This is just like `git_buf_grow` except that even if the allocation
|
||||
* fails, the git_buf will still be left in a valid state.
|
||||
*/
|
||||
int git_buf_try_grow(git_buf *buf, size_t target_size);
|
||||
|
||||
void git_buf_free(git_buf *buf);
|
||||
void git_buf_swap(git_buf *buf_a, git_buf *buf_b);
|
||||
char *git_buf_detach(git_buf *buf);
|
||||
void git_buf_attach(git_buf *buf, char *ptr, size_t asize);
|
||||
|
||||
/**
|
||||
* Test if there have been any reallocation failures with this git_buf.
|
||||
*
|
||||
* Any function that writes to a git_buf can fail due to memory allocation
|
||||
* issues. If one fails, the git_buf will be marked with an OOM error and
|
||||
* further calls to modify the buffer will fail. Check git_buf_oom() at the
|
||||
* end of your sequence and it will be true if you ran out of memory at any
|
||||
* point with that buffer.
|
||||
*
|
||||
* @return false if no error, true if allocation error
|
||||
*/
|
||||
GIT_INLINE(bool) git_buf_oom(const git_buf *buf)
|
||||
{
|
||||
return (buf->ptr == git_buf__oom);
|
||||
}
|
||||
|
||||
/*
|
||||
* Functions below that return int value error codes will return 0 on
|
||||
* success or -1 on failure (which generally means an allocation failed).
|
||||
* Using a git_buf where the allocation has failed with result in -1 from
|
||||
* all further calls using that buffer. As a result, you can ignore the
|
||||
* return code of these functions and call them in a series then just call
|
||||
* git_buf_oom at the end.
|
||||
*/
|
||||
int git_buf_set(git_buf *buf, const char *data, size_t len);
|
||||
int git_buf_sets(git_buf *buf, const char *string);
|
||||
int git_buf_putc(git_buf *buf, char c);
|
||||
int git_buf_put(git_buf *buf, const char *data, size_t len);
|
||||
int git_buf_puts(git_buf *buf, const char *string);
|
||||
int git_buf_printf(git_buf *buf, const char *format, ...) GIT_FORMAT_PRINTF(2, 3);
|
||||
int git_buf_vprintf(git_buf *buf, const char *format, va_list ap);
|
||||
void git_buf_clear(git_buf *buf);
|
||||
void git_buf_consume(git_buf *buf, const char *end);
|
||||
void git_buf_truncate(git_buf *buf, size_t len);
|
||||
void git_buf_rtruncate_at_char(git_buf *path, char separator);
|
||||
|
||||
int git_buf_join_n(git_buf *buf, char separator, int nbuf, ...);
|
||||
int git_buf_join(git_buf *buf, char separator, const char *str_a, const char *str_b);
|
||||
|
||||
/**
|
||||
* Join two strings as paths, inserting a slash between as needed.
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
GIT_INLINE(int) git_buf_joinpath(git_buf *buf, const char *a, const char *b)
|
||||
{
|
||||
return git_buf_join(buf, '/', a, b);
|
||||
}
|
||||
|
||||
GIT_INLINE(const char *) git_buf_cstr(const git_buf *buf)
|
||||
{
|
||||
return buf->ptr;
|
||||
}
|
||||
|
||||
GIT_INLINE(size_t) git_buf_len(const git_buf *buf)
|
||||
{
|
||||
return buf->size;
|
||||
}
|
||||
|
||||
void git_buf_copy_cstr(char *data, size_t datasize, const git_buf *buf);
|
||||
|
||||
#define git_buf_PUTS(buf, str) git_buf_put(buf, str, sizeof(str) - 1)
|
||||
|
||||
GIT_INLINE(ssize_t) git_buf_rfind_next(git_buf *buf, char ch)
|
||||
{
|
||||
ssize_t idx = (ssize_t)buf->size - 1;
|
||||
while (idx >= 0 && buf->ptr[idx] == ch) idx--;
|
||||
while (idx >= 0 && buf->ptr[idx] != ch) idx--;
|
||||
return idx;
|
||||
}
|
||||
|
||||
/* Remove whitespace from the end of the buffer */
|
||||
void git_buf_rtrim(git_buf *buf);
|
||||
|
||||
int git_buf_cmp(const git_buf *a, const git_buf *b);
|
||||
|
||||
/* Fill buf with the common prefix of a array of strings */
|
||||
int git_buf_common_prefix(git_buf *buf, const git_strarray *strings);
|
||||
|
||||
/* Check if buffer looks like it contains binary data */
|
||||
bool git_buf_is_binary(const git_buf *buf);
|
||||
|
||||
#endif
|
114
src/cache.c
114
src/cache.c
@ -1,63 +1,34 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* 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.
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "repository.h"
|
||||
#include "commit.h"
|
||||
#include "thread-utils.h"
|
||||
#include "util.h"
|
||||
#include "cache.h"
|
||||
|
||||
int git_cache_init(git_cache *cache, size_t size, git_cached_obj_freeptr free_ptr)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (size < 8)
|
||||
size = 8;
|
||||
size = git__size_t_powerof2(size);
|
||||
|
||||
/* round up size to closest power of 2 */
|
||||
size--;
|
||||
size |= size >> 1;
|
||||
size |= size >> 2;
|
||||
size |= size >> 4;
|
||||
size |= size >> 8;
|
||||
size |= size >> 16;
|
||||
|
||||
cache->size_mask = size;
|
||||
cache->size_mask = size - 1;
|
||||
cache->lru_count = 0;
|
||||
cache->free_obj = free_ptr;
|
||||
|
||||
cache->nodes = git__malloc((size + 1) * sizeof(cache_node));
|
||||
if (cache->nodes == NULL)
|
||||
return GIT_ENOMEM;
|
||||
git_mutex_init(&cache->lock);
|
||||
|
||||
for (i = 0; i < (size + 1); ++i) {
|
||||
git_mutex_init(&cache->nodes[i].lock);
|
||||
cache->nodes[i].ptr = NULL;
|
||||
}
|
||||
cache->nodes = git__malloc(size * sizeof(git_cached_obj *));
|
||||
GITERR_CHECK_ALLOC(cache->nodes);
|
||||
|
||||
return GIT_SUCCESS;
|
||||
memset(cache->nodes, 0x0, size * sizeof(git_cached_obj *));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void git_cache_free(git_cache *cache)
|
||||
@ -65,65 +36,64 @@ void git_cache_free(git_cache *cache)
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < (cache->size_mask + 1); ++i) {
|
||||
if (cache->nodes[i].ptr)
|
||||
git_cached_obj_decref(cache->nodes[i].ptr, cache->free_obj);
|
||||
|
||||
git_mutex_free(&cache->nodes[i].lock);
|
||||
if (cache->nodes[i] != NULL)
|
||||
git_cached_obj_decref(cache->nodes[i], cache->free_obj);
|
||||
}
|
||||
|
||||
free(cache->nodes);
|
||||
git__free(cache->nodes);
|
||||
}
|
||||
|
||||
void *git_cache_get(git_cache *cache, const git_oid *oid)
|
||||
{
|
||||
const uint32_t *hash;
|
||||
cache_node *node = NULL;
|
||||
void *result = NULL;
|
||||
uint32_t hash;
|
||||
git_cached_obj *node = NULL, *result = NULL;
|
||||
|
||||
hash = (const uint32_t *)oid->id;
|
||||
node = &cache->nodes[hash[0] & cache->size_mask];
|
||||
memcpy(&hash, oid->id, sizeof(hash));
|
||||
|
||||
git_mutex_lock(&node->lock);
|
||||
git_mutex_lock(&cache->lock);
|
||||
{
|
||||
if (node->ptr && git_cached_obj_compare(node->ptr, oid) == 0) {
|
||||
git_cached_obj_incref(node->ptr);
|
||||
result = node->ptr;
|
||||
node = cache->nodes[hash & cache->size_mask];
|
||||
|
||||
if (node != NULL && git_oid_cmp(&node->oid, oid) == 0) {
|
||||
git_cached_obj_incref(node);
|
||||
result = node;
|
||||
}
|
||||
}
|
||||
git_mutex_unlock(&node->lock);
|
||||
git_mutex_unlock(&cache->lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void *git_cache_try_store(git_cache *cache, void *entry)
|
||||
void *git_cache_try_store(git_cache *cache, void *_entry)
|
||||
{
|
||||
const uint32_t *hash;
|
||||
const git_oid *oid;
|
||||
cache_node *node = NULL;
|
||||
git_cached_obj *entry = _entry;
|
||||
uint32_t hash;
|
||||
|
||||
oid = &((git_cached_obj*)entry)->oid;
|
||||
hash = (const uint32_t *)oid->id;
|
||||
node = &cache->nodes[hash[0] & cache->size_mask];
|
||||
memcpy(&hash, &entry->oid, sizeof(hash));
|
||||
|
||||
/* increase the refcount on this object, because
|
||||
* the cache now owns it */
|
||||
git_cached_obj_incref(entry);
|
||||
git_mutex_lock(&node->lock);
|
||||
|
||||
if (node->ptr == NULL) {
|
||||
node->ptr = entry;
|
||||
} else if (git_cached_obj_compare(node->ptr, oid) == 0) {
|
||||
git_cached_obj_decref(entry, cache->free_obj);
|
||||
entry = node->ptr;
|
||||
} else {
|
||||
git_cached_obj_decref(node->ptr, cache->free_obj);
|
||||
node->ptr = entry;
|
||||
git_mutex_lock(&cache->lock);
|
||||
{
|
||||
git_cached_obj *node = cache->nodes[hash & cache->size_mask];
|
||||
|
||||
if (node == NULL) {
|
||||
cache->nodes[hash & cache->size_mask] = entry;
|
||||
} else if (git_oid_cmp(&node->oid, &entry->oid) == 0) {
|
||||
git_cached_obj_decref(entry, cache->free_obj);
|
||||
entry = node;
|
||||
} else {
|
||||
git_cached_obj_decref(node, cache->free_obj);
|
||||
cache->nodes[hash & cache->size_mask] = entry;
|
||||
}
|
||||
}
|
||||
git_mutex_unlock(&cache->lock);
|
||||
|
||||
/* increase the refcount again, because we are
|
||||
* returning it to the user */
|
||||
git_cached_obj_incref(entry);
|
||||
git_mutex_unlock(&node->lock);
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
28
src/cache.h
28
src/cache.h
@ -1,3 +1,9 @@
|
||||
/*
|
||||
* 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_cache_h__
|
||||
#define INCLUDE_cache_h__
|
||||
|
||||
@ -17,42 +23,32 @@ typedef struct {
|
||||
} git_cached_obj;
|
||||
|
||||
typedef struct {
|
||||
git_cached_obj *ptr;
|
||||
git_cached_obj **nodes;
|
||||
git_mutex lock;
|
||||
} cache_node;
|
||||
|
||||
typedef struct {
|
||||
cache_node *nodes;
|
||||
|
||||
unsigned int lru_count;
|
||||
size_t size_mask;
|
||||
git_cached_obj_freeptr free_obj;
|
||||
} git_cache;
|
||||
|
||||
|
||||
int git_cache_init(git_cache *cache, size_t size, git_cached_obj_freeptr free_ptr);
|
||||
void git_cache_free(git_cache *cache);
|
||||
|
||||
void *git_cache_try_store(git_cache *cache, void *entry);
|
||||
void *git_cache_get(git_cache *cache, const git_oid *oid);
|
||||
|
||||
|
||||
GIT_INLINE(int) git_cached_obj_compare(git_cached_obj *obj, const git_oid *oid)
|
||||
{
|
||||
return git_oid_cmp(&obj->oid, oid);
|
||||
}
|
||||
|
||||
GIT_INLINE(void) git_cached_obj_incref(git_cached_obj *obj)
|
||||
GIT_INLINE(void) git_cached_obj_incref(void *_obj)
|
||||
{
|
||||
git_cached_obj *obj = _obj;
|
||||
git_atomic_inc(&obj->refcount);
|
||||
}
|
||||
|
||||
GIT_INLINE(void) git_cached_obj_decref(git_cached_obj *obj, git_cached_obj_freeptr free_obj)
|
||||
GIT_INLINE(void) git_cached_obj_decref(void *_obj, git_cached_obj_freeptr free_obj)
|
||||
{
|
||||
git_cached_obj *obj = _obj;
|
||||
|
||||
if (git_atomic_dec(&obj->refcount) == 0)
|
||||
free_obj(obj);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,8 @@
|
||||
/*
|
||||
* cc-compat.h - C compiler compat macros for internal use
|
||||
* 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_compat_h__
|
||||
#define INCLUDE_compat_h__
|
||||
@ -8,66 +11,59 @@
|
||||
* See if our compiler is known to support flexible array members.
|
||||
*/
|
||||
#ifndef GIT_FLEX_ARRAY
|
||||
# if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
|
||||
# define GIT_FLEX_ARRAY /* empty */
|
||||
# elif defined(__GNUC__)
|
||||
# if (__GNUC__ >= 3)
|
||||
# define GIT_FLEX_ARRAY /* empty */
|
||||
# else
|
||||
# define GIT_FLEX_ARRAY 0 /* older GNU extension */
|
||||
# endif
|
||||
# endif
|
||||
# if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
|
||||
# define GIT_FLEX_ARRAY /* empty */
|
||||
# elif defined(__GNUC__)
|
||||
# if (__GNUC__ >= 3)
|
||||
# define GIT_FLEX_ARRAY /* empty */
|
||||
# else
|
||||
# define GIT_FLEX_ARRAY 0 /* older GNU extension */
|
||||
# endif
|
||||
# endif
|
||||
|
||||
/* Default to safer but a bit wasteful traditional style */
|
||||
# ifndef GIT_FLEX_ARRAY
|
||||
# define GIT_FLEX_ARRAY 1
|
||||
# endif
|
||||
# ifndef GIT_FLEX_ARRAY
|
||||
# define GIT_FLEX_ARRAY 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
# define GIT_TYPEOF(x) (__typeof__(x))
|
||||
# define GIT_TYPEOF(x) (__typeof__(x))
|
||||
#else
|
||||
# define GIT_TYPEOF(x)
|
||||
# define GIT_TYPEOF(x)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
# define GIT_UNUSED(x)
|
||||
#else
|
||||
# ifdef __GNUC__
|
||||
# define GIT_UNUSED(x) x __attribute__ ((__unused__))
|
||||
# else
|
||||
# define GIT_UNUSED(x) x
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define GIT_UNUSED_ARG(x) ((void)(x)); /* note trailing ; */
|
||||
#else
|
||||
#define GIT_UNUSED_ARG(x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Does our compiler/platform support the C99 <inttypes.h> and
|
||||
* <stdint.h> header files. (C99 requires that <inttypes.h>
|
||||
* includes <stdint.h>).
|
||||
*/
|
||||
#if !defined(_MSC_VER)
|
||||
# define GIT_HAVE_INTTYPES_H 1
|
||||
#endif
|
||||
#define GIT_UNUSED(x) ((void)(x))
|
||||
|
||||
/* Define the printf format specifer to use for size_t output */
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
# define PRIuZ "Iu"
|
||||
# define PRIuZ "Iu"
|
||||
#else
|
||||
# define PRIuZ "zu"
|
||||
# define PRIuZ "zu"
|
||||
#endif
|
||||
|
||||
/* Micosoft Visual C/C++ */
|
||||
#if defined(_MSC_VER)
|
||||
/* disable "deprecated function" warnings */
|
||||
# pragma warning ( disable : 4996 )
|
||||
# pragma warning ( disable : 4996 )
|
||||
/* disable "conditional expression is constant" level 4 warnings */
|
||||
# pragma warning ( disable : 4127 )
|
||||
# pragma warning ( disable : 4127 )
|
||||
#endif
|
||||
|
||||
#if defined (_MSC_VER)
|
||||
typedef unsigned char bool;
|
||||
# define true 1
|
||||
# define false 0
|
||||
#else
|
||||
# include <stdbool.h>
|
||||
#endif
|
||||
|
||||
#ifndef va_copy
|
||||
# ifdef __va_copy
|
||||
# define va_copy(dst, src) __va_copy(dst, src)
|
||||
# else
|
||||
# define va_copy(dst, src) ((dst) = (src))
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* INCLUDE_compat_h__ */
|
||||
|
365
src/commit.c
365
src/commit.c
@ -1,26 +1,8 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* 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.
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
|
||||
#include "git2/common.h"
|
||||
@ -32,25 +14,17 @@
|
||||
#include "odb.h"
|
||||
#include "commit.h"
|
||||
#include "signature.h"
|
||||
#include "message.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
#define COMMIT_BASIC_PARSE 0x0
|
||||
#define COMMIT_FULL_PARSE 0x1
|
||||
|
||||
#define COMMIT_PRINT(commit) {\
|
||||
char oid[41]; oid[40] = 0;\
|
||||
git_oid_fmt(oid, &commit->object.id);\
|
||||
printf("Oid: %s | In degree: %d | Time: %u\n", oid, commit->in_degree, commit->commit_time);\
|
||||
}
|
||||
|
||||
static void clear_parents(git_commit *commit)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < commit->parent_oids.length; ++i) {
|
||||
git_oid *parent = git_vector_get(&commit->parent_oids, i);
|
||||
free(parent);
|
||||
git__free(parent);
|
||||
}
|
||||
|
||||
git_vector_clear(&commit->parent_oids);
|
||||
@ -64,9 +38,9 @@ void git_commit__free(git_commit *commit)
|
||||
git_signature_free(commit->author);
|
||||
git_signature_free(commit->committer);
|
||||
|
||||
free(commit->message);
|
||||
free(commit->message_short);
|
||||
free(commit);
|
||||
git__free(commit->message);
|
||||
git__free(commit->message_encoding);
|
||||
git__free(commit);
|
||||
}
|
||||
|
||||
const git_oid *git_commit_id(git_commit *c)
|
||||
@ -74,97 +48,97 @@ const git_oid *git_commit_id(git_commit *c)
|
||||
return git_object_id((git_object *)c);
|
||||
}
|
||||
|
||||
|
||||
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,
|
||||
const git_oid *tree_oid,
|
||||
int parent_count,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
int i, error;
|
||||
const git_oid **oids;
|
||||
|
||||
oids = git__malloc(parent_count * sizeof(git_oid *));
|
||||
|
||||
va_start(ap, parent_count);
|
||||
for (i = 0; i < parent_count; ++i)
|
||||
oids[i] = va_arg(ap, const git_oid *);
|
||||
va_end(ap);
|
||||
|
||||
error = git_commit_create(
|
||||
oid, repo, update_ref, author, committer, message,
|
||||
tree_oid, parent_count, oids);
|
||||
|
||||
free((void *)oids);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
int git_commit_create_ov(
|
||||
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,
|
||||
...)
|
||||
{
|
||||
va_list ap;
|
||||
int i, error;
|
||||
const git_oid **oids;
|
||||
int i, res;
|
||||
const git_commit **parents;
|
||||
|
||||
oids = git__malloc(parent_count * sizeof(git_oid *));
|
||||
parents = git__malloc(parent_count * sizeof(git_commit *));
|
||||
GITERR_CHECK_ALLOC(parents);
|
||||
|
||||
va_start(ap, parent_count);
|
||||
for (i = 0; i < parent_count; ++i)
|
||||
oids[i] = git_object_id(va_arg(ap, const git_object *));
|
||||
parents[i] = va_arg(ap, const git_commit *);
|
||||
va_end(ap);
|
||||
|
||||
error = git_commit_create(
|
||||
oid, repo, update_ref, author, committer, message,
|
||||
git_object_id((git_object *)tree),
|
||||
parent_count, oids);
|
||||
res = git_commit_create(
|
||||
oid, repo, update_ref, author, committer,
|
||||
message_encoding, message,
|
||||
tree, parent_count, parents);
|
||||
|
||||
free((void *)oids);
|
||||
|
||||
return error;
|
||||
git__free((void *)parents);
|
||||
return res;
|
||||
}
|
||||
|
||||
int git_commit_create_o(
|
||||
git_oid *oid,
|
||||
git_repository *repo,
|
||||
const char *update_ref,
|
||||
const git_signature *author,
|
||||
const git_signature *committer,
|
||||
const char *message,
|
||||
const git_tree *tree,
|
||||
int parent_count,
|
||||
const git_commit *parents[])
|
||||
/* Update the reference named `ref_name` so it points to `oid` */
|
||||
static int update_reference(git_repository *repo, git_oid *oid, const char *ref_name)
|
||||
{
|
||||
int i, error;
|
||||
const git_oid **oids;
|
||||
git_reference *ref;
|
||||
int res;
|
||||
|
||||
oids = git__malloc(parent_count * sizeof(git_oid *));
|
||||
res = git_reference_lookup(&ref, repo, ref_name);
|
||||
|
||||
for (i = 0; i < parent_count; ++i)
|
||||
oids[i] = git_object_id((git_object *)parents[i]);
|
||||
/* If we haven't found the reference at all, we assume we need to create
|
||||
* a new reference and that's it */
|
||||
if (res == GIT_ENOTFOUND) {
|
||||
giterr_clear();
|
||||
return git_reference_create_oid(NULL, repo, ref_name, oid, 1);
|
||||
}
|
||||
|
||||
error = git_commit_create(
|
||||
oid, repo, update_ref, author, committer, message,
|
||||
git_object_id((git_object *)tree),
|
||||
parent_count, oids);
|
||||
|
||||
free((void *)oids);
|
||||
if (res < 0)
|
||||
return -1;
|
||||
|
||||
return error;
|
||||
/* If we have found a reference, but it's symbolic, we need to update
|
||||
* the direct reference it points to */
|
||||
if (git_reference_type(ref) == GIT_REF_SYMBOLIC) {
|
||||
git_reference *aux;
|
||||
const char *sym_target;
|
||||
|
||||
/* The target pointed at by this reference */
|
||||
sym_target = git_reference_target(ref);
|
||||
|
||||
/* resolve the reference to the target it points to */
|
||||
res = git_reference_resolve(&aux, ref);
|
||||
|
||||
/*
|
||||
* if the symbolic reference pointed to an inexisting ref,
|
||||
* this is means we're creating a new branch, for example.
|
||||
* We need to create a new direct reference with that name
|
||||
*/
|
||||
if (res == GIT_ENOTFOUND) {
|
||||
giterr_clear();
|
||||
res = git_reference_create_oid(NULL, repo, sym_target, oid, 1);
|
||||
git_reference_free(ref);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* free the original symbolic reference now; not before because
|
||||
* we're using the `sym_target` pointer */
|
||||
git_reference_free(ref);
|
||||
|
||||
if (res < 0)
|
||||
return -1;
|
||||
|
||||
/* store the newly found direct reference in its place */
|
||||
ref = aux;
|
||||
}
|
||||
|
||||
/* ref is made to point to `oid`: ref is either the original reference,
|
||||
* or the target of the symbolic reference we've looked up */
|
||||
res = git_reference_set_oid(ref, oid);
|
||||
git_reference_free(ref);
|
||||
return res;
|
||||
}
|
||||
|
||||
int git_commit_create(
|
||||
@ -173,150 +147,137 @@ int git_commit_create(
|
||||
const char *update_ref,
|
||||
const git_signature *author,
|
||||
const git_signature *committer,
|
||||
const char *message_encoding,
|
||||
const char *message,
|
||||
const git_oid *tree_oid,
|
||||
const git_tree *tree,
|
||||
int parent_count,
|
||||
const git_oid *parents[])
|
||||
const git_commit *parents[])
|
||||
{
|
||||
size_t final_size = 0;
|
||||
int message_length, author_length, committer_length;
|
||||
git_buf commit = GIT_BUF_INIT, cleaned_message = GIT_BUF_INIT;
|
||||
int i;
|
||||
git_odb *odb;
|
||||
|
||||
char *author_str, *committer_str;
|
||||
assert(git_object_owner((const git_object *)tree) == repo);
|
||||
|
||||
int error, i;
|
||||
git_odb_stream *stream;
|
||||
git_oid__writebuf(&commit, "tree ", git_object_id((const git_object *)tree));
|
||||
|
||||
message_length = strlen(message);
|
||||
author_length = git_signature__write(&author_str, "author", author);
|
||||
committer_length = git_signature__write(&committer_str, "committer", committer);
|
||||
|
||||
if (author_length < 0 || committer_length < 0)
|
||||
return git__throw(GIT_EINVALIDARGS, "Cannot create commit. Failed to parse signature");
|
||||
|
||||
final_size += GIT_OID_LINE_LENGTH("tree");
|
||||
final_size += GIT_OID_LINE_LENGTH("parent") * parent_count;
|
||||
final_size += author_length;
|
||||
final_size += committer_length;
|
||||
final_size += 1 + message_length;
|
||||
|
||||
if ((error = git_odb_open_wstream(&stream, repo->db, final_size, GIT_OBJ_COMMIT)) < GIT_SUCCESS)
|
||||
return git__rethrow(error, "Failed to create commit");
|
||||
|
||||
git__write_oid(stream, "tree", tree_oid);
|
||||
|
||||
for (i = 0; i < parent_count; ++i)
|
||||
git__write_oid(stream, "parent", parents[i]);
|
||||
|
||||
stream->write(stream, author_str, author_length);
|
||||
free(author_str);
|
||||
|
||||
stream->write(stream, committer_str, committer_length);
|
||||
free(committer_str);
|
||||
|
||||
|
||||
stream->write(stream, "\n", 1);
|
||||
stream->write(stream, message, message_length);
|
||||
|
||||
error = stream->finalize_write(oid, stream);
|
||||
stream->free(stream);
|
||||
|
||||
if (error == GIT_SUCCESS && update_ref != NULL) {
|
||||
git_reference *head;
|
||||
|
||||
error = git_reference_lookup(&head, repo, update_ref);
|
||||
if (error < GIT_SUCCESS)
|
||||
return git__rethrow(error, "Failed to create commit");
|
||||
|
||||
error = git_reference_resolve(&head, head);
|
||||
if (error < GIT_SUCCESS) {
|
||||
if (error != GIT_ENOTFOUND)
|
||||
return git__rethrow(error, "Failed to create commit");
|
||||
/*
|
||||
* The target of the reference was not found. This can happen
|
||||
* just after a repository has been initialized (the master
|
||||
* branch doesn't exist yet, as it doesn't have anything to
|
||||
* point to) or after an orphan checkout, so if the target
|
||||
* branch doesn't exist yet, create it and return.
|
||||
*/
|
||||
return git_reference_create_oid_f(&head, repo, git_reference_target(head), oid);
|
||||
}
|
||||
|
||||
error = git_reference_set_oid(head, oid);
|
||||
for (i = 0; i < parent_count; ++i) {
|
||||
assert(git_object_owner((const git_object *)parents[i]) == repo);
|
||||
git_oid__writebuf(&commit, "parent ", git_object_id((const git_object *)parents[i]));
|
||||
}
|
||||
|
||||
if (error < GIT_SUCCESS)
|
||||
return git__rethrow(error, "Failed to create commit");
|
||||
git_signature__writebuf(&commit, "author ", author);
|
||||
git_signature__writebuf(&commit, "committer ", committer);
|
||||
|
||||
return GIT_SUCCESS;
|
||||
if (message_encoding != NULL)
|
||||
git_buf_printf(&commit, "encoding %s\n", message_encoding);
|
||||
|
||||
git_buf_putc(&commit, '\n');
|
||||
|
||||
/* Remove comments by default */
|
||||
if (git_message_prettify(&cleaned_message, message, 1) < 0)
|
||||
goto on_error;
|
||||
|
||||
if (git_buf_puts(&commit, git_buf_cstr(&cleaned_message)) < 0)
|
||||
goto on_error;
|
||||
|
||||
git_buf_free(&cleaned_message);
|
||||
|
||||
if (git_repository_odb__weakptr(&odb, repo) < 0)
|
||||
goto on_error;
|
||||
|
||||
if (git_odb_write(oid, odb, commit.ptr, commit.size, GIT_OBJ_COMMIT) < 0)
|
||||
goto on_error;
|
||||
|
||||
git_buf_free(&commit);
|
||||
|
||||
if (update_ref != NULL)
|
||||
return update_reference(repo, oid, update_ref);
|
||||
|
||||
return 0;
|
||||
|
||||
on_error:
|
||||
git_buf_free(&commit);
|
||||
git_buf_free(&cleaned_message);
|
||||
giterr_set(GITERR_OBJECT, "Failed to create commit.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int commit_parse_buffer(git_commit *commit, const void *data, size_t len)
|
||||
int git_commit__parse_buffer(git_commit *commit, const void *data, size_t len)
|
||||
{
|
||||
const char *buffer = (char *)data;
|
||||
const char *buffer_end = (char *)data + len;
|
||||
const char *buffer = data;
|
||||
const char *buffer_end = (const char *)data + len;
|
||||
|
||||
git_oid parent_oid;
|
||||
int error;
|
||||
|
||||
git_vector_init(&commit->parent_oids, 4, NULL);
|
||||
|
||||
if ((error = git__parse_oid(&commit->tree_oid, &buffer, buffer_end, "tree ")) < GIT_SUCCESS)
|
||||
return git__rethrow(error, "Failed to parse buffer");
|
||||
if (git_oid__parse(&commit->tree_oid, &buffer, buffer_end, "tree ") < 0)
|
||||
goto bad_buffer;
|
||||
|
||||
/*
|
||||
* TODO: commit grafts!
|
||||
*/
|
||||
|
||||
while (git__parse_oid(&parent_oid, &buffer, buffer_end, "parent ") == GIT_SUCCESS) {
|
||||
while (git_oid__parse(&parent_oid, &buffer, buffer_end, "parent ") == 0) {
|
||||
git_oid *new_oid;
|
||||
|
||||
new_oid = git__malloc(sizeof(git_oid));
|
||||
GITERR_CHECK_ALLOC(new_oid);
|
||||
|
||||
git_oid_cpy(new_oid, &parent_oid);
|
||||
|
||||
if (git_vector_insert(&commit->parent_oids, new_oid) < GIT_SUCCESS)
|
||||
return GIT_ENOMEM;
|
||||
if (git_vector_insert(&commit->parent_oids, new_oid) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
commit->author = git__malloc(sizeof(git_signature));
|
||||
if ((error = git_signature__parse(commit->author, &buffer, buffer_end, "author ")) < GIT_SUCCESS)
|
||||
return git__rethrow(error, "Failed to parse buffer");
|
||||
GITERR_CHECK_ALLOC(commit->author);
|
||||
|
||||
if (git_signature__parse(commit->author, &buffer, buffer_end, "author ", '\n') < 0)
|
||||
return -1;
|
||||
|
||||
/* Always parse the committer; we need the commit time */
|
||||
commit->committer = git__malloc(sizeof(git_signature));
|
||||
if ((error = git_signature__parse(commit->committer, &buffer, buffer_end, "committer ")) < GIT_SUCCESS)
|
||||
return git__rethrow(error, "Failed to parse buffer");
|
||||
GITERR_CHECK_ALLOC(commit->committer);
|
||||
|
||||
/* parse commit message */
|
||||
while (buffer <= buffer_end && *buffer == '\n')
|
||||
buffer++;
|
||||
if (git_signature__parse(commit->committer, &buffer, buffer_end, "committer ", '\n') < 0)
|
||||
return -1;
|
||||
|
||||
if (buffer < buffer_end) {
|
||||
const char *line_end;
|
||||
size_t message_len;
|
||||
if (git__prefixcmp(buffer, "encoding ") == 0) {
|
||||
const char *encoding_end;
|
||||
buffer += strlen("encoding ");
|
||||
|
||||
/* Long message */
|
||||
message_len = buffer_end - buffer;
|
||||
commit->message = git__malloc(message_len + 1);
|
||||
memcpy(commit->message, buffer, message_len);
|
||||
commit->message[message_len] = 0;
|
||||
encoding_end = buffer;
|
||||
while (encoding_end < buffer_end && *encoding_end != '\n')
|
||||
encoding_end++;
|
||||
|
||||
/* Short message */
|
||||
if((line_end = memchr(buffer, '\n', buffer_end - buffer)) == NULL)
|
||||
line_end = buffer_end;
|
||||
message_len = line_end - buffer;
|
||||
commit->message_encoding = git__strndup(buffer, encoding_end - buffer);
|
||||
GITERR_CHECK_ALLOC(commit->message_encoding);
|
||||
|
||||
commit->message_short = git__malloc(message_len + 1);
|
||||
memcpy(commit->message_short, buffer, message_len);
|
||||
commit->message_short[message_len] = 0;
|
||||
buffer = encoding_end;
|
||||
}
|
||||
|
||||
return GIT_SUCCESS;
|
||||
/* parse commit message */
|
||||
while (buffer < buffer_end - 1 && *buffer == '\n')
|
||||
buffer++;
|
||||
|
||||
if (buffer <= buffer_end) {
|
||||
commit->message = git__strndup(buffer, buffer_end - buffer);
|
||||
GITERR_CHECK_ALLOC(commit->message);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
bad_buffer:
|
||||
giterr_set(GITERR_OBJECT, "Failed to parse bad commit object");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int git_commit__parse(git_commit *commit, git_odb_object *obj)
|
||||
{
|
||||
assert(commit);
|
||||
return commit_parse_buffer(commit, obj->raw.data, obj->raw.len);
|
||||
return git_commit__parse_buffer(commit, obj->raw.data, obj->raw.len);
|
||||
}
|
||||
|
||||
#define GIT_COMMIT_GETTER(_rvalue, _name, _return) \
|
||||
@ -329,7 +290,7 @@ int git_commit__parse(git_commit *commit, git_odb_object *obj)
|
||||
GIT_COMMIT_GETTER(const git_signature *, author, commit->author)
|
||||
GIT_COMMIT_GETTER(const git_signature *, committer, commit->committer)
|
||||
GIT_COMMIT_GETTER(const char *, message, commit->message)
|
||||
GIT_COMMIT_GETTER(const char *, message_short, commit->message_short)
|
||||
GIT_COMMIT_GETTER(const char *, message_encoding, commit->message_encoding)
|
||||
GIT_COMMIT_GETTER(git_time_t, time, commit->committer->when.time)
|
||||
GIT_COMMIT_GETTER(int, time_offset, commit->committer->when.offset)
|
||||
GIT_COMMIT_GETTER(unsigned int, parentcount, commit->parent_oids.length)
|
||||
@ -348,8 +309,10 @@ int git_commit_parent(git_commit **parent, git_commit *commit, unsigned int n)
|
||||
assert(commit);
|
||||
|
||||
parent_oid = git_vector_get(&commit->parent_oids, n);
|
||||
if (parent_oid == NULL)
|
||||
return git__throw(GIT_ENOTFOUND, "Parent %u does not exist", n);
|
||||
if (parent_oid == NULL) {
|
||||
giterr_set(GITERR_INVALID, "Parent %u does not exist", n);
|
||||
return GIT_ENOTFOUND;
|
||||
}
|
||||
|
||||
return git_commit_lookup(parent, commit->object.repo, parent_oid);
|
||||
}
|
||||
|
@ -1,3 +1,9 @@
|
||||
/*
|
||||
* 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_commit_h__
|
||||
#define INCLUDE_commit_h__
|
||||
|
||||
@ -17,11 +23,12 @@ struct git_commit {
|
||||
git_signature *author;
|
||||
git_signature *committer;
|
||||
|
||||
char *message_encoding;
|
||||
char *message;
|
||||
char *message_short;
|
||||
};
|
||||
|
||||
void git_commit__free(git_commit *c);
|
||||
int git_commit__parse(git_commit *commit, git_odb_object *obj);
|
||||
|
||||
int git_commit__parse_buffer(git_commit *commit, const void *data, size_t len);
|
||||
#endif
|
||||
|
52
src/common.h
52
src/common.h
@ -1,19 +1,15 @@
|
||||
/*
|
||||
* 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_common_h__
|
||||
#define INCLUDE_common_h__
|
||||
|
||||
/** Force 64 bit off_t size on POSIX. */
|
||||
#define _FILE_OFFSET_BITS 64
|
||||
|
||||
#if defined(_WIN32) && !defined(__CYGWIN__)
|
||||
#define GIT_WIN32 1
|
||||
#endif
|
||||
|
||||
#include "git2/thread-utils.h"
|
||||
#include "git2/common.h"
|
||||
#include "cc-compat.h"
|
||||
|
||||
#ifdef GIT_HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
@ -29,35 +25,47 @@
|
||||
# include <io.h>
|
||||
# include <direct.h>
|
||||
# include <windows.h>
|
||||
# include "msvc-compat.h"
|
||||
# include "mingw-compat.h"
|
||||
# include "win32/msvc-compat.h"
|
||||
# include "win32/mingw-compat.h"
|
||||
# ifdef GIT_THREADS
|
||||
# include "win32/pthread.h"
|
||||
# include "win32/pthread.h"
|
||||
#endif
|
||||
|
||||
# define snprintf _snprintf
|
||||
|
||||
typedef SSIZE_T ssize_t;
|
||||
|
||||
#else
|
||||
# include <unistd.h>
|
||||
# include <arpa/inet.h>
|
||||
|
||||
# ifdef GIT_THREADS
|
||||
# include <pthread.h>
|
||||
# include <pthread.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include "git2/common.h"
|
||||
#include "git2/types.h"
|
||||
#include "git2/errors.h"
|
||||
#include "thread-utils.h"
|
||||
#include "bswap.h"
|
||||
|
||||
#define GIT_PATH_MAX 4096
|
||||
extern int git__throw(int error, const char *, ...) GIT_FORMAT_PRINTF(2, 3);
|
||||
extern int git__rethrow(int error, const char *, ...) GIT_FORMAT_PRINTF(2, 3);
|
||||
#include <regex.h>
|
||||
|
||||
extern void git___throw(const char *, ...) GIT_FORMAT_PRINTF(1, 2);
|
||||
#define git__throw(error, ...) \
|
||||
(git___throw(__VA_ARGS__), error)
|
||||
|
||||
extern void git___rethrow(const char *, ...) GIT_FORMAT_PRINTF(1, 2);
|
||||
#define git__rethrow(error, ...) \
|
||||
(git___rethrow(__VA_ARGS__), error)
|
||||
|
||||
|
||||
#define GITERR_CHECK_ALLOC(ptr) if (ptr == NULL) { return -1; }
|
||||
|
||||
void giterr_set_oom(void);
|
||||
void giterr_set(int error_class, const char *string, ...);
|
||||
void giterr_clear(void);
|
||||
void giterr_set_str(int error_class, const char *string);
|
||||
void giterr_set_regex(const regex_t *regex, int error_code);
|
||||
|
||||
#include "util.h"
|
||||
|
||||
|
||||
#endif /* INCLUDE_common_h__ */
|
||||
|
180
src/compat/fnmatch.c
Normal file
180
src/compat/fnmatch.c
Normal file
@ -0,0 +1,180 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
|
||||
* Compares a filename or pathname to a pattern.
|
||||
*/
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fnmatch.h"
|
||||
|
||||
#define EOS '\0'
|
||||
|
||||
#define RANGE_MATCH 1
|
||||
#define RANGE_NOMATCH 0
|
||||
#define RANGE_ERROR (-1)
|
||||
|
||||
static int rangematch(const char *, char, int, char **);
|
||||
|
||||
int
|
||||
p_fnmatch(const char *pattern, const char *string, int flags)
|
||||
{
|
||||
const char *stringstart;
|
||||
char *newp;
|
||||
char c, test;
|
||||
|
||||
for (stringstart = string;;)
|
||||
switch (c = *pattern++) {
|
||||
case EOS:
|
||||
if ((flags & FNM_LEADING_DIR) && *string == '/')
|
||||
return (0);
|
||||
return (*string == EOS ? 0 : FNM_NOMATCH);
|
||||
case '?':
|
||||
if (*string == EOS)
|
||||
return (FNM_NOMATCH);
|
||||
if (*string == '/' && (flags & FNM_PATHNAME))
|
||||
return (FNM_NOMATCH);
|
||||
if (*string == '.' && (flags & FNM_PERIOD) &&
|
||||
(string == stringstart ||
|
||||
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
|
||||
return (FNM_NOMATCH);
|
||||
++string;
|
||||
break;
|
||||
case '*':
|
||||
c = *pattern;
|
||||
/* Collapse multiple stars. */
|
||||
while (c == '*')
|
||||
c = *++pattern;
|
||||
|
||||
if (*string == '.' && (flags & FNM_PERIOD) &&
|
||||
(string == stringstart ||
|
||||
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
|
||||
return (FNM_NOMATCH);
|
||||
|
||||
/* Optimize for pattern with * at end or before /. */
|
||||
if (c == EOS) {
|
||||
if (flags & FNM_PATHNAME)
|
||||
return ((flags & FNM_LEADING_DIR) ||
|
||||
strchr(string, '/') == NULL ?
|
||||
0 : FNM_NOMATCH);
|
||||
else
|
||||
return (0);
|
||||
} else if (c == '/' && (flags & FNM_PATHNAME)) {
|
||||
if ((string = strchr(string, '/')) == NULL)
|
||||
return (FNM_NOMATCH);
|
||||
break;
|
||||
}
|
||||
|
||||
/* General case, use recursion. */
|
||||
while ((test = *string) != EOS) {
|
||||
if (!p_fnmatch(pattern, string, flags & ~FNM_PERIOD))
|
||||
return (0);
|
||||
if (test == '/' && (flags & FNM_PATHNAME))
|
||||
break;
|
||||
++string;
|
||||
}
|
||||
return (FNM_NOMATCH);
|
||||
case '[':
|
||||
if (*string == EOS)
|
||||
return (FNM_NOMATCH);
|
||||
if (*string == '/' && (flags & FNM_PATHNAME))
|
||||
return (FNM_NOMATCH);
|
||||
if (*string == '.' && (flags & FNM_PERIOD) &&
|
||||
(string == stringstart ||
|
||||
((flags & FNM_PATHNAME) && *(string - 1) == '/')))
|
||||
return (FNM_NOMATCH);
|
||||
|
||||
switch (rangematch(pattern, *string, flags, &newp)) {
|
||||
case RANGE_ERROR:
|
||||
/* not a good range, treat as normal text */
|
||||
goto normal;
|
||||
case RANGE_MATCH:
|
||||
pattern = newp;
|
||||
break;
|
||||
case RANGE_NOMATCH:
|
||||
return (FNM_NOMATCH);
|
||||
}
|
||||
++string;
|
||||
break;
|
||||
case '\\':
|
||||
if (!(flags & FNM_NOESCAPE)) {
|
||||
if ((c = *pattern++) == EOS) {
|
||||
c = '\\';
|
||||
--pattern;
|
||||
}
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
normal:
|
||||
if (c != *string && !((flags & FNM_CASEFOLD) &&
|
||||
(tolower((unsigned char)c) ==
|
||||
tolower((unsigned char)*string))))
|
||||
return (FNM_NOMATCH);
|
||||
++string;
|
||||
break;
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static int
|
||||
rangematch(const char *pattern, char test, int flags, char **newp)
|
||||
{
|
||||
int negate, ok;
|
||||
char c, c2;
|
||||
|
||||
/*
|
||||
* A bracket expression starting with an unquoted circumflex
|
||||
* character produces unspecified results (IEEE 1003.2-1992,
|
||||
* 3.13.2). This implementation treats it like '!', for
|
||||
* consistency with the regular expression syntax.
|
||||
* J.T. Conklin (conklin@ngai.kaleida.com)
|
||||
*/
|
||||
if ((negate = (*pattern == '!' || *pattern == '^')) != 0)
|
||||
++pattern;
|
||||
|
||||
if (flags & FNM_CASEFOLD)
|
||||
test = (char)tolower((unsigned char)test);
|
||||
|
||||
/*
|
||||
* A right bracket shall lose its special meaning and represent
|
||||
* itself in a bracket expression if it occurs first in the list.
|
||||
* -- POSIX.2 2.8.3.2
|
||||
*/
|
||||
ok = 0;
|
||||
c = *pattern++;
|
||||
do {
|
||||
if (c == '\\' && !(flags & FNM_NOESCAPE))
|
||||
c = *pattern++;
|
||||
if (c == EOS)
|
||||
return (RANGE_ERROR);
|
||||
if (c == '/' && (flags & FNM_PATHNAME))
|
||||
return (RANGE_NOMATCH);
|
||||
if ((flags & FNM_CASEFOLD))
|
||||
c = (char)tolower((unsigned char)c);
|
||||
if (*pattern == '-'
|
||||
&& (c2 = *(pattern+1)) != EOS && c2 != ']') {
|
||||
pattern += 2;
|
||||
if (c2 == '\\' && !(flags & FNM_NOESCAPE))
|
||||
c2 = *pattern++;
|
||||
if (c2 == EOS)
|
||||
return (RANGE_ERROR);
|
||||
if (flags & FNM_CASEFOLD)
|
||||
c2 = (char)tolower((unsigned char)c2);
|
||||
if (c <= test && test <= c2)
|
||||
ok = 1;
|
||||
} else if (c == test)
|
||||
ok = 1;
|
||||
} while ((c = *pattern++) != ']');
|
||||
|
||||
*newp = (char *)pattern;
|
||||
return (ok == negate ? RANGE_NOMATCH : RANGE_MATCH);
|
||||
}
|
||||
|
27
src/compat/fnmatch.h
Normal file
27
src/compat/fnmatch.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* 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_fnmatch__compat_h__
|
||||
#define INCLUDE_fnmatch__compat_h__
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define FNM_NOMATCH 1 /* Match failed. */
|
||||
#define FNM_NOSYS 2 /* Function not supported (unused). */
|
||||
|
||||
#define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */
|
||||
#define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */
|
||||
#define FNM_PERIOD 0x04 /* Period must be matched by period. */
|
||||
#define FNM_LEADING_DIR 0x08 /* Ignore /<tail> after Imatch. */
|
||||
#define FNM_CASEFOLD 0x10 /* Case insensitive search. */
|
||||
|
||||
#define FNM_IGNORECASE FNM_CASEFOLD
|
||||
#define FNM_FILE_NAME FNM_PATHNAME
|
||||
|
||||
extern int p_fnmatch(const char *pattern, const char *string, int flags);
|
||||
|
||||
#endif /* _FNMATCH_H */
|
||||
|
537
src/config.c
537
src/config.c
@ -1,34 +1,18 @@
|
||||
/*
|
||||
* 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.
|
||||
* Copyright (C) 2009-2012 the libgit2 contributors
|
||||
*
|
||||
* 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.
|
||||
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||
* a Linking Exception. For full terms see the included COPYING file.
|
||||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "fileops.h"
|
||||
#include "hashtable.h"
|
||||
#include "config.h"
|
||||
#include "git2/config.h"
|
||||
#include "vector.h"
|
||||
#if GIT_WIN32
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
@ -37,55 +21,7 @@ typedef struct {
|
||||
int priority;
|
||||
} file_internal;
|
||||
|
||||
int git_config_open_file(git_config **out, const char *path)
|
||||
{
|
||||
git_config_file *file = NULL;
|
||||
git_config *cfg = NULL;
|
||||
int error = GIT_SUCCESS;
|
||||
|
||||
error = git_config_new(&cfg);
|
||||
if (error < GIT_SUCCESS)
|
||||
return error;
|
||||
|
||||
error = git_config_file__ondisk(&file, path);
|
||||
if (error < GIT_SUCCESS) {
|
||||
git_config_free(cfg);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = git_config_add_file(cfg, file, 1);
|
||||
if (error < GIT_SUCCESS) {
|
||||
file->free(file);
|
||||
git_config_free(cfg);
|
||||
return error;
|
||||
}
|
||||
|
||||
error = file->open(file);
|
||||
if (error < GIT_SUCCESS) {
|
||||
git_config_free(cfg);
|
||||
return git__rethrow(error, "Failed to open config file");
|
||||
}
|
||||
|
||||
*out = cfg;
|
||||
|
||||
return GIT_SUCCESS;
|
||||
}
|
||||
|
||||
int git_config_open_global(git_config **out)
|
||||
{
|
||||
char full_path[GIT_PATH_MAX];
|
||||
const char *home;
|
||||
|
||||
home = getenv("HOME");
|
||||
if (home == NULL)
|
||||
return git__throw(GIT_EOSERR, "Failed to open global config file. Cannot find $HOME variable");
|
||||
|
||||
git__joinpath(full_path, home, GIT_CONFIG_FILENAME);
|
||||
|
||||
return git_config_open_file(out, full_path);
|
||||
}
|
||||
|
||||
void git_config_free(git_config *cfg)
|
||||
static void config_free(git_config *cfg)
|
||||
{
|
||||
unsigned int i;
|
||||
git_config_file *file;
|
||||
@ -95,17 +31,25 @@ void git_config_free(git_config *cfg)
|
||||
internal = git_vector_get(&cfg->files, i);
|
||||
file = internal->file;
|
||||
file->free(file);
|
||||
free(internal);
|
||||
git__free(internal);
|
||||
}
|
||||
|
||||
git_vector_free(&cfg->files);
|
||||
free(cfg);
|
||||
git__free(cfg);
|
||||
}
|
||||
|
||||
void git_config_free(git_config *cfg)
|
||||
{
|
||||
if (cfg == NULL)
|
||||
return;
|
||||
|
||||
GIT_REFCOUNT_DEC(cfg, config_free);
|
||||
}
|
||||
|
||||
static int config_backend_cmp(const void *a, const void *b)
|
||||
{
|
||||
const file_internal *bk_a = *(const file_internal **)(a);
|
||||
const file_internal *bk_b = *(const file_internal **)(b);
|
||||
const file_internal *bk_a = (const file_internal *)(a);
|
||||
const file_internal *bk_b = (const file_internal *)(b);
|
||||
|
||||
return bk_b->priority - bk_a->priority;
|
||||
}
|
||||
@ -115,52 +59,86 @@ int git_config_new(git_config **out)
|
||||
git_config *cfg;
|
||||
|
||||
cfg = git__malloc(sizeof(git_config));
|
||||
if (cfg == NULL)
|
||||
return GIT_ENOMEM;
|
||||
GITERR_CHECK_ALLOC(cfg);
|
||||
|
||||
memset(cfg, 0x0, sizeof(git_config));
|
||||
|
||||
if (git_vector_init(&cfg->files, 3, config_backend_cmp) < 0) {
|
||||
free(cfg);
|
||||
return GIT_ENOMEM;
|
||||
git__free(cfg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*out = cfg;
|
||||
GIT_REFCOUNT_INC(cfg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return GIT_SUCCESS;
|
||||
int git_config_add_file_ondisk(git_config *cfg, const char *path, int priority)
|
||||
{
|
||||
git_config_file *file = NULL;
|
||||
|
||||
if (git_config_file__ondisk(&file, path) < 0)
|
||||
return -1;
|
||||
|
||||
if (git_config_add_file(cfg, file, priority) < 0) {
|
||||
/*
|
||||
* free manually; the file is not owned by the config
|
||||
* instance yet and will not be freed on cleanup
|
||||
*/
|
||||
file->free(file);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_config_open_ondisk(git_config **cfg, const char *path)
|
||||
{
|
||||
if (git_config_new(cfg) < 0)
|
||||
return -1;
|
||||
|
||||
if (git_config_add_file_ondisk(*cfg, path, 1) < 0) {
|
||||
git_config_free(*cfg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_config_add_file(git_config *cfg, git_config_file *file, int priority)
|
||||
{
|
||||
file_internal *internal;
|
||||
int result;
|
||||
|
||||
assert(cfg && file);
|
||||
|
||||
if ((result = file->open(file)) < 0)
|
||||
return result;
|
||||
|
||||
internal = git__malloc(sizeof(file_internal));
|
||||
if (internal == NULL)
|
||||
return GIT_ENOMEM;
|
||||
GITERR_CHECK_ALLOC(internal);
|
||||
|
||||
internal->file = file;
|
||||
internal->priority = priority;
|
||||
|
||||
if (git_vector_insert(&cfg->files, internal) < 0) {
|
||||
free(internal);
|
||||
return GIT_ENOMEM;
|
||||
git__free(internal);
|
||||
return -1;
|
||||
}
|
||||
|
||||
git_vector_sort(&cfg->files);
|
||||
internal->file->cfg = cfg;
|
||||
|
||||
return GIT_SUCCESS;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Loop over all the variables
|
||||
*/
|
||||
|
||||
int git_config_foreach(git_config *cfg, int (*fn)(const char *, void *), void *data)
|
||||
int git_config_foreach(git_config *cfg, int (*fn)(const char *, const char *, void *), void *data)
|
||||
{
|
||||
int ret = GIT_SUCCESS;
|
||||
int ret = 0;
|
||||
unsigned int i;
|
||||
file_internal *internal;
|
||||
git_config_file *file;
|
||||
@ -174,25 +152,33 @@ int git_config_foreach(git_config *cfg, int (*fn)(const char *, void *), void *d
|
||||
return ret;
|
||||
}
|
||||
|
||||
int git_config_delete(git_config *cfg, const char *name)
|
||||
{
|
||||
file_internal *internal;
|
||||
git_config_file *file;
|
||||
|
||||
assert(cfg->files.length);
|
||||
|
||||
internal = git_vector_get(&cfg->files, 0);
|
||||
file = internal->file;
|
||||
|
||||
return file->del(file, name);
|
||||
}
|
||||
|
||||
/**************
|
||||
* Setters
|
||||
**************/
|
||||
|
||||
/*
|
||||
* Internal function to actually set the string value of a variable
|
||||
*/
|
||||
|
||||
int git_config_set_long(git_config *cfg, const char *name, long int value)
|
||||
int git_config_set_int64(git_config *cfg, const char *name, int64_t value)
|
||||
{
|
||||
char str_value[32]; /* All numbers should fit in here */
|
||||
snprintf(str_value, sizeof(str_value), "%ld", value);
|
||||
p_snprintf(str_value, sizeof(str_value), "%" PRId64, value);
|
||||
return git_config_set_string(cfg, name, str_value);
|
||||
}
|
||||
|
||||
int git_config_set_int(git_config *cfg, const char *name, int value)
|
||||
int git_config_set_int32(git_config *cfg, const char *name, int32_t value)
|
||||
{
|
||||
return git_config_set_long(cfg, name, value);
|
||||
return git_config_set_int64(cfg, name, (int64_t)value);
|
||||
}
|
||||
|
||||
int git_config_set_bool(git_config *cfg, const char *name, int value)
|
||||
@ -205,8 +191,7 @@ int git_config_set_string(git_config *cfg, const char *name, const char *value)
|
||||
file_internal *internal;
|
||||
git_config_file *file;
|
||||
|
||||
if (cfg->files.length == 0)
|
||||
return git__throw(GIT_EINVALIDARGS, "Cannot set variable value; no files open in the `git_config` instance");
|
||||
assert(cfg->files.length);
|
||||
|
||||
internal = git_vector_get(&cfg->files, 0);
|
||||
file = internal->file;
|
||||
@ -214,109 +199,309 @@ int git_config_set_string(git_config *cfg, const char *name, const char *value)
|
||||
return file->set(file, name, value);
|
||||
}
|
||||
|
||||
/***********
|
||||
* Getters
|
||||
***********/
|
||||
|
||||
int git_config_get_long(git_config *cfg, const char *name, long int *out)
|
||||
static int parse_int64(int64_t *out, const char *value)
|
||||
{
|
||||
const char *value, *num_end;
|
||||
int ret;
|
||||
long int num;
|
||||
const char *num_end;
|
||||
int64_t num;
|
||||
|
||||
ret = git_config_get_string(cfg, name, &value);
|
||||
if (ret < GIT_SUCCESS)
|
||||
return git__rethrow(ret, "Failed to get value for %s", name);
|
||||
|
||||
ret = git__strtol32(&num, value, &num_end, 0);
|
||||
if (ret < GIT_SUCCESS)
|
||||
return git__rethrow(ret, "Failed to get value for %s", name);
|
||||
if (git__strtol64(&num, value, &num_end, 0) < 0)
|
||||
return -1;
|
||||
|
||||
switch (*num_end) {
|
||||
case '\0':
|
||||
break;
|
||||
case 'g':
|
||||
case 'G':
|
||||
num *= 1024;
|
||||
/* fallthrough */
|
||||
|
||||
case 'm':
|
||||
case 'M':
|
||||
num *= 1024;
|
||||
/* fallthrough */
|
||||
|
||||
case 'k':
|
||||
case 'K':
|
||||
num *= 1024;
|
||||
break;
|
||||
case 'm':
|
||||
case 'M':
|
||||
num *= 1024 * 1024;
|
||||
break;
|
||||
case 'g':
|
||||
case 'G':
|
||||
num *= 1024 * 1024 * 1024;
|
||||
break;
|
||||
|
||||
/* check that that there are no more characters after the
|
||||
* given modifier suffix */
|
||||
if (num_end[1] != '\0')
|
||||
return -1;
|
||||
|
||||
/* fallthrough */
|
||||
|
||||
case '\0':
|
||||
*out = num;
|
||||
return 0;
|
||||
|
||||
default:
|
||||
return git__throw(GIT_EINVALIDTYPE, "Failed to get value for %s. Value is of invalid type", name);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int parse_int32(int32_t *out, const char *value)
|
||||
{
|
||||
int64_t tmp;
|
||||
int32_t truncate;
|
||||
|
||||
if (parse_int64(&tmp, value) < 0)
|
||||
return -1;
|
||||
|
||||
truncate = tmp & 0xFFFFFFFF;
|
||||
if (truncate != tmp)
|
||||
return -1;
|
||||
|
||||
*out = truncate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/***********
|
||||
* Getters
|
||||
***********/
|
||||
int git_config_lookup_map_value(
|
||||
git_cvar_map *maps, size_t map_n, const char *value, int *out)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
if (!value)
|
||||
return GIT_ENOTFOUND;
|
||||
|
||||
for (i = 0; i < map_n; ++i) {
|
||||
git_cvar_map *m = maps + i;
|
||||
|
||||
switch (m->cvar_type) {
|
||||
case GIT_CVAR_FALSE:
|
||||
case GIT_CVAR_TRUE: {
|
||||
int bool_val;
|
||||
|
||||
if (git__parse_bool(&bool_val, value) == 0 &&
|
||||
bool_val == (int)m->cvar_type) {
|
||||
*out = m->map_value;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case GIT_CVAR_INT32:
|
||||
if (parse_int32(out, value) == 0)
|
||||
return 0;
|
||||
break;
|
||||
|
||||
case GIT_CVAR_STRING:
|
||||
if (strcasecmp(value, m->str_match) == 0) {
|
||||
*out = m->map_value;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*out = num;
|
||||
|
||||
return GIT_SUCCESS;
|
||||
return GIT_ENOTFOUND;
|
||||
}
|
||||
|
||||
int git_config_get_int(git_config *cfg, const char *name, int *out)
|
||||
{
|
||||
long int tmp;
|
||||
int ret;
|
||||
|
||||
ret = git_config_get_long(cfg, name, &tmp);
|
||||
|
||||
*out = (int) tmp;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int git_config_get_bool(git_config *cfg, const char *name, int *out)
|
||||
int git_config_get_mapped(
|
||||
int *out,
|
||||
git_config *cfg,
|
||||
const char *name,
|
||||
git_cvar_map *maps,
|
||||
size_t map_n)
|
||||
{
|
||||
const char *value;
|
||||
int error = GIT_SUCCESS;
|
||||
int ret;
|
||||
|
||||
error = git_config_get_string(cfg, name, &value);
|
||||
if (error < GIT_SUCCESS)
|
||||
return git__rethrow(error, "Failed to get value for %s", name);
|
||||
ret = git_config_get_string(&value, cfg, name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* A missing value means true */
|
||||
if (value == NULL) {
|
||||
*out = 1;
|
||||
return GIT_SUCCESS;
|
||||
}
|
||||
if (!git_config_lookup_map_value(maps, map_n, value, out))
|
||||
return 0;
|
||||
|
||||
if (!strcasecmp(value, "true") ||
|
||||
!strcasecmp(value, "yes") ||
|
||||
!strcasecmp(value, "on")) {
|
||||
*out = 1;
|
||||
return GIT_SUCCESS;
|
||||
}
|
||||
if (!strcasecmp(value, "false") ||
|
||||
!strcasecmp(value, "no") ||
|
||||
!strcasecmp(value, "off")) {
|
||||
*out = 0;
|
||||
return GIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* Try to parse it as an integer */
|
||||
error = git_config_get_int(cfg, name, out);
|
||||
if (error == GIT_SUCCESS)
|
||||
*out = !!(*out);
|
||||
|
||||
if (error < GIT_SUCCESS)
|
||||
return git__rethrow(error, "Failed to get value for %s", name);
|
||||
return error;
|
||||
giterr_set(GITERR_CONFIG,
|
||||
"Failed to map the '%s' config variable with a valid value", name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int git_config_get_string(git_config *cfg, const char *name, const char **out)
|
||||
int git_config_get_int64(int64_t *out, git_config *cfg, const char *name)
|
||||
{
|
||||
const char *value;
|
||||
int ret;
|
||||
|
||||
ret = git_config_get_string(&value, cfg, name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (parse_int64(out, value) < 0) {
|
||||
giterr_set(GITERR_CONFIG, "Failed to parse '%s' as an integer", value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_config_get_int32(int32_t *out, git_config *cfg, const char *name)
|
||||
{
|
||||
const char *value;
|
||||
int ret;
|
||||
|
||||
ret = git_config_get_string(&value, cfg, name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (parse_int32(out, value) < 0) {
|
||||
giterr_set(GITERR_CONFIG, "Failed to parse '%s' as a 32-bit integer", value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_config_get_bool(int *out, git_config *cfg, const char *name)
|
||||
{
|
||||
const char *value;
|
||||
int ret;
|
||||
|
||||
ret = git_config_get_string(&value, cfg, name);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (git__parse_bool(out, value) == 0)
|
||||
return 0;
|
||||
|
||||
if (parse_int32(out, value) == 0) {
|
||||
*out = !!(*out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
giterr_set(GITERR_CONFIG, "Failed to parse '%s' as a boolean value", value);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int git_config_get_string(const char **out, git_config *cfg, const char *name)
|
||||
{
|
||||
file_internal *internal;
|
||||
unsigned int i;
|
||||
|
||||
assert(cfg->files.length);
|
||||
|
||||
*out = NULL;
|
||||
|
||||
git_vector_foreach(&cfg->files, i, internal) {
|
||||
git_config_file *file = internal->file;
|
||||
int ret = file->get(file, name, out);
|
||||
if (ret != GIT_ENOTFOUND)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return GIT_ENOTFOUND;
|
||||
}
|
||||
|
||||
int git_config_get_multivar(git_config *cfg, const char *name, const char *regexp,
|
||||
int (*fn)(const char *value, void *data), void *data)
|
||||
{
|
||||
file_internal *internal;
|
||||
git_config_file *file;
|
||||
int ret = GIT_ENOTFOUND;
|
||||
unsigned int i;
|
||||
|
||||
if (cfg->files.length == 0)
|
||||
return git__throw(GIT_EINVALIDARGS, "Cannot get variable value; no files open in the `git_config` instance");
|
||||
assert(cfg->files.length);
|
||||
|
||||
internal = git_vector_get(&cfg->files, 0);
|
||||
file = internal->file;
|
||||
/*
|
||||
* This loop runs the "wrong" way 'round because we need to
|
||||
* look at every value from the most general to most specific
|
||||
*/
|
||||
for (i = cfg->files.length; i > 0; --i) {
|
||||
internal = git_vector_get(&cfg->files, i - 1);
|
||||
file = internal->file;
|
||||
ret = file->get_multivar(file, name, regexp, fn, data);
|
||||
if (ret < 0 && ret != GIT_ENOTFOUND)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return file->get(file, name, out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_config_set_multivar(git_config *cfg, const char *name, const char *regexp, const char *value)
|
||||
{
|
||||
file_internal *internal;
|
||||
git_config_file *file;
|
||||
int ret = GIT_ENOTFOUND;
|
||||
unsigned int i;
|
||||
|
||||
for (i = cfg->files.length; i > 0; --i) {
|
||||
internal = git_vector_get(&cfg->files, i - 1);
|
||||
file = internal->file;
|
||||
ret = file->set_multivar(file, name, regexp, value);
|
||||
if (ret < 0 && ret != GIT_ENOTFOUND)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_config_find_global_r(git_buf *path)
|
||||
{
|
||||
return git_futils_find_global_file(path, GIT_CONFIG_FILENAME);
|
||||
}
|
||||
|
||||
int git_config_find_global(char *global_config_path, size_t length)
|
||||
{
|
||||
git_buf path = GIT_BUF_INIT;
|
||||
int ret = git_config_find_global_r(&path);
|
||||
|
||||
if (ret < 0) {
|
||||
git_buf_free(&path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (path.size >= length) {
|
||||
git_buf_free(&path);
|
||||
giterr_set(GITERR_NOMEMORY,
|
||||
"Path is to long to fit on the given buffer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
git_buf_copy_cstr(global_config_path, length, &path);
|
||||
git_buf_free(&path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_config_find_system_r(git_buf *path)
|
||||
{
|
||||
return git_futils_find_system_file(path, GIT_CONFIG_FILENAME_SYSTEM);
|
||||
}
|
||||
|
||||
int git_config_find_system(char *system_config_path, size_t length)
|
||||
{
|
||||
git_buf path = GIT_BUF_INIT;
|
||||
int ret = git_config_find_system_r(&path);
|
||||
|
||||
if (ret < 0) {
|
||||
git_buf_free(&path);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (path.size >= length) {
|
||||
git_buf_free(&path);
|
||||
giterr_set(GITERR_NOMEMORY,
|
||||
"Path is to long to fit on the given buffer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
git_buf_copy_cstr(system_config_path, length, &path);
|
||||
git_buf_free(&path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int git_config_open_global(git_config **out)
|
||||
{
|
||||
int error;
|
||||
git_buf path = GIT_BUF_INIT;
|
||||
|
||||
if ((error = git_config_find_global_r(&path)) < 0)
|
||||
return error;
|
||||
|
||||
error = git_config_open_ondisk(out, git_buf_cstr(&path));
|
||||
git_buf_free(&path);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
|
19
src/config.h
19
src/config.h
@ -1,14 +1,33 @@
|
||||
/*
|
||||
* 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_config_h__
|
||||
#define INCLUDE_config_h__
|
||||
|
||||
#include "git2.h"
|
||||
#include "git2/config.h"
|
||||
#include "vector.h"
|
||||
#include "repository.h"
|
||||
|
||||
#define GIT_CONFIG_FILENAME ".gitconfig"
|
||||
#define GIT_CONFIG_FILENAME_INREPO "config"
|
||||
#define GIT_CONFIG_FILENAME_SYSTEM "gitconfig"
|
||||
#define GIT_CONFIG_FILE_MODE 0666
|
||||
|
||||
struct git_config {
|
||||
git_refcount rc;
|
||||
git_vector files;
|
||||
};
|
||||
|
||||
extern int git_config_find_global_r(git_buf *global_config_path);
|
||||
extern int git_config_find_system_r(git_buf *system_config_path);
|
||||
|
||||
extern int git_config_parse_bool(int *out, const char *bool_string);
|
||||
|
||||
extern int git_config_lookup_map_value(
|
||||
git_cvar_map *maps, size_t map_n, const char *value, int *out);
|
||||
|
||||
#endif
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user