diff --git a/.gitignore b/.gitignore index a0c67a7fdc..e59d6338c1 100644 --- a/.gitignore +++ b/.gitignore @@ -4,12 +4,12 @@ tmp/* # ignore tests -tests/*.php -tests/*.sh -tests/*.log -tests/*.diff -tests/*.exp -tests/*.out +tests/*/*.php +tests/*/*.sh +tests/*/*.log +tests/*/*.diff +tests/*/*.exp +tests/*/*.out # ignore phpized files Makefile.global diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..bbf4f9db34 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "libgit2"] + path = libgit2 + url = https://github.com/libgit2/libgit2.git + ignore = dirty diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..bfe6af5ccf --- /dev/null +++ b/.travis.yml @@ -0,0 +1,26 @@ +language: php + +php: + - 5.3 + - 5.4 + - 5.5 + +install: + - sudo apt-get -qq update + - sudo apt-get -qq install cmake libssh2-1-dev openssh-client openssh-server + +script: + - script/cibuild.sh + +notifications: + irc: + channels: + - irc.freenode.net#php-git + on_success: change + on_failure: always + use_notice: true + skip_join: true + slack: + on_success: always + on_failure: always + secure: KH9+7GLccFrGWe+E6RhSqHxh+w5DIdsVxn41Iqb2C8rfm5rrnK0KVDTWJXk2BDHc2B1ab28o6m/Vcd8C/lgURd7yx4QfUASQRrHEn4FfpsB7UgES+/aENb59ma3DVz5PqVDUSVSvABU9OCqEkLmN/9w2mL/q3rW4slUq4LzMweI= diff --git a/CREDITS b/CREDITS deleted file mode 100644 index 5b4a19f66f..0000000000 --- a/CREDITS +++ /dev/null @@ -1,2 +0,0 @@ -PHP libgit2 bindings -Shuhei Tanuma diff --git a/EXPERIMENTAL b/EXPERIMENTAL deleted file mode 100644 index 80afdcd19e..0000000000 --- a/EXPERIMENTAL +++ /dev/null @@ -1,5 +0,0 @@ -this extension is experimental, -its functions may change their names -or move to extension all together -so do not rely to much on them -you have been warned! diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000..a68c9c890c --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright (c) 2010 - 2012 Shuhei Tanuma + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/README.md b/README.md index a818dbefe0..175ec8fcc2 100644 --- a/README.md +++ b/README.md @@ -1,112 +1,128 @@ # PHP-Git2 - libgit2 bindings in PHP php-git2 is a PHP bindings to the libgit2 linkable C Git library. -this extension are re-writing php-git as that code too dirty. -# Important Notice +* API Documentation: http://libgit2.github.com/libgit2/#v0.20.0 (also see Signature conversions section) +* IRC: #php-git on irc.freenode.net. -php-git changed it's API drastically. this changes doesn't care about compatibility between old one. -please check tests cases. +## Requirements -# Installing And Running +PHP 5.3 above -```` -git clone https://github.com/libgit2/php-git.git -cd php-git +## Status + +0.3.0 Alpha (switching to functions) + +https://docs.google.com/spreadsheet/ccc?key=0AjvShWAWqvfHdDRneEtIUF9GRUZMNVVVR1hpdURiUWc&usp=sharing + +## How to build + +``` +# build libgit2.a +## For 32bit systems +git submodule init && git submodule update +mkdir libgit2/build +cd libgit2/build +cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=OFF -DBUILD_CLAR=OFF .. +cmake --build . + +# For 64bit systems +git submodule init && git submodule update +mkdir libgit2/build +cd libgit2/build +cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=OFF -DBUILD_CLAR=OFF +-DCMAKE_C_FLAGS=-fPIC .. +cmake --build . + + +# build php-git2 +cd ../../ phpize -./configure +./configure --enable-git2-debug make -sudo make Install -```` +make install +# add extension=git2.so to your php.ini +``` -# API - -## Repository Access - -````php -$repo = new Git2\Repository($path); -/* - bool = $repo->isExist(string sha1) - Git2\Object = $repo->read(string sha1) - string sha1 = $repo->hash(string content, long type) - string sha1 = $repo->write(string content, long type) - bool = $repo->isBare() - bool = $repo->isEmpty() - bool = $repo->headDetached() - bool = $repo->headOrphan() - string path = Git2\Repository::discover("/Users/chobie/projects/work/repo/lib/subdir"); - // => /Users/chobie/projects/work/repo/.git - - Git2\Repository = Git2\Repository::init(string $path, bool isBare) -*/ -```` +## For Contributors + +##### Issue first. + +please make a issue first. don't work before creating it. -## Object Access +##### Coding Styles -## Tree Access +follow pecl coding standards (except 8 at this moment). + +* http://git.php.net/?p=php-src.git;a=blob_plain;f=CODING_STANDARDS;hb=HEAD + +##### Signature conversions ```` -$repo = new Git2\Repository($path); -$tree = $repo->lookup(tree sha); // specify tree sha +GIT_EXTERN(int) git_repository_init( + git_repository **out, + const char *path, + unsigned is_bare); + -foreach ($tree as $oid => $entry) { - var_dump($entry); -} +// error code should handle in extension. +// resource creation or getting functions will return their resource or bool. +resource|bool function git_repository_init(string $path, long $is_bare); + +public struct (e.g: git_config_entry) should consider return as an array. ```` -## Ref Management +##### file name rules. + +basically, we rely libgit2 grouping at this time. (`branch` group functions should be in branch.c) +some group (e.g config) will conflicts php header files. we choose `g_` prefix for now. + +check grouping here libgit2.github.com/libgit2/#v0.20.0 + +##### generating files + +if you wanna try to work new file. please use gen.php and generate stubs. as declarations are bored task. +(sometimes, this generator might output wrong headers. then just comment out or fix generator) ```` -$ref = Git2\Reference::lookup($repo, "refs/heads/master"); - sha = $ref->getTarget(); - str = $ref->getName(); +PRINT_HEADER=1 php ng.php libgit2/include/git2/branch.h > branch.h +php ng.php libgit2/include/git2/branch.h > branch.c ```` +you can generate `PHP_FE` with this. past it to `php_git2.c` + ```` -foreach (Git2\Reference::each($repo) as $ref) { - echo $ref->getName() . PHP_EOL; -} +php fe.php target.c ```` +Note: usually, these generators might output needless variables. DON'T PR `prettify codes` at this moment. +As we have more than 500 php functions. we like to use some fixer command than fix by hand. -## Commit +##### documents -```` -insert(new Git2\TreeEntry(array( - "name" => "README.txt", - "oid" => "63542fbea05732b78711479a31557bd1b0aa2116", - "attributes" => octdec('100644'), -))); -$tree = $bld->write($repo); - -$parent = ""; -$parents = array(); -$parent = Git2\Commit::create($repo, array( - "author" => $author, - "committer" => $author, - "message" => "Hello World", - "tree" => $tree, - "parents" => $parents, -)); -$parents = array($parent); -```` +use prototype. -## Revision Walking +``` + /* {{{ proto int abs(int number) + Returns the absolute value of the number */ + PHP_FUNCTION(abs) + { + ... + } + /* }}} */ +``` -```` -$repo = new Git2\Repository($path); -$walker = new Git2\Walker($repo); -/* specify HEAD oid */ -$walker->push("6e20138dc38f9f626107f1cd3ef0f9838c43defe"); - -foreach ($walker as $oid => $commit) { - printf("oid: %s\n", $oid); - printf("message: %s\n", $commit->getMessage()); -} \ No newline at end of file +document will generate later. please check source code before publish docs. + +##### testing + +[group]/[function].phpt + +##### policy + +* don't create OOP interface in extension for ease of maintenance. +* follow latest libgit2 api. don't consider BC at this time. + +## LICENSE + +MIT License diff --git a/attr.c b/attr.c new file mode 100644 index 0000000000..fd894261f8 --- /dev/null +++ b/attr.c @@ -0,0 +1,138 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "attr.h" + +/* {{{ proto resource git_attr_value(string $attr) + */ +PHP_FUNCTION(git_attr_value) +{ + git_attr_t result; + char *attr = NULL; + int attr_len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "s", &attr, &attr_len) == FAILURE) { + return; + } + + result = git_attr_value(attr); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_attr_get(resource $repo, long $flags, string $path, string $name) + */ +PHP_FUNCTION(git_attr_get) +{ + php_git2_t *_repo = NULL; + char *value_out = NULL, *path = NULL, *name = NULL; + zval *repo = NULL; + long flags = 0; + int path_len = 0, name_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rlss", &repo, &flags, &path, &path_len, &name, &name_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_attr_get(&value_out, PHP_GIT2_V(_repo, repository), flags, path, name); + if (php_git2_check_error(error, "git_attr_get" TSRMLS_CC)) { + RETURN_FALSE; + } + RETURN_STRING(value_out, 1); +} +/* }}} */ + +/* {{{ proto resource git_attr_get_many(resource $repo, long $flags, string $path, long $num_attr, string $names) + */ +PHP_FUNCTION(git_attr_get_many) +{ + php_git2_t *_repo = NULL; + char *values_out = NULL, *path = NULL; + zval *repo = NULL, *names = NULL; + long flags = 0, num_attr = 0; + int path_len = 0, error = 0; + + /* TODO(chobie): write array to const char** conversion */ + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rlsla", &repo, &flags, &path, &path_len, &num_attr, &names) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + /* TODO(chobie): emalloc values_out */ + error = git_attr_get_many(&values_out, PHP_GIT2_V(_repo, repository), flags, path, num_attr, names); + if (php_git2_check_error(error, "git_attr_get_many" TSRMLS_CC)) { + RETURN_FALSE; + } + RETURN_STRING(values_out, 1); +} +/* }}} */ + +/* {{{ proto long git_attr_foreach(resource $repo, long $flags, string $path, Callable $callback, $payload) + */ +PHP_FUNCTION(git_attr_foreach) +{ + int result = 0, path_len = 0; + zval *repo = NULL, *payload = NULL; + php_git2_t *_repo = NULL; + long flags = 0; + char *path = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rlsfz", &repo, &flags, &path, &path_len, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + // TODO(chobie): implement this + //result = git_attr_foreach(PHP_GIT2_V(_repo, repository), flags, path, , cb); + php_git2_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto void git_attr_cache_flush(resource $repo) + */ +PHP_FUNCTION(git_attr_cache_flush) +{ + zval *repo = NULL; + php_git2_t *_repo = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + git_attr_cache_flush(PHP_GIT2_V(_repo, repository)); +} +/* }}} */ + +/* {{{ proto long git_attr_add_macro(resource $repo, string $name, string $values) + */ +PHP_FUNCTION(git_attr_add_macro) +{ + int result = 0, name_len = 0, values_len = 0; + zval *repo = NULL; + php_git2_t *_repo = NULL; + char *name = NULL, *values = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rss", &repo, &name, &name_len, &values, &values_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_attr_add_macro(PHP_GIT2_V(_repo, repository), name, values); + RETURN_LONG(result); +} +/* }}} */ + diff --git a/attr.h b/attr.h new file mode 100644 index 0000000000..946906f974 --- /dev/null +++ b/attr.h @@ -0,0 +1,90 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_ATTR_H +#define PHP_GIT2_ATTR_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_attr_value, 0, 0, 1) + ZEND_ARG_INFO(0, attr) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_attr_get, 0, 0, 4) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, flags) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_attr_get_many, 0, 0, 5) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, flags) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, num_attr) + ZEND_ARG_INFO(0, names) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_attr_foreach, 0, 0, 5) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, flags) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_attr_cache_flush, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_attr_add_macro, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, values) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_attr_value(attr) +*/ +PHP_FUNCTION(git_attr_value); + +/* {{{ proto resource git_attr_get(repo, flags, path, name) +*/ +PHP_FUNCTION(git_attr_get); + +/* {{{ proto resource git_attr_get_many(repo, flags, path, num_attr, names) +*/ +PHP_FUNCTION(git_attr_get_many); + +/* {{{ proto long git_attr_foreach(repo, flags, path, callback, payload) +*/ +PHP_FUNCTION(git_attr_foreach); + +/* {{{ proto void git_attr_cache_flush(repo) +*/ +PHP_FUNCTION(git_attr_cache_flush); + +/* {{{ proto long git_attr_add_macro(repo, name, values) +*/ +PHP_FUNCTION(git_attr_add_macro); + +#endif \ No newline at end of file diff --git a/blame.c b/blame.c new file mode 100644 index 0000000000..87035a6558 --- /dev/null +++ b/blame.c @@ -0,0 +1,258 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "blame.h" + +static void php_git2_array_to_git_blame_options(git_blame_options *options, zval *array TSRMLS_DC) +{ + zval *tmp; + + options->version = php_git2_read_arrval_long(array, ZEND_STRS("version") TSRMLS_CC); + options->flags = php_git2_read_arrval_long(array, ZEND_STRS("flags") TSRMLS_CC); + options->min_match_characters = php_git2_read_arrval_long(array, ZEND_STRS("min_match_characters") TSRMLS_CC); + tmp = php_git2_read_arrval(array, ZEND_STRS("newest_commit") TSRMLS_CC); + if (Z_TYPE_P(tmp) != NULL) { + if (Z_TYPE_P(tmp) != IS_STRING) { + convert_to_string(tmp); + } + if (git_oid_fromstrn(&options->newest_commit, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)) != GIT_OK) { + return; + } + } + + tmp = php_git2_read_arrval(array, ZEND_STRS("oldest_commit") TSRMLS_CC); + if (Z_TYPE_P(tmp) != NULL) { + if (Z_TYPE_P(tmp) != IS_STRING) { + convert_to_string(tmp); + } + if (git_oid_fromstrn(&options->newest_commit, Z_STRVAL_P(tmp), Z_STRLEN_P(tmp)) != GIT_OK) { + return; + } + } + + options->min_line = php_git2_read_arrval_long(array, ZEND_STRS("min_line") TSRMLS_CC); + options->max_line = php_git2_read_arrval_long(array, ZEND_STRS("max_line") TSRMLS_CC); + +} + +static void php_git2_git_blame_options_to_array(git_blame_options *options, zval **out TSRMLS_DC) +{ + zval *result = NULL; + char buf[41] = {0}; + + MAKE_STD_ZVAL(result); + array_init(result); + + add_assoc_long_ex(result, ZEND_STRS("version"), options->version); + add_assoc_long_ex(result, ZEND_STRS("flags"), options->flags); + add_assoc_long_ex(result, ZEND_STRS("min_match_characters"), options->min_match_characters); + + if (git_oid_iszero(&options->newest_commit) != 1) { + git_oid_fmt(buf, &options->newest_commit); + add_assoc_string_ex(result, ZEND_STRS("newest_commit"), out, 1); + } else { + add_assoc_null_ex(result, ZEND_STRS("newest_commit")); + } + + if (git_oid_iszero(&options->oldest_commit) != 1) { + git_oid_fmt(buf, &options->oldest_commit); + add_assoc_string_ex(result, ZEND_STRS("oldest_commit"), out, 1); + } else { + add_assoc_null_ex(result, ZEND_STRS("oldest_commit")); + } + + add_assoc_long_ex(result, ZEND_STRS("min_line"), options->min_line); + add_assoc_long_ex(result, ZEND_STRS("max_line"), options->max_line); + *out = result; +} + +static void php_git2_git_blame_hunk_to_array(git_blame_hunk *hunk, zval **out TSRMLS_DC) +{ + zval *result = NULL, *final = NULL, *orig = NULL; + char buf[41] = {0}; + + MAKE_STD_ZVAL(result); + array_init(result); + + add_assoc_long_ex(result, ZEND_STRS("lines_in_hunk"), hunk->lines_in_hunk); + + git_oid_fmt(buf, &hunk->final_commit_id); + add_assoc_string_ex(result, ZEND_STRS("final_commit_id"), buf, 1); + + php_git2_signature_to_array(hunk->final_signature, &final TSRMLS_CC); + add_assoc_zval_ex(result, ZEND_STRS("final_signature"), final); + + add_assoc_long_ex(result, ZEND_STRS("final_start_line_number"), hunk->final_start_line_number); + + git_oid_fmt(buf, &hunk->orig_commit_id); + add_assoc_string_ex(result, ZEND_STRS("orig_commit_id"), buf, 1); + add_assoc_string_ex(result, ZEND_STRS("orig_path"), hunk->orig_path, 1); + + add_assoc_long_ex(result, ZEND_STRS("orig_start_line_number"), hunk->orig_start_line_number); + if (hunk->orig_signature) { + php_git2_signature_to_array(hunk->orig_signature, &orig TSRMLS_CC); + } else { + MAKE_STD_ZVAL(orig); + ZVAL_NULL(orig); + } + add_assoc_zval_ex(result, ZEND_STRS("orig_signature"), orig); + + add_assoc_stringl_ex(result, ZEND_STRS("boundary"), &hunk->boundary, 1, 1); + + *out = result; +} + +/* {{{ proto long git_blame_get_hunk_count(resource $blame) + */ +PHP_FUNCTION(git_blame_get_hunk_count) +{ + uint32_t result = 0; + zval *blame = NULL; + php_git2_t *_blame = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &blame) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_blame, php_git2_t*, &blame, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_blame_get_hunk_count(PHP_GIT2_V(_blame, blame)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_blame_get_hunk_byindex(resource $blame, long $index) + */ +PHP_FUNCTION(git_blame_get_hunk_byindex) +{ + const git_blame_hunk *result = NULL; + zval *blame = NULL, *array = NULL; + php_git2_t *_blame = NULL; + long index = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &blame, &index) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_blame, php_git2_t*, &blame, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_blame_get_hunk_byindex(PHP_GIT2_V(_blame, blame), index); + if (result == NULL) { + RETURN_FALSE; + } + php_git2_git_blame_hunk_to_array(result, &array TSRMLS_CC); + RETURN_ZVAL(array, 0, 1); +} +/* }}} */ + +/* {{{ proto resource git_blame_get_hunk_byline(resource $blame, long $lineno) + */ +PHP_FUNCTION(git_blame_get_hunk_byline) +{ + const git_blame_hunk *result = NULL; + zval *blame = NULL, *array = NULL; + php_git2_t *_blame = NULL; + long lineno = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &blame, &lineno) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_blame, php_git2_t*, &blame, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_blame_get_hunk_byline(PHP_GIT2_V(_blame, blame), lineno); + if (result == NULL) { + RETURN_FALSE; + } + php_git2_git_blame_hunk_to_array(result, &array TSRMLS_CC); + RETURN_ZVAL(array, 0, 1); +} +/* }}} */ + +/* {{{ proto resource git_blame_file(resource $repo, string $path, $options) + */ +PHP_FUNCTION(git_blame_file) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_blame *out = NULL; + zval *repo = NULL, *options = NULL; + git_blame_options opts = GIT_BLAME_OPTIONS_INIT; + char *path = NULL; + int path_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsa", &repo, &path, &path_len, &options) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + php_git2_array_to_git_blame_options(&opts, options TSRMLS_CC); + error = git_blame_file(&out, PHP_GIT2_V(_repo, repository), path, &opts); + if (php_git2_check_error(error, "git_blame_file" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_BLAME, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_blame_buffer(resource $reference, string $buffer) + */ +PHP_FUNCTION(git_blame_buffer) +{ + php_git2_t *result = NULL, *_reference = NULL; + git_blame *out = NULL; + zval *reference = NULL; + char *buffer = NULL; + int buffer_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &reference, &buffer, &buffer_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_reference, php_git2_t*, &reference, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_blame_buffer(&out, PHP_GIT2_V(_reference, blame), buffer, buffer_len); + if (php_git2_check_error(error, "git_blame_buffer" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_BLAME, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto void git_blame_free(resource $blame) + */ +PHP_FUNCTION(git_blame_free) +{ + zval *blame = NULL; + php_git2_t *_blame = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &blame) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_blame, php_git2_t*, &blame, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_blame)) { + git_blame_free(PHP_GIT2_V(_blame, blame)); + GIT2_SHOULD_FREE(_blame) = 0; + }; + zval_ptr_dtor(&blame); +} +/* }}} */ + +/* {{{ proto void git_blame_options_new() + */ +PHP_FUNCTION(git_blame_options_new) +{ + zval *result; + git_blame_options options = GIT_BLAME_OPTIONS_INIT; + + php_git2_git_blame_options_to_array(&options, &result TSRMLS_CC); + RETURN_ZVAL(result, 0, 1); +} +/* }}} */ diff --git a/blame.h b/blame.h new file mode 100644 index 0000000000..44fd4761b5 --- /dev/null +++ b/blame.h @@ -0,0 +1,90 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_BLAME_H +#define PHP_GIT2_BLAME_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_blame_get_hunk_count, 0, 0, 1) + ZEND_ARG_INFO(0, blame) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_blame_get_hunk_byindex, 0, 0, 2) + ZEND_ARG_INFO(0, blame) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_blame_get_hunk_byline, 0, 0, 2) + ZEND_ARG_INFO(0, blame) + ZEND_ARG_INFO(0, lineno) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_blame_file, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, options) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_blame_buffer, 0, 0, 3) + ZEND_ARG_INFO(0, reference) + ZEND_ARG_INFO(0, buffer) + ZEND_ARG_INFO(0, buffer_len) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_blame_free, 0, 0, 1) + ZEND_ARG_INFO(0, blame) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_blame_options_new, 0, 0, 0) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_blame_get_hunk_count(blame) +*/ +PHP_FUNCTION(git_blame_get_hunk_count); + +/* {{{ proto resource git_blame_get_hunk_byindex(blame, index) +*/ +PHP_FUNCTION(git_blame_get_hunk_byindex); + +/* {{{ proto resource git_blame_get_hunk_byline(blame, lineno) +*/ +PHP_FUNCTION(git_blame_get_hunk_byline); + +/* {{{ proto resource git_blame_file(repo, path, options) +*/ +PHP_FUNCTION(git_blame_file); + +/* {{{ proto resource git_blame_buffer(reference, buffer, buffer_len) +*/ +PHP_FUNCTION(git_blame_buffer); + +/* {{{ proto void git_blame_free(blame) +*/ +PHP_FUNCTION(git_blame_free); + +/* {{{ proto void git_blame_options_new() + */ +PHP_FUNCTION(git_blame_options_new); + +#endif \ No newline at end of file diff --git a/blob.c b/blob.c index ced9b81b6d..dd3bb5ba25 100644 --- a/blob.c +++ b/blob.c @@ -1,83 +1,338 @@ -/* - * The MIT License - * - * Copyright (c) 2010 - 2012 Shuhei Tanuma - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. +#include "php_git2.h" +#include "php_git2_priv.h" +#include "blob.h" + +/* {{{ proto resource git_blob_create_frombuffer(resource $repository, string $buffer) +*/ +PHP_FUNCTION(git_blob_create_frombuffer) +{ + zval *repository; + php_git2_t *git2; + char *buffer; + int buffer_len; + int error; + git_oid id; + char out[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repository, &buffer, &buffer_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &repository, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_blob_create_frombuffer(&id, PHP_GIT2_V(git2, repository), buffer, buffer_len); + if (php_git2_check_error(error, "git_blob_create_frombuffer" TSRMLS_CC)) { + RETURN_FALSE + } + + git_oid_fmt(out, &id); + RETURN_STRING(out, 1); +} +/* }}} */ + +/* {{{ proto long git_blob_create_fromchunks(string $id, resource $repo, string $hintpath, Callable $callback, $payload) */ +PHP_FUNCTION(git_blob_create_fromchunks) +{ + int result = 0, id_len = 0, hintpath_len = 0; + char *id = NULL, *hintpath = NULL; + git_oid __id = {0}; + zval *repo = NULL, *payload = NULL; + php_git2_t *_repo = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb = NULL; -#include "php_git2.h" + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "srsfz", &id, &id_len, &repo, &hintpath, &hintpath_len, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__id, id, id_len)) { + RETURN_FALSE; + } + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + // TODO(chobie) implement this */ + //result = git_blob_create_fromchunks(__id, PHP_GIT2_V(_repo, repository), hintpath, , cb); + php_git2_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto resource git_blob_create_fromdisk(resource $repository, string $path) +*/ +PHP_FUNCTION(git_blob_create_fromdisk) +{ + zval *repository; + php_git2_t *git2; + char *path; + int path_len; + int error; + git_oid id; + char out[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repository, &path, &path_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &repository, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); -PHPAPI zend_class_entry *git2_blob_class_entry; + error = git_blob_create_fromdisk(&id, PHP_GIT2_V(git2, repository), path); + if (php_git2_check_error(error, "git_blob_create_fromdisk" TSRMLS_CC)) { + RETURN_FALSE + } + + git_oid_fmt(out, &id); + RETURN_STRING(out, 1); +} +/* }}} */ -static void php_git2_blob_free_storage(php_git2_blob *object TSRMLS_DC) +/* {{{ proto resource git_blob_create_fromworkdir(resource $repository, string $relative_path) +*/ +PHP_FUNCTION(git_blob_create_fromworkdir) { - if (object->blob != NULL) { - git_blob_free(object->blob); - object->blob = NULL; + zval *repository; + php_git2_t *git2; + char *path; + int path_len; + int error; + git_oid id; + char out[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repository, &path, &path_len) == FAILURE) { + return; } - zend_object_std_dtor(&object->zo TSRMLS_CC); - efree(object); + + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &repository, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + error = git_blob_create_fromworkdir(&id, PHP_GIT2_V(git2, repository), path); + if (php_git2_check_error(error, "git_blob_create_fromdisk" TSRMLS_CC)) { + RETURN_FALSE + } + + git_oid_fmt(out, &id); + RETURN_STRING(out, 1); } +/* }}} */ -zend_object_value php_git2_blob_new(zend_class_entry *ce TSRMLS_DC) +/* {{{ proto resource git_blob_filtered_content(resource $blob, string $as_path, long $check_for_binary_data) + */ +PHP_FUNCTION(git_blob_filtered_content) { - zend_object_value retval; + php_git2_t *result = NULL, *_blob = NULL; + git_buf out = {0}; + zval *blob = NULL; + char *as_path = NULL; + int as_path_len = 0, error = 0; + long check_for_binary_data = 0; - PHP_GIT2_STD_CREATE_OBJECT(php_git2_blob); - return retval; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsl", &blob, &as_path, &as_path_len, &check_for_binary_data) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_blob, php_git2_t*, &blob, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_blob_filtered_content(&out, PHP_GIT2_V(_blob, blob), as_path, check_for_binary_data); + if (php_git2_check_error(error, "git_blob_filtered_content" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_BUF, &out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto void git_blob_free(resource $blob) + */ +PHP_FUNCTION(git_blob_free) +{ + zval *blob = NULL; + php_git2_t *_blob = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &blob) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_blob, php_git2_t*, &blob, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_blob)) { + git_blob_free(PHP_GIT2_V(_blob, blob)); + GIT2_SHOULD_FREE(_blob) = 0; + }; + zval_ptr_dtor(&blob); } +/* }}} */ + +/* {{{ proto resource git_blob_id(resource $blob) +*/ +PHP_FUNCTION(git_blob_id) +{ + zval *blob; + php_git2_t *git2; + char out[GIT2_OID_HEXSIZE] = {0}; + const git_oid *id; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &blob) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &blob, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + id = git_blob_id(PHP_GIT2_V(git2, blob)); + git_oid_fmt(out, id); + RETURN_STRING(out, 1); +} +/* }}} */ -/* -{{{ proto: Git2\Blob::__toString() +/* {{{ proto resource git_blob_is_binary(resource $blob) */ -PHP_METHOD(git2_blob, __toString) +PHP_FUNCTION(git_blob_is_binary) +{ + zval *blob; + php_git2_t *git2; + int result; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &blob) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &blob, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_blob_is_binary(PHP_GIT2_V(git2, blob)); + RETURN_BOOL(result); +} +/* }}} */ + +/* {{{ proto long git_blob_lookup(resource $repo, string $id) + */ +PHP_FUNCTION(git_blob_lookup) +{ + int result = 0, id_len = 0; + git_blob *blob = NULL; + zval *repo = NULL; + php_git2_t *_repo = NULL, *_result = NULL; + char *id = NULL; + git_oid __id = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repo, &id, &id_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__id, id, id_len)) { + RETURN_FALSE; + } + result = git_blob_lookup(&blob, PHP_GIT2_V(_repo, repository), &__id); + if (php_git2_make_resource(&_result, PHP_GIT2_TYPE_BLOB, blob, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(_result)); +} +/* }}} */ + + +/* {{{ proto long git_blob_lookup_prefix(resource $repo, string $id, long $len) + */ +PHP_FUNCTION(git_blob_lookup_prefix) +{ + int result = 0, id_len = 0; + git_blob *blob = NULL; + zval *repo = NULL; + php_git2_t *_repo = NULL, *_result = NULL; + char *id = NULL; + git_oid __id = {0}; + long len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsl", &repo, &id, &id_len, &len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__id, id, id_len)) { + RETURN_FALSE; + } + result = git_blob_lookup_prefix(&blob, PHP_GIT2_V(_repo, repository), &__id, len); + if (php_git2_make_resource(&_result, PHP_GIT2_TYPE_BLOB, blob, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(_result)); +} +/* }}} */ + + +/* {{{ proto resource git_blob_owner(resource $blob) + */ +PHP_FUNCTION(git_blob_owner) { - char *data; - php_git2_blob *m_blob; - - m_blob = PHP_GIT2_GET_OBJECT(php_git2_blob, getThis()); - - if (m_blob != NULL) { - if (m_blob->blob == NULL) { - RETURN_FALSE; - } - - RETURN_STRINGL(git_blob_rawcontent(m_blob->blob), git_blob_rawsize(m_blob->blob),1); - } else { + git_repository *result = NULL; + zval *blob = NULL; + php_git2_t *_blob = NULL, *__result = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &blob) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_blob, php_git2_t*, &blob, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_blob_owner(PHP_GIT2_V(_blob, blob)); + if (php_git2_make_resource(&__result, PHP_GIT2_TYPE_BLOB, result, 0 TSRMLS_CC)) { RETURN_FALSE; } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(__result)); } /* }}} */ -static zend_function_entry php_git2_blob_methods[] = { - PHP_ME(git2_blob, __toString, NULL, ZEND_ACC_PUBLIC) - {NULL,NULL,NULL} -}; +/* {{{ proto resource git_blob_rawcontent(resource $blob) +*/ +PHP_FUNCTION(git_blob_rawcontent) +{ + zval *blob; + php_git2_t *git2; + const char *buffer = NULL; + git_off_t size; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &blob) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &blob, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + buffer = git_blob_rawcontent(PHP_GIT2_V(git2, blob)); + if (buffer == NULL) { + RETURN_FALSE; + } + size = git_blob_rawsize(PHP_GIT2_V(git2, blob)); + RETURN_STRINGL(buffer, size, 1); +} +/* }}} */ -void php_git2_blob_init(TSRMLS_D) +/* {{{ proto resource git_blob_rawsize(resource $blob, string $oid) +*/ +PHP_FUNCTION(git_blob_rawsize) { - zend_class_entry ce; - - INIT_NS_CLASS_ENTRY(ce, PHP_GIT2_NS, "Blob", php_git2_blob_methods); - git2_blob_class_entry = zend_register_internal_class(&ce TSRMLS_CC); - git2_blob_class_entry->create_object = php_git2_blob_new; -} \ No newline at end of file + zval *blob; + php_git2_t *git2; + git_off_t size; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &blob) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &blob, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + size = git_blob_rawsize(PHP_GIT2_V(git2, blob)); + RETURN_LONG(size); +} +/* }}} */ \ No newline at end of file diff --git a/blob.h b/blob.h new file mode 100644 index 0000000000..c4b5a4a754 --- /dev/null +++ b/blob.h @@ -0,0 +1,146 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_BLOB_H +#define PHP_GIT2_BLOB_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_blob_create_frombuffer, 0, 0, 2) + ZEND_ARG_INFO(0, repository) + ZEND_ARG_INFO(0, buffer) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_blob_create_fromchunks, 0, 0, 3) + ZEND_ARG_INFO(0, repository) + ZEND_ARG_INFO(0, hintpath) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_blob_create_fromdisk, 0, 0, 2) + ZEND_ARG_INFO(0, repository) + ZEND_ARG_INFO(0, path) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_blob_create_fromworkdir, 0, 0, 2) + ZEND_ARG_INFO(0, repository) + ZEND_ARG_INFO(0, relative_path) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_blob_filtered_content, 0, 0, 2) + ZEND_ARG_INFO(0, blob) + ZEND_ARG_INFO(0, as_path) + ZEND_ARG_INFO(0, check_for_binary_data) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_blob_free, 0, 0, 1) + ZEND_ARG_INFO(0, blob) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_blob_id, 0, 0, 1) + ZEND_ARG_INFO(0, blob) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_blob_is_binary, 0, 0, 1) + ZEND_ARG_INFO(0, blob) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_blob_lookup, 0, 0, 2) + ZEND_ARG_INFO(0, repository) + ZEND_ARG_INFO(0, id) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_blob_lookup_prefix, 0, 0, 3) + ZEND_ARG_INFO(0, repository) + ZEND_ARG_INFO(0, id) + ZEND_ARG_INFO(0, length) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_blob_owner, 0, 0, 1) + ZEND_ARG_INFO(0, blob) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_blob_rawcontent, 0, 0, 1) + ZEND_ARG_INFO(0, blob) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_blob_rawsize, 0, 0, 1) + ZEND_ARG_INFO(0, blob) +ZEND_END_ARG_INFO() + + +/* {{{ proto resource git_blob_create_frombuffer(resource $repository, string $buffer) +*/ +PHP_FUNCTION(git_blob_create_frombuffer); + +/* {{{ proto resource git_blob_create_fromchunks(resource $repository, string $hintpath, Callable $callback, mixed payload) +*/ +PHP_FUNCTION(git_blob_create_fromchunks); + +/* {{{ proto resource git_blob_create_fromdisk(resource $repository, string $path) +*/ +PHP_FUNCTION(git_blob_create_fromdisk); + +/* {{{ proto resource git_blob_create_fromworkdir(resource $repository, string $relative_path) +*/ +PHP_FUNCTION(git_blob_create_fromworkdir); + + +/* {{{ proto resource git_blob_filtered_content($blob, $as_path, $check_for_binary_data) +*/ +PHP_FUNCTION(git_blob_filtered_content); + +/* {{{ proto resource git_blob_free(resource $blob) +*/ +PHP_FUNCTION(git_blob_free); + +/* {{{ proto resource git_blob_id(resource $blob) +*/ +PHP_FUNCTION(git_blob_id); + +/* {{{ proto resource git_blob_is_binary(resource $blob) +*/ +PHP_FUNCTION(git_blob_is_binary); + +/* {{{ proto resource git_blob_lookup(resource $blob, string $oid) +*/ +PHP_FUNCTION(git_blob_lookup); + +/* {{{ proto resource git_blob_lookup_prefix(resource $blob, string $oid) +*/ +PHP_FUNCTION(git_blob_lookup_prefix); + +/* {{{ proto resource git_blob_owner(resource $blob, string $oid) +*/ +PHP_FUNCTION(git_blob_owner); + +/* {{{ proto resource git_blob_rawcontent(resource $blob, string $oid) +*/ +PHP_FUNCTION(git_blob_rawcontent); + +/* {{{ proto resource git_blob_rawsize(resource $blob, string $oid) +*/ +PHP_FUNCTION(git_blob_rawsize); + +#endif \ No newline at end of file diff --git a/branch.c b/branch.c new file mode 100644 index 0000000000..9d19d0fec0 --- /dev/null +++ b/branch.c @@ -0,0 +1,307 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "branch.h" + +/* {{{ proto resource git_branch_create(resource $repo, string $branch_name, resource $target, long $force) + */ +PHP_FUNCTION(git_branch_create) +{ + php_git2_t *result = NULL, *_repo = NULL, *_target = NULL; + git_reference *out = NULL; + zval *repo = NULL, *target = NULL; + char *branch_name = NULL; + int branch_name_len = 0, error = 0; + long force = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsrl", &repo, &branch_name, &branch_name_len, &target, &force) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_target, php_git2_t*, &target, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_branch_create(&out, PHP_GIT2_V(_repo, repository), branch_name, PHP_GIT2_V(_target, commit), force); + if (php_git2_check_error(error, "git_branch_create" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REFERENCE, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto long git_branch_delete(resource $branch) + */ +PHP_FUNCTION(git_branch_delete) +{ + int result = 0; + zval *branch = NULL; + php_git2_t *_branch = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &branch) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_branch, php_git2_t*, &branch, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_branch_delete(PHP_GIT2_V(_branch, reference)); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto resource git_branch_iterator_new(resource $repo, $list_flags) + */ +PHP_FUNCTION(git_branch_iterator_new) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_branch_iterator *out = NULL; + zval *repo = NULL; + int error = 0; + long list_flags = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &repo, &list_flags) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_branch_iterator_new(&out, PHP_GIT2_V(_repo, repository), list_flags); + if (php_git2_check_error(error, "git_branch_iterator_new" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_BRANCH_ITERATOR, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto resource git_branch_next(long $out_type, resource $iter) + */ +PHP_FUNCTION(git_branch_next) +{ + php_git2_t *result = NULL, *_iter = NULL; + git_reference *out = NULL; + zval *iter = NULL; + long out_type = 0; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "lr", &out_type, &iter) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_iter, php_git2_t*, &iter, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_branch_next(&out, out_type, PHP_GIT2_V(_iter, branch_iterator)); + if (php_git2_check_error(error, "git_branch_next" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REFERENCE, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto void git_branch_iterator_free(resource $iter) + */ +PHP_FUNCTION(git_branch_iterator_free) +{ + zval *iter = NULL; + php_git2_t *_iter = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &iter) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_iter, php_git2_t*, &iter, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_iter)) { + git_branch_iterator_free(PHP_GIT2_V(_iter, branch_iterator)); + GIT2_SHOULD_FREE(_iter) = 0; + }; + zval_ptr_dtor(&iter); +} +/* }}} */ + +/* {{{ proto resource git_branch_move(resource $branch, string $new_branch_name, long $force) + */ +PHP_FUNCTION(git_branch_move) +{ + php_git2_t *result = NULL, *_branch = NULL; + git_reference *out = NULL; + zval *branch = NULL; + char *new_branch_name = NULL; + int new_branch_name_len = 0, error = 0; + long force = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsl", &branch, &new_branch_name, &new_branch_name_len, &force) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_branch, php_git2_t*, &branch, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_branch_move(&out, PHP_GIT2_V(_branch, reference), new_branch_name, force); + if (php_git2_check_error(error, "git_branch_move" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REFERENCE, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto resource git_branch_lookup(resource $repo, string $branch_name, $branch_type) + */ +PHP_FUNCTION(git_branch_lookup) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_reference *out = NULL; + zval *repo = NULL; + char *branch_name = NULL; + int branch_name_len = 0, error = 0; + long branch_type = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsl", &repo, &branch_name, &branch_name_len, &branch_type) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_branch_lookup(&out, PHP_GIT2_V(_repo, repository), branch_name, branch_type); + if (php_git2_check_error(error, "git_branch_lookup" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REFERENCE, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_branch_name(resource $ref) + */ +PHP_FUNCTION(git_branch_name) +{ + char out[GIT2_BUFFER_SIZE] = {0}; + zval *ref = NULL; + php_git2_t *_ref = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &ref) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_ref, php_git2_t*, &ref, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_branch_name(&out, PHP_GIT2_V(_ref, reference)); + if (php_git2_check_error(error, "git_branch_name" TSRMLS_CC)) { + RETURN_FALSE; + } + RETURN_STRING(out, 1); +} +/* }}} */ + +/* {{{ proto resource git_branch_upstream(resource $branch) + */ +PHP_FUNCTION(git_branch_upstream) +{ + php_git2_t *result = NULL, *_branch = NULL; + git_reference *out = NULL; + zval *branch = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &branch) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_branch, php_git2_t*, &branch, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_branch_upstream(&out, PHP_GIT2_V(_branch, reference)); + if (php_git2_check_error(error, "git_branch_upstream" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REFERENCE, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto resource git_branch_upstream_name(resource $repo, string $canonical_branch_name) + */ +PHP_FUNCTION(git_branch_upstream_name) +{ + char tracking_branch_name_out[GIT2_BUFFER_SIZE] = {0}; + long buffer_size = GIT2_BUFFER_SIZE; + zval *repo = NULL; + php_git2_t *_repo = NULL; + char *canonical_branch_name = NULL; + int canonical_branch_name_len = 0; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repo, &canonical_branch_name, &canonical_branch_name_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_branch_upstream_name(&tracking_branch_name_out, buffer_size, PHP_GIT2_V(_repo, repository), canonical_branch_name); + if (php_git2_check_error(error, "git_branch_upstream_name" TSRMLS_CC)) { + RETURN_FALSE; + } + RETURN_STRING(tracking_branch_name_out, 1); +} +/* }}} */ + +/* {{{ proto long git_branch_is_head(resource $branch) + */ +PHP_FUNCTION(git_branch_is_head) +{ + int result = 0; + zval *branch = NULL; + php_git2_t *_branch = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &branch) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_branch, php_git2_t*, &branch, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_branch_is_head(PHP_GIT2_V(_branch, reference)); + RETURN_BOOL(result); +} +/* }}} */ + +/* {{{ proto resource git_branch_remote_name(resource $repo, string $canonical_branch_name) + */ +PHP_FUNCTION(git_branch_remote_name) +{ + char remote_name_out[GIT2_BUFFER_SIZE] = {0}; + long buffer_size = GIT2_BUFFER_SIZE; + zval *repo = NULL; + php_git2_t *_repo = NULL; + char *canonical_branch_name = NULL; + int canonical_branch_name_len = 0; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repo, &canonical_branch_name, &canonical_branch_name_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_branch_remote_name(&remote_name_out, buffer_size, PHP_GIT2_V(_repo, repository), canonical_branch_name); + if (php_git2_check_error(error, "git_branch_remote_name" TSRMLS_CC)) { + RETURN_FALSE; + } + RETURN_STRING(remote_name_out, 1); +} +/* }}} */ diff --git a/branch.h b/branch.h new file mode 100644 index 0000000000..5e5ae0f83f --- /dev/null +++ b/branch.h @@ -0,0 +1,147 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_BRANCH_H +#define PHP_GIT2_BRANCH_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_branch_create, 0, 0, 4) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, branch_name) + ZEND_ARG_INFO(0, target) + ZEND_ARG_INFO(0, force) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_branch_delete, 0, 0, 1) + ZEND_ARG_INFO(0, branch) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_branch_iterator_new, 0, 0, 2) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, list_flags) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_branch_next, 0, 0, 2) + ZEND_ARG_INFO(0, out_type) + ZEND_ARG_INFO(0, iter) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_branch_iterator_free, 0, 0, 1) + ZEND_ARG_INFO(0, iter) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_branch_move, 0, 0, 3) + ZEND_ARG_INFO(0, branch) + ZEND_ARG_INFO(0, new_branch_name) + ZEND_ARG_INFO(0, force) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_branch_lookup, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, branch_name) + ZEND_ARG_INFO(0, branch_type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_branch_name, 0, 0, 1) + ZEND_ARG_INFO(0, ref) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_branch_upstream, 0, 0, 1) + ZEND_ARG_INFO(0, branch) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_branch_set_upstream, 0, 0, 2) + ZEND_ARG_INFO(0, branch) + ZEND_ARG_INFO(0, upstream_name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_branch_upstream_name, 0, 0, 3) + ZEND_ARG_INFO(0, buffer_size) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, canonical_branch_name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_branch_is_head, 0, 0, 1) + ZEND_ARG_INFO(0, branch) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_branch_remote_name, 0, 0, 3) + ZEND_ARG_INFO(0, buffer_size) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, canonical_branch_name) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_branch_create(repo, branch_name, target, force) +*/ +PHP_FUNCTION(git_branch_create); + +/* {{{ proto long git_branch_delete(branch) +*/ +PHP_FUNCTION(git_branch_delete); + +/* {{{ proto resource git_branch_iterator_new(repo, list_flags) +*/ +PHP_FUNCTION(git_branch_iterator_new); + +/* {{{ proto resource git_branch_next(out_type, iter) +*/ +PHP_FUNCTION(git_branch_next); + +/* {{{ proto void git_branch_iterator_free(iter) +*/ +PHP_FUNCTION(git_branch_iterator_free); + +/* {{{ proto resource git_branch_move(branch, new_branch_name, force) +*/ +PHP_FUNCTION(git_branch_move); + +/* {{{ proto resource git_branch_lookup(repo, branch_name, branch_type) +*/ +PHP_FUNCTION(git_branch_lookup); + +/* {{{ proto resource git_branch_name(ref) +*/ +PHP_FUNCTION(git_branch_name); + +/* {{{ proto resource git_branch_upstream(branch) +*/ +PHP_FUNCTION(git_branch_upstream); + +/* {{{ proto long git_branch_set_upstream(branch, upstream_name) +*/ +PHP_FUNCTION(git_branch_set_upstream); + +/* {{{ proto resource git_branch_upstream_name(buffer_size, repo, canonical_branch_name) +*/ +PHP_FUNCTION(git_branch_upstream_name); + +/* {{{ proto long git_branch_is_head(branch) +*/ +PHP_FUNCTION(git_branch_is_head); + +/* {{{ proto resource git_branch_remote_name(buffer_size, repo, canonical_branch_name) +*/ +PHP_FUNCTION(git_branch_remote_name); + +#endif \ No newline at end of file diff --git a/checkout.c b/checkout.c new file mode 100644 index 0000000000..e5f0ef763a --- /dev/null +++ b/checkout.c @@ -0,0 +1,91 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "checkout.h" + +/* {{{ proto long git_checkout_head(resource $repo, $opts) + */ +PHP_FUNCTION(git_checkout_head) +{ + zval *opts = NULL, *repo = NULL; + php_git2_t *_repo = NULL; + int result = 0, shoud_free = 0; + git_checkout_opts *options; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r|a", &repo, &opts) == FAILURE) { + return; + } + + if (opts != NULL) { + if (php_git2_array_to_git_checkout_opts(&options, opts TSRMLS_CC)) { + RETURN_FALSE; + } + shoud_free = 1; + } else { + //memset(&options, '\0', sizeof(git_checkout_opts)); + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_checkout_head(PHP_GIT2_V(_repo, repository), options); + if (shoud_free) { + php_git_git_checkout_opts_free(options TSRMLS_CC); + } + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto long git_checkout_index(resource $repo, resource $index, $opts) + */ +PHP_FUNCTION(git_checkout_index) +{ + int result = 0; + zval *repo = NULL, *index = NULL, *opts = NULL; + php_git2_t *_repo = NULL, *_index = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rra", &repo, &index, &opts) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_checkout_index(PHP_GIT2_V(_repo, repository), PHP_GIT2_V(_index, index), opts); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto long git_checkout_tree(resource $repo, resource $treeish, $opts) + */ +PHP_FUNCTION(git_checkout_tree) +{ + int result = 0; + zval *repo = NULL, *treeish = NULL, *opts = NULL; + php_git2_t *_repo = NULL, *_treeish = NULL; + git_checkout_opts options = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rra", &repo, &treeish, &opts) == FAILURE) { + return; + } + + if (opts != NULL && php_git2_array_to_git_checkout_opts(&options, opts TSRMLS_CC)) { + RETURN_FALSE; + } else { + memset(&options, '\0', sizeof(git_checkout_opts)); + } + + if (treeish != NULL) { + ZEND_FETCH_RESOURCE(_treeish, php_git2_t*, &treeish, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + treeish = PHP_GIT2_V(_treeish, object); + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_treeish, php_git2_t*, &treeish, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_checkout_tree(PHP_GIT2_V(_repo, repository), PHP_GIT2_V(_treeish, object), opts); + RETURN_LONG(result); +} +/* }}} */ + + diff --git a/checkout.h b/checkout.h new file mode 100644 index 0000000000..29eb09d27a --- /dev/null +++ b/checkout.h @@ -0,0 +1,58 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_CHECKOUT_H +#define PHP_GIT2_CHECKOUT_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_checkout_head, 0, 0, 2) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, opts) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_checkout_index, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, opts) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_checkout_tree, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, treeish) + ZEND_ARG_INFO(0, opts) +ZEND_END_ARG_INFO() + +/* {{{ proto long git_checkout_head(repo, opts) +*/ +PHP_FUNCTION(git_checkout_head); + +/* {{{ proto long git_checkout_index(repo, index, opts) +*/ +PHP_FUNCTION(git_checkout_index); + +/* {{{ proto long git_checkout_tree(repo, treeish, opts) +*/ +PHP_FUNCTION(git_checkout_tree); + +#endif \ No newline at end of file diff --git a/clone.c b/clone.c new file mode 100644 index 0000000000..095aa5dc38 --- /dev/null +++ b/clone.c @@ -0,0 +1,68 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "clone.h" + +static void php_git2_git_clone_options_to_array(git_clone_options *options, zval **out TSRMLS_DC) +{ + zval *result, *pathspec; + + MAKE_STD_ZVAL(result); + array_init(result); + + add_assoc_long_ex(result, ZEND_STRS("version"), options->version); + add_assoc_long_ex(result, ZEND_STRS("bare"), options->bare); + add_assoc_long_ex(result, ZEND_STRS("ignore_cert_errors"), options->ignore_cert_errors); + /* TODO: make other options available */ + *out = result; +} + +static void php_git2_array_to_git_clone_options(git_clone_options *options, zval *array TSRMLS_DC) +{ + options->version = php_git2_read_arrval_long2(array, ZEND_STRS("version"), 1 TSRMLS_CC); + options->bare = php_git2_read_arrval_long2(array, ZEND_STRS("bare"), 0 TSRMLS_CC); + options->ignore_cert_errors = php_git2_read_arrval_long2(array, ZEND_STRS("ignore_cert_errors"), 0 TSRMLS_CC); +} + +/* {{{ proto resource git_clone(string $url, string $localpath[, array $options]) +*/ +PHP_FUNCTION(git_clone) +{ + char *url, *localpath; + int url_len, localpath_len; + zval *opts = NULL;// = GIT_OPTIONS_INIT; + php_git2_t *git2; + git_repository *repository; + int error; + git_clone_options options = GIT_CLONE_OPTIONS_INIT; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "ss|a", &url, &url_len, &localpath, &localpath_len, &opts) == FAILURE) { + return; + } + + /* TODO(chobie): convert options to git_clone_options */ + + php_git2_array_to_git_clone_options(&options, opts TSRMLS_CC); + + + error = git_clone(&repository, url, localpath, &options); + if (php_git2_check_error(error, "git_clone" TSRMLS_CC)) { + RETURN_FALSE + } + + PHP_GIT2_MAKE_RESOURCE(git2); + + PHP_GIT2_V(git2, repository) = repository; + git2->type = PHP_GIT2_TYPE_REPOSITORY; + git2->resource_id = PHP_GIT2_LIST_INSERT(git2, git2_resource_handle); + git2->should_free_v = 1; + + ZVAL_RESOURCE(return_value, git2->resource_id); +} + +/* {{{ proto int git_clone_into(resource $repository, resource $remote, long $co_opts, string $branch) +*/ +PHP_FUNCTION(git_clone_into) +{ + /* TODO(chobie): implement this*/ +} diff --git a/clone.h b/clone.h new file mode 100644 index 0000000000..a6d759016a --- /dev/null +++ b/clone.h @@ -0,0 +1,50 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_CLONE_H +#define PHP_GIT2_CLONE_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_clone, 0, 0, 3) + ZEND_ARG_INFO(0, url) + ZEND_ARG_INFO(0, localpath) + ZEND_ARG_INFO(0, options) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_clone_into, 0, 0, 4) + ZEND_ARG_INFO(0, repository) + ZEND_ARG_INFO(0, remote) + ZEND_ARG_INFO(0, co_opts) + ZEND_ARG_INFO(0, branch) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_clone(string $url, string $localpath[, long $options]) +*/ +PHP_FUNCTION(git_clone); + +/* {{{ proto int git_clone_into(resource $repository, resource $remote, long $co_opts, string $branch) +*/ +PHP_FUNCTION(git_clone_into); + +#endif \ No newline at end of file diff --git a/commit.c b/commit.c index 6b639caae3..1f38036672 100644 --- a/commit.c +++ b/commit.c @@ -1,318 +1,489 @@ -/* - * The MIT License - * - * Copyright (c) 2010 - 2012 Shuhei Tanuma - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. +#include "php_git2.h" +#include "php_git2_priv.h" +#include "commit.h" + +/* {{{ proto long git_commit_lookup(resource $repo, string $id) */ +PHP_FUNCTION(git_commit_lookup) +{ + int result = 0, id_len = 0; + git_commit *commit = NULL; + zval *repo = NULL; + php_git2_t *_repo = NULL, *_result = NULL; + char *id = NULL; + git_oid __id = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repo, &id, &id_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__id, id, id_len)) { + RETURN_FALSE; + } + result = git_commit_lookup(&commit, PHP_GIT2_V(_repo, repository), &__id); + if (php_git2_make_resource(&_result, PHP_GIT2_TYPE_COMMIT, commit, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(_result)); +} +/* }}} */ -#include "php_git2.h" +/* {{{ proto resource git_commit_author(resource $commit) +*/ +PHP_FUNCTION(git_commit_author) +{ + php_git2_t *git2; + zval *commit; + git_signature *author; + zval *result; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &commit) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &commit, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); -PHPAPI zend_class_entry *git2_commit_class_entry; + author = git_commit_author(PHP_GIT2_V(git2, commit)); + php_git2_signature_to_array(author, &result TSRMLS_CC); + RETURN_ZVAL(result, 0, 1); +} +/* }}} */ -static void php_git2_commit_free_storage(php_git2_commit *object TSRMLS_DC) +/* {{{ proto resource git_commit_tree(resource $commit) + */ +PHP_FUNCTION(git_commit_tree) { - if (object->commit != NULL) { - git_commit_free(object->commit); - object->commit = NULL; + php_git2_t *result = NULL, *_commit = NULL; + git_tree *tree_out = NULL; + zval *commit = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &commit) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_commit, php_git2_t*, &commit, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_commit_tree(&tree_out, PHP_GIT2_V(_commit, commit)); + if (php_git2_check_error(error, "git_commit_tree" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_TREE, tree_out, 1 TSRMLS_CC)) { + RETURN_FALSE; } - zend_object_std_dtor(&object->zo TSRMLS_CC); - efree(object); + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); } +/* }}} */ -zend_object_value php_git2_commit_new(zend_class_entry *ce TSRMLS_DC) +/* {{{ proto long git_commit_lookup_prefix(resource $repo, string $id, long $len) + */ +PHP_FUNCTION(git_commit_lookup_prefix) { - zend_object_value retval; + int result = 0, id_len = 0; + git_commit *commit = NULL; + zval *repo = NULL; + php_git2_t *_repo = NULL, *_result = NULL; + char *id = NULL; + git_oid __id = {0}; + long len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsl", &repo, &id, &id_len, &len) == FAILURE) { + return; + } - PHP_GIT2_STD_CREATE_OBJECT(php_git2_commit); - return retval; + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__id, id, id_len)) { + RETURN_FALSE; + } + result = git_commit_lookup_prefix(&commit, PHP_GIT2_V(_repo, repository), &__id, len); + if (php_git2_make_resource(&_result, PHP_GIT2_TYPE_COMMIT, commit, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(_result)); } +/* }}} */ -ZEND_BEGIN_ARG_INFO_EX(arginfo_git2_commit_create, 0,0,2) - ZEND_ARG_INFO(0, repository) - ZEND_ARG_INFO(0, data) -ZEND_END_ARG_INFO() +/* {{{ proto resource git_commit_id(resource $commit) + */ +PHP_FUNCTION(git_commit_id) +{ + const git_oid *result = NULL; + zval *commit = NULL; + php_git2_t *_commit = NULL; + char __result[GIT2_OID_HEXSIZE] = {0}; -/* -{{{ proto: Git2\Commit::getMessage() -*/ -PHP_METHOD(git2_commit, getMessage) + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &commit) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_commit, php_git2_t*, &commit, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_commit_id(PHP_GIT2_V(_commit, commit)); + git_oid_fmt(__result, result); + RETURN_STRING(__result, 1); +} +/* }}} */ + +/* {{{ proto resource git_commit_owner(resource $commit) + */ +PHP_FUNCTION(git_commit_owner) { - char *data; - php_git2_commit *m_commit; - - m_commit = PHP_GIT2_GET_OBJECT(php_git2_commit, getThis()); + git_repository *result = NULL; + zval *commit = NULL; + php_git2_t *_commit = NULL, *__result = NULL; - if (m_commit != NULL) { - if (m_commit->commit == NULL) { - RETURN_FALSE; - } - - RETURN_STRING(git_commit_message(m_commit->commit),1); - } else { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &commit) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_commit, php_git2_t*, &commit, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_commit_owner(PHP_GIT2_V(_commit, commit)); + if (php_git2_make_resource(&__result, PHP_GIT2_TYPE_COMMIT, result, 1 TSRMLS_CC)) { RETURN_FALSE; } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(__result)); } /* }}} */ -/* -{{{ proto: Git2\Commit::getMessageEncoding() + +/* {{{ proto resource git_commit_message_encoding(commit) */ -PHP_METHOD(git2_commit, getMessageEncoding) +PHP_FUNCTION(git_commit_message_encoding) { + zval *commit; + php_git2_t *_commit; const char *encoding; - php_git2_commit *m_commit; - - m_commit = PHP_GIT2_GET_OBJECT(php_git2_commit, getThis()); - if (m_commit != NULL) { - if (m_commit->commit == NULL) { - RETURN_FALSE; - } - - encoding = git_commit_message_encoding(m_commit->commit); - if (encoding != NULL) { - RETURN_STRING(encoding,1); - } else { - RETURN_STRING("UTF-8",1); - } - } - RETURN_FALSE; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &commit) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_commit, php_git2_t*, &commit, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + encoding = git_commit_message_encoding(PHP_GIT2_V(_commit, commit)); + RETURN_STRING(encoding, 1); } /* }}} */ +/* {{{ proto resource git_commit_message(commit) +*/ +PHP_FUNCTION(git_commit_message) +{ + zval *commit; + php_git2_t *_commit; + const char *message; -/* -{{{ proto: Git2\Commit::parentCount() + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &commit) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_commit, php_git2_t*, &commit, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + message = git_commit_message(PHP_GIT2_V(_commit, commit)); + RETURN_STRING(message, 1); +} +/* }}} */ + +/* {{{ proto resource git_commit_message_raw(commit) */ -PHP_METHOD(git2_commit, parentCount) +PHP_FUNCTION(git_commit_message_raw) { - unsigned int parent_count = 0; - php_git2_commit *m_commit; - - m_commit = PHP_GIT2_GET_OBJECT(php_git2_commit, getThis()); + zval *commit; + php_git2_t *_commit; + const char *message; - if (m_commit != NULL) { - if (m_commit->commit == NULL) { - RETURN_FALSE; - } - - parent_count = git_commit_parentcount(m_commit->commit); - RETURN_LONG(parent_count); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &commit) == FAILURE) { + return; } - RETURN_FALSE; + + ZEND_FETCH_RESOURCE(_commit, php_git2_t*, &commit, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + message = git_commit_message_raw(PHP_GIT2_V(_commit, commit)); + RETURN_STRING(message, 1); } /* }}} */ -/* -{{{ proto: Git2\Commit::getAuthor() +/* {{{ proto resource git_commit_time(commit) */ -PHP_METHOD(git2_commit, getAuthor) +PHP_FUNCTION(git_commit_time) { - unsigned int parent_count = 0; - php_git2_commit *m_commit; - zval *z_signature, *date; - - m_commit = PHP_GIT2_GET_OBJECT(php_git2_commit, getThis()); + zval *commit; + php_git2_t *_commit; + git_time_t time; - if (m_commit != NULL) { - if (m_commit->commit == NULL) { - RETURN_FALSE; - } + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &commit) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_commit, php_git2_t*, &commit, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + time = git_commit_time(PHP_GIT2_V(_commit, commit)); - php_git2_create_signature_from_commit(&z_signature, m_commit->commit, 0 TSRMLS_CC); - RETVAL_ZVAL(z_signature, 0, 1); - } else { - RETURN_FALSE; + /* NOTE(chobie) should this return as a string? */ + RETURN_LONG(time); +} +/* }}} */ + +/* {{{ proto long git_commit_time_offset(commit) +*/ +PHP_FUNCTION(git_commit_time_offset) +{ + zval *commit; + php_git2_t *_commit; + int result = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &commit) == FAILURE) { + return; } + ZEND_FETCH_RESOURCE(_commit, php_git2_t*, &commit, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_commit_time_offset(PHP_GIT2_V(_commit, commit)); + RETURN_LONG(result); } /* }}} */ -/* -{{{ proto: Git2\Commit::getCommitter() +/* {{{ proto resource git_commit_committer(commit) */ -PHP_METHOD(git2_commit, getCommitter) +PHP_FUNCTION(git_commit_committer) { - unsigned int parent_count = 0; - php_git2_commit *m_commit; - zval *z_signature, *date; - - m_commit = PHP_GIT2_GET_OBJECT(php_git2_commit, getThis()); + zval *commit; + php_git2_t *git2; + git_signature *committer; + zval *result; - if (m_commit != NULL) { - if (m_commit->commit == NULL) { - RETURN_FALSE; - } + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &commit) == FAILURE) { + return; + } - php_git2_create_signature_from_commit(&z_signature, m_commit->commit,1 TSRMLS_CC); - RETVAL_ZVAL(z_signature, 0, 1); - } else { - RETURN_FALSE; + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &commit, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + committer = git_commit_committer(PHP_GIT2_V(git2, commit)); + php_git2_signature_to_array(committer, &result TSRMLS_CC); + RETURN_ZVAL(result, 0, 1); +} +/* }}} */ + +/* {{{ proto resource git_commit_raw_header(commit) +*/ +PHP_FUNCTION(git_commit_raw_header) +{ + zval *commit; + php_git2_t *_commit; + const char *header; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &commit) == FAILURE) { + return; } + ZEND_FETCH_RESOURCE(_commit, php_git2_t*, &commit, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + header = git_commit_raw_header(PHP_GIT2_V(_commit, commit)); + + RETURN_STRING(header, 1); } /* }}} */ -/* -{{{ proto: Git2\Commit::create(Git2\Repository $repo, array $data) +/* {{{ proto resource git_commit_tree_id(commit) */ -PHP_METHOD(git2_commit, create) +PHP_FUNCTION(git_commit_tree_id) { - php_git2_tree *m_tree; - php_git2_signature *m_author,*m_committer; - php_git2_repository *m_repository; - zval *repository, **element, *z_parents, *z_tree, *z_author, *z_committer, *z_array, **value_pp = NULL; - HashTable *hash; - const git_commit **parents = NULL; - git_commit **free_list = NULL; - git_tree *tree; - git_signature *author, *committer; - git_oid commit_oid; - char *message, *encoding, *ref, oid_out[GIT_OID_HEXSZ]; - int parent_count, i, error = 0; - HashPosition pos; + zval *commit; + php_git2_t *_commit; + char out[GIT2_OID_HEXSIZE] = {0}; + const git_oid *id; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "Oa", &repository, git2_repository_class_entry,&z_array) == FAILURE) { + "r", &commit) == FAILURE) { return; } - - m_repository = PHP_GIT2_GET_OBJECT(php_git2_repository, repository); + ZEND_FETCH_RESOURCE(_commit, php_git2_t*, &commit, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + id = git_commit_tree_id(PHP_GIT2_V(_commit, commit)); + + git_oid_fmt(out, id); + RETURN_STRING(out, 1); +} +/* }}} */ - hash = Z_ARRVAL_P(z_array); - if (zend_hash_find(hash,"author",sizeof("author"),(void **)&value_pp) != FAILURE) { - z_author = *value_pp; - m_author = PHP_GIT2_GET_OBJECT(php_git2_signature,z_author); +/* {{{ proto resource git_commit_parentcount(commit) +*/ +PHP_FUNCTION(git_commit_parentcount) +{ + zval *commit; + php_git2_t *_commit; + unsigned long count; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &commit) == FAILURE) { + return; } + ZEND_FETCH_RESOURCE(_commit, php_git2_t*, &commit, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + count = git_commit_parentcount(PHP_GIT2_V(_commit, commit)); + RETURN_LONG(count); +} +/* }}} */ + +/* {{{ proto resource git_commit_parent(commit, n) +*/ +PHP_FUNCTION(git_commit_parent) +{ + zval *commit; + php_git2_t *_commit, *result; + git_commit *parent; + long n = 0; + int error = 0; - if (zend_hash_find(hash,"committer",sizeof("committer"),(void **)&value_pp) != FAILURE) { - z_committer = *value_pp; - m_committer = PHP_GIT2_GET_OBJECT(php_git2_signature,z_committer); - } else { - z_committer = z_author; - m_committer = PHP_GIT2_GET_OBJECT(php_git2_signature,z_committer); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &commit, &n) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_commit, php_git2_t*, &commit, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_commit_parent(&parent, PHP_GIT2_V(_commit, commit), n); + if (php_git2_check_error(error, "git_commit_parent" TSRMLS_CC)) { + RETURN_FALSE } - if (zend_hash_find(hash,"tree",sizeof("tree"),(void **)&value_pp) != FAILURE) { - z_tree = *value_pp; - if (Z_TYPE_P(z_tree) == IS_STRING) { - git_oid oid; - error = git_oid_fromstr(&oid, Z_STRVAL_P(z_tree)); - error = git_tree_lookup(&tree, m_repository->repository,&oid); - } else { - m_tree = PHP_GIT2_GET_OBJECT(php_git2_tree, z_tree); - tree = m_tree->tree; - } + PHP_GIT2_MAKE_RESOURCE(result); + PHP_GIT2_V(result, commit) = parent; + result->type = PHP_GIT2_TYPE_COMMIT; + result->resource_id = PHP_GIT2_LIST_INSERT(result, git2_resource_handle); + result->should_free_v = 0; + + ZVAL_RESOURCE(return_value, result->resource_id); +} +/* }}} */ + +/* {{{ proto resource git_commit_parent_id(commit, n) +*/ +PHP_FUNCTION(git_commit_parent_id) +{ + zval *commit; + php_git2_t *_commit; + long n; + git_oid *oid; + char out[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &commit, &n) == FAILURE) { + return; } + ZEND_FETCH_RESOURCE(_commit, php_git2_t*, &commit, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + oid = git_commit_parent_id(PHP_GIT2_V(_commit, commit), n); + git_oid_fmt(out, oid); + + RETURN_STRING(out, 1); +} +/* }}} */ + +/* {{{ proto resource git_commit_nth_gen_ancestor(commit, n) +*/ +PHP_FUNCTION(git_commit_nth_gen_ancestor) +{ + zval *commit; + php_git2_t *_commit, *result; + git_commit *ancestor; + long n; + int error; - if (zend_hash_find(hash,"parents",sizeof("parents"),(void **)&value_pp) != FAILURE) { - z_parents = *value_pp; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &commit, &n) == FAILURE) { + return; } + ZEND_FETCH_RESOURCE(_commit, php_git2_t*, &commit, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); - if (zend_hash_find(hash,"ref",sizeof("ref"),(void **)&value_pp) != FAILURE) { - ref = emalloc(sizeof(char)*Z_STRLEN_PP(value_pp)+1); - sprintf(ref, Z_STRVAL_PP(value_pp)); - } else { - ref = emalloc(sizeof(char)*5); - sprintf(ref,"HEAD"); + error = git_commit_nth_gen_ancestor(&ancestor, PHP_GIT2_V(_commit, commit), n); + if (php_git2_check_error(error, "git_commit_nth_gen_ancestor" TSRMLS_CC)) { + RETURN_FALSE } - if (zend_hash_find(hash,"message",sizeof("message"),(void **)&value_pp) != FAILURE) { - message = Z_STRVAL_PP(value_pp); + PHP_GIT2_MAKE_RESOURCE(result); + PHP_GIT2_V(result, commit) = ancestor; + result->type = PHP_GIT2_TYPE_COMMIT; + result->resource_id = PHP_GIT2_LIST_INSERT(result, git2_resource_handle); + result->should_free_v = 0; + + ZVAL_RESOURCE(return_value, result->resource_id); + +} +/* }}} */ + +/* {{{ proto resource git_commit_create( + resource $repo, string $update_ref, array $author, array $committer, + string $message_encoding, string $message, resource $tree, array $parents) +*/ +PHP_FUNCTION(git_commit_create) +{ + zval *repo, *tree, *parents, *committer, *author, **element; + char *update_ref = {0}, *message_encoding = {0}, *message = {0}; + int update_ref_len, message_encoding_len, message_len, parent_count = 0, error = 0, i; + php_git2_t *_repo, *_tree; + git_signature __author, __committer; + char out[GIT2_OID_HEXSIZE] = {0}; + git_oid oid; + const git_commit **__parents = NULL; + HashPosition pos; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsaassra", &repo, &update_ref, &update_ref_len, &author, + &committer, &message_encoding, &message_encoding_len, &message, + &message_len, &tree, &parents) == FAILURE) { + return; } - if (zend_hash_find(hash,"encoding",sizeof("encoding"),(void **)&value_pp) != FAILURE) { - encoding = emalloc(sizeof(char)*Z_STRLEN_PP(value_pp)+1); - sprintf(encoding, Z_STRVAL_PP(value_pp)); - } else { - encoding = emalloc(sizeof(char)*6); - sprintf(encoding,"UTF-8"); + memset(&__author, '\0', sizeof(git_signature)); + memset(&__committer, '\0', sizeof(git_signature)); + + if (committer == NULL || Z_TYPE_P(committer) == IS_NULL) { + committer = author; } - - parent_count = zend_hash_num_elements(Z_ARRVAL_P(z_parents)); - parents = emalloc(parent_count * sizeof(void *)); - free_list = emalloc(parent_count * sizeof(void *)); - - for(i = 0, zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(z_parents), &pos); - zend_hash_get_current_data_ex(Z_ARRVAL_P(z_parents), (void **)&element, &pos) == SUCCESS; - zend_hash_move_forward_ex(Z_ARRVAL_P(z_parents), &pos) + + php_git2_array_to_signature(&__author, author TSRMLS_CC); + php_git2_array_to_signature(&__committer, committer TSRMLS_CC); + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_tree, php_git2_t*, &tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + parent_count = zend_hash_num_elements(Z_ARRVAL_P(parents)); + __parents = emalloc(parent_count * sizeof(void *)); + for(i = 0, zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(parents), &pos); + zend_hash_get_current_data_ex(Z_ARRVAL_P(parents), (void **)&element, &pos) == SUCCESS; + zend_hash_move_forward_ex(Z_ARRVAL_P(parents), &pos) ) { - git_commit *parent = NULL; - git_commit *free_ptr = NULL; - + git_commit *p = NULL; + if (Z_TYPE_PP(element) == IS_STRING) { - git_oid oid; error = git_oid_fromstr(&oid, Z_STRVAL_PP(element)); - git_commit_lookup(&parent, m_repository->repository,&oid); - - free_ptr = parent; - } else { - php_git2_commit *m_commit; - m_commit = PHP_GIT2_GET_OBJECT(php_git2_commit, *element); - parent = m_commit->commit; + git_commit_lookup(&p, PHP_GIT2_V(_repo, repository), &oid); + } else if (Z_TYPE_PP(element) == IS_RESOURCE) { + php_git2_t *t; + ZEND_FETCH_RESOURCE(t, php_git2_t*, element, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + p = PHP_GIT2_V(t, commit); } - - parents[i] = parent; - free_list[i] = free_ptr; + + __parents[i] = p; i++; } - + error = git_commit_create( - &commit_oid, - m_repository->repository, - ref, - m_author->signature, - m_committer->signature, - encoding, + &oid, + PHP_GIT2_V(_repo, repository), + update_ref, + &__author, + &__committer, + message_encoding, message, - tree, + PHP_GIT2_V(_tree, tree), parent_count, - parents + __parents ); - git_oid_fmt(oid_out, &commit_oid); - RETVAL_STRINGL(oid_out,GIT_OID_HEXSZ,1); - - for (i =0; i < parent_count; ++i) { - git_object_free((git_object *)free_list[i]); + efree(__parents); + + if (php_git2_check_error(error, "git_commit_create" TSRMLS_CC)) { + RETURN_FALSE } - efree(ref); - efree(parents); - efree(free_list); - efree(encoding); -} -/* }}} */ -static zend_function_entry php_git2_commit_methods[] = { - PHP_ME(git2_commit, getMessage, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_commit, getMessageEncoding, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_commit, parentCount, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_commit, getAuthor, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_commit, getCommitter, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_commit, create, arginfo_git2_commit_create, ZEND_ACC_STATIC | ZEND_ACC_PUBLIC) - {NULL,NULL,NULL} -}; - -void php_git2_commit_init(TSRMLS_D) -{ - zend_class_entry ce; - - INIT_NS_CLASS_ENTRY(ce, PHP_GIT2_NS, "Commit", php_git2_commit_methods); - git2_commit_class_entry = zend_register_internal_class(&ce TSRMLS_CC); - git2_commit_class_entry->create_object = php_git2_commit_new; + git_oid_fmt(out, &oid); + RETURN_STRING(out, 1); } \ No newline at end of file diff --git a/commit.h b/commit.h new file mode 100644 index 0000000000..fd3af615a8 --- /dev/null +++ b/commit.h @@ -0,0 +1,200 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_COMMIT_H +#define PHP_GIT2_COMMIT_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_lookup, 0, 0, 2) + ZEND_ARG_INFO(0, repository) + ZEND_ARG_INFO(0, oid) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_author, 0, 0, 1) + ZEND_ARG_INFO(0, commit) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_tree, 0, 0, 1) + ZEND_ARG_INFO(0, commit) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_lookup_prefix, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, id) + ZEND_ARG_INFO(0, len) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_id, 0, 0, 1) + ZEND_ARG_INFO(0, commit) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_owner, 0, 0, 1) + ZEND_ARG_INFO(0, commit) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_message_encoding, 0, 0, 1) + ZEND_ARG_INFO(0, commit) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_message, 0, 0, 1) + ZEND_ARG_INFO(0, commit) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_message_raw, 0, 0, 1) + ZEND_ARG_INFO(0, commit) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_time, 0, 0, 1) + ZEND_ARG_INFO(0, commit) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_time_offset, 0, 0, 1) + ZEND_ARG_INFO(0, commit) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_committer, 0, 0, 1) + ZEND_ARG_INFO(0, commit) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_raw_header, 0, 0, 1) + ZEND_ARG_INFO(0, commit) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_tree_id, 0, 0, 1) + ZEND_ARG_INFO(0, commit) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_parentcount, 0, 0, 1) + ZEND_ARG_INFO(0, commit) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_parent, 0, 0, 2) + ZEND_ARG_INFO(0, commit) + ZEND_ARG_INFO(0, n) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_parent_id, 0, 0, 2) + ZEND_ARG_INFO(0, commit) + ZEND_ARG_INFO(0, n) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_nth_gen_ancestor, 0, 0, 2) + ZEND_ARG_INFO(0, commit) + ZEND_ARG_INFO(0, n) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_commit_create, 0, 0, 8) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, update_ref) + ZEND_ARG_INFO(0, author) + ZEND_ARG_INFO(0, committer) + ZEND_ARG_INFO(0, message_encoding) + ZEND_ARG_INFO(0, message) + ZEND_ARG_INFO(0, tree) + ZEND_ARG_INFO(0, parents) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_commit_lookup(resource $repository, mixed $oid) +*/ +PHP_FUNCTION(git_commit_lookup); + +/* {{{ proto resource git_commit_author(resource $commit) +*/ +PHP_FUNCTION(git_commit_author); + +/* {{{ proto resource git_commit_tree(resource $commit) +*/ +PHP_FUNCTION(git_commit_tree); + +/* {{{ proto resource git_commit_lookup_prefix(repo, id, len) +*/ +PHP_FUNCTION(git_commit_lookup_prefix); + +/* {{{ proto resource git_commit_id(commit) +*/ +PHP_FUNCTION(git_commit_id); + +/* {{{ proto resource git_commit_owner(commit) +*/ +PHP_FUNCTION(git_commit_owner); + +/* {{{ proto resource git_commit_message_encoding(commit) +*/ +PHP_FUNCTION(git_commit_message_encoding); + +/* {{{ proto resource git_commit_message(commit) +*/ +PHP_FUNCTION(git_commit_message); + +/* {{{ proto resource git_commit_message_raw(commit) +*/ +PHP_FUNCTION(git_commit_message_raw); + +/* {{{ proto resource git_commit_time(commit) +*/ +PHP_FUNCTION(git_commit_time); + +/* {{{ proto long git_commit_time_offset(commit) +*/ +PHP_FUNCTION(git_commit_time_offset); + +/* {{{ proto resource git_commit_committer(commit) +*/ +PHP_FUNCTION(git_commit_committer); + +/* {{{ proto resource git_commit_raw_header(commit) +*/ +PHP_FUNCTION(git_commit_raw_header); + +/* {{{ proto resource git_commit_tree(commit) +*/ +PHP_FUNCTION(git_commit_tree); + +/* {{{ proto resource git_commit_tree_id(commit) +*/ +PHP_FUNCTION(git_commit_tree_id); + +/* {{{ proto resource git_commit_parentcount(commit) +*/ +PHP_FUNCTION(git_commit_parentcount); + +/* {{{ proto resource git_commit_parent(commit, n) +*/ +PHP_FUNCTION(git_commit_parent); + +/* {{{ proto resource git_commit_parent_id(commit, n) +*/ +PHP_FUNCTION(git_commit_parent_id); + +/* {{{ proto resource git_commit_nth_gen_ancestor(commit, n) +*/ +PHP_FUNCTION(git_commit_nth_gen_ancestor); + +/* {{{ proto resource git_commit_create( + resource $repo, string $update_ref, array $author, array $committer, + string $message_encoding, string $message, resource $tree, array $parents) +*/ +PHP_FUNCTION(git_commit_create); + +#endif \ No newline at end of file diff --git a/config.m4 b/config.m4 index 34aab37435..fed1775bce 100644 --- a/config.m4 +++ b/config.m4 @@ -1,51 +1,28 @@ PHP_ARG_ENABLE(git2, Whether to enable the "git2" extension, [ --enable-git2 Enable "php-git2" extension support]) -PHP_ARG_WITH(libgit2-dir, for libgit2, - [ --with-libgit2-dir[=DIR] Set the path to libgit2 install prefix.], yes) +PHP_ARG_ENABLE(git2-debug, for git2 debug support, + [ --enable-git2-debug Enable git2 debug support], no, no) if test $PHP_GIT2 != "no"; then - if test "$PHP_LIBGIT2_DIR" != "no" && test "$PHP_LIBGIT2_DIR" != "yes"; then - LIBGIT2_SEARCH_DIRS=$PHP_LIBGIT2_DIR - else - LIBGIT2_SEARCH_DIRS="/usr/local /usr" - fi + PHP_SUBST(GIT2_SHARED_LIBADD) - for i in $LIBGIT2_SEARCH_DIRS; do - if test -f $i/include/libgit2/git2.h; then - LIBGIT2_DIR=$i - LIBGIT2_INCDIR=$i/include/libgit2 - elif test -f $i/include/git2.h; then - LIBGIT2_DIR=$i - LIBGIT2_INCDIR=$i/include - fi - done + PHP_NEW_EXTENSION(git2, php_git2.c repository.c commit.c tree.c clone.c blob.c helper.c revwalk.c treebuilder.c reference.c g_config.c object.c index.c revparse.c branch.c tag.c status.c cred.c remote.c transport.c diff.c checkout.c filter.c ignore.c indexer.c pathspec.c patch.c merge.c note.c odb.c reflog.c blame.c packbuilder.c stash.c signature.c attr.c reset.c message.c submodule.c giterr.c push.c refspec.c graph.c, $ext_shared) + PHP_ADD_INCLUDE([$ext_srcdir/libgit2/include]) - if test -z "$LIBGIT2_DIR"; then - AC_MSG_ERROR(Cannot find libgit2) - fi + # for now + CFLAGS=" $CFLAGS -Wunused-variable -Wpointer-sign -Wimplicit-function-declaration -Winline -Wunused-macros -Wredundant-decls -Wstrict-aliasing=2 -Wswitch-enum -Wdeclaration-after-statement -Wl,libgit2/build/libgit2.a" - LIBGIT2_LIBDIR=$LIBGIT2_DIR/$PHP_LIBDIR - PHP_ADD_LIBRARY_WITH_PATH(git2, $LIBGIT2_LIBDIR, GIT2_SHARED_LIBADD) + if test "$PHP_GIT2_DEBUG" != "no"; then + CFLAGS="-g -O0 $CFLAGS" + fi - PHP_SUBST(GIT2_SHARED_LIBADD) - PHP_NEW_EXTENSION(git2, git2.c \ - repository.c \ - commit.c \ - blob.c \ - tree.c \ - tree_builder.c \ - tree_entry.c \ - signature.c \ - walker.c \ - reference.c \ - index.c \ - index_entry.c \ - , $ext_shared) + PHP_ADD_LIBPATH($ext_srcdir/libgit2/build, GIT2_SHARED_LIBADD) + #PHP_ADD_LIBRARY(git2,, GIT2_SHARED_LIBADD) + PHP_SUBST([CFLAGS]) ifdef([PHP_ADD_EXTENSION_DEP], [ - PHP_ADD_EXTENSION_DEP(git, spl, true) + PHP_ADD_EXTENSION_DEP(git2, spl, true) ]) - fi diff --git a/cred.c b/cred.c new file mode 100644 index 0000000000..d3a2f1c95d --- /dev/null +++ b/cred.c @@ -0,0 +1,128 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "cred.h" + +/* {{{ proto long git_cred_has_username(resource $cred) + */ +PHP_FUNCTION(git_cred_has_username) +{ + int result = 0; + zval *cred = NULL; + php_git2_t *_cred = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &cred) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_cred, php_git2_t*, &cred, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_cred_has_username(PHP_GIT2_V(_cred, cred)); + RETURN_BOOL(result); +} +/* }}} */ + +/* {{{ proto resource git_cred_userpass_plaintext_new(string $username, string $password) + */ +PHP_FUNCTION(git_cred_userpass_plaintext_new) +{ + php_git2_t *result = NULL; + git_cred *out = NULL; + char *username = NULL, *password = NULL; + int username_len = 0, password_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "ss", &username, &username_len, &password, &password_len) == FAILURE) { + return; + } + + error = git_cred_userpass_plaintext_new(&out, username, password); + if (php_git2_check_error(error, "git_cred_userpass_plaintext_new" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_CRED, out, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto resource git_cred_ssh_key_new(string $username, string $publickey, string $privatekey, string $passphrase) + */ +PHP_FUNCTION(git_cred_ssh_key_new) +{ + php_git2_t *result = NULL; + git_cred *out = NULL; + char *username = NULL, *publickey = NULL, *privatekey = NULL, *passphrase = NULL; + int username_len = 0, publickey_len = 0, privatekey_len = 0, passphrase_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "ssss", &username, &username_len, &publickey, &publickey_len, &privatekey, &privatekey_len, &passphrase, &passphrase_len) == FAILURE) { + return; + } + + error = git_cred_ssh_key_new(&out, username, publickey, privatekey, passphrase); + if (php_git2_check_error(error, "git_cred_ssh_key_new" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_CRED, out, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + + +/* {{{ proto resource git_cred_ssh_custom_new(username, publickey, publickey_len, sign_fn, sign_data) +*/ +PHP_FUNCTION(git_cred_ssh_custom_new) +{ + + /* TODO(chobie): implement this */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "git_cred_ssh_custom_new not implemented yet"); + return; + +// if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, +// "ssr", &username, &username_len, &publickey, &publickey_len, &publickey_len, &sign_fn, &sign_data) == FAILURE) { +// return; +// } +// ZEND_FETCH_RESOURCE(_username, php_git2_t*, &username, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); +} + +/* {{{ proto resource git_cred_default_new() + */ +PHP_FUNCTION(git_cred_default_new) +{ + php_git2_t *result = NULL; + git_cred *out = NULL; + int error = 0; + + error = git_cred_default_new(&out); + if (php_git2_check_error(error, "git_cred_default_new" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_CRED, out, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + + +/* {{{ proto resource git_cred_userpass(url, user_from_url, allowed_types, payload) +*/ +PHP_FUNCTION(git_cred_userpass) +{ + + /* TODO(chobie): implement this */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "git_cred_userpass not implemented yet"); + return; + +// if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, +// "ssl", &url, &url_len, &user_from_url, &user_from_url_len, &allowed_types, &payload) == FAILURE) { +// return; +// } +} + diff --git a/cred.h b/cred.h new file mode 100644 index 0000000000..d21c744600 --- /dev/null +++ b/cred.h @@ -0,0 +1,87 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_CRED_H +#define PHP_GIT2_CRED_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_cred_has_username, 0, 0, 1) + ZEND_ARG_INFO(0, cred) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_cred_userpass_plaintext_new, 0, 0, 2) + ZEND_ARG_INFO(0, username) + ZEND_ARG_INFO(0, password) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_cred_ssh_key_new, 0, 0, 4) + ZEND_ARG_INFO(0, username) + ZEND_ARG_INFO(0, publickey) + ZEND_ARG_INFO(0, privatekey) + ZEND_ARG_INFO(0, passphrase) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_cred_ssh_custom_new, 0, 0, 5) + ZEND_ARG_INFO(0, username) + ZEND_ARG_INFO(0, publickey) + ZEND_ARG_INFO(0, publickey_len) + ZEND_ARG_INFO(0, sign_fn) + ZEND_ARG_INFO(0, sign_data) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_cred_default_new, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_cred_userpass, 0, 0, 4) + ZEND_ARG_INFO(0, url) + ZEND_ARG_INFO(0, user_from_url) + ZEND_ARG_INFO(0, allowed_types) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +/* {{{ proto long git_cred_has_username(cred) +*/ +PHP_FUNCTION(git_cred_has_username); + +/* {{{ proto resource git_cred_userpass_plaintext_new(username, password) +*/ +PHP_FUNCTION(git_cred_userpass_plaintext_new); + +/* {{{ proto resource git_cred_ssh_key_new(username, publickey, privatekey, passphrase) +*/ +PHP_FUNCTION(git_cred_ssh_key_new); + +/* {{{ proto resource git_cred_ssh_custom_new(username, publickey, publickey_len, sign_fn, sign_data) +*/ +PHP_FUNCTION(git_cred_ssh_custom_new); + +/* {{{ proto resource git_cred_default_new() +*/ +PHP_FUNCTION(git_cred_default_new); + +/* {{{ proto resource git_cred_userpass(url, user_from_url, allowed_types, payload) +*/ +PHP_FUNCTION(git_cred_userpass); + +#endif \ No newline at end of file diff --git a/diff.c b/diff.c new file mode 100644 index 0000000000..7acd39a64c --- /dev/null +++ b/diff.c @@ -0,0 +1,469 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "diff.h" + +/* {{{ proto void git_diff_free(resource $diff) + */ +PHP_FUNCTION(git_diff_free) +{ + zval *diff = NULL; + php_git2_t *_diff = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &diff) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_diff, php_git2_t*, &diff, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_diff)) { + git_diff_free(PHP_GIT2_V(_diff, diff)); + GIT2_SHOULD_FREE(_diff) = 0; + }; + zval_ptr_dtor(&diff); +} +/* }}} */ + +/* {{{ proto long git_diff_tree_to_tree(resource $repo, resource $old_tree, resource $new_tree, $opts) + */ +PHP_FUNCTION(git_diff_tree_to_tree) +{ + int result = 0; + git_diff *diff = NULL; + zval *repo = NULL; + php_git2_t *_repo = NULL; + zval *old_tree = NULL; + php_git2_t *_old_tree = NULL; + zval *new_tree = NULL; + php_git2_t *_new_tree = NULL; + zval *opts = NULL; + git_diff_options options = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rrra", &repo, &old_tree, &new_tree, &opts) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_old_tree, php_git2_t*, &old_tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_new_tree, php_git2_t*, &new_tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + php_git2_array_to_git_diff_options(&options, opts TSRMLS_CC); + result = git_diff_tree_to_tree(&diff, PHP_GIT2_V(_repo, repository), PHP_GIT2_V(_old_tree, tree), PHP_GIT2_V(_new_tree, tree), opts); + php_git2_git_diff_options_free(&options); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto long git_diff_tree_to_index(resource $repo, resource $old_tree, resource $index, $opts) + */ +PHP_FUNCTION(git_diff_tree_to_index) +{ + int result = 0; + git_diff *diff = NULL; + zval *repo = NULL, *old_tree = NULL, *index = NULL, *opts = NULL; + php_git2_t *_repo = NULL, *_old_tree = NULL, *_index = NULL, *_diff = NULL; + git_diff_options options = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rrra", &repo, &old_tree, &index, &opts) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_old_tree, php_git2_t*, &old_tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + php_git2_array_to_git_diff_options(&options, opts TSRMLS_CC); + result = git_diff_tree_to_index(&diff, PHP_GIT2_V(_repo, repository), PHP_GIT2_V(_old_tree, tree), PHP_GIT2_V(_index, index), opts); + php_git2_git_diff_options_free(&options); + if (php_git2_make_resource(&_diff, PHP_GIT2_TYPE_DIFF, diff, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(_diff)); + +} +/* }}} */ + +/* {{{ proto long git_diff_index_to_workdir(resource $repo, resource $index, $opts) + */ +PHP_FUNCTION(git_diff_index_to_workdir) +{ + int result = 0; + git_diff *diff = NULL; + zval *repo = NULL, *index = NULL, *opts = NULL; + php_git2_t *_repo = NULL, *_index = NULL, *_diff = NULL; + git_diff_options options = GIT_DIFF_OPTIONS_INIT; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rra", &repo, &index, &opts) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + php_git2_array_to_git_diff_options(&options, opts TSRMLS_CC); + result = git_diff_index_to_workdir(&diff, PHP_GIT2_V(_repo, repository), PHP_GIT2_V(_index, index), opts); + php_git2_git_diff_options_free(&options); + if (php_git2_make_resource(&_diff, PHP_GIT2_TYPE_DIFF, diff, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(_diff)); +} +/* }}} */ + +/* {{{ proto long git_diff_tree_to_workdir(resource $repo, resource $old_tree, $opts) + */ +PHP_FUNCTION(git_diff_tree_to_workdir) +{ + int result = 0; + git_diff *diff = NULL; + zval *repo = NULL, *old_tree = NULL, *opts = NULL; + php_git2_t *_repo = NULL, *_old_tree = NULL, *_result; + git_diff_options options = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rra", &repo, &old_tree, &opts) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_old_tree, php_git2_t*, &old_tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + php_git2_array_to_git_diff_options(&options, opts TSRMLS_CC); + result = git_diff_tree_to_workdir(&diff, PHP_GIT2_V(_repo, repository), PHP_GIT2_V(_old_tree, tree), &options); + if (php_git2_check_error(result, "git_diff_tree_to_workdir" TSRMLS_CC)) { + php_git2_git_diff_options_free(&options); + RETURN_FALSE + } + + php_git2_git_diff_options_free(&options); + + if (php_git2_make_resource(&_result, PHP_GIT2_TYPE_DIFF, diff, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(_result)); +} +/* }}} */ + +/* {{{ proto long git_diff_tree_to_workdir_with_index(resource $repo, resource $old_tree, $opts) + */ +PHP_FUNCTION(git_diff_tree_to_workdir_with_index) +{ + int result = 0; + git_diff *diff = NULL; + zval *repo = NULL, *old_tree = NULL, *opts = NULL; + php_git2_t *_repo = NULL, *_old_tree = NULL, *_diff = NULL; + git_diff_options options = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rra", &repo, &old_tree, &opts) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_old_tree, php_git2_t*, &old_tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + php_git2_array_to_git_diff_options(&options, opts TSRMLS_CC); + result = git_diff_tree_to_workdir_with_index(&diff, PHP_GIT2_V(_repo, repository), PHP_GIT2_V(_old_tree, tree), opts); + php_git2_git_diff_options_free(&options); + if (php_git2_make_resource(&_diff, PHP_GIT2_TYPE_DIFF, diff, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(_diff)); +} +/* }}} */ + +/* {{{ proto long git_diff_merge(resource $onto, resource $from) + */ +PHP_FUNCTION(git_diff_merge) +{ + int result = 0; + zval *onto = NULL, *from = NULL; + php_git2_t *_onto = NULL, *_from = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rr", &onto, &from) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_onto, php_git2_t*, &onto, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_from, php_git2_t*, &from, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_diff_merge(PHP_GIT2_V(_onto, diff), PHP_GIT2_V(_from, diff)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_diff_find_similar(resource $diff, $options) + */ +PHP_FUNCTION(git_diff_find_similar) +{ + int result = 0; + zval *diff = NULL; + php_git2_t *_diff = NULL; + zval *options = NULL; + git_diff_options _options = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "ra", &diff, &options) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_diff, php_git2_t*, &diff, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + php_git2_array_to_git_diff_options(&_options, options TSRMLS_CC); + result = git_diff_find_similar(PHP_GIT2_V(_diff, diff), &_options); + php_git2_git_diff_options_free(&_options); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_diff_options_init(long $version) + */ +PHP_FUNCTION(git_diff_options_init) +{ + int result = 0; + git_diff_options options = {0}; + long version = GIT_DIFF_OPTIONS_VERSION; + zval *out; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "|l", &version) == FAILURE) { + return; + } + + result = git_diff_options_init(&options, version); + php_git2_git_diff_options_to_array(&options, &out TSRMLS_CC); + RETURN_ZVAL(out, 0, 1); +} +/* }}} */ + +/* {{{ proto long git_diff_num_deltas(resource $diff) + */ +PHP_FUNCTION(git_diff_num_deltas) +{ + size_t result = 0; + zval *diff = NULL; + php_git2_t *_diff = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &diff) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_diff, php_git2_t*, &diff, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_diff_num_deltas(PHP_GIT2_V(_diff, diff)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_diff_num_deltas_of_type(resource $diff, $type) + */ +PHP_FUNCTION(git_diff_num_deltas_of_type) +{ + size_t result = 0; + zval *diff = NULL; + php_git2_t *_diff = NULL; + long type = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &diff, &type) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_diff, php_git2_t*, &diff, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_diff_num_deltas_of_type(PHP_GIT2_V(_diff, diff), type); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_diff_get_delta(resource $diff, long $idx) + */ +PHP_FUNCTION(git_diff_get_delta) +{ + const git_diff_delta *result = NULL; + zval *diff = NULL, *_result; + php_git2_t *_diff = NULL; + long idx = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &diff, &idx) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_diff, php_git2_t*, &diff, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_diff_get_delta(PHP_GIT2_V(_diff, diff), idx); + php_git2_diff_delta_to_array(result, &_result TSRMLS_CC); + RETURN_ZVAL(_result, 0, 1); +} +/* }}} */ + +/* {{{ proto long git_diff_is_sorted_icase(resource $diff) + */ +PHP_FUNCTION(git_diff_is_sorted_icase) +{ + int result = 0; + zval *diff = NULL; + php_git2_t *_diff = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &diff) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_diff, php_git2_t*, &diff, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_diff_is_sorted_icase(PHP_GIT2_V(_diff, diff)); + RETURN_BOOL(result); +} +/* }}} */ + + +/* {{{ proto long git_diff_foreach(resource $diff, Callable $file_cb, Callable $hunk_cb, Callable $line_cb, $payload) + */ +PHP_FUNCTION(git_diff_foreach) +{ + int result = 0; + zval *diff = NULL, *payload = NULL; + php_git2_t *_diff = NULL; + zend_fcall_info file_fci = empty_fcall_info; + zend_fcall_info_cache file_fcc = empty_fcall_info_cache; + zend_fcall_info hunk_fci = empty_fcall_info; + zend_fcall_info_cache hunk_fcc = empty_fcall_info_cache; + zend_fcall_info line_fci = empty_fcall_info; + zend_fcall_info_cache line_fcc = empty_fcall_info_cache; + php_git2_multi_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rfffz", &diff, &file_fci, &file_fcc, &hunk_fci, &hunk_fcc, &line_fci, &line_fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_diff, php_git2_t*, &diff, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + php_git2_multi_cb_init(&cb, payload TSRMLS_CC, 3, + &file_fci, &file_fcc, + &hunk_fci, &hunk_fcc, + &line_fci, &line_fcc + ); + + result = git_diff_foreach(PHP_GIT2_V(_diff, diff), php_git2_git_diff_file_cb, php_git2_git_diff_hunk_cb, php_git2_git_diff_line_cb, cb); + php_git2_multi_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto string git_diff_status_char( $status) + */ +PHP_FUNCTION(git_diff_status_char) +{ + char result; + long status = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "l", &status) == FAILURE) { + return; + } + + result = git_diff_status_char(status); + RETURN_STRINGL(&result, 1, 1); +} +/* }}} */ + +/* {{{ proto long git_diff_print(resource $diff, long $format, Callable $print_cb, $payload) + */ +PHP_FUNCTION(git_diff_print) +{ + int result = 0; + zval *diff = NULL, *payload = NULL; + php_git2_t *_diff = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_multi_cb_t *cb = NULL; + long format = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rlfz", &diff, &format, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_diff, php_git2_t*, &diff, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_multi_cb_init(&cb, payload TSRMLS_CC, 3, &empty_fcall_info, &empty_fcall_info_cache, &empty_fcall_info, &empty_fcall_info_cache, &fci, &fcc)) { + RETURN_FALSE; + } + result = git_diff_print(PHP_GIT2_V(_diff, diff), format, php_git2_git_diff_line_cb, cb); + php_git2_multi_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_diff_blobs(resource $old_blob, string $old_as_path, resource $new_blob, string $new_as_path, $options, Callable $file_cb, Callable $hunk_cb, Callable $line_cb, $payload) + */ +PHP_FUNCTION(git_diff_blobs) +{ + int result = 0, old_as_path_len = 0, new_as_path_len = 0; + zval *old_blob = NULL, *new_blob = NULL, *options = NULL, *payload = NULL; + php_git2_t *_old_blob = NULL, *_new_blob = NULL; + char *old_as_path = NULL, *new_as_path = NULL; + zend_fcall_info file_fci = empty_fcall_info; + zend_fcall_info_cache file_fcc = empty_fcall_info_cache; + zend_fcall_info hunk_fci = empty_fcall_info; + zend_fcall_info_cache hunk_fcc = empty_fcall_info_cache; + zend_fcall_info line_fci = empty_fcall_info; + zend_fcall_info_cache line_fcc = empty_fcall_info_cache; + php_git2_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsrsafffz", &old_blob, &old_as_path, &old_as_path_len, &new_blob, &new_as_path, &new_as_path_len, &options, + &file_fci, &file_fcc, &hunk_fci, &hunk_fcc, &line_fci, &line_fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_old_blob, php_git2_t*, &old_blob, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_new_blob, php_git2_t*, &new_blob, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + php_git2_multi_cb_init(&cb, payload TSRMLS_CC, 3, + &file_fci, &file_fcc, + &hunk_fci, &hunk_fcc, + &line_fci, &line_fcc + ); + result = git_diff_blobs( + PHP_GIT2_V(_old_blob, blob), old_as_path, + PHP_GIT2_V(_new_blob, blob), new_as_path, NULL, + php_git2_git_diff_file_cb, php_git2_git_diff_hunk_cb, php_git2_git_diff_line_cb, cb); + php_git2_multi_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_diff_blob_to_buffer(resource $old_blob, string $old_as_path, string $buffer, long $buffer_len, string $buffer_as_path, $options, Callable $file_cb, Callable $hunk_cb, Callable $line_cb, $payload) + */ +PHP_FUNCTION(git_diff_blob_to_buffer) +{ + int result = 0, old_as_path_len = 0, buffer_len = 0, buffer_as_path_len = 0; + zval *old_blob = NULL, *options = NULL, *payload = NULL; + php_git2_t *_old_blob = NULL; + char *old_as_path = NULL, *buffer = NULL, *buffer_as_path = NULL; + zend_fcall_info file_fci = empty_fcall_info; + zend_fcall_info_cache file_fcc = empty_fcall_info_cache; + zend_fcall_info hunk_fci = empty_fcall_info; + zend_fcall_info_cache hunk_fcc = empty_fcall_info_cache; + zend_fcall_info line_fci = empty_fcall_info; + zend_fcall_info_cache line_fcc = empty_fcall_info_cache; + php_git2_multi_cb_t *cb = NULL; + git_diff_options opts = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsslsafffz", &old_blob, &old_as_path, &old_as_path_len, + &buffer, &buffer_len, &buffer_len, &buffer_as_path, &buffer_as_path_len, &options, + &file_fci, &file_fcc, &hunk_fci, &hunk_fcc, &line_fci, &line_fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_old_blob, php_git2_t*, &old_blob, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + php_git2_multi_cb_init(&cb, payload TSRMLS_CC, 3, + &file_fci, &file_fcc, + &hunk_fci, &hunk_fcc, + &line_fci, &line_fcc + ); + result = git_diff_blob_to_buffer( + PHP_GIT2_V(_old_blob, blob), old_as_path, + buffer, buffer_len, buffer_as_path, + &opts, + php_git2_git_diff_file_cb, php_git2_git_diff_hunk_cb, php_git2_git_diff_line_cb, cb); + php_git2_multi_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ diff --git a/diff.h b/diff.h new file mode 100644 index 0000000000..2f3b99c872 --- /dev/null +++ b/diff.h @@ -0,0 +1,215 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_DIFF_H +#define PHP_GIT2_DIFF_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_diff_free, 0, 0, 1) + ZEND_ARG_INFO(0, diff) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_diff_tree_to_tree, 0, 0, 4) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, old_tree) + ZEND_ARG_INFO(0, new_tree) + ZEND_ARG_INFO(0, opts) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_diff_tree_to_index, 0, 0, 4) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, old_tree) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, opts) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_diff_index_to_workdir, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, opts) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_diff_tree_to_workdir, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, old_tree) + ZEND_ARG_INFO(0, opts) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_diff_tree_to_workdir_with_index, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, old_tree) + ZEND_ARG_INFO(0, opts) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_diff_merge, 0, 0, 2) + ZEND_ARG_INFO(0, onto) + ZEND_ARG_INFO(0, from) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_diff_find_similar, 0, 0, 2) + ZEND_ARG_INFO(0, diff) + ZEND_ARG_INFO(0, options) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_diff_options_init, 0, 0, 2) + ZEND_ARG_INFO(0, options) + ZEND_ARG_INFO(0, version) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_diff_num_deltas, 0, 0, 1) + ZEND_ARG_INFO(0, diff) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_diff_num_deltas_of_type, 0, 0, 2) + ZEND_ARG_INFO(0, diff) + ZEND_ARG_INFO(0, type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_diff_get_delta, 0, 0, 2) + ZEND_ARG_INFO(0, diff) + ZEND_ARG_INFO(0, idx) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_diff_is_sorted_icase, 0, 0, 1) + ZEND_ARG_INFO(0, diff) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_diff_foreach, 0, 0, 5) + ZEND_ARG_INFO(0, diff) + ZEND_ARG_INFO(0, file_cb) + ZEND_ARG_INFO(0, hunk_cb) + ZEND_ARG_INFO(0, line_cb) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_diff_status_char, 0, 0, 1) + ZEND_ARG_INFO(0, status) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_diff_print, 0, 0, 4) + ZEND_ARG_INFO(0, diff) + ZEND_ARG_INFO(0, format) + ZEND_ARG_INFO(0, print_cb) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_diff_blobs, 0, 0, 9) + ZEND_ARG_INFO(0, old_blob) + ZEND_ARG_INFO(0, old_as_path) + ZEND_ARG_INFO(0, new_blob) + ZEND_ARG_INFO(0, new_as_path) + ZEND_ARG_INFO(0, options) + ZEND_ARG_INFO(0, file_cb) + ZEND_ARG_INFO(0, hunk_cb) + ZEND_ARG_INFO(0, line_cb) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_diff_blob_to_buffer, 0, 0, 10) + ZEND_ARG_INFO(0, old_blob) + ZEND_ARG_INFO(0, old_as_path) + ZEND_ARG_INFO(0, buffer) + ZEND_ARG_INFO(0, buffer_len) + ZEND_ARG_INFO(0, buffer_as_path) + ZEND_ARG_INFO(0, options) + ZEND_ARG_INFO(0, file_cb) + ZEND_ARG_INFO(0, hunk_cb) + ZEND_ARG_INFO(0, line_cb) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +/* {{{ proto void git_diff_free(diff) +*/ +PHP_FUNCTION(git_diff_free); + +/* {{{ proto resource git_diff_tree_to_tree(repo, old_tree, new_tree, opts) +*/ +PHP_FUNCTION(git_diff_tree_to_tree); + +/* {{{ proto resource git_diff_tree_to_index(repo, old_tree, index, opts) +*/ +PHP_FUNCTION(git_diff_tree_to_index); + +/* {{{ proto resource git_diff_index_to_workdir(repo, index, opts) +*/ +PHP_FUNCTION(git_diff_index_to_workdir); + +/* {{{ proto resource git_diff_tree_to_workdir(repo, old_tree, opts) +*/ +PHP_FUNCTION(git_diff_tree_to_workdir); + +/* {{{ proto resource git_diff_tree_to_workdir_with_index(repo, old_tree, opts) +*/ +PHP_FUNCTION(git_diff_tree_to_workdir_with_index); + +/* {{{ proto long git_diff_merge(onto, from) +*/ +PHP_FUNCTION(git_diff_merge); + +/* {{{ proto long git_diff_find_similar(diff, options) +*/ +PHP_FUNCTION(git_diff_find_similar); + +/* {{{ proto long git_diff_options_init(options, version) +*/ +PHP_FUNCTION(git_diff_options_init); + +/* {{{ proto resource git_diff_num_deltas(diff) +*/ +PHP_FUNCTION(git_diff_num_deltas); + +/* {{{ proto resource git_diff_num_deltas_of_type(diff, type) +*/ +PHP_FUNCTION(git_diff_num_deltas_of_type); + +/* {{{ proto resource git_diff_get_delta(diff, idx) +*/ +PHP_FUNCTION(git_diff_get_delta); + +/* {{{ proto long git_diff_is_sorted_icase(diff) +*/ +PHP_FUNCTION(git_diff_is_sorted_icase); + +/* {{{ proto long git_diff_foreach(diff, file_cb, hunk_cb, line_cb, payload) +*/ +PHP_FUNCTION(git_diff_foreach); + +/* {{{ proto resource git_diff_status_char(status) +*/ +PHP_FUNCTION(git_diff_status_char); + +/* {{{ proto long git_diff_print(diff, format, print_cb, payload) +*/ +PHP_FUNCTION(git_diff_print); + +/* {{{ proto long git_diff_blobs(old_blob, old_as_path, new_blob, new_as_path, options, file_cb, hunk_cb, line_cb, payload) +*/ +PHP_FUNCTION(git_diff_blobs); + +/* {{{ proto long git_diff_blob_to_buffer(old_blob, old_as_path, buffer, buffer_len, buffer_as_path, options, file_cb, hunk_cb, line_cb, payload) +*/ +PHP_FUNCTION(git_diff_blob_to_buffer); + + +#endif \ No newline at end of file diff --git a/example/blame.php b/example/blame.php new file mode 100644 index 0000000000..66e6ca70b3 --- /dev/null +++ b/example/blame.php @@ -0,0 +1,25 @@ +", $hunk['final_signature']['name'], $hunk['final_signature']['email']); + printf("%s ( %-30s, %4d) %s\n", substr($hunk['final_commit_id'], 10), + $sig, + $i+1, + $data + ); + $i++; +} \ No newline at end of file diff --git a/example/clone.php b/example/clone.php new file mode 100644 index 0000000000..4b671805b1 --- /dev/null +++ b/example/clone.php @@ -0,0 +1,2 @@ + "chobie filter", + "initialize" => function () { + echo "\e[32m# Initialize\e[m\n"; + }, + "check" => function ($payload, $src, $attr) { + echo "\e[32m# Check\e[m\n"; + var_dump($src); + var_dump($attr); + + // return true means apply filter to this file. + return true; + }, + "apply" => function ($payload, $from, $src) { + echo "\e[32m# Apply\e[m\n"; + // apply function should return string or GIT_PASSTHROUGH + return preg_replace("/\s/", "", $from); + }, + "shutdown" => function () { + echo "\n\e[32m# Shutdown\e[m\n"; + }, + "cleanup" => function () { + echo "\e[32m# clean up\e[m\n"; + } +); + +$v = git_filter_new($a); +git_filter_register("chobie", $v, 100); + +$blob = git_blob_lookup($repo, "74f5770df516cbbef16372a7628a9528277637d6"); +$l = git_filter_list_load($repo, $blob, "example/diff.php", GIT_FILTER_SMUDGE); + +echo "\e[32m# <<< ORIGINAL CONTENT >>>\e[m\n"; +echo git_blob_rawcontent($blob); + +echo "\e[32m# <<< FILTERED CONTENT >>>\e[m\n"; +$out = git_filter_list_apply_to_blob($l, $blob); +echo $out; diff --git a/example/odb_backend.php b/example/odb_backend.php new file mode 100644 index 0000000000..fc83a8225a --- /dev/null +++ b/example/odb_backend.php @@ -0,0 +1,103 @@ + function($oid){ + echo "\e[32m# read $oid\e[m\n"; + return array( + Pool::$pool[$oid][0], + Pool::$pool[$oid][1], + ); + }, + "read_prefix" => function($short_oid){ + echo "\e[32m# read_prefix $short_oid\e[m\n"; + + $actual_oid = null; + foreach (Pool::$pool as $key => $value) { + if (preg_match("/^{$short_oid}/", $key)) { + $actual_oid = $key; + break; + } + } + + return array( + Pool::$pool[$actual_oid][0], + Pool::$pool[$actual_oid][1], + $actual_oid, + ); + }, + "read_header" => function($oid) { + echo "\e[32m# read header$oid\e[m\n"; + return array( + strlen(Pool::$pool[$oid][0]), + Pool::$pool[$oid][1], + ); + }, + "write" => function($oid, $buffer, $otype) { + echo "\e[32m# write $oid\e[m\n"; + Pool::$pool[$oid] = array($buffer, $otype); + }, + "writestream" => function() { + + }, + "readstream" => function() { + + }, + "exists" => function($oid) { + $retval = 0; + if (isset(Pool::$pool[$oid])) { + $retval = 1; + } + + echo "\e[32m# exists $retval\e[m\n"; + return $retval; + }, + "refresh" => function() { + echo "\e[32m# refreshed!\e[m\n"; + }, + "foreach" => function($foreach_cb, &$payload) { // this payload was passed by git_odb_foreach callback. + echo "\e[32m# foreach (iterate all backends)\e[m\n"; + foreach (Pool::$pool as $oid => $value) { + $retval = $foreach_cb($oid, $payload); + if ($retval == GIT_EUSER) { + return $retval; + } + } + return 0; + }, + "writepack" => function() { + + }, + "free" => function() { + echo "\e[32m# free'd!\e[m\n"; + } +); +$memory_backend = git_odb_backend_new($a); + +$repo = git_repository_open("."); +$odb = git_repository_odb($repo); +git_odb_add_backend($odb, $memory_backend, 1000); + +$oid = git_odb_write($odb, "Helo World(php memory backend)", GIT_OBJ_BLOB); +$obj = git_odb_read($odb, $oid); + +echo git_odb_object_data($obj); +echo "\n"; + +$header = git_odb_read_header($odb, $oid); +var_dump($header); // size, otype + +$obj = git_odb_read_prefix($odb, substr($oid, 0, 10)); +var_dump($obj); + +$payload = array(); +git_odb_foreach($odb, function($oid, &$payload) { + echo "."; +}, $payload); +echo PHP_EOL; +git_odb_refresh($odb); +exit; diff --git a/example/odb_foreach.php b/example/odb_foreach.php new file mode 100644 index 0000000000..f3655fb318 --- /dev/null +++ b/example/odb_foreach.php @@ -0,0 +1,8 @@ + function($url, $username_from_url, $allowed_types, &$payload) { + // NOTE(chobie): you need to build with LibSSH2 when communicating with ssh protocol. */ + if ($allowed_types & GIT_CREDTYPE_USERPASS_PLAINTEXT) { + return git_cred_userpass_plaintext_new("chobie", getenv("GITHUB_TOKEN")); + } else { + error_log("not supported allowed types"); + } +}]; + +git_remote_set_callbacks($remote, $remote_callbacks); +if (git_remote_connect($remote, GIT_DIRECTION_PUSH)) { + $push = git_push_new($remote); + + git_push_add_refspec($push, "refs/heads/master:refs/heads/master"); + git_push_finish($push); + git_push_unpack_ok($push); + + git_push_status_foreach($push, function($ref, $name, &$payload){ + var_dump($ref, $name, $payload); + }, $payload); + + git_push_update_tips($push); + git_remote_disconnect($remote); +} diff --git a/example/ref_lookup.php b/example/ref_lookup.php new file mode 100644 index 0000000000..de7e40629b --- /dev/null +++ b/example/ref_lookup.php @@ -0,0 +1,6 @@ +...\" to unstage)\n"); +printf("#\n"); + +$cnt = git_status_list_entrycount($list); +for ($i = 0; $i < $cnt; $i++) { + $entry = git_status_byindex($list, $i); + $flags = $entry['status']; + $stat = getStat($flags); + + if (is_array($entry['head_to_index'])) { + printf("# %15s %s\n", $stat, $entry['head_to_index']['new_file']['path']); + } +} + +printf("#\n"); +printf("# Changes not staged for commit:\n"); +printf("# (use \"git add ...\" to update what will be committed)\n"); +printf("# (use \"git checkout -- ...\" to discard changes in working directory)\n"); +printf("#\n"); + +for ($i = 0; $i < $cnt; $i++) { + $entry = git_status_byindex($list, $i); + $flags = $entry['status']; + $stat = getStat($flags); + + if (is_array($entry['index_to_workdir'])) { + printf("# %15s %s\n", $stat, $entry['index_to_workdir']['new_file']['path']); + } +} +printf("#\n"); + + +function getStat($flags) +{ + $stat = ""; + if ($flags & GIT_STATUS_IGNORED) { + return; + } + if ($flags == GIT_STATUS_CURRENT) { + return; + } + if ($flags & GIT_STATUS_INDEX_NEW){ + $stat = "new file:"; + } + if ($flags & GIT_STATUS_WT_NEW) { + $stat = "untracked:"; + } + if ($flags & GIT_STATUS_INDEX_MODIFIED ||$flags & GIT_STATUS_WT_MODIFIED) { + $stat = "modified:"; + } + if ($flags & GIT_STATUS_INDEX_DELETED || $flags & GIT_STATUS_WT_DELETED) { + $stat = "deleted:"; + } + if ($flags & GIT_STATUS_INDEX_RENAMED || $flags & GIT_STATUS_WT_RENAMED) { + $stat = "renamed:"; + } + if ($flags & GIT_STATUS_INDEX_TYPECHANGE || $flags & GIT_STATUS_WT_TYPECHANGE) { + $stat = "typechange:"; + } + return $stat; +} \ No newline at end of file diff --git a/example/submodule.php b/example/submodule.php new file mode 100644 index 0000000000..23313573fe --- /dev/null +++ b/example/submodule.php @@ -0,0 +1,9 @@ +multi; + const unsigned char *ptr = self->attributes; + int last_is_space = 0; + int attribute_count = 0, len = 0; + GIT2_TSRMLS_SET(p->tsrm_ls) + + if (self->attributes != NULL) { + while (*ptr != '\0') { + if (*ptr == 0x09 || *ptr == 0x20 && last_is_space == 0) { + attribute_count++; + } + + if (*ptr == 0x09 || *ptr == 0x20) { + last_is_space = 1; + } else { + last_is_space = 0; + } + ptr++; + len++; + } + if (len > 0) { + attribute_count++; + } + } + + MAKE_STD_ZVAL(param_payload); + MAKE_STD_ZVAL(param_source); + MAKE_STD_ZVAL(param_attr); + ZVAL_NULL(param_payload); + if (php_git2_make_resource(&filter_source, PHP_GIT2_TYPE_FILTER_SOURCE, src, 0 TSRMLS_CC)) { + return GIT_EUSER; + } + ZVAL_RESOURCE(param_source, GIT2_RVAL_P(filter_source)); + + array_init(param_attr); + + if (attribute_count > 0) { + int y = 0; + for (y = 0; y < attribute_count; y++) { + if (GIT_ATTR_TRUE(attr_values[y])) { + add_next_index_bool(param_attr, 1); + } else if (GIT_ATTR_FALSE(attr_values[y])) { + add_next_index_bool(param_attr, 0); + } else if (GIT_ATTR_UNSPECIFIED(attr_values[y])) { + add_next_index_null(param_attr); + } else { + add_next_index_string(param_attr, attr_values[y], 1); + } + } + } else { + } + + if (php_git2_call_function_v(&p->callbacks[2].fci, &p->callbacks[2].fcc TSRMLS_CC, &retval_ptr, 3, + ¶m_payload, ¶m_source, ¶m_attr)) { + return GIT_EUSER; + } + + if (retval_ptr) { + result = Z_LVAL_P(retval_ptr); + + /* NOTE(chobie): adjust return value */ + if (result == 0) { + result = GIT_PASSTHROUGH; + } else if (result == 1) { + result = 0; + } + } + zval_ptr_dtor(&retval_ptr); + + return result; +} + +static void php_git2_git_filter_shutdown_fn(git_filter *self) +{ + zval *param_self = NULL, *param_payload = NULL, *retval_ptr = NULL; + php_git2_filter *filter = (php_git2_filter*)self; + php_git2_multi_cb_t *p = filter->multi; + GIT2_TSRMLS_SET(p->tsrm_ls) + + MAKE_STD_ZVAL(param_self); + MAKE_STD_ZVAL(param_payload); + ZVAL_NULL(param_self); + ZVAL_NULL(param_payload); + + if (php_git2_call_function_v(&p->callbacks[1].fci, &p->callbacks[1].fcc TSRMLS_CC, &retval_ptr, 2, ¶m_self, ¶m_payload)) { + } + zval_ptr_dtor(&retval_ptr); +} + +static int php_git2_git_filter_init_fn(git_filter *self) +{ + zval *param_self = NULL, *param_payload = NULL, *retval_ptr = NULL; + php_git2_filter *filter = (php_git2_filter*)self; + php_git2_multi_cb_t *p = filter->multi; + GIT2_TSRMLS_SET(p->tsrm_ls) + + MAKE_STD_ZVAL(param_self); + MAKE_STD_ZVAL(param_payload); + ZVAL_NULL(param_self); + ZVAL_NULL(param_payload); + + if (php_git2_call_function_v(&p->callbacks[0].fci, &p->callbacks[0].fcc TSRMLS_CC, &retval_ptr, 2, ¶m_self, ¶m_payload)) { + } + zval_ptr_dtor(&retval_ptr); +} + +static int php_git2_git_filter_apply_fn( + git_filter *self, + void **payload, /* may be read and/or set */ + git_buf *to, + const git_buf *from, + const git_filter_source *src) +{ + php_git2_filter *filter = (php_git2_filter*)self; + php_git2_t *filter_source; + zval *param_payload = NULL, *param_from = NULL, *param_src = NULL, *retval_ptr = NULL; + php_git2_multi_cb_t *p = filter->multi; + int retval = 0; + GIT2_TSRMLS_SET(p->tsrm_ls) + + MAKE_STD_ZVAL(param_payload); + MAKE_STD_ZVAL(param_from); + MAKE_STD_ZVAL(param_src); + ZVAL_NULL(param_payload); + ZVAL_STRINGL(param_from, from->ptr, from->size, 1); + if (php_git2_make_resource(&filter_source, PHP_GIT2_TYPE_FILTER_SOURCE, src, 0 TSRMLS_CC)) { + return GIT_EUSER; + } + ZVAL_RESOURCE(param_src, GIT2_RVAL_P(filter_source)); + + if (php_git2_call_function_v(&p->callbacks[3].fci, &p->callbacks[3].fcc TSRMLS_CC, &retval_ptr, 3, + ¶m_payload, ¶m_from, ¶m_src)) { + return GIT_EUSER; + } + + if (retval_ptr) { + if (Z_TYPE_P(retval_ptr) == IS_LONG) { + retval = Z_LVAL_P(retval_ptr); + } else { + if (Z_TYPE_P(retval_ptr) != IS_STRING) { + convert_to_string(retval_ptr); + } + git_buf_set(to, Z_STRVAL_P(retval_ptr), Z_STRLEN_P(retval_ptr)); + } + } + + zval_ptr_dtor(&retval_ptr); + return retval; +} + +static void php_git2_git_filter_cleanup_fn( + git_filter *self, + void *payload) +{ + zval *param_self = NULL, *param_payload = NULL, *retval_ptr = NULL; + php_git2_filter *filter = (php_git2_filter*)self; + php_git2_multi_cb_t *p = filter->multi; + GIT2_TSRMLS_SET(p->tsrm_ls) + + MAKE_STD_ZVAL(param_self); + MAKE_STD_ZVAL(param_payload); + ZVAL_NULL(param_self); + ZVAL_NULL(param_payload); + + if (php_git2_call_function_v(&p->callbacks[4].fci, &p->callbacks[4].fcc TSRMLS_CC, &retval_ptr, 2, ¶m_self, ¶m_payload)) { + } +} + +/* {{{ proto long git_filter_list_load(resource $repo, resource $blob, string $path, $mode) + */ +PHP_FUNCTION(git_filter_list_load) +{ + int result = 0, path_len = 0; + git_filter_list *filters = NULL; + zval *repo = NULL, *blob = NULL; + php_git2_t *_repo = NULL, *_blob = NULL, *_result; + char *path = NULL; + long mode = 0; + git_blob *__blob = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r|zsl", &repo, &blob, &path, &path_len, &mode) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + if (blob != NULL && Z_TYPE_P(blob) == IS_RESOURCE) { + ZEND_FETCH_RESOURCE(_blob, php_git2_t*, &blob, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + __blob = PHP_GIT2_V(_blob, blob); + } + + result = git_filter_list_load(&filters, PHP_GIT2_V(_repo, repository), blob, path, mode); + if (php_git2_check_error(result, "git_filter_list_load" TSRMLS_CC)) { + RETURN_FALSE + } + if (php_git2_make_resource(&_result, PHP_GIT2_TYPE_FILTER_LIST, filters, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(_result)); +} +/* }}} */ + +/* {{{ proto resource git_filter_list_apply_to_data(resource $filters, resource $in) + */ +PHP_FUNCTION(git_filter_list_apply_to_data) +{ + php_git2_t *_filters = NULL, *_in = NULL; + git_buf out = {0}; + zval *filters = NULL, *in = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rr", &filters, &in) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_filters, php_git2_t*, &filters, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_in, php_git2_t*, &in, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_filter_list_apply_to_data(&out, PHP_GIT2_V(_filters, filter_list), PHP_GIT2_V(_in, buf)); + if (php_git2_check_error(error, "git_filter_list_apply_to_data" TSRMLS_CC)) { + RETURN_FALSE; + } + RETVAL_STRINGL(out.ptr, out.size, 1); + git_buf_free(&out); +} +/* }}} */ + +/* {{{ proto resource git_filter_list_apply_to_file(resource $filters, resource $repo, string $path) + */ +PHP_FUNCTION(git_filter_list_apply_to_file) +{ + php_git2_t *_filters = NULL, *_repo = NULL; + git_buf out = {0}; + zval *filters = NULL, *repo = NULL; + char *path = NULL; + int path_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rrs", &filters, &repo, &path, &path_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_filters, php_git2_t*, &filters, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_filter_list_apply_to_file(&out, PHP_GIT2_V(_filters, filter_list), PHP_GIT2_V(_repo, repository), path); + if (php_git2_check_error(error, "git_filter_list_apply_to_file" TSRMLS_CC)) { + RETURN_FALSE; + } + RETVAL_STRINGL(out.ptr, out.size, 1); + git_buf_free(&out); +} +/* }}} */ + +/* {{{ proto resource git_filter_list_apply_to_blob(resource $filters, resource $blob) + */ +PHP_FUNCTION(git_filter_list_apply_to_blob) +{ + php_git2_t *result = NULL, *_filters = NULL, *_blob = NULL; + git_buf out = {0}; + zval *filters = NULL, *blob = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rr", &filters, &blob) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_filters, php_git2_t*, &filters, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_blob, php_git2_t*, &blob, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + error = git_filter_list_apply_to_blob(&out, PHP_GIT2_V(_filters, filter_list), PHP_GIT2_V(_blob, blob)); + if (php_git2_check_error(error, "git_filter_list_apply_to_blob" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_BUF, &out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + RETVAL_STRINGL(out.ptr, out.size, 1); + git_buf_free(&out); +} +/* }}} */ + +/* {{{ proto void git_filter_list_free(resource $filters) + */ +PHP_FUNCTION(git_filter_list_free) +{ + zval *filters = NULL; + php_git2_t *_filters = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &filters) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_filters, php_git2_t*, &filters, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_filters)) { + git_filter_list_free(PHP_GIT2_V(_filters, filter_list)); + GIT2_SHOULD_FREE(_filters) = 0; + }; + zval_ptr_dtor(&filters); +} +/* }}} */ + + +/* sys/filter */ + +/* {{{ proto resource git_filter_lookup(string $name) + */ +PHP_FUNCTION(git_filter_lookup) +{ + git_filter *result = NULL; + char *name = NULL; + int name_len = 0; + zval *filter; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "s", &name, &name_len) == FAILURE) { + return; + } + + result = git_filter_lookup(name); + if (result == NULL) { + RETURN_FALSE; + } + MAKE_STD_ZVAL(filter); + array_init(filter); + add_assoc_long_ex(filter, ZEND_STRS("version"), result->version); + + RETURN_ZVAL(filter, 0, 1); +} +/* }}} */ + +/* {{{ proto resource git_filter_list_new(resource $repo, $mode) + */ +PHP_FUNCTION(git_filter_list_new) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_filter_list *out = NULL; + zval *repo = NULL; + long mode = 0; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &repo, &mode) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_filter_list_new(&out, PHP_GIT2_V(_repo, repository), mode); + if (php_git2_check_error(error, "git_filter_list_new" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_FILTER_LIST, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto long git_filter_list_push(resource $fl, resource $filter, mixed $payload) + */ +PHP_FUNCTION(git_filter_list_push) +{ + int result = 0; + zval *fl = NULL, *filter = NULL, *payload = NULL; + php_git2_t *_fl = NULL, *_filter = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rr|z", &fl, &filter, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_fl, php_git2_t*, &fl, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_filter, php_git2_t*, &filter, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_filter_list_push(PHP_GIT2_V(_fl, filter_list), PHP_GIT2_V(_filter, filter), NULL); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_filter_list_length(resource $fl) + */ +PHP_FUNCTION(git_filter_list_length) +{ + size_t result = 0; + zval *fl = NULL; + php_git2_t *_fl = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &fl) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_fl, php_git2_t*, &fl, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_filter_list_length(PHP_GIT2_V(_fl, filter_list)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_filter_source_repo(resource $src) + */ +PHP_FUNCTION(git_filter_source_repo) +{ + git_repository *result = NULL; + zval *src = NULL; + php_git2_t *_src = NULL, *_result; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &src) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_src, php_git2_t*, &src, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_filter_source_repo(PHP_GIT2_V(_src, filter_source)); + if (php_git2_make_resource(&_result, PHP_GIT2_TYPE_REPOSITORY, result, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(_result)); +} +/* }}} */ + +/* {{{ proto string git_filter_source_path(resource $src) + */ +PHP_FUNCTION(git_filter_source_path) +{ + const char *result = NULL; + zval *src = NULL; + php_git2_t *_src = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &src) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_src, php_git2_t*, &src, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_filter_source_path(PHP_GIT2_V(_src, filter_source)); + RETURN_STRING(result, 1); +} +/* }}} */ + +/* {{{ proto long git_filter_source_filemode(resource $src) + */ +PHP_FUNCTION(git_filter_source_filemode) +{ + uint16_t result = 0; + zval *src = NULL; + php_git2_t *_src = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &src) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_src, php_git2_t*, &src, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_filter_source_filemode(PHP_GIT2_V(_src, filter_source)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_filter_source_id(resource $src) + */ +PHP_FUNCTION(git_filter_source_id) +{ + const git_oid *result = NULL; + zval *src = NULL; + php_git2_t *_src = NULL; + char __result[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &src) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_src, php_git2_t*, &src, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_filter_source_id(PHP_GIT2_V(_src, filter_source)); + git_oid_fmt(__result, result); + RETURN_STRING(__result, 1); +} +/* }}} */ + +/* {{{ proto long git_filter_source_mode(resource $src) + */ +PHP_FUNCTION(git_filter_source_mode) +{ + git_filter_mode_t result; + zval *src = NULL; + php_git2_t *_src = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &src) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_src, php_git2_t*, &src, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_filter_source_mode(PHP_GIT2_V(_src, filter_source)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_filter_register(string $name, resource $filter, long $priority) + */ +PHP_FUNCTION(git_filter_register) +{ + int result = 0, name_len = 0; + char *name = NULL; + zval *filter = NULL; + php_git2_t *_filter = NULL; + long priority = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "srl", &name, &name_len, &filter, &priority) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_filter, php_git2_t*, &filter, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_filter_register(name, PHP_GIT2_V(_filter, filter), priority); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_filter_unregister(string $name) + */ +PHP_FUNCTION(git_filter_unregister) +{ + int result = 0, name_len = 0; + char *name = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "s", &name, &name_len) == FAILURE) { + return; + } + + result = git_filter_unregister(name); + RETURN_LONG(result); +} +/* }}} */ + +PHP_FUNCTION(git_filter_new) +{ + git_filter *filter = NULL; + php_git2_t *result = NULL; + php_git2_filter *_filter = NULL; + zval *mixed = NULL, *tmp = NULL; + zend_fcall_info initialize_fci, shutdown_fci, check_fci, apply_fci, cleanup_fci; + zend_fcall_info_cache initialize_fcc, shutdown_fcc, check_fcc, apply_fcc, cleanup_fcc; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "a", &mixed) == FAILURE) { + return; + } + + _filter = (php_git2_filter*)ecalloc(1, sizeof(php_git2_filter)); + filter = (git_filter*)&_filter->super; + filter->version = GIT_FILTER_VERSION; + filter->attributes = php_git2_read_arrval_string(mixed, ZEND_STRS("attributes") TSRMLS_CC); + + if (tmp = php_git2_read_arrval(mixed, ZEND_STRS("initialize") TSRMLS_CC)) { + php_git2_fcall_info_wrapper2(tmp, &initialize_fci, &initialize_fcc TSRMLS_CC); + } + if (tmp = php_git2_read_arrval(mixed, ZEND_STRS("shutdown") TSRMLS_CC)) { + php_git2_fcall_info_wrapper2(tmp, &shutdown_fci, &shutdown_fcc TSRMLS_CC); + } + if (tmp = php_git2_read_arrval(mixed, ZEND_STRS("check") TSRMLS_CC)) { + php_git2_fcall_info_wrapper2(tmp, &check_fci, &check_fcc TSRMLS_CC); + } + if (tmp = php_git2_read_arrval(mixed, ZEND_STRS("apply") TSRMLS_CC)) { + php_git2_fcall_info_wrapper2(tmp, &apply_fci, &apply_fcc TSRMLS_CC); + } + if (tmp = php_git2_read_arrval(mixed, ZEND_STRS("cleanup") TSRMLS_CC)) { + php_git2_fcall_info_wrapper2(tmp, &cleanup_fci, &cleanup_fcc TSRMLS_CC); + } + + filter->initialize = php_git2_git_filter_init_fn; + filter->shutdown = php_git2_git_filter_shutdown_fn; + filter->check = php_git2_git_filter_check_fn; + filter->apply = php_git2_git_filter_apply_fn; + filter->cleanup = php_git2_git_filter_cleanup_fn; + + Z_ADDREF_P(mixed); + php_git2_multi_cb_init(&_filter->multi, mixed TSRMLS_CC, 5, + &initialize_fci, &initialize_fcc, + &shutdown_fci, &shutdown_fcc, + &check_fci, &check_fcc, + &apply_fci, &apply_fcc, + &cleanup_fci, &cleanup_fcc + ); + + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_FILTER, filter, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} diff --git a/filter.h b/filter.h new file mode 100644 index 0000000000..c24bc8a056 --- /dev/null +++ b/filter.h @@ -0,0 +1,178 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_FILTER_H +#define PHP_GIT2_FILTER_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_filter_list_load, 0, 0, 1) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, blob) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, mode) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_filter_list_apply_to_data, 0, 0, 2) + ZEND_ARG_INFO(0, filters) + ZEND_ARG_INFO(0, in) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_filter_list_apply_to_file, 0, 0, 3) + ZEND_ARG_INFO(0, filters) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, path) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_filter_list_apply_to_blob, 0, 0, 2) + ZEND_ARG_INFO(0, filters) + ZEND_ARG_INFO(0, blob) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_filter_list_free, 0, 0, 1) + ZEND_ARG_INFO(0, filters) +ZEND_END_ARG_INFO() + + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_filter_lookup, 0, 0, 1) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_filter_list_new, 0, 0, 2) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, mode) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_filter_list_push, 0, 0, 3) + ZEND_ARG_INFO(0, fl) + ZEND_ARG_INFO(0, filter) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_filter_list_length, 0, 0, 1) + ZEND_ARG_INFO(0, fl) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_filter_source_repo, 0, 0, 1) + ZEND_ARG_INFO(0, src) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_filter_source_path, 0, 0, 1) + ZEND_ARG_INFO(0, src) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_filter_source_filemode, 0, 0, 1) + ZEND_ARG_INFO(0, src) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_filter_source_id, 0, 0, 1) + ZEND_ARG_INFO(0, src) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_filter_source_mode, 0, 0, 1) + ZEND_ARG_INFO(0, src) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_filter_register, 0, 0, 3) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, filter) + ZEND_ARG_INFO(0, priority) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_filter_unregister, 0, 0, 1) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_filter_new, 0, 0, 1) + ZEND_ARG_INFO(0, payload) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_filter_list_load(repo, blob, path, mode) +*/ +PHP_FUNCTION(git_filter_list_load); + +/* {{{ proto resource git_filter_list_apply_to_data(filters, in) +*/ +PHP_FUNCTION(git_filter_list_apply_to_data); + +/* {{{ proto resource git_filter_list_apply_to_file(filters, repo, path) +*/ +PHP_FUNCTION(git_filter_list_apply_to_file); + +/* {{{ proto resource git_filter_list_apply_to_blob(filters, blob) +*/ +PHP_FUNCTION(git_filter_list_apply_to_blob); + +/* {{{ proto void git_filter_list_free(filters) +*/ +PHP_FUNCTION(git_filter_list_free); + +/* {{{ proto resource git_filter_lookup(name) +*/ +PHP_FUNCTION(git_filter_lookup); + +/* {{{ proto resource git_filter_list_new(repo, mode) +*/ +PHP_FUNCTION(git_filter_list_new); + +/* {{{ proto long git_filter_list_push(fl, filter, payload) +*/ +PHP_FUNCTION(git_filter_list_push); + +/* {{{ proto resource git_filter_list_length(fl) +*/ +PHP_FUNCTION(git_filter_list_length); + +/* {{{ proto resource git_filter_source_repo(src) +*/ +PHP_FUNCTION(git_filter_source_repo); + +/* {{{ proto resource git_filter_source_path(src) +*/ +PHP_FUNCTION(git_filter_source_path); + +/* {{{ proto resource git_filter_source_filemode(src) +*/ +PHP_FUNCTION(git_filter_source_filemode); + +/* {{{ proto resource git_filter_source_id(src) +*/ +PHP_FUNCTION(git_filter_source_id); + +/* {{{ proto resource git_filter_source_mode(src) +*/ +PHP_FUNCTION(git_filter_source_mode); + +/* {{{ proto long git_filter_register(name, filter, priority) +*/ +PHP_FUNCTION(git_filter_register); + +/* {{{ proto long git_filter_unregister(name) +*/ +PHP_FUNCTION(git_filter_unregister); + +/* {{{ proto resource git_filter_new(payload) +*/ +PHP_FUNCTION(git_filter_new); + +#endif diff --git a/fixer.php b/fixer.php new file mode 100644 index 0000000000..3a7ccafe09 --- /dev/null +++ b/fixer.php @@ -0,0 +1,265 @@ + error.log +// grep "unused variables" error.log > error2.log +// php fixer.php +$data = file_get_contents("error2.log"); +$result = array(); +foreach (explode("\n", $data) as $line) { + if (preg_match("!(.+?):(\d+):(\d+): warning: unused variable '(.+?)'!", $line, $match)) { + $filename = basename($match[1]); + $line = $match[2]; + $columns = $match[3]; + $name = $match[4]; + + if ($filename == $target) { + $result[$filename][] = array( + "line" => $line, + "columns" => $columns, + "name" => $name, + ); + } + } +} + +//var_dump($result); +$file = file_get_contents($target); +$lines = explode("\n", $file); +if (!isset($result[$target])) { + echo "nothing"; + exit; +} +foreach ($result[$target] as $value) { + //echo $lines[$value['line']-1] . PHP_EOL; + + $line = $lines[$value['line']-1]; + $l = parseLine($line); + $l->remove($value['name']); + $hhh = $l->toLine(); + $lines[$value['line']-1] = $hhh; +} +$buffer = ""; +for ($i = 0; $i < count($lines); $i++) { + $line = $lines[$i]; + if ($line == "==========REMOVED==========") { + continue; + } + $buffer .= $line; + if ($i + 1 < count($lines)) { + $buffer .= "\n"; + } +} +//echo $buffer;exit; +file_put_contents($target, $buffer); + +function parseLine($line) +{ + for ($i = 0; $i < strlen($line); $i++) { + if ($line[$i] == "\t") { + continue; + } else { + break; + } + } + + $l = new Line($i); + $arg = substr($line, $i); + $type = null; + $args = array(); + $tmp = null; + $base = null; + foreach (explode(",", $arg) as $arg2) { + $tokens = preg_split("/(\s+|;)/", $arg2); + + $cnt = count($tokens); + $state = 0; + for ($i = 0; $i < $cnt; $i++) { + if ($state == 0) { + if (empty($tokens[$i])) { + continue; + } + if (!$type) { + if ($tokens[$i] != "const") { + $type = $tokens[$i]; + $state = 1; + if (!$tmp) { + $tmp = new Variable(); + $tmp->setType($tokens[$i]); + $base = clone $tmp; + } + } else { + $tmp = new Variable(); + $tmp->is_const = 1; + $tmp->setType($tokens[$i+1]); + $i++; + $state = 1; + $base = clone $tmp; + } + } else { + $state = 1; + $tmp = clone $base; + $tmp->setName($tokens[$i]); + } + } else if ($state == 1) { + if ($tokens[$i] == "=") { + $state = 2; + } else { + $tmp->setName($tokens[$i]); + } + } else if ($state == 2) { + $tmp->setDefault($tokens[$i]); + $l->add($tmp); + unset($tmp); + $state = 0; + } + } + if (isset($tmp)) { + $l->add($tmp); + } + } + + return $l; +} + +class Line +{ + public $indent; + public $variables = array(); + + public function __construct($indent) + { + $this->indent = $indent; + } + + public function add(Variable $var) + { + $this->variables[] = $var; + } + + public function remove($name) + { + foreach ($this->variables as $o => $var) { + if ($var->name == $name) { + unset($this->variables[$o]); + } + } + } + + public function isEmpty() + { + if (count($this->variables)) { + return false; + } else { + return true; + } + } + + public function toLine() + { + $type = null; + $buffer = str_repeat("\t", $this->indent); + $values = array(); + foreach ($this->variables as $var) { + if (!$type) { + if ($var->getNameWithPtr() === "") { + continue; + } + + $type = $var->type; + if ($var->is_const) { + $buffer .= "const "; + } + $buffer .= sprintf("%s ", $var->type); + + if ($var->default !== NULL) { + $values[] = sprintf("%s = %s", $var->getNameWithPtr(), $var->default); + } else { + $values[] = $var->getNameWithPtr(); + } + } else { + if ($var->getNameWithPtr() === "") { + continue; + } + + + if ($var->default !== NULL) { + $values[] = sprintf("%s = %s", $var->getNameWithPtr(), $var->default); + } else { + $values[] = $var->getNameWithPtr(); + } + } + } + + if (count($values)) { + $buffer .= join(", ", $values); + } else { + return "==========REMOVED=========="; + } + if (strlen($buffer) > $this->indent) { + $buffer .= ";"; + } + + $check = trim($buffer, " \t"); + if (!$check) { + return "==========REMOVED=========="; + } + + return $buffer; + } +} + +class Variable +{ + public $name; + public $type; + public $default; + public $is_static; + public $is_const; + public $ptr = 0; + + public function __construct() + { + } + + public function setType($type) + { + $this->type = $type; + } + + public function setName($name) + { + $ptr = 0; + for ($i =0; $i < strlen($name); $i++) { + if ($name[$i] == '*') { + $ptr++; + } + } + + $this->name = substr($name, $ptr); + if ($ptr) { + $this->ptr = $ptr; + } + } + + public function setPtr($ptr) + { + $this->ptr = $ptr; + } + + public function setDefault($default) + { + $this->default = $default; + } + + public function getNameWithPtr() + { + if ($this->name) { + return str_repeat("*", $this->ptr) . $this->name; + } else { + return ""; + } + } +} diff --git a/g_config.c b/g_config.c new file mode 100644 index 0000000000..cb15c30ad5 --- /dev/null +++ b/g_config.c @@ -0,0 +1,867 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "g_config.h" + +enum php_git2_config { + PHP_GIT2_CONFIG_STRING, + PHP_GIT2_CONFIG_BOOL, + PHP_GIT2_CONFIG_INT64, + PHP_GIT2_CONFIG_INT32, +}; + +static void php_git2_config_entry_to_array(git_config_entry *entry, zval **result); + +static int php_git2_config_foreach_cb(const git_config_entry *entry, void *payload) +{ + php_git2_t *result; + zval *param_config_entry, *retval_ptr = NULL; + php_git2_cb_t *p = (php_git2_cb_t*)payload; + long retval = 0; + GIT2_TSRMLS_SET(p->tsrm_ls) + + php_git2_config_entry_to_array(entry, ¶m_config_entry); + Z_ADDREF_P(p->payload); + + if (php_git2_call_function_v(p->fci, p->fcc TSRMLS_CC, &retval_ptr, 2, ¶m_config_entry, &p->payload)) { + zval_ptr_dtor(¶m_config_entry); + zval_ptr_dtor(&p->payload); + zend_list_delete(result->resource_id); + retval = 0; + return 0; + } + + retval = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + return retval; +} + + +static void php_git2_config_get_with(INTERNAL_FUNCTION_PARAMETERS, enum php_git2_config type) +{ + zval *cfg; + php_git2_t *_cfg; + char *name = {0}; + int name_len; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &cfg, &name, &name_len) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_cfg, php_git2_t*, &cfg, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + switch (type) { + case PHP_GIT2_CONFIG_STRING: { + const char *ptr; + error = git_config_get_string(&ptr, PHP_GIT2_V(_cfg, config), name); + if (php_git2_check_error(error, "git_config_get_string" TSRMLS_CC)) { + RETURN_FALSE + } + RETURN_STRING(ptr, 1); + break; + } + case PHP_GIT2_CONFIG_BOOL: { + int ptr; + error = git_config_get_bool(&ptr, PHP_GIT2_V(_cfg, config), name); + if (php_git2_check_error(error, "git_config_get_bool" TSRMLS_CC)) { + RETURN_FALSE + } + RETURN_BOOL(ptr); + break; + } + case PHP_GIT2_CONFIG_INT64: { + int64_t ptr; + error = git_config_get_int64(&ptr, PHP_GIT2_V(_cfg, config), name); + if (php_git2_check_error(error, "git_config_get_int64" TSRMLS_CC)) { + RETURN_FALSE + } + RETURN_LONG(ptr); + break; + } + case PHP_GIT2_CONFIG_INT32: { + int32_t ptr; + error = git_config_get_int32(&ptr, PHP_GIT2_V(_cfg, config), name); + if (php_git2_check_error(error, "git_config_get_int32" TSRMLS_CC)) { + RETURN_FALSE + } + RETURN_LONG(ptr); + break; + } + } +} + +static void php_git2_config_set_with(INTERNAL_FUNCTION_PARAMETERS, enum php_git2_config type) +{ + zval *cfg; + php_git2_t *_cfg; + char *name = {0}; + int name_len; + int error = 0; + zval *value; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsz", &cfg, &name, &name_len, &value) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_cfg, php_git2_t*, &cfg, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + switch (type) { + case PHP_GIT2_CONFIG_STRING: { + if (Z_TYPE_P(value) != IS_STRING) { + convert_to_string(value); + } + error = git_config_set_string(PHP_GIT2_V(_cfg, config), name, Z_STRVAL_P(value)); + if (php_git2_check_error(error, "git_config_set_string" TSRMLS_CC)) { + RETURN_FALSE + } + RETURN_TRUE; + break; + } + case PHP_GIT2_CONFIG_BOOL: { + if (Z_TYPE_P(value) != IS_BOOL) { + convert_to_boolean(value); + } + error = git_config_set_bool(PHP_GIT2_V(_cfg, config), name, Z_LVAL_P(value)); + if (php_git2_check_error(error, "git_config_set_bool" TSRMLS_CC)) { + RETURN_FALSE + } + RETURN_TRUE; + break; + } + case PHP_GIT2_CONFIG_INT32: { + if (Z_TYPE_P(value) != IS_LONG) { + convert_to_long(value); + } + error = git_config_set_int32(PHP_GIT2_V(_cfg, config), name, Z_LVAL_P(value)); + if (php_git2_check_error(error, "git_config_set_int32" TSRMLS_CC)) { + RETURN_FALSE + } + RETURN_TRUE; + break; + } + case PHP_GIT2_CONFIG_INT64: { + if (Z_TYPE_P(value) != IS_LONG) { + convert_to_long(value); + } + error = git_config_set_int64(PHP_GIT2_V(_cfg, config), name, Z_LVAL_P(value)); + if (php_git2_check_error(error, "git_config_set_int64" TSRMLS_CC)) { + RETURN_FALSE + } + RETURN_TRUE; + break; + } + } +} + + +static void php_git2_config_parse_with(INTERNAL_FUNCTION_PARAMETERS, enum php_git2_config type) +{ + char *value = {0}; + int value_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "s", &value, &value_len) == FAILURE) { + return; + } + + switch (type) { + case PHP_GIT2_CONFIG_BOOL: { + int result; + result = git_config_parse_bool(&result, value); + RETURN_BOOL(result); + break; + } + case PHP_GIT2_CONFIG_INT32: { + int32_t result; + result = git_config_parse_int32(&result, value); + RETURN_LONG(result); + break; + } + case PHP_GIT2_CONFIG_INT64: { + int64_t result; + result = git_config_parse_int64(&result, value); + RETURN_LONG(result); + break; + } + } +} + +static void php_git2_config_entry_to_array(git_config_entry *entry, zval **result) +{ + zval *tmp; + + MAKE_STD_ZVAL(tmp); + array_init(tmp); + + add_assoc_string_ex(tmp, ZEND_STRS("name"), entry->name, 1); + add_assoc_string_ex(tmp, ZEND_STRS("value"), entry->value, 1); + add_assoc_long_ex(tmp, ZEND_STRS("level"), entry->level); + *result = tmp; +} + +/* {{{ proto resource git_config_find_global() +*/ +PHP_FUNCTION(git_config_find_global) +{ + char buffer[GIT2_BUFFER_SIZE]; + size_t buffer_len = GIT2_BUFFER_SIZE; + int error = 0; + + error = git_config_find_global(buffer, buffer_len); + if (php_git2_check_error(error, "git_config_find_global" TSRMLS_CC)) { + RETURN_FALSE + } + RETURN_STRING(buffer, 1); +} + +/* {{{ proto resource git_config_find_xdg(length) +*/ +PHP_FUNCTION(git_config_find_xdg) +{ + + /* TODO(chobie): implement this */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "git_config_find_xdg not implemented yet"); + return; + +// if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, +// "", &length) == FAILURE) { +// return; +// } +} + +/* {{{ proto resource git_config_find_system(length) +*/ +PHP_FUNCTION(git_config_find_system) +{ + char buffer[GIT2_BUFFER_SIZE]; + size_t buffer_len = GIT2_BUFFER_SIZE; + int error = 0; + + error = git_config_find_system(buffer, buffer_len); + if (php_git2_check_error(error, "git_config_find_system" TSRMLS_CC)) { + RETURN_FALSE + } + RETURN_STRING(buffer, 1); +} + +/* {{{ proto resource git_config_open_default() +*/ +PHP_FUNCTION(git_config_open_default) +{ + git_config *config; + int error = 0; + php_git2_t *result; + + error = git_config_open_default(&config); + if (php_git2_check_error(error, "git_config_open_default" TSRMLS_CC)) { + RETURN_FALSE + } + + PHP_GIT2_MAKE_RESOURCE(result); + PHP_GIT2_V(result, config) = config; + result->type = PHP_GIT2_TYPE_CONFIG; + result->resource_id = PHP_GIT2_LIST_INSERT(result, git2_resource_handle); + result->should_free_v = 1; + + ZVAL_RESOURCE(return_value, result->resource_id); +} + +/* {{{ proto resource git_config_new() +*/ +PHP_FUNCTION(git_config_new) +{ + git_config *config; + php_git2_t *result; + int error = 0; + + error = git_config_new(&config); + if (php_git2_check_error(error, "git_config_new" TSRMLS_CC)) { + RETURN_FALSE + } + + PHP_GIT2_MAKE_RESOURCE(result); + PHP_GIT2_V(result, config) = config; + result->type = PHP_GIT2_TYPE_CONFIG; + result->resource_id = PHP_GIT2_LIST_INSERT(result, git2_resource_handle); + result->should_free_v = 1; + + ZVAL_RESOURCE(return_value, result->resource_id); +} + +/* {{{ proto long git_config_add_file_ondisk(cfg, path, level, force) +*/ +PHP_FUNCTION(git_config_add_file_ondisk) +{ + zval *cfg; + php_git2_t *_cfg; + char *path = {0}; + int path_len; + long level; + long force = 0; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsrl", &cfg, &path, &path_len, &level, &force) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_cfg, php_git2_t*, &cfg, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_config_add_file_ondisk(PHP_GIT2_V(_cfg, config), path, level, force); + if (php_git2_check_error(error, "git_config_add_file_ondisk" TSRMLS_CC)) { + RETURN_FALSE + } + RETURN_TRUE; +} + +/* {{{ proto resource git_config_open_ondisk(path) +*/ +PHP_FUNCTION(git_config_open_ondisk) +{ + char *path = {0}; + int path_len; + git_config *config; + php_git2_t *result; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "s", &path, &path_len) == FAILURE) { + return; + } + error = git_config_open_ondisk(&config, path); + if (php_git2_check_error(error, "git_config_open_ondisk" TSRMLS_CC)) { + RETURN_FALSE + } + PHP_GIT2_MAKE_RESOURCE(result); + PHP_GIT2_V(result, config) = config; + result->type = PHP_GIT2_TYPE_CONFIG; + result->resource_id = PHP_GIT2_LIST_INSERT(result, git2_resource_handle); + result->should_free_v = 1; + + ZVAL_RESOURCE(return_value, result->resource_id); +} + +/* {{{ proto resource git_config_open_level(parent, level) +*/ +PHP_FUNCTION(git_config_open_level) +{ + zval *parent; + php_git2_t *_parent, *result; + long level; + int error = 0; + git_config *out; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &parent, &level) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_parent, php_git2_t*, &parent, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + error = git_config_open_level(&out, PHP_GIT2_V(_parent, config), level); + if (php_git2_check_error(error, "git_config_open_level" TSRMLS_CC)) { + RETURN_FALSE + } + PHP_GIT2_MAKE_RESOURCE(result); + PHP_GIT2_V(result, config) = out; + result->type = PHP_GIT2_TYPE_CONFIG; + result->resource_id = PHP_GIT2_LIST_INSERT(result, git2_resource_handle); + result->should_free_v = 1; + + ZVAL_RESOURCE(return_value, result->resource_id); +} + +/* {{{ proto resource git_config_open_global(config) +*/ +PHP_FUNCTION(git_config_open_global) +{ + zval *config; + php_git2_t *_config, *result; + git_config *out; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &config) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_config, php_git2_t*, &config, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_config_open_global(&out, PHP_GIT2_V(_config, config)); + if (php_git2_check_error(error, "git_config_open_global" TSRMLS_CC)) { + RETURN_FALSE + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_CONFIG, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, result->resource_id); +} + +/* {{{ proto long git_config_refresh(cfg) +*/ +PHP_FUNCTION(git_config_refresh) +{ + zval *cfg; + php_git2_t *_cfg; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &cfg) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_cfg, php_git2_t*, &cfg, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_config_refresh(PHP_GIT2_V(_cfg, config)); + if (php_git2_check_error(error, "git_config_refresh" TSRMLS_CC)) { + RETURN_FALSE + } + + RETURN_TRUE; +} + +/* {{{ proto void git_config_free(resource $cfg) + */ +PHP_FUNCTION(git_config_free) +{ + zval *cfg = NULL; + php_git2_t *_cfg = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &cfg) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_cfg, php_git2_t*, &cfg, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_cfg)) { + git_config_free(PHP_GIT2_V(_cfg, config)); + GIT2_SHOULD_FREE(_cfg) = 0; + }; + zval_ptr_dtor(&cfg); +} +/* }}} */ + +/* {{{ proto resource git_config_get_entry(cfg, name) +*/ +PHP_FUNCTION(git_config_get_entry) +{ + zval *cfg; + php_git2_t *_cfg; + char *name = {0}; + int name_len; + git_config_entry *entry; + int error = 0; + zval *result; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &cfg, &name, &name_len) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_cfg, php_git2_t*, &cfg, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_config_get_entry(&entry, PHP_GIT2_V(_cfg, config), name); + if (php_git2_check_error(error, "git_config_get_entry" TSRMLS_CC)) { + RETURN_FALSE + } + + php_git2_config_entry_to_array(entry, &result); + RETURN_ZVAL(result, 0, 1); +} + +/* {{{ proto resource git_config_get_int32(cfg, name) +*/ +PHP_FUNCTION(git_config_get_int32) +{ + php_git2_config_get_with(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GIT2_CONFIG_INT32); +} + +/* {{{ proto resource git_config_get_int64(cfg, name) +*/ +PHP_FUNCTION(git_config_get_int64) +{ + php_git2_config_get_with(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GIT2_CONFIG_INT64); +} + +/* {{{ proto resource git_config_get_bool(cfg, name) +*/ +PHP_FUNCTION(git_config_get_bool) +{ + php_git2_config_get_with(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GIT2_CONFIG_BOOL); +} + +/* {{{ proto resource git_config_get_string(cfg, name) +*/ +PHP_FUNCTION(git_config_get_string) +{ + php_git2_config_get_with(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GIT2_CONFIG_STRING); +} + +/* {{{ proto long git_config_get_multivar_foreach(resource $cfg, string $name, string $regexp, Callable $callback, $payload) + */ +PHP_FUNCTION(git_config_get_multivar_foreach) +{ + int result = 0, name_len = 0, regexp_len = 0; + zval *cfg = NULL, *payload = NULL; + php_git2_t *_cfg = NULL; + char *name = NULL, *regexp = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rssfz", &cfg, &name, &name_len, ®exp, ®exp_len, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_cfg, php_git2_t*, &cfg, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_config_get_multivar_foreach(PHP_GIT2_V(_cfg, config), name, regexp, php_git2_config_foreach_cb, cb); + php_git2_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto resource git_config_multivar_iterator_new(resource $cfg, string $name, string $regexp) + */ +PHP_FUNCTION(git_config_multivar_iterator_new) +{ + php_git2_t *result = NULL, *_cfg = NULL; + git_config_iterator *out = NULL; + zval *cfg = NULL; + char *name = NULL, *regexp = NULL; + int name_len = 0, regexp_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rss", &cfg, &name, &name_len, ®exp, ®exp_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_cfg, php_git2_t*, &cfg, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_config_multivar_iterator_new(&out, PHP_GIT2_V(_cfg, config), name, regexp); + if (php_git2_check_error(error, "git_config_multivar_iterator_new" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_CONFIG_ITERATOR, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto long git_config_next(resource $iter) + */ +PHP_FUNCTION(git_config_next) +{ + int result = 0; + git_config_entry *entry = NULL; + zval *iter = NULL; + php_git2_t *_iter = NULL; + zval *out; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &iter) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_iter, php_git2_t*, &iter, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_config_next(&entry, PHP_GIT2_V(_iter, config_iterator)); + if (result == GIT_ITEROVER || php_git2_check_error(result, "git_config_next" TSRMLS_CC)) { + RETURN_FALSE + } + php_git2_config_entry_to_array(entry, &out); + RETURN_ZVAL(out, 0, 1); +} +/* }}} */ + +/* {{{ proto void git_config_iterator_free(resource $iter) + */ +PHP_FUNCTION(git_config_iterator_free) +{ + zval *iter = NULL; + php_git2_t *_iter = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &iter) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_iter, php_git2_t*, &iter, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_iter)) { + git_config_iterator_free(PHP_GIT2_V(_iter, config_iterator)); + GIT2_SHOULD_FREE(_iter) = 0; + }; + zval_ptr_dtor(&iter); +} +/* }}} */ + +/* {{{ proto long git_config_set_int32(cfg, name, value) +*/ +PHP_FUNCTION(git_config_set_int32) +{ + php_git2_config_set_with(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GIT2_CONFIG_INT32); +} + +/* {{{ proto long git_config_set_int64(cfg, name, value) +*/ +PHP_FUNCTION(git_config_set_int64) +{ + php_git2_config_set_with(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GIT2_CONFIG_INT64); +} + +/* {{{ proto long git_config_set_bool(cfg, name, value) +*/ +PHP_FUNCTION(git_config_set_bool) +{ + php_git2_config_set_with(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GIT2_CONFIG_BOOL); +} + +/* {{{ proto long git_config_set_string(cfg, name, value) +*/ +PHP_FUNCTION(git_config_set_string) +{ + php_git2_config_set_with(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GIT2_CONFIG_STRING); +} + +/* {{{ proto long git_config_set_multivar(resource $cfg, string $name, string $regexp, string $value) + */ +PHP_FUNCTION(git_config_set_multivar) +{ + int result = 0, name_len = 0, regexp_len = 0, value_len = 0; + zval *cfg = NULL; + php_git2_t *_cfg = NULL; + char *name = NULL, *regexp = NULL, *value = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsss", &cfg, &name, &name_len, ®exp, ®exp_len, &value, &value_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_cfg, php_git2_t*, &cfg, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_config_set_multivar(PHP_GIT2_V(_cfg, config), name, regexp, value); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_config_delete_entry(cfg, name) +*/ +PHP_FUNCTION(git_config_delete_entry) +{ + zval *cfg; + php_git2_t *_cfg; + char *name = {0}; + int name_len; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &cfg, &name, &name_len) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_cfg, php_git2_t*, &cfg, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + error = git_config_delete_entry(PHP_GIT2_V(_cfg, config), name); + if (php_git2_check_error(error, "git_config_delete_entry" TSRMLS_CC)) { + RETURN_FALSE + } + + RETURN_TRUE; +} + +/* {{{ proto long git_config_delete_multivar(resource $cfg, string $name, string $regexp) + */ +PHP_FUNCTION(git_config_delete_multivar) +{ + int result = 0, name_len = 0, regexp_len = 0; + zval *cfg = NULL; + php_git2_t *_cfg = NULL; + char *name = NULL, *regexp = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rss", &cfg, &name, &name_len, ®exp, ®exp_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_cfg, php_git2_t*, &cfg, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_config_delete_multivar(PHP_GIT2_V(_cfg, config), name, regexp); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_config_foreach(resource $cfg, $callback, $payload) + */ +PHP_FUNCTION(git_config_foreach) +{ + int result = 0; + zval *cfg = NULL; + php_git2_t *_cfg = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb; + zval *payload = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rfz", &cfg, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_cfg, php_git2_t*, &cfg, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_config_foreach(PHP_GIT2_V(_cfg, config), php_git2_config_foreach_cb, cb); + php_git2_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto resource git_config_iterator_new(resource $cfg) + */ +PHP_FUNCTION(git_config_iterator_new) +{ + php_git2_t *result = NULL, *_cfg = NULL; + git_config_iterator *out = NULL; + zval *cfg = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &cfg) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_cfg, php_git2_t*, &cfg, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_config_iterator_new(&out, PHP_GIT2_V(_cfg, config)); + if (php_git2_check_error(error, "git_config_iterator_new" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_CONFIG_ITERATOR, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_config_iterator_glob_new(resource $cfg, string $regexp) + */ +PHP_FUNCTION(git_config_iterator_glob_new) +{ + php_git2_t *result = NULL, *_cfg = NULL; + git_config_iterator *out = NULL; + zval *cfg = NULL; + char *regexp = NULL; + int regexp_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &cfg, ®exp, ®exp_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_cfg, php_git2_t*, &cfg, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_config_iterator_glob_new(&out, PHP_GIT2_V(_cfg, config), regexp); + if (php_git2_check_error(error, "git_config_iterator_glob_new" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_CONFIG_ITERATOR, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto long git_config_foreach_match(resource $cfg, string $regexp, Callable $callback, $payload) + */ +PHP_FUNCTION(git_config_foreach_match) +{ + int result = 0, regexp_len = 0; + zval *cfg = NULL, *payload = NULL; + php_git2_t *_cfg = NULL; + char *regexp = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsfz", &cfg, ®exp, ®exp_len, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_cfg, php_git2_t*, &cfg, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_config_foreach_match(PHP_GIT2_V(_cfg, config), regexp, php_git2_config_foreach_cb, cb); + php_git2_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto resource git_config_get_mapped(cfg, name, maps, map_n) +*/ +PHP_FUNCTION(git_config_get_mapped) +{ + + /* TODO(chobie): implement this */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "git_config_get_mapped not implemented yet"); + return; + +// if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, +// "rsr", &cfg, &name, &name_len, &maps, &map_n) == FAILURE) { +// return; +// } +// ZEND_FETCH_RESOURCE(_cfg, php_git2_t*, &cfg, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); +} + +/* {{{ proto resource git_config_lookup_map_value(maps, map_n, value) +*/ +PHP_FUNCTION(git_config_lookup_map_value) +{ + zval *maps; + php_git2_t *_maps; + + /* TODO(chobie): implement this */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "git_config_lookup_map_value not implemented yet"); + return; + +// if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, +// "rs", &maps, &map_n, &value, &value_len) == FAILURE) { +// return; +// } + ZEND_FETCH_RESOURCE(_maps, php_git2_t*, &maps, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); +} + +/* {{{ proto resource git_config_parse_bool(value) +*/ +PHP_FUNCTION(git_config_parse_bool) +{ + php_git2_config_parse_with(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GIT2_CONFIG_BOOL); +} + +/* {{{ proto resource git_config_parse_int32(value) +*/ +PHP_FUNCTION(git_config_parse_int32) +{ + php_git2_config_parse_with(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GIT2_CONFIG_INT32); +} + +/* {{{ proto resource git_config_parse_int64(value) +*/ +PHP_FUNCTION(git_config_parse_int64) +{ + php_git2_config_parse_with(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_GIT2_CONFIG_INT64); +} + +/* {{{ proto long git_config_backend_foreach_match(backend, regexp, , ), data) +*/ +PHP_FUNCTION(git_config_backend_foreach_match) +{ + zval *backend; + php_git2_t *_backend; + long ; + + /* TODO(chobie): implement this */ + php_error_docref(NULL TSRMLS_CC, E_WARNING, "git_config_backend_foreach_match not implemented yet"); + return; + +// if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, +// "rsl", &backend, ®exp, ®exp_len, &, &), &data) == FAILURE) { +// return; +// } + ZEND_FETCH_RESOURCE(_backend, php_git2_t*, &backend, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); +} diff --git a/g_config.h b/g_config.h new file mode 100644 index 0000000000..c4874a8ecc --- /dev/null +++ b/g_config.h @@ -0,0 +1,366 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_G_CONFIG_H +#define PHP_GIT2_G_CONFIG_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_find_global, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_find_xdg, 0, 0, 2) + ZEND_ARG_INFO(0, length) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_find_system, 0, 0, 2) + ZEND_ARG_INFO(0, length) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_open_default, 0, 0, 1) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_new, 0, 0, 1) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_add_file_ondisk, 0, 0, 4) + ZEND_ARG_INFO(0, cfg) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, level) + ZEND_ARG_INFO(0, force) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_open_ondisk, 0, 0, 2) + ZEND_ARG_INFO(0, path) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_open_level, 0, 0, 3) + ZEND_ARG_INFO(0, parent) + ZEND_ARG_INFO(0, level) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_open_global, 0, 0, 2) + ZEND_ARG_INFO(0, config) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_refresh, 0, 0, 1) + ZEND_ARG_INFO(0, cfg) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_free, 0, 0, 1) + ZEND_ARG_INFO(0, cfg) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_get_entry, 0, 0, 3) + ZEND_ARG_INFO(0, cfg) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_get_int32, 0, 0, 3) + ZEND_ARG_INFO(0, cfg) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_get_int64, 0, 0, 3) + ZEND_ARG_INFO(0, cfg) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_get_bool, 0, 0, 3) + ZEND_ARG_INFO(0, cfg) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_get_string, 0, 0, 3) + ZEND_ARG_INFO(0, cfg) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_get_multivar_foreach, 0, 0, 5) + ZEND_ARG_INFO(0, cfg) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, regexp) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_multivar_iterator_new, 0, 0, 4) + ZEND_ARG_INFO(0, cfg) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, regexp) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_next, 0, 0, 2) + ZEND_ARG_INFO(0, iter) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_iterator_free, 0, 0, 1) + ZEND_ARG_INFO(0, iter) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_set_int32, 0, 0, 3) + ZEND_ARG_INFO(0, cfg) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_set_int64, 0, 0, 3) + ZEND_ARG_INFO(0, cfg) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_set_bool, 0, 0, 3) + ZEND_ARG_INFO(0, cfg) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_set_string, 0, 0, 3) + ZEND_ARG_INFO(0, cfg) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_set_multivar, 0, 0, 4) + ZEND_ARG_INFO(0, cfg) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, regexp) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_delete_entry, 0, 0, 2) + ZEND_ARG_INFO(0, cfg) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_delete_multivar, 0, 0, 3) + ZEND_ARG_INFO(0, cfg) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, regexp) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_foreach, 0, 0, 3) + ZEND_ARG_INFO(0, cfg) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_iterator_new, 0, 0, 2) + ZEND_ARG_INFO(0, cfg) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_iterator_glob_new, 0, 0, 3) + ZEND_ARG_INFO(0, cfg) + ZEND_ARG_INFO(0, regexp) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_foreach_match, 0, 0, 4) + ZEND_ARG_INFO(0, cfg) + ZEND_ARG_INFO(0, regexp) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_get_mapped, 0, 0, 5) + ZEND_ARG_INFO(0, cfg) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, maps) + ZEND_ARG_INFO(0, map_n) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_lookup_map_value, 0, 0, 4) + ZEND_ARG_INFO(0, maps) + ZEND_ARG_INFO(0, map_n) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_parse_bool, 0, 0, 2) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_parse_int32, 0, 0, 2) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_parse_int64, 0, 0, 2) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_config_backend_foreach_match, 0, 0, 5) + ZEND_ARG_INFO(0, backend) + ZEND_ARG_INFO(0, regexp) +// ZEND_ARG_INFO(0, ) +// ZEND_ARG_INFO(0, )) +// ZEND_ARG_INFO(0, data) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_config_find_global(length) +*/ +PHP_FUNCTION(git_config_find_global); + +/* {{{ proto resource git_config_find_xdg(length) +*/ +PHP_FUNCTION(git_config_find_xdg); + +/* {{{ proto resource git_config_find_system(length) +*/ +PHP_FUNCTION(git_config_find_system); + +/* {{{ proto resource git_config_open_default() +*/ +PHP_FUNCTION(git_config_open_default); + +/* {{{ proto resource git_config_new() +*/ +PHP_FUNCTION(git_config_new); + +/* {{{ proto long git_config_add_file_ondisk(cfg, path, level, force) +*/ +PHP_FUNCTION(git_config_add_file_ondisk); + +/* {{{ proto resource git_config_open_ondisk(path) +*/ +PHP_FUNCTION(git_config_open_ondisk); + +/* {{{ proto resource git_config_open_level(parent, level) +*/ +PHP_FUNCTION(git_config_open_level); + +/* {{{ proto resource git_config_open_global(config) +*/ +PHP_FUNCTION(git_config_open_global); + +/* {{{ proto long git_config_refresh(cfg) +*/ +PHP_FUNCTION(git_config_refresh); + +/* {{{ proto void git_config_free(cfg) +*/ +PHP_FUNCTION(git_config_free); + +/* {{{ proto resource git_config_get_entry(cfg, name) +*/ +PHP_FUNCTION(git_config_get_entry); + +/* {{{ proto resource git_config_get_int32(cfg, name) +*/ +PHP_FUNCTION(git_config_get_int32); + +/* {{{ proto resource git_config_get_int64(cfg, name) +*/ +PHP_FUNCTION(git_config_get_int64); + +/* {{{ proto resource git_config_get_bool(cfg, name) +*/ +PHP_FUNCTION(git_config_get_bool); + +/* {{{ proto resource git_config_get_string(cfg, name) +*/ +PHP_FUNCTION(git_config_get_string); + +/* {{{ proto long git_config_get_multivar_foreach(cfg, name, regexp, callback, payload) +*/ +PHP_FUNCTION(git_config_get_multivar_foreach); + +/* {{{ proto resource git_config_multivar_iterator_new(cfg, name, regexp) +*/ +PHP_FUNCTION(git_config_multivar_iterator_new); + +/* {{{ proto resource git_config_next(iter) +*/ +PHP_FUNCTION(git_config_next); + +/* {{{ proto void git_config_iterator_free(iter) +*/ +PHP_FUNCTION(git_config_iterator_free); + +/* {{{ proto long git_config_set_int32(cfg, name, value) +*/ +PHP_FUNCTION(git_config_set_int32); + +/* {{{ proto long git_config_set_int64(cfg, name, value) +*/ +PHP_FUNCTION(git_config_set_int64); + +/* {{{ proto long git_config_set_bool(cfg, name, value) +*/ +PHP_FUNCTION(git_config_set_bool); + +/* {{{ proto long git_config_set_string(cfg, name, value) +*/ +PHP_FUNCTION(git_config_set_string); + +/* {{{ proto long git_config_set_multivar(cfg, name, regexp, value) +*/ +PHP_FUNCTION(git_config_set_multivar); + +/* {{{ proto long git_config_delete_entry(cfg, name) +*/ +PHP_FUNCTION(git_config_delete_entry); + +/* {{{ proto long git_config_delete_multivar(cfg, name, regexp) +*/ +PHP_FUNCTION(git_config_delete_multivar); + +/* {{{ proto long git_config_foreach(cfg, callback, payload) +*/ +PHP_FUNCTION(git_config_foreach); + +/* {{{ proto resource git_config_iterator_new(cfg) +*/ +PHP_FUNCTION(git_config_iterator_new); + +/* {{{ proto resource git_config_iterator_glob_new(cfg, regexp) +*/ +PHP_FUNCTION(git_config_iterator_glob_new); + +/* {{{ proto long git_config_foreach_match(cfg, regexp, callback, payload) +*/ +PHP_FUNCTION(git_config_foreach_match); + +/* {{{ proto resource git_config_get_mapped(cfg, name, maps, map_n) +*/ +PHP_FUNCTION(git_config_get_mapped); + +/* {{{ proto resource git_config_lookup_map_value(maps, map_n, value) +*/ +PHP_FUNCTION(git_config_lookup_map_value); + +/* {{{ proto resource git_config_parse_bool(value) +*/ +PHP_FUNCTION(git_config_parse_bool); + +/* {{{ proto resource git_config_parse_int32(value) +*/ +PHP_FUNCTION(git_config_parse_int32); + +/* {{{ proto resource git_config_parse_int64(value) +*/ +PHP_FUNCTION(git_config_parse_int64); + +/* {{{ proto long git_config_backend_foreach_match(backend, regexp, , ), data) +*/ +PHP_FUNCTION(git_config_backend_foreach_match); + +#endif \ No newline at end of file diff --git a/gen.php b/gen.php new file mode 100644 index 0000000000..78824e1149 --- /dev/null +++ b/gen.php @@ -0,0 +1,224 @@ + generate header +// 1 => generate source +// +// filter: +// - prefix: don't show matched keywords +// e.g ) -cred +// will ignore codes which have `cred` keyword +// default: show matched keywords only +// e.g ) cred +// will show codes which have `cred` keyword +// +// php gen.php libgit2/include/git2/.h (0|1) [filter] > target.h or target.c + +$data = file_get_contents($_SERVER['argv'][1]); + +$table = array(); +$buffer = ""; +if (preg_match_all("/GIT_EXTERN\((.+?)\)\s*([a-zA-Z0-9_-]+)\((.+?)\);/s", $data, $match)) { + + for ($i = 0; $i < count($match[0]); $i++) { + $tmp = array( + "args" => array(), + ); + + $list = array_map("trim", explode(",", $match[3][$i])); + + $tmp['name'] = $match[2][$i]; + $tmp['retval'] = $match[1][$i]; + + $d = count($list); + if ((preg_match("/(\*\*|out)/", $list[0]) || preg_match("/(write|create|new)/", $match[2][$i]))) { + $d--; + } + + + if (isset($_SERVER['argv'][3])) { + if ($_SERVER['argv'][3][0] == "-") { + $_SERVER['argv'][3] = substr($_SERVER['argv'][3][0], 1); + $flag = true; + } else { + $flag = false; + } + if (preg_match("/{$_SERVER['argv'][3]}/", $match[2][$i]) == $flag) { + continue; + } + } + + $match[3][$i] = trim(preg_replace("/\r?\n/", "", $match[3][$i])); + $match[3][$i] = trim(preg_replace("/\t/", " ", $match[3][$i])); + + if ($_SERVER['argv'][2] == "0") { + $buffer .= "ZEND_BEGIN_ARG_INFO_EX(arginfo_{$match[2][$i]}, 0, 0, $d)\n"; + } + + $o = 0; + foreach ($list as $l) { + $b = array_map(function($l){return trim($l, " *");}, explode(" ", $l)); + $type = substr($l, 0, strrpos($l, " ")); + + $n = array_pop($b); + $b = array_pop($b); + + if ($o == 0 && (preg_match("/(\*\*|out)/", $l) || preg_match("/(write|create|new)/", $match[2][$i]))) { + $w = 1; + $tmp['retval'] = "resource"; + }else { + $w = 0; + } + + if (!$w) { + $tmp['args'][] = array( + "write" => $w, + "name" => $n, + "type" => $type, + ); + if ($_SERVER['argv'][2] == "0") { + $buffer .= "\tZEND_ARG_INFO(0, $n)\n"; + } + } + + $o++; + } + + if ($_SERVER['argv'][2] == "0") { + $buffer .= "ZEND_END_ARG_INFO()\n"; + $buffer .= "\n"; + + } + + $table[] = $tmp; + } +} + +if ($_SERVER['argv'][2] == "1") { + $buffer .= '#include "php_git2.h"' . "\n"; + $buffer .= '#include "php_git2_priv.h"' . "\n"; + $buffer .= '#include ".h"' . "\n"; +} + + +foreach ($table as $func) { + $ret = getReturnType($func['retval']); + + $t = array(); + foreach ($func['args'] as $a) { + $t[] = $a['name']; + } + $sig = join(", ", $t); + + $buffer .= "/* {{{ proto $ret {$func['name']}($sig)\n"; + $buffer .= "*/\n"; + + if ($_SERVER['argv'][2] == "0") { + $buffer .= "PHP_FUNCTION({$func['name']});\n"; + $buffer .= "\n"; + } else { + $buffer .= "PHP_FUNCTION({$func['name']})\n"; + $buffer .= "{\n"; + $buffer .= getDeclarations($func); + + $buffer .= "\t/* TODO(chobie): implement this */\n"; + $buffer .= "\tphp_error_docref(NULL TSRMLS_CC, E_WARNING, " . '"' . "{$func['name']} not implemented yet" . '"' . ");\n"; + $buffer .= "\treturn;\n\n"; + + $buffer .= "\tif (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,\n"; + $buffer .= "\t\t" . sprintf('"%s", %s) == FAILURE) {%s', getParseStr($func), getParseStr2($func), "\n"); + $buffer .= "\t\treturn;\n"; + $buffer .= "\t}\n"; + if (hasResource($func)) { + $t = $func['args'][0]; + $buffer .= "\tZEND_FETCH_RESOURCE(_{$t['name']}, php_git2_t*, &{$t['name']}, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);\n"; + } + $buffer .= "}\n"; + $buffer .= "\n"; + } +} + +echo $buffer; + + +function hasResource($func) +{ + $result = false; + foreach ($func['args'] as $arg) { + if (preg_match("/char/", $arg['type'])) { + } else if (preg_match("/git_oid/", $arg['type'])) { + } else if (preg_match("/git_/", $arg['type'])) { + $result = true; + } + } + return $result; +} + +function getDeclarations($func) +{ + $result = array(); + foreach ($func['args'] as $arg) { + if (preg_match("/char/", $arg['type'])) { + $result[] = "\tchar *" . $arg['name'] . " = {0};"; + $result[] = "\tint " . $arg['name'] . "_len;"; + } else if (preg_match("/int/", $arg['type'])) { + $result[] = "\tlong " . $arg['name'] . ";"; + } else if (preg_match("/git_oid/", $arg['type'])) { + $result[] = "\tchar *" . $arg['name'] . " = {0};"; + $result[] = "\tint " . $arg['name'] . "_len;"; + } else if (preg_match("/git_/", $arg['type'])) { + $result[] = "\tzval *" . $arg['name'] . ";"; + $result[] = "\tphp_git2_t *_" . $arg['name'] . ";"; + } + } + $result[] = ""; + $result[] = ""; + + return join("\n", $result); +} + +function getParseStr($func) +{ + $result = array(); + foreach ($func['args'] as $arg) { + if (preg_match("/char/", $arg['type'])) { + $result[] = "s"; + } else if (preg_match("/git_oid/", $arg['type'])) { + $result[] = "s"; + } else if (preg_match("/int/", $arg['type'])) { + $result[] = "l"; + } else if (preg_match("/git_/", $arg['type'])) { + $result[] = "r"; + } + } + + return join("", $result); +} + +function getParseStr2($func) +{ + $result = array(); + foreach ($func['args'] as $arg) { + $result[] = "&" . $arg['name']; + if (preg_match("/char/", $arg['type'])) { + $result[] = "&" . $arg['name'] . "_len"; + } else if (preg_match("/git_oid/", $arg['type'])) { + $result[] = "&" . $arg['name'] . "_len"; + } + } + + return join(", ", $result); +} + +function getReturnType($name) +{ + switch($name) { + case "int": + return "long"; + case "void": + return "void"; + default: + return "resource"; + } +} \ No newline at end of file diff --git a/git2.c b/git2.c deleted file mode 100644 index bc8f5dec91..0000000000 --- a/git2.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2010 - 2012 Shuhei Tanuma - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "php_git2.h" - -extern void php_git2_repository_init(TSRMLS_D); -extern void php_git2_commit_init(TSRMLS_D); -extern void php_git2_blob_init(TSRMLS_D); -extern void php_git2_tree_init(TSRMLS_D); -extern void php_git2_tree_builder_init(TSRMLS_D); -extern void php_git2_signature_init(TSRMLS_D); -extern void php_git2_walker_init(TSRMLS_D); -extern void php_git2_reference_init(TSRMLS_D); - - -int php_git2_call_user_function_v(zval **retval, zval *obj, char *method, unsigned int method_len, unsigned int param_count, ...) -{ - va_list ap; - size_t i; - int error = 0; - zval **params, *method_name, *ret= NULL; - TSRMLS_FETCH(); - - if (param_count > 0) { - params = emalloc(sizeof(zval**) * param_count); - va_start(ap, param_count); - for (i = 0; i < param_count; i ++) { - params[i] = va_arg(ap, zval*); - } - va_end(ap); - } else { - params = NULL; - } - - MAKE_STD_ZVAL(ret); - MAKE_STD_ZVAL(method_name); - - ZVAL_NULL(ret); - ZVAL_STRINGL(method_name, method, method_len, 1); - - error = call_user_function(NULL, &obj, method_name, ret, param_count, params TSRMLS_CC); - - if (param_count > 0) { - for (i = 0; i < param_count; i++) { - if (params[i] != NULL) { - zval_ptr_dtor(¶ms[i]); - } - } - efree(params); - params = NULL; - } - *retval = ret; - zval_ptr_dtor(&method_name); - - return error; -} - -zval* php_git2_object_new(git_repository *repository, git_object *object TSRMLS_DC) -{ - zval *result = NULL; - MAKE_STD_ZVAL(result); - - switch (git_object_type(object)) { - case GIT_OBJ_COMMIT: { - php_git2_commit *m_obj = NULL; - - object_init_ex(result, git2_commit_class_entry); - m_obj = PHP_GIT2_GET_OBJECT(php_git2_commit, result); - m_obj->commit = (git_commit*)object; - break; - } - case GIT_OBJ_BLOB: { - php_git2_blob *m_obj = NULL; - - object_init_ex(result, git2_blob_class_entry); - m_obj = PHP_GIT2_GET_OBJECT(php_git2_blob, result); - m_obj->blob = (git_blob*)object; - break; - } - case GIT_OBJ_TREE: { - php_git2_tree *m_obj = NULL; - unsigned int *numbers = 0; - int i = 0; - zval *m_array; - - object_init_ex(result, git2_tree_class_entry); - m_obj = PHP_GIT2_GET_OBJECT(php_git2_tree, result); - m_obj->tree = (git_tree*)object; - m_obj->repository = repository; - numbers = git_tree_entrycount(m_obj->tree); - MAKE_STD_ZVAL(m_array); - array_init(m_array); - - for (i = 0;i < numbers; i++) { - const char *entry_name = {0}; - const char entry_oid[GIT_OID_HEXSZ+1] = {0}; - const git_tree_entry *entry; - const git_oid *oid = NULL; - zval *m_entry = NULL; - - entry = git_tree_entry_byindex(m_obj->tree, i); - entry_name = git_tree_entry_name(entry); - oid = git_tree_entry_id(entry); - git_oid_fmt(entry_oid, oid); - - MAKE_STD_ZVAL(m_entry); - object_init_ex(m_entry, git2_tree_entry_class_entry); - add_property_stringl_ex(m_entry, "name", sizeof("name"), entry_name, strlen(entry_name), 1 TSRMLS_CC); - add_property_stringl_ex(m_entry, "oid", sizeof("oid"), entry_oid, strlen(entry_oid), 1 TSRMLS_CC); - add_property_long_ex(m_entry, "attributes", sizeof("attributes"), git_tree_entry_attributes(entry) TSRMLS_CC); - add_next_index_zval(m_array, m_entry); - } - - add_property_zval_ex(result, "entries",sizeof("entries"),m_array TSRMLS_CC); - zval_ptr_dtor(&m_array); - - break; - } - case GIT_OBJ_TAG: { - break; - } - default: - break; - } - - return result; -} - -int php_git2_add_protected_property_string_ex(zval *object, char *name, int name_length, char *data, zend_bool duplicate TSRMLS_DC) -{ - zval *tmp; - char *key; - int length; - - MAKE_STD_ZVAL(tmp); - ZVAL_STRING(tmp,data,duplicate); - zend_mangle_property_name(&key, &length, "*",1,name,name_length,0); - zend_hash_update(Z_OBJPROP_P(object),key,length,&tmp,sizeof(zval *),NULL); - efree(key); - - return SUCCESS; -} - - -PHP_MINIT_FUNCTION(git2) -{ - php_git2_repository_init(TSRMLS_C); - php_git2_commit_init(TSRMLS_C); - php_git2_blob_init(TSRMLS_C); - php_git2_tree_init(TSRMLS_C); - php_git2_tree_builder_init(TSRMLS_C); - php_git2_tree_entry_init(TSRMLS_C); - php_git2_signature_init(TSRMLS_C); - php_git2_walker_init(TSRMLS_C); - php_git2_reference_init(TSRMLS_C); - php_git2_index_entry_init(TSRMLS_C); - php_git2_index_init(TSRMLS_C); - - return SUCCESS; -} - -PHP_MINFO_FUNCTION(git2) -{ - php_printf("PHP libgit2 Extension\n"); - php_info_print_table_start(); - php_info_print_table_row(2,"Version", PHP_GIT2_EXTVER "-dev"); - php_info_print_table_row(2,"libgit2 version", LIBGIT2_VERSION); - php_info_print_table_end(); -} - -zend_module_entry git2_module_entry = { -#if ZEND_MODULE_API_NO >= 20010901 - STANDARD_MODULE_HEADER, -#endif - PHP_GIT2_EXTNAME, - NULL, /* Functions */ - PHP_MINIT(git2), /* MINIT */ - NULL, /* MSHUTDOWN */ - NULL, /* RINIT */ - NULL, /* RSHUTDOWN */ - PHP_MINFO(git2), /* MFINFO */ -#if ZEND_MODULE_API_NO >= 20010901 - PHP_GIT2_EXTVER, -#endif - STANDARD_MODULE_PROPERTIES -}; - -#ifdef COMPILE_DL_GIT2 -ZEND_GET_MODULE(git2) -#endif \ No newline at end of file diff --git a/giterr.c b/giterr.c new file mode 100644 index 0000000000..23229485a8 --- /dev/null +++ b/giterr.c @@ -0,0 +1,81 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "giterr.h" + +static void php_git2_error_to_array(const git_error *error, zval **out) +{ + zval *array; + + MAKE_STD_ZVAL(array); + array_init(array); + if (error == NULL) { + add_next_index_string(array, "", 1); + add_next_index_long(array, 0); + } else { + add_next_index_string(array, error->message, 1); + add_next_index_long(array, error->klass); + } + *out = array; +} + +/* {{{ proto resource giterr_last() + */ +PHP_FUNCTION(giterr_last) +{ + const git_error *result = {0}; + zval *array; + + result = giterr_last(); + php_git2_error_to_array(result, &array); + + RETURN_ZVAL(array, 0, 1); +} +/* }}} */ + +/* {{{ proto void giterr_clear() + */ +PHP_FUNCTION(giterr_clear) +{ + giterr_clear(); +} +/* }}} */ + +/* {{{ proto array giterr_detach() + */ +PHP_FUNCTION(giterr_detach) +{ + int result = 0; + git_error cpy; + zval *array; + + result = giterr_detach(&cpy); + php_git2_error_to_array(&cpy, &array); + RETURN_ZVAL(array, 0, 1); +} +/* }}} */ + +/* {{{ proto void giterr_set_str(long $error_class, string $string) + */ +PHP_FUNCTION(giterr_set_str) +{ + long error_class = 0; + char *string = NULL; + int string_len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "ls", &error_class, &string, &string_len) == FAILURE) { + return; + } + + giterr_set_str(error_class, string); +} +/* }}} */ + +/* {{{ proto void giterr_set_oom() + */ +PHP_FUNCTION(giterr_set_oom) +{ + giterr_set_oom(); +} +/* }}} */ + diff --git a/giterr.h b/giterr.h new file mode 100644 index 0000000000..ff25692c15 --- /dev/null +++ b/giterr.h @@ -0,0 +1,70 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_GITERR_H +#define PHP_GIT2_GITERR_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_giterr_last, 0, 0, 1) + ZEND_ARG_INFO(0, void) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_giterr_clear, 0, 0, 1) + ZEND_ARG_INFO(0, void) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_giterr_detach, 0, 0, 1) + ZEND_ARG_INFO(0, cpy) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_giterr_set_str, 0, 0, 2) + ZEND_ARG_INFO(0, error_class) + ZEND_ARG_INFO(0, string) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_giterr_set_oom, 0, 0, 1) + ZEND_ARG_INFO(0, void) +ZEND_END_ARG_INFO() + +/* {{{ proto resource giterr_last(void) +*/ +PHP_FUNCTION(giterr_last); + +/* {{{ proto void giterr_clear(void) +*/ +PHP_FUNCTION(giterr_clear); + +/* {{{ proto long giterr_detach(cpy) +*/ +PHP_FUNCTION(giterr_detach); + +/* {{{ proto void giterr_set_str(error_class, string) +*/ +PHP_FUNCTION(giterr_set_str); + +/* {{{ proto void giterr_set_oom(void) +*/ +PHP_FUNCTION(giterr_set_oom); + +#endif \ No newline at end of file diff --git a/graph.c b/graph.c new file mode 100644 index 0000000000..cd2463d619 --- /dev/null +++ b/graph.c @@ -0,0 +1,38 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "graph.h" + +/* {{{ proto long git_graph_ahead_behind(resource $repo, string $local, string $upstream) + */ +PHP_FUNCTION(git_graph_ahead_behind) +{ + int result = 0, local_len = 0, upstream_len = 0; + zval *repo = NULL, *array = NULL; + php_git2_t *_repo = NULL; + char *local = NULL, *upstream = NULL; + git_oid __local = {0}, __upstream = {0}; + size_t ahead = 0, behind = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rss", &ahead, &behind, &repo, &local, &local_len, &upstream, &upstream_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__local, local, local_len)) { + RETURN_FALSE; + } + if (git_oid_fromstrn(&__upstream, upstream, upstream_len)) { + RETURN_FALSE; + } + result = git_graph_ahead_behind(&ahead, &behind, PHP_GIT2_V(_repo, repository), &__local, &__upstream); + + MAKE_STD_ZVAL(array); + array_init(array); + add_next_index_long(array, ahead); + add_next_index_long(array, behind); + + RETURN_ZVAL(array, 0, 1); +} +/* }}} */ + diff --git a/graph.h b/graph.h new file mode 100644 index 0000000000..3c1dbabc86 --- /dev/null +++ b/graph.h @@ -0,0 +1,39 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_GRAPH_H +#define PHP_GIT2_GRAPH_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_graph_ahead_behind, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, local) + ZEND_ARG_INFO(0, upstream) +ZEND_END_ARG_INFO() + +/* {{{ proto long git_graph_ahead_behind(long $ahead, long $behind, resource $repo, string $local, string $upstream) + */ +PHP_FUNCTION(git_graph_ahead_behind); + +#endif diff --git a/helper.c b/helper.c new file mode 100644 index 0000000000..84c898d2f1 --- /dev/null +++ b/helper.c @@ -0,0 +1,786 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "helper.h" + +static zval* datetime_instantiate(zend_class_entry *pce, zval *object TSRMLS_DC) +{ +#if PHP_VERSION_ID <= 50304 + Z_TYPE_P(object) = IS_OBJECT; + object_init_ex(object, pce); + Z_SET_REFCOUNT_P(object, 1); + Z_UNSET_ISREF_P(object); + return object; +#else + return php_date_instantiate(pce, object TSRMLS_CC); +#endif +} + +int php_git2_check_error(int error_code, const char *action TSRMLS_DC) +{ + int result = 0; + const git_error * error; + if (!error_code) { + return result; + } + + error = giterr_last(); + php_error_docref(NULL TSRMLS_CC, E_WARNING, "WARNING %d %s - %s", + error_code, action, (error && error->message) ? error->message : "???"); + + result = 1; + return result; +} + + +zval* php_git2_read_arrval(zval *array, char *name, size_t name_len TSRMLS_DC) +{ + zval *result = NULL, **element; + + if (zend_hash_find(Z_ARRVAL_P(array), name, name_len, (void**)&element) == SUCCESS) { + result = *element; + } + + return result; +} + +long php_git2_read_arrval_long2(zval *array, char *name, size_t name_len, long value TSRMLS_DC) +{ + zval *tmp; + long result = value; + + tmp = php_git2_read_arrval(array, name, name_len TSRMLS_CC); + if (tmp) { + result = Z_LVAL_P(tmp); + } + + return result; +} + +long php_git2_read_arrval_long(zval *array, char *name, size_t name_len TSRMLS_DC) +{ + zval *tmp; + long result = 0; + + tmp = php_git2_read_arrval(array, name, name_len TSRMLS_CC); + if (tmp) { + result = Z_LVAL_P(tmp); + } + + return result; +} + +const char* php_git2_read_arrval_string(zval *array, char *name, size_t name_len TSRMLS_DC) +{ + zval *tmp; + const char *result = NULL; + + tmp = php_git2_read_arrval(array, name, name_len TSRMLS_CC); + if (tmp) { + result = Z_STRVAL_P(tmp); + } + + return result; +} + +void php_git2_array_to_signature(git_signature *signature, zval *author TSRMLS_DC) +{ + zval *name = NULL, *email = NULL, *time = NULL; + + name = php_git2_read_arrval(author, ZEND_STRS("name") TSRMLS_CC); + email = php_git2_read_arrval(author, ZEND_STRS("email") TSRMLS_CC); + time = php_git2_read_arrval(author, ZEND_STRS("time") TSRMLS_CC); + + signature->name = Z_STRVAL_P(name); + signature->email = Z_STRVAL_P(email); + + //instanceof_function_ex(const zend_class_entry *instance_ce, const zend_class_entry *ce, zend_bool interfaces_only TSRMLS_DC); + if (time != NULL && + Z_TYPE_P(time) == IS_OBJECT && + instanceof_function_ex(Z_OBJCE_P(time), php_date_get_date_ce(), 0 TSRMLS_CC)) { + php_date_obj *date; + + date = (php_date_obj *)zend_object_store_get_object(time TSRMLS_CC); + signature->when.time = date->time->sse; + signature->when.offset = date->time->z; + } +} + +void php_git2_signature_to_array(const git_signature *signature, zval **out TSRMLS_DC) +{ + zval *result, *datetime, *timezone; + php_timezone_obj *tzobj; + char time_str[12] = {0}; + + MAKE_STD_ZVAL(result); + array_init(result); + + MAKE_STD_ZVAL(datetime); + MAKE_STD_ZVAL(timezone); + + datetime_instantiate(php_date_get_date_ce(), datetime TSRMLS_CC); + snprintf(time_str,12,"%c%ld",'@', signature->when.time); + + datetime_instantiate(php_date_get_timezone_ce(), timezone TSRMLS_CC); + tzobj = (php_timezone_obj *) zend_object_store_get_object(timezone TSRMLS_CC); + tzobj->initialized = 1; + tzobj->type = TIMELIB_ZONETYPE_OFFSET; + tzobj->tzi.utc_offset = -signature->when.offset; // doesn't work + + /* TODO(chobie): how do i set offset? */ + php_date_initialize(zend_object_store_get_object(datetime TSRMLS_CC), time_str, strlen(time_str), NULL, timezone, 0 TSRMLS_CC); + + if (signature->name == NULL) { + add_assoc_null_ex(result, ZEND_STRS("name")); + } else { + add_assoc_string_ex(result, ZEND_STRS("name"), signature->name, 1); + } + if (signature->email == NULL) { + add_assoc_null_ex(result, ZEND_STRS("email")); + } else { + add_assoc_string_ex(result, ZEND_STRS("email"), signature->email, 1); + } + add_assoc_zval_ex(result, ZEND_STRS("time"), datetime); + + zval_ptr_dtor(&timezone); + + *out = result; +} + +void php_git2_strarray_to_array(git_strarray *array, zval **out TSRMLS_DC) +{ + zval *result; + int i = 0; + + MAKE_STD_ZVAL(result); + array_init(result); + + for (i = 0; i < array->count; i++) { + add_next_index_string(result, array->strings[i], 1); + } + *out = result; +} + +int php_git2_call_function_v( + zend_fcall_info *fci, zend_fcall_info_cache *fcc TSRMLS_DC, zval **retval_ptr_ptr, zend_uint param_count, ...) +{ + zval **params = NULL; + va_list ap; + int i = 0; + + if (param_count > 0) { + params = emalloc(sizeof(zval*) * param_count); + va_start(ap, param_count); + for (i = 0; i < param_count; i++) { + params[i] = va_arg(ap, zval**); + } + va_end(ap); + } else { + params = NULL; + } + + if (ZEND_FCI_INITIALIZED(*fci)) { + fci->params = params; + fci->retval_ptr_ptr = retval_ptr_ptr; + fci->param_count = param_count; + fci->no_separation = 1; + + if (zend_call_function(fci, fcc TSRMLS_CC) != SUCCESS) { + if (param_count > 0) { + for (i = 0; i < param_count; i++) { + zval_ptr_dtor(params[i]); + } + efree(params); + } + return 1; + } + zend_fcall_info_args_clear(fci, 0); + } + + if (param_count > 0) { + for (i = 0; i < param_count; i++) { + zval_ptr_dtor(params[i]); + } + efree(params); + } + return 0; +} + +int php_git2_cb_init(php_git2_cb_t **out, zend_fcall_info *fci, zend_fcall_info_cache *fcc, void *payload TSRMLS_DC) +{ + php_git2_cb_t *cb; + + cb = (struct php_git2_cb_t*)emalloc(sizeof(php_git2_cb_t)); + if (cb == NULL) { + return 1; + } + + cb->payload = payload; + cb->fci = fci; + cb->fcc = fcc; + GIT2_TSRMLS_SET2(cb, TSRMLS_C); + + *out = cb; + return 0; +} + +void php_git2_cb_free(php_git2_cb_t *target) +{ + efree(target); +} + +void php_git2_array_to_strarray(git_strarray *out, zval *array TSRMLS_DC) +{ + int elements = 0, i; + HashPosition pos; + zval **value; + + if (array == NULL) { + return; + } + if (Z_TYPE_P(array) != IS_ARRAY){ + return; + } + if (zend_hash_num_elements(Z_ARRVAL_P(array)) == 0) { + return; + } + + elements = zend_hash_num_elements(Z_ARRVAL_P(array)); + out->strings = (char**)emalloc(sizeof(char*) * elements); + out->count = elements; + for (i = 0, zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(array), &pos); + zend_hash_get_current_data_ex(Z_ARRVAL_P(array), (void **)&value, &pos) == SUCCESS; + zend_hash_move_forward_ex(Z_ARRVAL_P(array), &pos), i++) { + char *buffer; + + Z_STRVAL_PP(value); + buffer = emalloc(sizeof(char*) * Z_STRLEN_PP(value) + 1); + memcpy(buffer, Z_STRVAL_PP(value), Z_STRLEN_PP(value)); + buffer[Z_STRLEN_PP(value)] = '\0'; + out->strings[i] = buffer; + } +} + +void php_git2_strarray_free(git_strarray *out) +{ + int i = 0; + for (i = 0; i < out->count; i++) { + efree(out->strings[i]); + } + efree(out->strings); +} + +void php_git2_git_checkout_opts_to_array(git_checkout_opts *opts, zval **out TSRMLS_DC) +{ + zval *result; + git_checkout_opts tmp = GIT_CHECKOUT_OPTS_INIT; + opts = &tmp; + + MAKE_STD_ZVAL(result); + array_init(result); + + add_assoc_long_ex(result, ZEND_STRS("version"), opts->version); + add_assoc_long_ex(result, ZEND_STRS("checkout_strategy"), opts->checkout_strategy); + add_assoc_long_ex(result, ZEND_STRS("disable_filters"), opts->disable_filters); + add_assoc_long_ex(result, ZEND_STRS("dir_mode"), opts->dir_mode); + add_assoc_long_ex(result, ZEND_STRS("file_mode"), opts->file_mode); + add_assoc_long_ex(result, ZEND_STRS("file_open_flags"), opts->file_open_flags); + add_assoc_long_ex(result, ZEND_STRS("notify_flags"), opts->notify_flags); + + if (opts->notify_payload != NULL) { + + } else { + add_assoc_null_ex(result, ZEND_STRS("notify_cb")); + } + + if (opts->notify_payload != NULL) { + + } else { + add_assoc_null_ex(result, ZEND_STRS("notify_payload")); + } + + if (opts->progress_cb != NULL) { + + } else { + add_assoc_null_ex(result, ZEND_STRS("progress_cb")); + } + + if (opts->progress_payload != NULL) { + + } else { + add_assoc_null_ex(result, ZEND_STRS("progress_payload")); + } + + if (opts->paths.count > 0) { + zval *paths; + php_git2_strarray_to_array(&opts->paths, &paths TSRMLS_CC); + add_assoc_zval_ex(result, ZEND_STRS("paths"), paths); + } else { + zval *paths; + MAKE_STD_ZVAL(paths); + array_init(paths); + add_assoc_zval_ex(result, ZEND_STRS("paths"), paths); + } + + if (opts->baseline != NULL) { + // git_tree + + } else { + add_assoc_null_ex(result, ZEND_STRS("baseline")); + } + add_assoc_string_ex(result, ZEND_STRS("target_directory"), (opts->target_directory) ? opts->target_directory : "", 1); + add_assoc_string_ex(result, ZEND_STRS("our_label"), (opts->our_label) ? opts->our_label : "", 1); + add_assoc_string_ex(result, ZEND_STRS("their_label"), (opts->their_label) ? opts->their_label : "", 1); + + *out = result; +} + +void php_git_git_checkout_opts_free(git_checkout_opts *target TSRMLS_DC) +{ + php_git2_cb_t *tmp; + + if (target->notify_payload) { + tmp = (php_git2_cb_t*)target->notify_payload; + if (tmp->fci) { + efree(tmp->fci); + } + if (tmp->fcc) { + efree(tmp->fcc); + } + efree(target->notify_payload); + } + if (target->progress_payload) { + tmp = (php_git2_cb_t*)target->progress_payload; + if (tmp->fci) { + efree(tmp->fci); + } + if (tmp->fcc) { + efree(tmp->fcc); + } + efree(target->progress_payload); + } + + php_git2_strarray_free(&target->paths); + efree(target); +} + + +static int php_git2_git_checkout_notify_cb(git_checkout_notify_t why, + const char *path, + const git_diff_file *baseline, + const git_diff_file *target, + const git_diff_file *workdir, + void *payload) +{ + /* TODO(chobie): implement callback */ +} + +void php_git2_git_checkout_progress_cb(const char *path, + size_t completed_steps, + size_t total_steps, + void *payload) +{ + zval *param_path, *param_completed_steps, *param_total_steps, *retval_ptr = NULL; + php_git2_cb_t *p = (php_git2_cb_t*)payload; + GIT2_TSRMLS_SET(p->tsrm_ls); + + Z_ADDREF_P(p->payload); + MAKE_STD_ZVAL(param_path); + MAKE_STD_ZVAL(param_completed_steps); + MAKE_STD_ZVAL(param_total_steps); + ZVAL_NULL(param_path); + if (path != NULL) { + ZVAL_STRING(param_path, path, 1); + } + ZVAL_LONG(param_completed_steps, completed_steps); + ZVAL_LONG(param_total_steps, total_steps); + + SEPARATE_ZVAL_TO_MAKE_IS_REF(&p->payload); + if (php_git2_call_function_v(p->fci, p->fcc TSRMLS_CC, &retval_ptr, 4, ¶m_path, ¶m_completed_steps, ¶m_total_steps, &p->payload)) { + return; + } + + zval_ptr_dtor(&retval_ptr); +} + + +void php_git2_fcall_info_wrapper(zval *target, zend_fcall_info **out_fci, zend_fcall_info_cache **out_fcc TSRMLS_DC) +{ + char *is_callable_error = NULL; + zend_fcall_info *fci = NULL; + zend_fcall_info_cache *fcc = NULL; + + fci = (zend_fcall_info*)emalloc(sizeof(zend_fcall_info)); + fcc = (zend_fcall_info_cache*)emalloc(sizeof(zend_fcall_info_cache)); + memcpy(fci, &empty_fcall_info, sizeof(zend_fcall_info)); + memcpy(fcc, &empty_fcall_info_cache, sizeof(zend_fcall_info_cache)); + + if (zend_fcall_info_init(target, 0, fci, fcc, NULL, &is_callable_error TSRMLS_CC) == SUCCESS) { + if (is_callable_error) { + efree(is_callable_error); + } + } else { + fprintf(stderr, "FAILED"); + efree(fci); + efree(fcc); + return; + } + + *out_fci = fci; + *out_fcc = fcc; +} + +void php_git2_fcall_info_wrapper2(zval *target, zend_fcall_info *fci, zend_fcall_info_cache *fcc TSRMLS_DC) +{ + char *is_callable_error = NULL; + + memcpy(fci, &empty_fcall_info, sizeof(zend_fcall_info)); + memcpy(fcc, &empty_fcall_info_cache, sizeof(zend_fcall_info_cache)); + + if (zend_fcall_info_init(target, 0, fci, fcc, NULL, &is_callable_error TSRMLS_CC) == SUCCESS) { + if (is_callable_error) { + efree(is_callable_error); + } + } else { + fprintf(stderr, "FAILED"); + efree(fci); + efree(fcc); + return; + } +} + + + +int php_git2_array_to_git_checkout_opts(git_checkout_opts **out, zval *array TSRMLS_DC) +{ + const char *target_directory, *our_label, *their_label; + git_checkout_opts *opts = NULL, def = GIT_CHECKOUT_OPTS_INIT; + php_git2_cb_t *notify_payload = NULL, *progress_payload= NULL; + zval *notify_cb = NULL, *progress_cb = NULL; + + opts = (git_checkout_opts*)emalloc(sizeof(struct git_checkout_opts)); + memcpy(opts, &def, sizeof(git_checkout_opts)); + + notify_cb = php_git2_read_arrval(array, ZEND_STRS("notify_cb") TSRMLS_CC); + progress_cb = php_git2_read_arrval(array, ZEND_STRS("progress_cb") TSRMLS_CC); + + + opts->notify_cb = php_git2_git_checkout_notify_cb; + opts->progress_cb = php_git2_git_checkout_progress_cb; + opts->version = php_git2_read_arrval_long(array, ZEND_STRS("version") TSRMLS_CC); + opts->checkout_strategy = php_git2_read_arrval_long(array, ZEND_STRS("checkout_strategy") TSRMLS_CC); + opts->disable_filters = php_git2_read_arrval_long(array, ZEND_STRS("disable_filters") TSRMLS_CC); + opts->dir_mode = php_git2_read_arrval_long(array, ZEND_STRS("dir_mode") TSRMLS_CC); + opts->file_mode = php_git2_read_arrval_long(array, ZEND_STRS("file_mode") TSRMLS_CC); + opts->file_open_flags = php_git2_read_arrval_long(array, ZEND_STRS("file_open_flags") TSRMLS_CC); + opts->notify_flags = php_git2_read_arrval_long(array, ZEND_STRS("notify_flags") TSRMLS_CC); + + //notify_cb + if (Z_TYPE_P(notify_cb) != IS_NULL) { + zend_fcall_info *fci; + zend_fcall_info_cache *fcc; + + php_git2_fcall_info_wrapper(notify_cb, &fci, &fcc TSRMLS_CC); + if (php_git2_cb_init(¬ify_payload, fci, fcc, + php_git2_read_arrval(array, ZEND_STRS("notify_payload") TSRMLS_CC) TSRMLS_CC)) { + } + opts->notify_payload = notify_payload; + } else { + opts->notify_cb = NULL; + } + + //progress_cb + if (Z_TYPE_P(progress_cb) != IS_NULL) { + zend_fcall_info *fci; + zend_fcall_info_cache *fcc; + + php_git2_fcall_info_wrapper(progress_cb, &fci, &fcc TSRMLS_CC); + if (php_git2_cb_init(&progress_payload, fci, fcc, + php_git2_read_arrval(array, ZEND_STRS("progress_payload") TSRMLS_CC) TSRMLS_CC)) { + } + opts->progress_payload = progress_payload; + } else { + opts->progress_cb = NULL; + } + + + php_git2_array_to_strarray(&opts->paths, php_git2_read_arrval(array, ZEND_STRS("paths") TSRMLS_CC) TSRMLS_CC); + + // TODO: assign baseline(git_tree) + + target_directory = php_git2_read_arrval_string(array, ZEND_STRS("target_directory") TSRMLS_CC); + our_label = php_git2_read_arrval_string(array, ZEND_STRS("our_label") TSRMLS_CC); + their_label = php_git2_read_arrval_string(array, ZEND_STRS("their_label") TSRMLS_CC); + opts->target_directory = target_directory; + opts->our_label = our_label; + opts->their_label = their_label; + + *out = opts; + return 0; +} + +int php_git2_multi_cb_init(php_git2_multi_cb_t **out, void *payload TSRMLS_DC, int num_callbacks, ...) +{ + php_git2_multi_cb_t *cb; + int i = 0; + va_list ap; + + cb = (struct php_git2_multi_cb_t*)emalloc(sizeof(php_git2_multi_cb_t)); + if (cb == NULL) { + return 1; + } + + cb->payload = payload; + cb->num_callbacks = num_callbacks; + GIT2_TSRMLS_SET2(cb, TSRMLS_C); + + cb->callbacks = emalloc(sizeof(php_git2_fcall_t) * num_callbacks); + memset(cb->callbacks, '\0', sizeof(php_git2_fcall_t) * num_callbacks); + va_start(ap, num_callbacks * 2); + for (i = 0; i < num_callbacks; i++) { + memcpy(&cb->callbacks[i].fci, va_arg(ap, zend_fcall_info*), sizeof(zend_fcall_info)); + memcpy(&cb->callbacks[i].fcc, va_arg(ap, zend_fcall_info_cache*), sizeof(zend_fcall_info_cache)); + } + va_end(ap); + + *out = cb; + return 0; +} + +void php_git2_multi_cb_free(php_git2_multi_cb_t *target) +{ + efree(target->callbacks); + efree(target); +} + +void php_git2_diff_line_to_array(git_diff_line *line, zval **out TSRMLS_DC) +{ + zval *result; + + MAKE_STD_ZVAL(result); + array_init(result); + add_assoc_stringl_ex(result, ZEND_STRS("origin"), &line->origin, 1, 1); + add_assoc_long_ex(result, ZEND_STRS("old_lineno"), line->old_lineno); + add_assoc_long_ex(result, ZEND_STRS("new_lineno"), line->new_lineno); + add_assoc_long_ex(result, ZEND_STRS("num_lines"), line->num_lines); + add_assoc_long_ex(result, ZEND_STRS("content_len"), line->content_len); + add_assoc_long_ex(result, ZEND_STRS("content_offset"), line->content_offset); + add_assoc_stringl_ex(result, ZEND_STRS("content"), line->content, line->content_len, 1); + + *out = result; +} + +void php_git2_diff_hunk_to_array(git_diff_hunk *hunk, zval **out TSRMLS_DC) +{ + zval *result; + + MAKE_STD_ZVAL(result); + if (hunk == NULL) { + ZVAL_NULL(result); + } else { + array_init(result); + add_assoc_long_ex(result, ZEND_STRS("old_start"), hunk->old_start); + add_assoc_long_ex(result, ZEND_STRS("old_lines"), hunk->old_lines); + add_assoc_long_ex(result, ZEND_STRS("new_start"), hunk->new_start); + add_assoc_long_ex(result, ZEND_STRS("new_lines"), hunk->new_lines); + add_assoc_stringl_ex(result, ZEND_STRS("header"), hunk->header, 128, 1); + } + + *out = result; +} + +void php_git2_diff_file_to_array(git_diff_file *file, zval **out TSRMLS_DC) +{ + zval *result; + char buf[41] = {0}; + + MAKE_STD_ZVAL(result); + array_init(result); + git_oid_fmt(buf, &file->oid); + + add_assoc_string_ex(result, ZEND_STRS("oid"), buf, 1); + add_assoc_string_ex(result, ZEND_STRS("path"), file->path, 1); + add_assoc_long_ex(result, ZEND_STRS("size"), file->size); + add_assoc_long_ex(result, ZEND_STRS("flags"), file->flags); + add_assoc_long_ex(result, ZEND_STRS("mode"), file->mode); + + *out = result; +} + +void php_git2_diff_delta_to_array(git_diff_delta *delta, zval **out TSRMLS_DC) +{ + zval *result, *old, *new; + + MAKE_STD_ZVAL(result); + array_init(result); + + add_assoc_long_ex(result, ZEND_STRS("status"), delta->status); + add_assoc_long_ex(result, ZEND_STRS("flags"), delta->flags); + add_assoc_long_ex(result, ZEND_STRS("similarity"), delta->similarity); + add_assoc_long_ex(result, ZEND_STRS("nfiles"), delta->nfiles); + + php_git2_diff_file_to_array(&delta->old_file, &old TSRMLS_CC); + php_git2_diff_file_to_array(&delta->new_file, &new TSRMLS_CC); + + add_assoc_zval_ex(result, ZEND_STRS("old_file"), old); + add_assoc_zval_ex(result, ZEND_STRS("new_file"), new); + + *out = result; +} + +void php_git2_array_to_git_diff_options(git_diff_options *options, zval *array TSRMLS_DC) +{ + git_diff_options_init(options, GIT_DIFF_OPTIONS_VERSION); + + options->version = php_git2_read_arrval_long(array, ZEND_STRS("version") TSRMLS_CC); + options->flags = php_git2_read_arrval_long(array, ZEND_STRS("flags") TSRMLS_CC); + options->ignore_submodules = php_git2_read_arrval_long(array, ZEND_STRS("ignore_submodules") TSRMLS_CC); + + php_git2_array_to_strarray(&options->pathspec, php_git2_read_arrval(array, ZEND_STRS("pathspec") TSRMLS_CC) TSRMLS_CC); + // TODO(chobie): support notify cb + + options->context_lines = php_git2_read_arrval_long(array, ZEND_STRS("context_lines") TSRMLS_CC); + options->interhunk_lines = php_git2_read_arrval_long(array, ZEND_STRS("interhunk_lines") TSRMLS_CC); + options->oid_abbrev = php_git2_read_arrval_long(array, ZEND_STRS("oid_abbrev") TSRMLS_CC); + options->max_size = php_git2_read_arrval_long(array, ZEND_STRS("max_size") TSRMLS_CC); + options->old_prefix = php_git2_read_arrval_string(array, ZEND_STRS("old_prefix") TSRMLS_CC); + options->new_prefix = php_git2_read_arrval_string(array, ZEND_STRS("new_prefix") TSRMLS_CC); +} + +void php_git2_git_diff_options_free(git_diff_options *options) +{ + if (options->pathspec.count > 0) { + efree(options->pathspec.strings); + } +} + +void php_git2_git_diff_options_to_array(git_diff_options *options, zval **out TSRMLS_DC) +{ + zval *result, *pathspec; + + MAKE_STD_ZVAL(result); + array_init(result); + add_assoc_long_ex(result, ZEND_STRS("version"), options->version); + add_assoc_long_ex(result, ZEND_STRS("flags"), options->flags); + add_assoc_long_ex(result, ZEND_STRS("ignore_submodules"), options->ignore_submodules); + + MAKE_STD_ZVAL(pathspec); + array_init(pathspec); + if (options->pathspec.count > 0) { + } else { + add_assoc_zval_ex(result, ZEND_STRS("pathspec"), pathspec); + } + + if (options->notify_cb) { + } else { + add_assoc_null_ex(result, ZEND_STRS("notify_cb")); + } + + add_assoc_long_ex(result, ZEND_STRS("context_lines"), options->context_lines); + add_assoc_long_ex(result, ZEND_STRS("interhunk_lines"), options->interhunk_lines); + add_assoc_long_ex(result, ZEND_STRS("oid_abbrev"), options->oid_abbrev); + add_assoc_long_ex(result, ZEND_STRS("max_size"), options->max_size); + if (options->notify_payload) { + } else { + add_assoc_null_ex(result, ZEND_STRS("notify_payload")); + } + if (options->old_prefix) { + add_assoc_string_ex(result, ZEND_STRS("old_prefix"), options->old_prefix, 1); + } else { + add_assoc_null_ex(result, ZEND_STRS("old_prefix")); + } + if (options->new_prefix) { + add_assoc_string_ex(result, ZEND_STRS("new_prefix"), options->new_prefix, 1); + } else { + add_assoc_null_ex(result, ZEND_STRS("new_prefix")); + } + + *out = result; +} + +int php_git2_git_diff_file_cb( + const git_diff_delta *delta, + float progress, + void *payload) +{ + zval *param_delta = NULL, *param_progress = NULL, *retval_ptr = NULL; + php_git2_multi_cb_t *p = (php_git2_multi_cb_t*)payload; + int retval = 0; + GIT2_TSRMLS_SET(p->tsrm_ls) + + Z_ADDREF_P(p->payload); + MAKE_STD_ZVAL(param_progress); + ZVAL_DOUBLE(param_progress, progress); + php_git2_diff_delta_to_array(delta, ¶m_delta TSRMLS_CC); + if (php_git2_call_function_v(&p->callbacks[0].fci, &p->callbacks[0].fcc TSRMLS_CC, &retval_ptr, 3, ¶m_delta, ¶m_progress, &p->payload)) { + return GIT_EUSER; + } + retval = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + + return retval; +} + +int php_git2_git_diff_hunk_cb( + const git_diff_delta *delta, + const git_diff_hunk *hunk, + void *payload) +{ + zval *param_delta = NULL, *param_hunk = NULL, *retval_ptr = NULL; + php_git2_multi_cb_t *p = (php_git2_multi_cb_t*)payload; + int retval = 0; + GIT2_TSRMLS_SET(p->tsrm_ls) + + Z_ADDREF_P(p->payload); + php_git2_diff_delta_to_array(delta, ¶m_delta TSRMLS_CC); + php_git2_diff_hunk_to_array(hunk, ¶m_hunk TSRMLS_CC); + + if (php_git2_call_function_v(&p->callbacks[1].fci, &p->callbacks[1].fcc TSRMLS_CC, &retval_ptr, 3, ¶m_delta, ¶m_hunk, &p->payload)) { + return GIT_EUSER; + } + + retval = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + return retval; +} + +int php_git2_git_diff_line_cb( + const git_diff_delta *delta, + const git_diff_hunk *hunk, + const git_diff_line *line, + void *payload) { + zval *param_delta = NULL, *param_hunk = NULL, *param_line = NULL, *retval_ptr = NULL; + php_git2_multi_cb_t *p = (php_git2_multi_cb_t*)payload; + int retval = 0; + GIT2_TSRMLS_SET(p->tsrm_ls) + + Z_ADDREF_P(p->payload); + php_git2_diff_delta_to_array(delta, ¶m_delta TSRMLS_CC); + php_git2_diff_hunk_to_array(hunk, ¶m_hunk TSRMLS_CC); + php_git2_diff_line_to_array(line, ¶m_line TSRMLS_CC); + + if (php_git2_call_function_v(&p->callbacks[2].fci, &p->callbacks[2].fcc TSRMLS_CC, &retval_ptr, 4, ¶m_delta, ¶m_hunk, ¶m_line, &p->payload)) { + return GIT_EUSER; + } + + retval = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + return retval; +} + +void php_git2_git_transfer_progress_to_array(git_transfer_progress *progress, zval **out TSRMLS_DC) +{ + zval *result; + + MAKE_STD_ZVAL(result); + array_init(result); + + add_assoc_long_ex(result, ZEND_STRS("total_objects"), progress->total_objects); + add_assoc_long_ex(result, ZEND_STRS("indexed_objects"), progress->indexed_objects); + add_assoc_long_ex(result, ZEND_STRS("received_objects"), progress->received_objects); + add_assoc_long_ex(result, ZEND_STRS("local_objects"), progress->local_objects); + add_assoc_long_ex(result, ZEND_STRS("total_deltas"), progress->total_deltas); + add_assoc_long_ex(result, ZEND_STRS("indexed_deltas"), progress->indexed_deltas); + add_assoc_long_ex(result, ZEND_STRS("received_bytes"), progress->received_bytes); + + *out = result; +} diff --git a/helper.h b/helper.h new file mode 100644 index 0000000000..424f1c3f89 --- /dev/null +++ b/helper.h @@ -0,0 +1,103 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_HELPER_H +#define PHP_GIT2_HELPER_H + +/* NOTE(chobie): all functions should have `php_git2_` prefix */ + +int php_git2_check_error(int error_code, const char *action TSRMLS_DC); + +zval* php_git2_read_arrval(zval *array, char *name, size_t name_len TSRMLS_DC); + +long php_git2_read_arrval_long2(zval *array, char *name, size_t name_len, long value TSRMLS_DC); + +long php_git2_read_arrval_long(zval *array, char *name, size_t name_len TSRMLS_DC); + +const char* php_git2_read_arrval_string(zval *array, char *name, size_t name_len TSRMLS_DC); + +void php_git2_array_to_signature(git_signature *signature, zval *author TSRMLS_DC); + +void php_git2_signature_to_array(const git_signature *signature, zval **out TSRMLS_DC); + +void php_git2_strarray_to_array(git_strarray *array, zval **out TSRMLS_DC); + +int php_git2_call_function_v( + zend_fcall_info *fci, zend_fcall_info_cache *fcc TSRMLS_DC, zval **retval_ptr_ptr, zend_uint param_count, ...); + +int php_git2_cb_init(php_git2_cb_t **out, zend_fcall_info *fci, zend_fcall_info_cache *fcc, void *payload TSRMLS_DC); + +void php_git2_cb_free(php_git2_cb_t *target); + +void php_git2_array_to_strarray(git_strarray *out, zval *array TSRMLS_DC); + +void php_git2_strarray_free(git_strarray *out); + +void php_git2_git_checkout_opts_to_array(git_checkout_opts *opts, zval **out TSRMLS_DC); + +void php_git_git_checkout_opts_free(git_checkout_opts *target TSRMLS_DC); + +int php_git2_array_to_git_checkout_opts(git_checkout_opts **out, zval *array TSRMLS_DC); + +int php_git2_multi_cb_init(php_git2_multi_cb_t **out, void *payload TSRMLS_DC, int num_callbacks, ...); + +void php_git2_multi_cb_free(php_git2_multi_cb_t *target); + +void php_git2_diff_line_to_array(git_diff_line *line, zval **out TSRMLS_DC); + +void php_git2_diff_hunk_to_array(git_diff_hunk *hunk, zval **out TSRMLS_DC); + +void php_git2_diff_file_to_array(git_diff_file *file, zval **out TSRMLS_DC); + +void php_git2_diff_delta_to_array(git_diff_delta *delta, zval **out TSRMLS_DC); + +void php_git2_array_to_git_diff_options(git_diff_options *options, zval *array TSRMLS_DC); + +void php_git2_git_diff_options_free(git_diff_options *options); + +void php_git2_git_diff_options_to_array(git_diff_options *options, zval **out TSRMLS_DC); + +int php_git2_git_diff_file_cb( + const git_diff_delta *delta, + float progress, + void *payload); + +int php_git2_git_diff_hunk_cb( + const git_diff_delta *delta, + const git_diff_hunk *hunk, + void *payload); +int php_git2_git_diff_line_cb( + const git_diff_delta *delta, + const git_diff_hunk *hunk, + const git_diff_line *line, + void *payload); + +void php_git2_git_transfer_progress_to_array(git_transfer_progress *progress, zval **out TSRMLS_DC); + +void php_git2_fcall_info_wrapper(zval *target, zend_fcall_info **out_fci, zend_fcall_info_cache **out_fcc TSRMLS_DC); + +void php_git2_fcall_info_wrapper2(zval *target, zend_fcall_info *fci, zend_fcall_info_cache *fcc TSRMLS_DC); + +#endif \ No newline at end of file diff --git a/ignore.c b/ignore.c new file mode 100644 index 0000000000..56dab079ae --- /dev/null +++ b/ignore.c @@ -0,0 +1,64 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "ignore.h" + +/* {{{ proto long git_ignore_add_rule(resource $repo, string $rules) + */ +PHP_FUNCTION(git_ignore_add_rule) +{ + int result = 0, rules_len = 0; + zval *repo = NULL; + php_git2_t *_repo = NULL; + char *rules = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repo, &rules, &rules_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_ignore_add_rule(PHP_GIT2_V(_repo, repository), rules); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_ignore_clear_internal_rules(resource $repo) + */ +PHP_FUNCTION(git_ignore_clear_internal_rules) +{ + int result = 0; + zval *repo = NULL; + php_git2_t *_repo = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_ignore_clear_internal_rules(PHP_GIT2_V(_repo, repository)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_ignore_path_is_ignored(long $ignored, resource $repo, string $path) + */ +PHP_FUNCTION(git_ignore_path_is_ignored) +{ + int result = 0, path_len = 0; + long ignored = 0; + zval *repo = NULL; + php_git2_t *_repo = NULL; + char *path = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "lrs", &ignored, &repo, &path, &path_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_ignore_path_is_ignored(ignored, PHP_GIT2_V(_repo, repository), path); + RETURN_BOOL(result); +} +/* }}} */ + diff --git a/ignore.h b/ignore.h new file mode 100644 index 0000000000..9fc261047a --- /dev/null +++ b/ignore.h @@ -0,0 +1,56 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_IGNORE_H +#define PHP_GIT2_IGNORE_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_ignore_add_rule, 0, 0, 2) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, rules) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_ignore_clear_internal_rules, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_ignore_path_is_ignored, 0, 0, 3) + ZEND_ARG_INFO(0, ignored) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, path) +ZEND_END_ARG_INFO() + +/* {{{ proto long git_ignore_add_rule(repo, rules) +*/ +PHP_FUNCTION(git_ignore_add_rule); + +/* {{{ proto long git_ignore_clear_internal_rules(repo) +*/ +PHP_FUNCTION(git_ignore_clear_internal_rules); + +/* {{{ proto long git_ignore_path_is_ignored(ignored, repo, path) +*/ +PHP_FUNCTION(git_ignore_path_is_ignored); + +#endif \ No newline at end of file diff --git a/index.c b/index.c index ea2833ffe0..4e7d5be4e7 100644 --- a/index.c +++ b/index.c @@ -1,202 +1,866 @@ -/* - * The MIT License - * - * Copyright (c) 2010 - 2012 Shuhei Tanuma - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - #include "php_git2.h" -#include -#include +#include "php_git2_priv.h" +#include "index.h" + +static int php_git2_index_matched_path_cb(const char *path, const char *matched_pathspec, void *payload) +{ + zval *param_path, *param_matched_pathspec, *retval_ptr = NULL; + php_git2_cb_t *p = (php_git2_cb_t*)payload; + long retval = 0; + GIT2_TSRMLS_SET(p->tsrm_ls) + + Z_ADDREF_P(p->payload); + MAKE_STD_ZVAL(param_path); + MAKE_STD_ZVAL(param_matched_pathspec); + ZVAL_STRING(param_path, path, 1); + ZVAL_STRING(param_matched_pathspec, matched_pathspec, 1); -PHPAPI zend_class_entry *git2_index_class_entry; + if (php_git2_call_function_v(p->fci, p->fcc TSRMLS_CC, &retval_ptr, 3, ¶m_path, ¶m_matched_pathspec, &p->payload)) { + zval_ptr_dtor(¶m_path); + zval_ptr_dtor(¶m_matched_pathspec); + zval_ptr_dtor(&p->payload); + return 0; + } -static void php_git2_index_free_storage(php_git2_index *object TSRMLS_DC) + retval = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + return retval; +} + + +static int php_git2_array_to_index_entry(git_index_entry *entry, zval *array TSRMLS_DC) { - if (object->index != NULL) { - object->index = NULL; + zval *ctime, *mtime, *oid; + memset(entry, '\0', sizeof(git_index_entry)); + + ctime = php_git2_read_arrval(array, ZEND_STRS("ctime") TSRMLS_CC); + mtime = php_git2_read_arrval(array, ZEND_STRS("mtime") TSRMLS_CC); + + oid = php_git2_read_arrval(array, ZEND_STRS("oid") TSRMLS_CC); + if (git_oid_fromstrn(&entry->oid, Z_STRVAL_P(oid), Z_STRLEN_P(oid)) != GIT_OK) { + return 0; } - zend_object_std_dtor(&object->zo TSRMLS_CC); - efree(object); + + entry->ctime.seconds = php_git2_read_arrval_long(ctime, ZEND_STRS("seconds") TSRMLS_CC); + entry->ctime.nanoseconds = php_git2_read_arrval_long(ctime, ZEND_STRS("nanoseconds") TSRMLS_CC); + entry->mtime.seconds = php_git2_read_arrval_long(mtime, ZEND_STRS("seconds") TSRMLS_CC); + entry->mtime.nanoseconds = php_git2_read_arrval_long(mtime, ZEND_STRS("nanoseconds") TSRMLS_CC); + entry->dev = php_git2_read_arrval_long(array, ZEND_STRS("dev") TSRMLS_CC); + entry->ino = php_git2_read_arrval_long(array, ZEND_STRS("ino") TSRMLS_CC); + entry->mode = php_git2_read_arrval_long(array, ZEND_STRS("mode") TSRMLS_CC); + entry->uid = php_git2_read_arrval_long(array, ZEND_STRS("uid") TSRMLS_CC); + entry->gid = php_git2_read_arrval_long(array, ZEND_STRS("gid") TSRMLS_CC); + entry->file_size = php_git2_read_arrval_long(array, ZEND_STRS("file_size") TSRMLS_CC); + entry->flags = php_git2_read_arrval_long(array, ZEND_STRS("flags") TSRMLS_CC); + entry->flags_extended = php_git2_read_arrval_long(array, ZEND_STRS("flags_extended") TSRMLS_CC); + entry->path = php_git2_read_arrval_string(array, ZEND_STRS("path") TSRMLS_CC); + + return 1; } -zend_object_value php_git2_index_new(zend_class_entry *ce TSRMLS_DC) +static void php_git2_index_entry_to_array(const git_index_entry *entry, zval **result TSRMLS_DC) { - zend_object_value retval; + zval *tmp, *ctime, *mtime; + char buf[GIT2_OID_HEXSIZE] = {0}; - PHP_GIT2_STD_CREATE_OBJECT(php_git2_index); - return retval; + MAKE_STD_ZVAL(tmp); + MAKE_STD_ZVAL(ctime); + MAKE_STD_ZVAL(mtime); + array_init(tmp); + array_init(ctime); + array_init(mtime); + + git_oid_fmt(buf, &entry->oid); + + add_assoc_long_ex(ctime, ZEND_STRS("seconds"), entry->ctime.seconds); + add_assoc_long_ex(ctime, ZEND_STRS("nanoseconds"), entry->ctime.nanoseconds); + add_assoc_long_ex(mtime, ZEND_STRS("seconds"), entry->mtime.seconds); + add_assoc_long_ex(mtime, ZEND_STRS("nanoseconds"), entry->mtime.nanoseconds); + + add_assoc_zval_ex(tmp, ZEND_STRS("ctime"), ctime); + add_assoc_zval_ex(tmp, ZEND_STRS("mtime"), mtime); + + add_assoc_long_ex(tmp, ZEND_STRS("dev"), entry->dev); + add_assoc_long_ex(tmp, ZEND_STRS("ino"), entry->ino); + add_assoc_long_ex(tmp, ZEND_STRS("mode"), entry->mode); + add_assoc_long_ex(tmp, ZEND_STRS("uid"), entry->uid); + add_assoc_long_ex(tmp, ZEND_STRS("gid"), entry->gid); + add_assoc_long_ex(tmp, ZEND_STRS("file_size"), entry->file_size); + add_assoc_string_ex(tmp, ZEND_STRS("oid"), buf, 1); + add_assoc_long_ex(tmp, ZEND_STRS("flags"), entry->flags); + add_assoc_long_ex(tmp, ZEND_STRS("flags_extended"), entry->flags_extended); + add_assoc_string_ex(tmp, ZEND_STRS("path"), entry->path, 1); + + *result = tmp; } -ZEND_BEGIN_ARG_INFO_EX(arginfo_git2_index___construct, 0,0,1) - ZEND_ARG_INFO(0, entry) -ZEND_END_ARG_INFO() +/* {{{ proto resource git_index_open(index_path) +*/ +PHP_FUNCTION(git_index_open) +{ + char *index_path = {0}; + int index_path_len; + git_index *index; + php_git2_t *result; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "s", &index_path, &index_path_len) == FAILURE) { + return; + } + error = git_index_open(&index, index_path); + if (php_git2_check_error(error, "git_index_open" TSRMLS_CC)) { + RETURN_FALSE + } + + PHP_GIT2_MAKE_RESOURCE(result); + PHP_GIT2_V(result, index) = index; + result->type = PHP_GIT2_TYPE_INDEX; + result->resource_id = PHP_GIT2_LIST_INSERT(result, git2_resource_handle); + result->should_free_v = 1; + + ZVAL_RESOURCE(return_value, result->resource_id); +} -/* -{{{ proto: Git2\Index::__construct(string $path) +/* {{{ proto resource git_index_new() */ -PHP_METHOD(git2_index, __construct) +PHP_FUNCTION(git_index_new) { - char *path; git_index *index; - int error, path_len = 0; - php_git2_index *m_index; + php_git2_t *result; + int error = 0; + + error = git_index_new(&index); + if (php_git2_check_error(error, "git_index_new" TSRMLS_CC)) { + RETURN_FALSE + } + PHP_GIT2_MAKE_RESOURCE(result); + PHP_GIT2_V(result, index) = index; + result->type = PHP_GIT2_TYPE_INDEX; + result->resource_id = PHP_GIT2_LIST_INSERT(result, git2_resource_handle); + result->should_free_v = 1; + + ZVAL_RESOURCE(return_value, result->resource_id); +} + +/* {{{ proto void git_index_free(index) +*/ +PHP_FUNCTION(git_index_free) +{ + zval *index; + php_git2_t *_index; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "s", &path, &path_len) == FAILURE) { + "r", &index) == FAILURE) { return; } - - error = git_index_open(&index, path); - m_index = PHP_GIT2_GET_OBJECT(php_git2_index, getThis()); - m_index->index = index; + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (_index->should_free_v) { + git_index_free(PHP_GIT2_V(_index, index)); + _index->should_free_v = 0; + } + zval_ptr_dtor(&index); } -/* }}} */ +/* {{{ proto resource git_index_owner(index) +*/ +PHP_FUNCTION(git_index_owner) +{ + zval *index; + php_git2_t *_index, *result; + git_repository *repository; -/* -{{{ proto: Git2\Index::count() + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &index) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + repository = git_index_owner(PHP_GIT2_V(_index, index)); + PHP_GIT2_MAKE_RESOURCE(result); + PHP_GIT2_V(result, repository) = repository; + result->type = PHP_GIT2_TYPE_REPOSITORY; + result->resource_id = PHP_GIT2_LIST_INSERT(result, git2_resource_handle); + result->should_free_v = 0; + + ZVAL_RESOURCE(return_value, result->resource_id); +} + +/* {{{ proto resource git_index_caps(index) */ -PHP_METHOD(git2_index, count) +PHP_FUNCTION(git_index_caps) { - php_git2_index *m_index; - - m_index = PHP_GIT2_GET_OBJECT(php_git2_index, getThis()); - RETURN_LONG(git_index_entrycount(m_index->index)); + zval *index; + php_git2_t *_index; + unsigned int caps; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &index) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + caps = git_index_caps(PHP_GIT2_V(_index, index)); + RETURN_LONG(caps); } -/* }}} */ -/* -{{{ proto: Git2\Index::writeTree() +/* {{{ proto long git_index_set_caps(index, caps) */ -PHP_METHOD(git2_index, writeTree) +PHP_FUNCTION(git_index_set_caps) { - php_git2_index *m_index; - git_oid tree_oid; - char oid_out[GIT_OID_HEXSZ] = {0}; + zval *index; + php_git2_t *_index; + long caps; int error = 0; - - m_index = PHP_GIT2_GET_OBJECT(php_git2_index, getThis()); - error = git_tree_create_fromindex(&tree_oid, m_index->index); - git_oid_fmt(oid_out, &tree_oid); - RETVAL_STRINGL(oid_out,GIT_OID_HEXSZ,1); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &index, &caps) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_index_set_caps(PHP_GIT2_V(_index, index), caps); + RETURN_LONG(error); } -/* }}} */ +/* {{{ proto long git_index_read(index, force) +*/ +PHP_FUNCTION(git_index_read) +{ + zval *index; + php_git2_t *_index; + long force; + int error = 0; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &index, &force) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_index_read(PHP_GIT2_V(_index, index), force); + if (php_git2_check_error(error, "git_index_read" TSRMLS_CC)) { + RETURN_FALSE + } + RETURN_TRUE; +} -/* Iterator Implementation */ +/* {{{ proto resource git_index_write() +*/ +PHP_FUNCTION(git_index_write) +{ + zval *index; + php_git2_t *_index; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &index) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_index_write(PHP_GIT2_V(_index, index)); + if (php_git2_check_error(error, "git_index_write" TSRMLS_CC)) { + RETURN_FALSE + } + RETURN_TRUE; +} -/* -{{{ proto: Git2\Tree::current() +/* {{{ proto resource git_index_path(index) */ -PHP_METHOD(git2_index, current) +PHP_FUNCTION(git_index_path) { - php_git2_index *m_index; + zval *index; + php_git2_t *_index; + const char *path; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &index) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + path = git_index_path(PHP_GIT2_V(_index, index)); + RETURN_STRING(path, 1); +} + +/* {{{ proto long git_index_read_tree(index, tree) +*/ +PHP_FUNCTION(git_index_read_tree) +{ + zval *index; + php_git2_t *_index; + zval *tree; + php_git2_t *_tree; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rr", &index, &tree) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_tree, php_git2_t*, &tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_index_read_tree(PHP_GIT2_V(_index, index), PHP_GIT2_V(_tree, tree)); + if (php_git2_check_error(error, "git_index_read_tree" TSRMLS_CC)) { + RETURN_FALSE + } + RETURN_TRUE; +} + +/* {{{ proto resource git_index_write_tree(index) +*/ +PHP_FUNCTION(git_index_write_tree) +{ + zval *index; + php_git2_t *_index; + int error = 0; + git_oid id; + char out[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &index) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_index_write_tree(&id, PHP_GIT2_V(_index, index)); + if (php_git2_check_error(error, "git_index_write_tree" TSRMLS_CC)) { + RETURN_FALSE + } + git_oid_fmt(out, &id); + RETURN_STRING(out, 1); +} + +/* {{{ proto resource git_index_write_tree_to(index, repo) +*/ +PHP_FUNCTION(git_index_write_tree_to) +{ + zval *index; + php_git2_t *_index; + zval *repo; + php_git2_t *_repo; + git_oid id; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rr", &index, &repo) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_index_write_tree_to(&id, PHP_GIT2_V(_index, index), PHP_GIT2_V(_repo, repository)); + if (php_git2_check_error(error, "git_index_write_tree_to" TSRMLS_CC)) { + RETURN_FALSE + } + RETURN_TRUE; +} + +/* {{{ proto resource git_index_entrycount(index) +*/ +PHP_FUNCTION(git_index_entrycount) +{ + zval *index; + php_git2_t *_index; + size_t count; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &index) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + count = git_index_entrycount(PHP_GIT2_V(_index, index)); + RETURN_LONG(count); +} + +/* {{{ proto void git_index_clear(index) +*/ +PHP_FUNCTION(git_index_clear) +{ + zval *index; + php_git2_t *_index; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &index) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + git_index_clear(PHP_GIT2_V(_index, index)); +} + +/* {{{ proto resource git_index_get_byindex(index, n) +*/ +PHP_FUNCTION(git_index_get_byindex) +{ + zval *index; + php_git2_t *_index; + long n; const git_index_entry *entry; - zval *z_entry; + zval *result; - m_index = PHP_GIT2_GET_OBJECT(php_git2_index, getThis()); - entry = git_index_get(m_index->index, m_index->offset); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &index, &n) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + entry = git_index_get_byindex(PHP_GIT2_V(_index, index), n); if (entry == NULL) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, - "specified offset does not exist. %d"); RETURN_FALSE; } - - php_git2_create_index_entry(&z_entry, entry TSRMLS_CC); - RETURN_ZVAL(z_entry, 0, 1); + php_git2_index_entry_to_array(entry, &result TSRMLS_CC); + RETURN_ZVAL(result, 0, 1); } -/* -{{{ proto: Git2\Tree::key() +/* {{{ proto resource git_index_get_bypath(index, path, stage) */ -PHP_METHOD(git2_index, key) +PHP_FUNCTION(git_index_get_bypath) { - php_git2_index *m_index; + zval *index; + php_git2_t *_index; + char *path = {0}; + int path_len; + long stage = 0; + const git_index_entry *entry; + zval *result; - m_index = PHP_GIT2_GET_OBJECT(php_git2_index, getThis()); - RETURN_LONG(m_index->offset); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs|l", &index, &path, &path_len, &stage) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + entry = git_index_get_bypath(PHP_GIT2_V(_index, index), path, stage); + if (entry == NULL) { + RETURN_FALSE; + } + php_git2_index_entry_to_array(entry, &result TSRMLS_CC); + RETURN_ZVAL(result, 0, 1); } -/* -{{{ proto: Git2\Tree::valid() +/* {{{ proto long git_index_remove(index, path, stage) */ -PHP_METHOD(git2_index, next) +PHP_FUNCTION(git_index_remove) { - php_git2_index *m_index; + zval *index; + php_git2_t *_index; + char *path = {0}; + int path_len; + long stage = 0; + int error = 0; - m_index = PHP_GIT2_GET_OBJECT(php_git2_index, getThis()); - m_index->offset++; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsl", &index, &path, &path_len, &stage) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_index_remove(PHP_GIT2_V(_index, index), path, stage); + if (php_git2_check_error(error, "git_index_remove" TSRMLS_CC)) { + RETURN_FALSE; + } + RETURN_TRUE; } -/* -{{{ proto: Git2\Tree::rewind() +/* {{{ proto long git_index_remove_directory(index, dir, stage) */ -PHP_METHOD(git2_index, rewind) +PHP_FUNCTION(git_index_remove_directory) { - php_git2_index *m_index; + zval *index; + php_git2_t *_index; + char *dir = {0}; + int dir_len; + long stage = 0; + int error = 0; - m_index = PHP_GIT2_GET_OBJECT(php_git2_index, getThis()); - m_index->offset = 0; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsl", &index, &dir, &dir_len, &stage) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_index_remove_directory(PHP_GIT2_V(_index, index), dir, stage); + if (php_git2_check_error(error, "git_index_remove_directory" TSRMLS_CC)) { + RETURN_FALSE; + } + RETURN_TRUE; } -/* -{{{ proto: Git2\Index::valid() +/* {{{ proto long git_index_add(index, source_entry) */ -PHP_METHOD(git2_index, valid) +PHP_FUNCTION(git_index_add) { - php_git2_index *m_index; - int entry_count = 0; - - m_index = PHP_GIT2_GET_OBJECT(php_git2_index, getThis()); - entry_count = git_index_entrycount(m_index->index); - if (m_index->offset < entry_count && m_index->offset >= 0) { - RETURN_TRUE; - } else { + zval *index; + php_git2_t *_index; + zval *source_entry; + int error = 0; + git_index_entry entry; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "ra", &index, &source_entry) == FAILURE) { + return; + } + if (!php_git2_array_to_index_entry(&entry, source_entry TSRMLS_CC)) { + return; + } + + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_index_add(PHP_GIT2_V(_index, index), &entry); + if (php_git2_check_error(error, "git_index_add" TSRMLS_CC)) { + RETURN_FALSE + } + RETURN_TRUE; +} + +/* {{{ proto long git_index_entry_stage(entry) +*/ +PHP_FUNCTION(git_index_entry_stage) +{ + zval *source; + git_index_entry entry; + int result = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "a", &source) == FAILURE) { + return; + } + if (!php_git2_array_to_index_entry(&entry, source TSRMLS_CC)) { + return; + } + result = git_index_entry_stage(&entry); + RETURN_LONG(result); +} + +/* {{{ proto long git_index_add_bypath(index, path) +*/ +PHP_FUNCTION(git_index_add_bypath) +{ + zval *index; + php_git2_t *_index; + char *path = {0}; + int path_len; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &index, &path, &path_len) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_index_add_bypath(PHP_GIT2_V(_index, index), path); + if (php_git2_check_error(error, "git_index_add_bypath" TSRMLS_CC)) { + RETURN_FALSE + } + RETURN_TRUE; +} + +/* {{{ proto long git_index_remove_bypath(index, path) +*/ +PHP_FUNCTION(git_index_remove_bypath) +{ + zval *index; + php_git2_t *_index; + char *path = {0}; + int path_len; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &index, &path, &path_len) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_index_remove_bypath(PHP_GIT2_V(_index, index), path); + if (php_git2_check_error(error, "git_index_remove_bypath" TSRMLS_CC)) { + RETURN_FALSE + } + RETURN_TRUE; +} + +/* {{{ proto long git_index_add_all(resource $index, array $pathspec, long $flags, Callable $callback, $payload) + */ +PHP_FUNCTION(git_index_add_all) +{ + int result = 0; + zval *index = NULL, *pathspec = NULL, *payload = NULL; + php_git2_t *_index = NULL; + git_strarray _pathspec = {0}; + long flags = 0; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "ralfz", &index, &pathspec, &flags, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + php_git2_array_to_strarray(&_pathspec, pathspec TSRMLS_CC); + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_index_add_all(PHP_GIT2_V(_index, index), pathspec, flags, php_git2_index_matched_path_cb, cb); + php_git2_cb_free(cb); + php_git2_strarray_free(&_pathspec); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto long git_index_remove_all(resource $index, array $pathspec, Callable $callback, $payload) + */ +PHP_FUNCTION(git_index_remove_all) +{ + int result = 0; + zval *index = NULL, *pathspec = NULL, *payload = NULL; + php_git2_t *_index = NULL; + git_strarray _pathspec = {0}; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rafz", &index, &pathspec, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + php_git2_array_to_strarray(&_pathspec, pathspec TSRMLS_CC); + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_index_remove_all(PHP_GIT2_V(_index, index), pathspec, php_git2_index_matched_path_cb, cb); + php_git2_cb_free(cb); + php_git2_strarray_free(&_pathspec); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto long git_index_update_all(resource $index, array $pathspec, Callable $callback, $payload) + */ +PHP_FUNCTION(git_index_update_all) +{ + int result = 0; + zval *index = NULL, *pathspec = NULL, *payload = NULL; + php_git2_t *_index = NULL; + git_strarray _pathspec = {0}; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rafz", &index, &pathspec, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + php_git2_array_to_strarray(&_pathspec, pathspec TSRMLS_CC); + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_index_update_all(PHP_GIT2_V(_index, index), pathspec, php_git2_index_matched_path_cb, cb); + php_git2_cb_free(cb); + php_git2_strarray_free(&_pathspec); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto long git_index_find(at_pos, index, path) +*/ +PHP_FUNCTION(git_index_find) +{ + zval *index; + php_git2_t *_index; + char *path = {0}; + int path_len; + long at_pos; + int result = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "lrs", &at_pos, &index, &path, &path_len) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_index_find(at_pos, PHP_GIT2_V(_index, index), path); + RETURN_LONG(result); +} + +/* {{{ proto long git_index_conflict_add(resource $index, $ancestor_entry, $our_entry, $their_entry) + */ +PHP_FUNCTION(git_index_conflict_add) +{ + int result = 0; + zval *index = NULL, *ancestor_entry = NULL, *our_entry = NULL, *their_entry = NULL; + php_git2_t *_index = NULL; + git_index_entry ancestor = {0}, our = {0}, their = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "raaa", &index, &ancestor_entry, &our_entry, &their_entry) == FAILURE) { + return; + } + + php_git2_array_to_index_entry(&ancestor, ancestor_entry TSRMLS_CC); + php_git2_array_to_index_entry(&our, our_entry TSRMLS_CC); + php_git2_array_to_index_entry(&their, their_entry TSRMLS_CC); + + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_index_conflict_add(PHP_GIT2_V(_index, index), &ancestor, &our, &their); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_index_conflict_get(resource $index, string $path) + */ +PHP_FUNCTION(git_index_conflict_get) +{ + php_git2_t *_index = NULL; + git_index_entry *ancestor_out = NULL, *our_out = NULL, *their_out = NULL; + zval *index = NULL, *ancestor, *our, *their, *container; + char *path = NULL; + int path_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &index, &path, &path_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_index_conflict_get(&ancestor_out, &our_out, &their_out, PHP_GIT2_V(_index, index), path); + if (php_git2_check_error(error, "git_index_conflict_get" TSRMLS_CC)) { RETURN_FALSE; } + + php_git2_index_entry_to_array(ancestor_out, &ancestor TSRMLS_CC); + php_git2_index_entry_to_array(our_out, &our TSRMLS_CC); + php_git2_index_entry_to_array(their_out, &their TSRMLS_CC); + MAKE_STD_ZVAL(container); + array_init(container); + add_next_index_zval(container, ancestor); + add_next_index_zval(container, our); + add_next_index_zval(container, their); + RETURN_ZVAL(container, 0, 1); } /* }}} */ +/* {{{ proto long git_index_conflict_remove(resource $index, string $path) + */ +PHP_FUNCTION(git_index_conflict_remove) +{ + int result = 0, path_len = 0; + zval *index = NULL; + php_git2_t *_index = NULL; + char *path = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &index, &path, &path_len) == FAILURE) { + return; + } -static zend_function_entry php_git2_index_methods[] = { - PHP_ME(git2_index, __construct, arginfo_git2_index___construct, ZEND_ACC_PUBLIC) - PHP_ME(git2_index, count, NULL, ZEND_ACC_PUBLIC) - /* Iterator Implementation */ - PHP_ME(git2_index, current, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_index, key, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_index, next, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_index, rewind, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_index, valid, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_index, writeTree, NULL, ZEND_ACC_PUBLIC) - {NULL,NULL,NULL} -}; - -void php_git2_index_init(TSRMLS_D) -{ - zend_class_entry ce; - - INIT_NS_CLASS_ENTRY(ce, PHP_GIT2_NS, "Index", php_git2_index_methods); - git2_index_class_entry = zend_register_internal_class(&ce TSRMLS_CC); - git2_index_class_entry->create_object = php_git2_index_new; - zend_class_implements(git2_index_class_entry TSRMLS_CC, 1, spl_ce_Iterator); -} \ No newline at end of file + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_index_conflict_remove(PHP_GIT2_V(_index, index), path); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto void git_index_conflict_cleanup(resource $index) + */ +PHP_FUNCTION(git_index_conflict_cleanup) +{ + zval *index = NULL; + php_git2_t *_index = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &index) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + git_index_conflict_cleanup(PHP_GIT2_V(_index, index)); +} +/* }}} */ + +/* {{{ proto long git_index_has_conflicts(index) +*/ +PHP_FUNCTION(git_index_has_conflicts) +{ + zval *index; + php_git2_t *_index; + int conflict = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &index) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + conflict = git_index_has_conflicts(PHP_GIT2_V(_index, index)); + RETURN_LONG(conflict); +} + +/* {{{ proto resource git_index_conflict_iterator_new(resource $index) + */ +PHP_FUNCTION(git_index_conflict_iterator_new) +{ + php_git2_t *result = NULL, *_index = NULL; + git_index_conflict_iterator *iterator_out = NULL; + zval *index = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &index) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_index_conflict_iterator_new(&iterator_out, PHP_GIT2_V(_index, index)); + if (php_git2_check_error(error, "git_index_conflict_iterator_new" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_INDEX_CONFLICT_ITERATOR, iterator_out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_index_conflict_next(resource $iterator) + */ +PHP_FUNCTION(git_index_conflict_next) +{ + php_git2_t *_iterator = NULL; + git_index_entry *ancestor_out = NULL, *our_out = NULL, *their_out = NULL; + zval *iterator = NULL, *ancestor, *our, *their, *container; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &iterator) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_iterator, php_git2_t*, &iterator, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_index_conflict_next(&ancestor_out, &our_out, &their_out, PHP_GIT2_V(_iterator, index_conflict_iterator)); + if (php_git2_check_error(error, "git_index_conflict_next" TSRMLS_CC)) { + RETURN_FALSE; + } + + php_git2_index_entry_to_array(ancestor_out, &ancestor TSRMLS_CC); + php_git2_index_entry_to_array(our_out, &our TSRMLS_CC); + php_git2_index_entry_to_array(their_out, &their TSRMLS_CC); + MAKE_STD_ZVAL(container); + array_init(container); + add_next_index_zval(container, ancestor); + add_next_index_zval(container, our); + add_next_index_zval(container, their); + RETURN_ZVAL(container, 0, 1); + +} +/* }}} */ + +/* {{{ proto void git_index_conflict_iterator_free(resource $iterator) + */ +PHP_FUNCTION(git_index_conflict_iterator_free) +{ + zval *iterator = NULL; + php_git2_t *_iterator = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &iterator) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_iterator, php_git2_t*, &iterator, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_iterator)) { + git_index_conflict_iterator_free(PHP_GIT2_V(_iterator, index_conflict_iterator)); + GIT2_SHOULD_FREE(_iterator) = 0; + }; + zval_ptr_dtor(&iterator); +} +/* }}} */ diff --git a/index.h b/index.h new file mode 100644 index 0000000000..80f1ea6000 --- /dev/null +++ b/index.h @@ -0,0 +1,305 @@ +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_open, 0, 0, 1) + ZEND_ARG_INFO(0, index_path) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_new, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_free, 0, 0, 1) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_owner, 0, 0, 1) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_caps, 0, 0, 1) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_set_caps, 0, 0, 2) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, caps) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_read, 0, 0, 2) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, force) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_write, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_path, 0, 0, 1) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_read_tree, 0, 0, 2) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, tree) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_write_tree, 0, 0, 1) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_write_tree_to, 0, 0, 2) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_entrycount, 0, 0, 1) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_clear, 0, 0, 1) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_get_byindex, 0, 0, 2) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, n) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_get_bypath, 0, 0, 3) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, stage) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_remove, 0, 0, 3) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, stage) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_remove_directory, 0, 0, 3) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, dir) + ZEND_ARG_INFO(0, stage) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_add, 0, 0, 2) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, source_entry) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_entry_stage, 0, 0, 1) + ZEND_ARG_INFO(0, entry) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_add_bypath, 0, 0, 2) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, path) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_remove_bypath, 0, 0, 2) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, path) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_add_all, 0, 0, 5) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, pathspec) + ZEND_ARG_INFO(0, flags) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_remove_all, 0, 0, 4) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, pathspec) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_update_all, 0, 0, 4) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, pathspec) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_find, 0, 0, 3) + ZEND_ARG_INFO(0, at_pos) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, path) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_conflict_add, 0, 0, 4) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, ancestor_entry) + ZEND_ARG_INFO(0, our_entry) + ZEND_ARG_INFO(0, their_entry) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_conflict_get, 0, 0, 4) + ZEND_ARG_INFO(0, our_out) + ZEND_ARG_INFO(0, their_out) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, path) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_conflict_remove, 0, 0, 2) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, path) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_conflict_cleanup, 0, 0, 1) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_has_conflicts, 0, 0, 1) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_conflict_iterator_new, 0, 0, 1) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_conflict_next, 0, 0, 3) + ZEND_ARG_INFO(0, our_out) + ZEND_ARG_INFO(0, their_out) + ZEND_ARG_INFO(0, iterator) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_index_conflict_iterator_free, 0, 0, 1) + ZEND_ARG_INFO(0, iterator) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_index_open(index_path) +*/ +PHP_FUNCTION(git_index_open); + +/* {{{ proto resource git_index_new() +*/ +PHP_FUNCTION(git_index_new); + +/* {{{ proto void git_index_free(index) +*/ +PHP_FUNCTION(git_index_free); + +/* {{{ proto resource git_index_owner(index) +*/ +PHP_FUNCTION(git_index_owner); + +/* {{{ proto resource git_index_caps(index) +*/ +PHP_FUNCTION(git_index_caps); + +/* {{{ proto long git_index_set_caps(index, caps) +*/ +PHP_FUNCTION(git_index_set_caps); + +/* {{{ proto long git_index_read(index, force) +*/ +PHP_FUNCTION(git_index_read); + +/* {{{ proto resource git_index_write() +*/ +PHP_FUNCTION(git_index_write); + +/* {{{ proto resource git_index_path(index) +*/ +PHP_FUNCTION(git_index_path); + +/* {{{ proto long git_index_read_tree(index, tree) +*/ +PHP_FUNCTION(git_index_read_tree); + +/* {{{ proto resource git_index_write_tree(index) +*/ +PHP_FUNCTION(git_index_write_tree); + +/* {{{ proto resource git_index_write_tree_to(index, repo) +*/ +PHP_FUNCTION(git_index_write_tree_to); + +/* {{{ proto resource git_index_entrycount(index) +*/ +PHP_FUNCTION(git_index_entrycount); + +/* {{{ proto void git_index_clear(index) +*/ +PHP_FUNCTION(git_index_clear); + +/* {{{ proto resource git_index_get_byindex(index, n) +*/ +PHP_FUNCTION(git_index_get_byindex); + +/* {{{ proto resource git_index_get_bypath(index, path, stage) +*/ +PHP_FUNCTION(git_index_get_bypath); + +/* {{{ proto long git_index_remove(index, path, stage) +*/ +PHP_FUNCTION(git_index_remove); + +/* {{{ proto long git_index_remove_directory(index, dir, stage) +*/ +PHP_FUNCTION(git_index_remove_directory); + +/* {{{ proto long git_index_add(index, source_entry) +*/ +PHP_FUNCTION(git_index_add); + +/* {{{ proto long git_index_entry_stage(entry) +*/ +PHP_FUNCTION(git_index_entry_stage); + +/* {{{ proto long git_index_add_bypath(index, path) +*/ +PHP_FUNCTION(git_index_add_bypath); + +/* {{{ proto long git_index_remove_bypath(index, path) +*/ +PHP_FUNCTION(git_index_remove_bypath); + +/* {{{ proto long git_index_add_all(index, pathspec, flags, callback, payload) +*/ +PHP_FUNCTION(git_index_add_all); + +/* {{{ proto long git_index_remove_all(index, pathspec, callback, payload) +*/ +PHP_FUNCTION(git_index_remove_all); + +/* {{{ proto long git_index_update_all(index, pathspec, callback, payload) +*/ +PHP_FUNCTION(git_index_update_all); + +/* {{{ proto long git_index_find(at_pos, index, path) +*/ +PHP_FUNCTION(git_index_find); + +/* {{{ proto long git_index_conflict_add(index, ancestor_entry, our_entry, their_entry) +*/ +PHP_FUNCTION(git_index_conflict_add); + +/* {{{ proto resource git_index_conflict_get(our_out, their_out, index, path) +*/ +PHP_FUNCTION(git_index_conflict_get); + +/* {{{ proto long git_index_conflict_remove(index, path) +*/ +PHP_FUNCTION(git_index_conflict_remove); + +/* {{{ proto void git_index_conflict_cleanup(index) +*/ +PHP_FUNCTION(git_index_conflict_cleanup); + +/* {{{ proto long git_index_has_conflicts(index) +*/ +PHP_FUNCTION(git_index_has_conflicts); + +/* {{{ proto resource git_index_conflict_iterator_new(index) +*/ +PHP_FUNCTION(git_index_conflict_iterator_new); + +/* {{{ proto resource git_index_conflict_next(our_out, their_out, iterator) +*/ +PHP_FUNCTION(git_index_conflict_next); + +/* {{{ proto void git_index_conflict_iterator_free(iterator) +*/ +PHP_FUNCTION(git_index_conflict_iterator_free); + diff --git a/index_entry.c b/index_entry.c deleted file mode 100644 index 0579a9a61c..0000000000 --- a/index_entry.c +++ /dev/null @@ -1,72 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2010 - 2012 Shuhei Tanuma - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "php_git2.h" - -PHPAPI zend_class_entry *git2_index_entry_class_entry; - -static void php_git2_index_entry_free_storage(php_git2_index_entry *object TSRMLS_DC) -{ - if (object->entry != NULL) { - free(object->entry); - object->entry = NULL; - } - zend_object_std_dtor(&object->zo TSRMLS_CC); - efree(object); -} - -zend_object_value php_git2_index_entry_new(zend_class_entry *ce TSRMLS_DC) -{ - zend_object_value retval; - - PHP_GIT2_STD_CREATE_OBJECT(php_git2_index_entry); - return retval; -} - -static zend_function_entry php_git2_index_entry_methods[] = { - {NULL,NULL,NULL} -}; - -void php_git2_index_entry_init(TSRMLS_D) -{ - zend_class_entry ce; - - INIT_NS_CLASS_ENTRY(ce, PHP_GIT2_NS, "IndexEntry", php_git2_index_entry_methods); - git2_index_entry_class_entry = zend_register_internal_class(&ce TSRMLS_CC); - git2_index_entry_class_entry->create_object = php_git2_index_entry_new; - - zend_declare_property_null(git2_index_entry_class_entry, "path", sizeof("path")-1, ZEND_ACC_PUBLIC TSRMLS_CC); - zend_declare_property_null(git2_index_entry_class_entry, "oid", sizeof("oid")-1, ZEND_ACC_PUBLIC TSRMLS_CC); - zend_declare_property_null(git2_index_entry_class_entry, "dev", sizeof("dev")-1, ZEND_ACC_PUBLIC TSRMLS_CC); - zend_declare_property_null(git2_index_entry_class_entry, "ino", sizeof("ino")-1, ZEND_ACC_PUBLIC TSRMLS_CC); - zend_declare_property_null(git2_index_entry_class_entry, "mode", sizeof("mode")-1, ZEND_ACC_PUBLIC TSRMLS_CC); - zend_declare_property_null(git2_index_entry_class_entry, "uid", sizeof("uid")-1, ZEND_ACC_PUBLIC TSRMLS_CC); - zend_declare_property_null(git2_index_entry_class_entry, "gid", sizeof("gid")-1, ZEND_ACC_PUBLIC TSRMLS_CC); - zend_declare_property_null(git2_index_entry_class_entry, "file_size", sizeof("file_size")-1, ZEND_ACC_PUBLIC TSRMLS_CC); - zend_declare_property_null(git2_index_entry_class_entry, "flags", sizeof("flags")-1, ZEND_ACC_PUBLIC TSRMLS_CC); - zend_declare_property_null(git2_index_entry_class_entry, "flags_extended", sizeof("flags_extended")-1, ZEND_ACC_PUBLIC TSRMLS_CC); - zend_declare_property_null(git2_index_entry_class_entry, "mtime", sizeof("mtime")-1, ZEND_ACC_PUBLIC TSRMLS_CC); - zend_declare_property_null(git2_index_entry_class_entry, "ctime", sizeof("ctime")-1, ZEND_ACC_PUBLIC TSRMLS_CC); - -} \ No newline at end of file diff --git a/indexer.c b/indexer.c new file mode 100644 index 0000000000..e5184eea97 --- /dev/null +++ b/indexer.c @@ -0,0 +1,112 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "indexer.h" + +/* {{{ proto resource git_indexer_new(string $path, long $mode, resource $odb, $progress_cb, $progress_cb_payload) + */ +PHP_FUNCTION(git_indexer_new) +{ + php_git2_t *result = NULL, *_odb = NULL; + git_indexer *out = NULL; + char *path = NULL; + int path_len = 0, error = 0; + long mode = 0; + zval *odb = NULL, *progress_cb_payload = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "slrfz", &path, &path_len, &mode, &odb, &fci, &fcc, &progress_cb_payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_odb, php_git2_t*, &odb, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_cb_init(&cb, &fci, &fcc, progress_cb_payload TSRMLS_CC)) { + RETURN_FALSE; + } + //error = git_indexer_new(&out, path, mode, PHP_GIT2_V(_odb, odb), progress_cb, cb); + if (php_git2_check_error(error, "git_indexer_new" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_INDEXER, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto long git_indexer_append(resource $idx, $data, long $size, $stats) + */ +PHP_FUNCTION(git_indexer_append) +{ + +// if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, +// "rl", &idx, &data, &size, &stats) == FAILURE) { +// return; +// } +// +// ZEND_FETCH_RESOURCE(_idx, php_git2_t*, &idx, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); +// result = git_indexer_append(PHP_GIT2_V(_idx, indexer), data, size, stats); +// RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_indexer_commit(resource $idx, $stats) + */ +PHP_FUNCTION(git_indexer_commit) +{ + +// if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, +// "r", &idx, &stats) == FAILURE) { +// return; +// } +// +// ZEND_FETCH_RESOURCE(_idx, php_git2_t*, &idx, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); +// result = git_indexer_commit(PHP_GIT2_V(_idx, indexer), stats); +// RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_indexer_hash(resource $idx) + */ +PHP_FUNCTION(git_indexer_hash) +{ + const git_oid *result = NULL; + zval *idx = NULL; + php_git2_t *_idx = NULL; + char __result[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &idx) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_idx, php_git2_t*, &idx, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_indexer_hash(PHP_GIT2_V(_idx, indexer)); + git_oid_fmt(__result, result); + RETURN_STRING(__result, 1); +} +/* }}} */ + +/* {{{ proto void git_indexer_free(resource $idx) + */ +PHP_FUNCTION(git_indexer_free) +{ + zval *idx = NULL; + php_git2_t *_idx = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &idx) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_idx, php_git2_t*, &idx, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_idx)) { + git_indexer_free(PHP_GIT2_V(_idx, indexer)); + GIT2_SHOULD_FREE(_idx) = 0; + }; + zval_ptr_dtor(&idx); +} +/* }}} */ + diff --git a/indexer.h b/indexer.h new file mode 100644 index 0000000000..f159a870dc --- /dev/null +++ b/indexer.h @@ -0,0 +1,78 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_INDEXER_H +#define PHP_GIT2_INDEXER_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_indexer_new, 0, 0, 6) + ZEND_ARG_INFO(0, out) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, mode) + ZEND_ARG_INFO(0, odb) + ZEND_ARG_INFO(0, progress_cb) + ZEND_ARG_INFO(0, progress_cb_payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_indexer_append, 0, 0, 4) + ZEND_ARG_INFO(0, idx) + ZEND_ARG_INFO(0, data) + ZEND_ARG_INFO(0, size) + ZEND_ARG_INFO(0, stats) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_indexer_commit, 0, 0, 2) + ZEND_ARG_INFO(0, idx) + ZEND_ARG_INFO(0, stats) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_indexer_hash, 0, 0, 1) + ZEND_ARG_INFO(0, idx) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_indexer_free, 0, 0, 1) + ZEND_ARG_INFO(0, idx) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_indexer_new(string $path, long $mode, resource $odb, $progress_cb, $progress_cb_payload) + */ +PHP_FUNCTION(git_indexer_new); + +/* {{{ proto long git_indexer_append(resource $idx, $data, long $size, $stats) + */ +PHP_FUNCTION(git_indexer_append); + +/* {{{ proto long git_indexer_commit(resource $idx, $stats) + */ +PHP_FUNCTION(git_indexer_commit); + +/* {{{ proto resource git_indexer_hash(resource $idx) + */ +PHP_FUNCTION(git_indexer_hash); + +/* {{{ proto void git_indexer_free(resource $idx) + */ +PHP_FUNCTION(git_indexer_free); + +#endif diff --git a/libgit2 b/libgit2 new file mode 160000 index 0000000000..43cb8b3242 --- /dev/null +++ b/libgit2 @@ -0,0 +1 @@ +Subproject commit 43cb8b32428b1b29994874349ec22eb5372e152c diff --git a/merge.c b/merge.c new file mode 100644 index 0000000000..37c88e9f00 --- /dev/null +++ b/merge.c @@ -0,0 +1,321 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "merge.h" + +/* {{{ proto resource git_merge_base(resource $repo, string $one, string $two) + */ +PHP_FUNCTION(git_merge_base) +{ + php_git2_t *_repo = NULL; + git_oid out = {0}, __one = {0}, __two = {0}; + zval *repo = NULL; + char *one = NULL, *two = NULL, oid[41] = {0}; + int one_len = 0, two_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rss", &repo, &one, &one_len, &two, &two_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__one, one, one_len)) { + RETURN_FALSE; + } + if (git_oid_fromstrn(&__two, two, two_len)) { + RETURN_FALSE; + } + error = git_merge_base(&out, PHP_GIT2_V(_repo, repository), &__one, &__two); + if (php_git2_check_error(error, "git_merge_base" TSRMLS_CC)) { + RETURN_FALSE; + } + git_oid_fmt(oid, &out); + RETURN_STRING(oid, 1); +} +/* }}} */ + +/* {{{ proto resource git_merge_base_many(resource $repo, long $length, string $input_array[]) + */ +PHP_FUNCTION(git_merge_base_many) +{ +// php_git2_t *result = NULL, *_repo = NULL; +// git_oid out = {0}, __input_array[] = {0}; +// zval *repo = NULL; +// long length = 0; +// char *input_array[] = NULL; +// int input_array[]_len = 0, error = 0; + +// if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, +// "rls", &repo, &length, &input_array[], &input_array[]_len) == FAILURE) { +// return; +// } + +// ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); +// if (git_oid_fromstrn(&__input_array[], input_array[], input_array[]_len)) { +// RETURN_FALSE; +// } +// error = git_merge_base_many(&__out, PHP_GIT2_V(_repo, repository), length, __input_array[]); +// if (php_git2_check_error(error, "git_merge_base_many" TSRMLS_CC)) { +// RETURN_FALSE; +// } +// if (php_git2_make_resource(&result, PHP_GIT2_TYPE_OID, out, 1 TSRMLS_CC)) { +// RETURN_FALSE; +// } +// ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_merge_head_from_ref(resource $repo, resource $ref) + */ +PHP_FUNCTION(git_merge_head_from_ref) +{ + php_git2_t *result = NULL, *_repo = NULL, *_ref = NULL; + git_merge_head *out = NULL; + zval *repo = NULL, *ref = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rr", &repo, &ref) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_ref, php_git2_t*, &ref, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_merge_head_from_ref(&out, PHP_GIT2_V(_repo, repository), PHP_GIT2_V(_ref, reference)); + if (php_git2_check_error(error, "git_merge_head_from_ref" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_MERGE_HEAD, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_merge_head_from_fetchhead(resource $repo, string $branch_name, string $remote_url, string $oid) + */ +PHP_FUNCTION(git_merge_head_from_fetchhead) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_merge_head *out = NULL; + zval *repo = NULL; + char *branch_name = NULL, *remote_url = NULL, *oid = NULL; + int branch_name_len = 0, remote_url_len = 0, oid_len = 0, error = 0; + git_oid __oid = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsss", &repo, &branch_name, &branch_name_len, &remote_url, &remote_url_len, &oid, &oid_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__oid, oid, oid_len)) { + RETURN_FALSE; + } + error = git_merge_head_from_fetchhead(&out, PHP_GIT2_V(_repo, repository), branch_name, remote_url, &__oid); + if (php_git2_check_error(error, "git_merge_head_from_fetchhead" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_MERGE_HEAD, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_merge_head_from_oid(resource $repo, string $oid) + */ +PHP_FUNCTION(git_merge_head_from_oid) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_merge_head *out = NULL; + zval *repo = NULL; + char *oid = NULL; + int oid_len = 0, error = 0; + git_oid __oid = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repo, &oid, &oid_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__oid, oid, oid_len)) { + RETURN_FALSE; + } + error = git_merge_head_from_oid(&out, PHP_GIT2_V(_repo, repository), &__oid); + if (php_git2_check_error(error, "git_merge_head_from_oid" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_MERGE_HEAD, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto void git_merge_head_free(resource $head) + */ +PHP_FUNCTION(git_merge_head_free) +{ + zval *head = NULL; + php_git2_t *_head = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &head) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_head, php_git2_t*, &head, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_head)) { + git_merge_head_free(PHP_GIT2_V(_head, merge_head)); + GIT2_SHOULD_FREE(_head) = 0; + }; + zval_ptr_dtor(&head); +} +/* }}} */ + +/* {{{ proto resource git_merge_trees(resource $repo, resource $ancestor_tree, resource $our_tree, resource $their_tree, $opts) + */ +PHP_FUNCTION(git_merge_trees) +{ + php_git2_t *result = NULL, *_repo = NULL, *_ancestor_tree = NULL, *_our_tree = NULL, *_their_tree = NULL; + git_index *out = NULL; + zval *repo = NULL, *ancestor_tree = NULL, *our_tree = NULL, *their_tree = NULL, *opts = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rrrr", &repo, &ancestor_tree, &our_tree, &their_tree, &opts) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_ancestor_tree, php_git2_t*, &ancestor_tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_our_tree, php_git2_t*, &our_tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_their_tree, php_git2_t*, &their_tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_merge_trees(&out, PHP_GIT2_V(_repo, repository), PHP_GIT2_V(_ancestor_tree, tree), PHP_GIT2_V(_our_tree, tree), PHP_GIT2_V(_their_tree, tree), opts); + if (php_git2_check_error(error, "git_merge_trees" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_INDEX, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_merge(resource $repo, array $their_heads, array $opts) + */ +PHP_FUNCTION(git_merge) +{ + php_git2_t *result = NULL, *_repo = NULL, *_their_head = NULL; + git_merge_result *out = NULL; + zval *repo = NULL, *opts = NULL, *theirhead = NULL; + git_merge_head *heads[1]; + int error = 0; + git_merge_opts options = GIT_MERGE_OPTS_INIT; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rza", &repo, &theirhead, &opts) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_their_head, php_git2_t*, &theirhead, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + heads[0] = PHP_GIT2_V(_their_head, merge_head); + options.merge_flags = GIT_MERGE_NO_FASTFORWARD; + + error = git_merge(&out, PHP_GIT2_V(_repo, repository), heads, 1, &options); + if (php_git2_check_error(error, "git_merge" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_MERGE_RESULT, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto long git_merge_result_is_uptodate(resource $merge_result) + */ +PHP_FUNCTION(git_merge_result_is_uptodate) +{ + int result = 0; + zval *merge_result = NULL; + php_git2_t *_merge_result = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &merge_result) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_merge_result, php_git2_t*, &merge_result, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_merge_result_is_uptodate(PHP_GIT2_V(_merge_result, merge_result)); + RETURN_BOOL(result); +} +/* }}} */ + +/* {{{ proto long git_merge_result_is_fastforward(resource $merge_result) + */ +PHP_FUNCTION(git_merge_result_is_fastforward) +{ + int result = 0; + zval *merge_result = NULL; + php_git2_t *_merge_result = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &merge_result) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_merge_result, php_git2_t*, &merge_result, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_merge_result_is_fastforward(PHP_GIT2_V(_merge_result, merge_result)); + RETURN_BOOL(result); +} +/* }}} */ + +/* {{{ proto resource git_merge_result_fastforward_oid(resource $merge_result) + */ +PHP_FUNCTION(git_merge_result_fastforward_oid) +{ + php_git2_t *_merge_result = NULL; + git_oid out = {0}; + zval *merge_result = NULL; + int error = 0; + char buf[41] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &merge_result) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_merge_result, php_git2_t*, &merge_result, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_merge_result_fastforward_oid(&out, PHP_GIT2_V(_merge_result, merge_result)); + if (php_git2_check_error(error, "git_merge_result_fastforward_oid" TSRMLS_CC)) { + RETURN_FALSE; + } + git_oid_fmt(buf, &out); + RETURN_STRING(buf, 1); +} +/* }}} */ + +/* {{{ proto void git_merge_result_free(resource $merge_result) + */ +PHP_FUNCTION(git_merge_result_free) +{ + zval *merge_result = NULL; + php_git2_t *_merge_result = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &merge_result) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_merge_result, php_git2_t*, &merge_result, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_merge_result)) { + git_merge_result_free(PHP_GIT2_V(_merge_result, merge_result)); + GIT2_SHOULD_FREE(_merge_result) = 0; + }; + zval_ptr_dtor(&merge_result); +} +/* }}} */ + diff --git a/merge.h b/merge.h new file mode 100644 index 0000000000..0367b95ae7 --- /dev/null +++ b/merge.h @@ -0,0 +1,141 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_MERGE_H +#define PHP_GIT2_MERGE_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_merge_base, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, one) + ZEND_ARG_INFO(0, two) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_merge_base_many, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, length) + ZEND_ARG_INFO(0, input_array[]) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_merge_head_from_ref, 0, 0, 2) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, ref) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_merge_head_from_fetchhead, 0, 0, 4) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, branch_name) + ZEND_ARG_INFO(0, remote_url) + ZEND_ARG_INFO(0, oid) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_merge_head_from_oid, 0, 0, 2) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, oid) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_merge_head_free, 0, 0, 1) + ZEND_ARG_INFO(0, head) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_merge_trees, 0, 0, 5) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, ancestor_tree) + ZEND_ARG_INFO(0, our_tree) + ZEND_ARG_INFO(0, their_tree) + ZEND_ARG_INFO(0, opts) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_merge, 0, 0, 4) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, their_heads) + ZEND_ARG_INFO(0, their_heads_len) + ZEND_ARG_INFO(0, opts) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_merge_result_is_uptodate, 0, 0, 1) + ZEND_ARG_INFO(0, merge_result) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_merge_result_is_fastforward, 0, 0, 1) + ZEND_ARG_INFO(0, merge_result) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_merge_result_fastforward_oid, 0, 0, 1) + ZEND_ARG_INFO(0, merge_result) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_merge_result_free, 0, 0, 1) + ZEND_ARG_INFO(0, merge_result) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_merge_base(repo, one, two) +*/ +PHP_FUNCTION(git_merge_base); + +/* {{{ proto resource git_merge_base_many(repo, length, input_array[]) +*/ +PHP_FUNCTION(git_merge_base_many); + +/* {{{ proto resource git_merge_head_from_ref(repo, ref) +*/ +PHP_FUNCTION(git_merge_head_from_ref); + +/* {{{ proto resource git_merge_head_from_fetchhead(repo, branch_name, remote_url, oid) +*/ +PHP_FUNCTION(git_merge_head_from_fetchhead); + +/* {{{ proto resource git_merge_head_from_oid(repo, oid) +*/ +PHP_FUNCTION(git_merge_head_from_oid); + +/* {{{ proto void git_merge_head_free(head) +*/ +PHP_FUNCTION(git_merge_head_free); + +/* {{{ proto resource git_merge_trees(repo, ancestor_tree, our_tree, their_tree, opts) +*/ +PHP_FUNCTION(git_merge_trees); + +/* {{{ proto resource git_merge(repo, their_heads, their_heads_len, opts) +*/ +PHP_FUNCTION(git_merge); + +/* {{{ proto long git_merge_result_is_uptodate(merge_result) +*/ +PHP_FUNCTION(git_merge_result_is_uptodate); + +/* {{{ proto long git_merge_result_is_fastforward(merge_result) +*/ +PHP_FUNCTION(git_merge_result_is_fastforward); + +/* {{{ proto resource git_merge_result_fastforward_oid(merge_result) +*/ +PHP_FUNCTION(git_merge_result_fastforward_oid); + +/* {{{ proto void git_merge_result_free(merge_result) +*/ +PHP_FUNCTION(git_merge_result_free); + +#endif \ No newline at end of file diff --git a/message.c b/message.c new file mode 100644 index 0000000000..f23b00cbb4 --- /dev/null +++ b/message.c @@ -0,0 +1,24 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "message.h" + +/* {{{ proto resource git_message_prettify(string $message, long $strip_comments) + */ +PHP_FUNCTION(git_message_prettify) +{ + char *out = NULL, *message = NULL; + long out_size = 0, strip_comments = 0; + int message_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "sl", &message, &message_len, &strip_comments) == FAILURE) { + return; + } + + out_size = git_message_prettify(NULL, NULL, message, strip_comments); + out = (char*)emalloc(sizeof(char) * out_size); + error = git_message_prettify(out, out_size, message, strip_comments); + RETURN_STRING(out, 0); +} +/* }}} */ + diff --git a/message.h b/message.h new file mode 100644 index 0000000000..0b40007b40 --- /dev/null +++ b/message.h @@ -0,0 +1,39 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_MESSAGE_H +#define PHP_GIT2_MESSAGE_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_message_prettify, 0, 0, 3) + ZEND_ARG_INFO(0, out_size) + ZEND_ARG_INFO(0, message) + ZEND_ARG_INFO(0, strip_comments) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_message_prettify(out_size, message, strip_comments) +*/ +PHP_FUNCTION(git_message_prettify); + +#endif \ No newline at end of file diff --git a/ng.php b/ng.php new file mode 100644 index 0000000000..3631c78e96 --- /dev/null +++ b/ng.php @@ -0,0 +1,1261 @@ +name = $name; + $this->return_type = preg_replace("/\*/", "", $return_type); + + for ($i = 0; $i < count($return_type); $i++) { + if ($return_type[$i] == '*') { + $this->ptr++; + } + } + } + + public function getReturnType() + { + return $this->return_type; + } + + public function isResourceCreator() + { + if (count($this->args)) { + $first = $this->args[0]; + if (preg_match("/out/", $first->getName())) { + return true; + } + } else { + if (preg_match("/git_/", $this->getReturnType())) { + return true; + } + } + + return false; + } + + public function isStringCreator() + { + if (preg_match("/(char)/", $this->getReturnType())) { + return true; + } + } + + public function isLongCreator() + { + if (preg_match("/(size_t|int)/", $this->getReturnType())) { + return true; + } + } + + public function isArrayCreator() + { + if (preg_match("/git_/", $this->getReturnType())) { + return true; + } + } + + public function isVoidCreator() + { + if (preg_match("/void/", $this->getReturnType())) { + return true; + } + } + + public function isSavior() + { + if (preg_match('/_free$/', $this->getName())) { + return true; + } + } + + public function isCallbacker() + { + foreach($this->args as $arg) { + if (preg_match("/_cb$/", $arg->getType())) { + return true; + } + if (preg_match("/callback$/", $arg->getType())) { + return true; + } + if (preg_match("/packbuilder_progress/", $arg->getType())) { + return true; + } + } + + return false; + } + + public function getArguments() + { + return $this->args; + } + + public function addArgument(Arg $arg) + { + $this->args[] = $arg; + } + + public function getName() + { + return $this->name; + } + + public function first() + { + return $this->args[0]; + } +} + +class Arg +{ + protected $type; + protected $ptr = 0; + protected $name; + protected $const; + + public function getDefaultValue() + { + if (preg_match("/long/", $this->getZendType())) { + return "0"; + } else { + return "NULL"; + } + } + + public function getName() + { + return $this->name; + } + + public function setName($name) + { + return $this->name = $name; + } + + + public function getType() + { + return $this->type; + } + + public function isCallback() + { + if (preg_match("/_cb$/", $this->getType())) { + return true; + } + if (preg_match("/callback$/", $this->getType())) { + return true; + } + if (preg_match("/packbuilder_progress/", $this->getType())) { + return true; + } + if (preg_match("/git_push_transfer_progress/", $this->getType())) { + return true; + } + return false; + } + + public function getPtr() + { + return str_repeat("*", $this->ptr - 1); + } + + public function shouldWrite() + { + if ($this->ptr == 2) { + if (preg_match("/^git_/", $this->type)) { + return true; + } + } + + return false; + + } + + public function getZendType() + { + if (preg_match("/char/", $this->type)) { + return "char"; + } else if (preg_match("/(size_t|int)/", $this->type)) { + return "long"; + } else if (preg_match("/git_oid/", $this->type)) { + return "char"; + } else if (preg_match("/git_otype/", $this->type)) { + return "long"; + } else if (preg_match("/^git_/", $this->type)) { + return "zval"; + } else if (preg_match("/payload/", $this->name)) { + return "zval"; + } else { + error_log(sprintf("%s (zendtype)", $this->type)); + } + } + + public function __construct($type, $name) + { + $this->type = $type; + $this->name = $name; + + for ($i = 0; $i < strlen($name); $i++) { + if ($name[$i] == '*') { + $this->ptr++; + } + } + $this->name = preg_replace("/\*/", "", $this->name); + if (preg_match("/^const/", $this->type)) { + $this->const = 1; + $this->type = preg_replace("/^const\s+/", "", $this->type); + } + } +} + +class StringStream +{ + protected $buffer = ""; + + public function __construct($string = "") + { + $this->buffer = $string; + } + + public function append($string) + { + $this->buffer .= $string; + } + + public function assign($message) + { + $this->buffer = $message; + } + + public function __toString() + { + return $this->buffer; + } +} + +class ZeroCopyOutputStream +{ + protected $stream; + + public function __construct($stream) + { + $this->stream = $stream; + } + + public function write($message) + { + $this->stream->append($message); + } +} + +class Printer +{ + protected $replace; + protected $level = 0; + protected $indent_char = "\t"; + protected $stream; + + protected $next; + + public function __construct($stream, $replace) + { + $this->stream = $stream; + $this->replace = $replace; + } + + public function block(Callable $call) + { + $this->indent(); + $call($this); + $this->outdent(); + } + + public function indent() + { + $this->level++; + } + + public function outdent() + { + $this->level--; + if ($this->level < 0) { + throw new RuntimeException("too low indent level."); + } + } + + public function put($message/* $args */) + { + $args = func_get_args(); + array_shift($args); + + $key = ""; + $value = ""; + $tmp = array(); + if (count($args)) { + if (count($args) % 2 != 0) { + throw new InvalidArgumentException("parameter doesn't match"); + } + + for ($i = 0; $i < count($args); $i++) { + if ($i % 2 == 0) { + $key = $args[$i]; + } else { + $value = $args[$i]; + + $tmp[$key] = $value; + unset($key); + unset($value); + } + } + foreach ($tmp as $key => $value) { + $message = str_replace(sprintf("%s%s%s", $this->replace, $key, $this->replace), $value, $message); + } + } + + if ($this->next) { + $this->stream->write(str_repeat($this->indent_char, $this->level)); + } + + if (preg_match('/\n$/m', $message)) { + $this->next = true; + } else { + $this->next = false; + } + $this->stream->write($message); + } +} +class Fashion +{ + protected $name; + protected $flag; + + public function __construct($name, $flag = false) + { + $this->name = basename($name, ".h"); + $this->flag = $flag; + } + + public function shouldResource(Arg $arg) + { + static $types; + if (!$types) { + $types = array( + "git_repository", + "git_commit", + "git_tree", + "git_tree_entry", // really? + "git_blob", + "git_revwalk", + "git_treebuilder", + "git_reference", + "git_config", + "git_object", + "git_index", + "git_odb", + "git_refdb", + "git_status_list", + "git_branch_iterator", + "git_tag", + "git_cred", + "git_transport", + "git_remote", + "git_merge_head", + "git_merge_result", + "git_pathspec", + "git_pathspec_match_list", + "git_diff", + "git_patch", + "git_diff_hunk", + "git_filter_list", + "git_buf", + "git_filter_source", + "git_diff_line", + "git_reference_iterator", + "git_config_iterator", + "git_index_conflict_iterator", + "git_transport*", + "git_transport", + "git_note", + "git_note_iterator", + "git_odb", + "git_odb_object", + "git_odb_backend", + "git_odb_stream", + "struct git_odb", + "git_reflog", + "git_reflog_entry", + "git_blame", + "git_packbuilder", + "git_submodule", + "git_push", + "git_refspec", + "git_filter", + "git_indexer", + ); + } + + if (in_array($arg->getType(), $types)) { + return true; + } else { + return false; + } + } + + public function getReturnType(Func $f) + { + if ($f->isResourceCreator()) { + return "resource"; + } else { + if (preg_match("/(int|size_t)/", $f->getReturnType())) { + return "long"; + } else if (preg_match("/git_signature/", $f->getReturnType())) { + return "array"; + } else if (preg_match("/git/", $f->getReturnType())) { + return "resource"; + } else if (preg_match("/void/", $f->getReturnType())) { + return "void"; + } else if (preg_match("/char/", $f->getReturnType())) { + return "string"; + } else { + error_log(sprintf("%s does not support yet", $f->getReturnType())); + } + } + } + + public function generateProto(Printer $printer, Func $f) + { + $printer->put("/* {{{ proto `return_type` `function`", + "return_type", $this->getReturnType($f), + "function", $f->getName() + ); + $printer->put("("); + $cnt = count($f->getArguments()); + $i = 0; + + foreach ($f->getArguments() as $arg) { + /** @var Arg $arg */ + if ($i == 0 && $f->isResourceCreator()) { + $i++; + continue; + } + if ($arg->shouldWrite()) { + $i++; + continue; + } + + if ($this->shouldResource($arg)) { + $printer->put("resource"); + } else { + if (preg_match("/char/", $arg->getType())) { + $printer->put("string"); + } else if (preg_match("/(int|size_t)/", $arg->getType())) { + $printer->put("long"); + } else if (preg_match("/(git_oid)/", $arg->getType())) { + $printer->put("string"); + } else if (preg_match("/(git_signature)/", $arg->getType())) { + $printer->put("array"); + } else if (preg_match("/(git_strarray)/", $arg->getType())) { + $printer->put("array"); + } else if (preg_match("/_cb$/", $arg->getType())) { + $printer->put("Callable"); + } else if (preg_match("/git_otype/", $arg->getType())) { + $printer->put("long"); + } else { + error_log(sprintf("# unknown type (%s)", $arg->getType())); + } + } + $printer->put(" "); + + // variable name + $printer->put("\$`arg`", "arg", $arg->getName()); + if ($i +1 < $cnt) { + $printer->put(", "); + } + $i++; + } + $printer->put(")\n"); + $printer->put(" */\n"); + } + + public function isPtr(Arg $arg) + { + if (preg_match("/zval/", $arg->getZendType())) { + return "*"; + } else { + if (preg_match("/char/", $arg->getZendType())) { + return "*"; + } else { + return ""; + } + } + } + + public function generateDeclarations(Printer $printer, Func $f) + { + $tables = array(); + if ($f->isResourceCreator()) { + $tables["php_git2_t"][] = array( + "name" => "*result", + "value" => "NULL", + ); + } else if ($f->isArrayCreator()) { + $tables[$f->getReturnType()][] = array( + "name" => "*result", + "value" => "NULL", + ); + if (preg_match("/git_signature/", $f->getReturnType())) { + $tables["zval"][] = array( + "name" => "*__result", + "value" => "NULL", + ); + } + } else if ($f->isLongCreator()) { + $tables[$f->getReturnType()][] = array( + "name" => "result", + "value" => "0", + ); + } else if ($f->isStringCreator()) { + $tables[$f->getReturnType()][] = array( + "name" => "*result", + "value" => "NULL", + ); + } + + $i = 0; + $cnt = count($f->getArguments()); + foreach ($f->getArguments() as $arg) { + /** @var Arg $arg */ + if ($i == 0 && $f->isResourceCreator()) { + $tables[$arg->getType()][] = array( + "name" => sprintf("%s%s", $arg->getPtr(), $arg->getName()), + "value" => "NULL", + ); + $i++; + continue; + } + if ($arg->shouldWrite()) { + $tables[$arg->getType()][] = array( + "name" => sprintf("%s%s", $arg->getPtr(), $arg->getName()), + "value" => "NULL", + ); + } else { + /** @var Arg $arg */ + $tables[$arg->getZendType()][] = array( + "name" => sprintf("%s%s", $this->isPtr($arg), $arg->getName()), + "value" => $arg->getDefaultValue(), + ); + if ($this->shouldResource($arg)) { + $tables["php_git2_t"][] = array( + "name" => sprintf("*_%s", $arg->getName()), + "value" => "NULL", + ); + } + if ($arg->getType() == "git_strarray") { + $tables["git_strarray"][] = array( + "name" => sprintf("_%s", $arg->getName()), + "value" => "{0}", + ); + } + + if (preg_match("/char/", $arg->getZendType())) { + $tables["int"][] = array( + "name" => sprintf("%s_len", $arg->getName()), + "value" => "0", + ); + } + } + + if ($arg->getType() == "git_oid") { + $tables["git_oid"][] = array( + "name" => sprintf("__%s", $arg->getName()), + "value" => "{0}", + ); + } + + $i++; + } + if ($f->getReturnType() == "int") { + $tables[$f->getReturnType()][] = array( + "name" => "error", + "value" => "0", + ); + } + if (preg_match("/git_oid/", $f->getReturnType())) { + $tables["char"][] = array( + "name" => "__result[GIT2_OID_HEXSIZE]", + "value" => "{0}", + ); + } + if (preg_match("/_owner$/", $f->getName())) { + $tables["php_git2_t"][] = array( + "name" => "*__result", + "value" => "NULL", + ); + } + if ($f->isCallbacker()) { + $tables["zend_fcall_info"][] = array( + "name" => "fci", + "value" => "empty_fcall_info", + ); + $tables["zend_fcall_info_cache"][] = array( + "name" => "fcc", + "value" => "empty_fcall_info_cache", + ); + $tables["php_git2_cb_t"][] = array( + "name" => "*cb", + "value" => "NULL", + ); + } + + + foreach ($tables as $type => $values) { + $printer->put("`type` ", "type", $type); + $i = 0; + $cnt = count($values); + foreach ($values as $val) { + $printer->put("`name` = `value`", "name", $val['name'], "value", $val["value"]); + if ($i+1 < $cnt) { + $printer->put(", "); + } + $i++; + } + $printer->put(";\n"); + } + } + + public function generateParse(Printer $printer, Func $f) + { + $printer->put("if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,\n"); + $printer->block(function(Printer $printer) use ($f) { + $i = 0; + $cnt = count($f->getArguments()); + $printer->put('"'); + foreach ($f->getArguments() as $arg) { + /** @var Arg $arg */ + if ($i == 0 && $f->isResourceCreator()) { + $i++; + continue; + } + if ($arg->shouldWrite()) { + $i++; + continue; + } + + if (preg_match("/char/", $arg->getZendType())) { + $printer->put("s"); + } else if (preg_match("/long/", $arg->getZendType())) { + $printer->put("l"); + } else if (preg_match("/git_signature/", $arg->getType())) { + $printer->put("a"); + } else if (preg_match("/git_strarray/", $arg->getType())) { + $printer->put("a"); + } else if ($this->shouldResource($arg)) { + $printer->put("r"); + } else if ($arg->isCallback()) { + $printer->put("f"); + } else if ($f->isCallbacker() && preg_match("/payload/", $arg->getName())) { + $printer->put("z"); + } else { + $printer->put("<{$arg->getType()}>"); + } + } + $printer->put('", '); + + $i = 0; + foreach ($f->getArguments() as $arg) { + /** @var Arg $arg */ + if ($i == 0 && $f->isResourceCreator()) { + $i++; + continue; + } + if ($arg->shouldWrite()) { + $i++; + continue; + } + + if ($arg->isCallback()) { + $printer->put("&fci, "); + $printer->put("&fcc"); + } else { + $printer->put("&`name`", "name", $arg->getName()); + } + if (preg_match("/char/", $arg->getZendType())) { + $printer->put(", "); + $printer->put("&`name`_len", "name", $arg->getName()); + } + if ($i+1 < $cnt) { + $printer->put(", "); + } + $i++; + } + + $printer->put(") == FAILURE) {\n"); + $printer->put("return;\n"); + }); + $printer->put("}\n"); + } + + public function generateFetchResourceIfNeeded(Printer $printer, Func $f) + { + $i = 0; + foreach ($f->getArguments() as $arg) { + if ($f->isResourceCreator() && $i == 0) { + $i++; + continue; + } + + if ($this->shouldResource($arg) && !$arg->shouldWrite()) { + $printer->put("ZEND_FETCH_RESOURCE(_`container`, php_git2_t*, &`value`, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);\n", + "container", $arg->getName(), + "value", $arg->getName() + ); + } + $i++; + } + } + + public function generateOidTranslation(Printer $printer, Func $f) + { + foreach ($f->getArguments() as $arg) { + /** @var Arg $arg */ + if ($arg->getType() == "git_oid") { + $printer->put("if (git_oid_fromstrn(&__`name`, `name`, `name`_len)) {\n", + "name", $arg->getName() + ); + $printer->block(function(Printer $printer) use($arg) { + $printer->put("RETURN_FALSE;\n"); + }); + $printer->put("}\n"); + $arg->setName("__" . $arg->getName()); + } + } + } + + public function generateCallbackInit(Printer $printer, Func $f) + { + if ($f->isCallbacker()) { + $printer->put("if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) {\n"); + $printer->block(function(Printer $printer) { + $printer->put("RETURN_FALSE;\n"); + }); + $printer->put("}\n"); + } + } + + public function generateCallbackFree(Printer $printer, Func $f) + { + if ($f->isCallbacker()) { + $printer->put("php_git2_cb_free(cb);\n"); + } + } + + public function generateFunctionCall(Printer $printer, Func $f) + { + $this->generateOidTranslation($printer, $f); + $this->generateCallbackInit($printer, $f); + if ($f->getReturnType() == "int" && $f->isResourceCreator()) { + $printer->put("error = `function`", + "function", $f->getName() + ); + $printer->put("("); + + $i = 0; + $cnt = count($f->getArguments()); + foreach ($f->getArguments() as $arg) { + /** @var Arg $arg */ + if ($i == 0 && $f->isResourceCreator()) { + $printer->put("&"); + } + + if ($i != 0) { + if ($this->shouldResource($arg) && !$arg->shouldWrite()) { + $printer->put("PHP_GIT2_V(_`name`, `type`)", + "name", $arg->getName(), + "type", $this->getNormarizedTypeName($arg) + ); + } else if ($arg->shouldWrite()) { + $printer->put("&`name`", "name", $arg->getName()); + } else { + $printer->put("`name`", "name", $arg->getName()); + } + } else { + $printer->put("`name`", "name", $arg->getName()); + } + + if ($i + 1 < $cnt) { + $printer->put(", "); + } + $i++; + } + + $printer->put(");"); + $printer->put("\n"); + } else if ($f->isResourceCreator()) { + $printer->put("`retval` = `function`", + "retval", "result", + "function", $f->getName() + ); + $printer->put("("); + + + $i = 0; + $cnt = count($f->getArguments()); + foreach ($f->getArguments() as $arg) { + /** @var Arg $arg */ + if ($i == 0 && $f->isResourceCreator()) { + $printer->put("&"); + } + + if ($i != 0) { + if ($this->shouldResource($arg) && !$arg->shouldWrite()) { + $printer->put("PHP_GIT2_V(_`name`, `type`)", + "name", $arg->getName(), + "type", $this->getNormarizedTypeName($arg) + ); + } else if ($arg->shouldWrite()) { + $printer->put("&`name`", "name", $arg->getName()); + } else { + $printer->put("`name`", "name", $arg->getName()); + } + } else { + $printer->put("`name`", "name", $arg->getName()); + } + + if ($i + 1 < $cnt) { + $printer->put(", "); + } + $i++; + } + $printer->put(");\n"); + } else if ($f->isArrayCreator()) { + $printer->put("result = `function`", + "function", $f->getName() + ); + $printer->put("("); + + $i = 0; + $cnt = count($f->getArguments()); + foreach ($f->getArguments() as $arg) { + /** @var Arg $arg */ + + if ($this->shouldResource($arg) && !$arg->shouldWrite()) { + $printer->put("PHP_GIT2_V(_`name`, `type`)", + "name", $arg->getName(), + "type", $this->getNormarizedTypeName($arg) + ); + } else if ($arg->shouldWrite()) { + $printer->put("&`name`", "name", $arg->getName()); + } else { + $printer->put("`name`", "name", $arg->getName()); + } + + if ($i + 1 < $cnt) { + $printer->put(", "); + } + $i++; + } + + $printer->put(");\n"); + if (preg_match("/git_oid/", $f->getReturnType())) { + $printer->put("git_oid_fmt(__result, `name`);\n", "name", "result"); + $printer->put("RETURN_STRING(__result, 1);\n"); + } else if (preg_match("/_owner$/", $f->getName())) { + $this->generateMakeResourceIfNeeded($printer, $f, "__result", 1); + } else if (preg_match("/_type/", $f->getName())) { + $printer->put("RETURN_LONG(`name`);\n", "name", "result"); + } else if (preg_match("/git_signature/", $f->getReturnType())) { + $printer->put("php_git2_signature_to_array(result, &__result TSRMLS_CC);\n"); + $printer->put("RETURN_ZVAL(__result, 0, 1);\n"); + } else { + $printer->put("/* TODO(chobie): implement this */\n"); + } + } else if ($f->isLongCreator()) { + $printer->put("result = `function`", + "function", $f->getName() + ); + $printer->put("("); + $i = 0; + $cnt = count($f->getArguments()); + foreach ($f->getArguments() as $arg) { + /** @var Arg $arg */ + + if ($this->shouldResource($arg) && !$arg->shouldWrite()) { + $printer->put("PHP_GIT2_V(_`name`, `type`)", + "name", $arg->getName(), + "type", $this->getNormarizedTypeName($arg) + ); + } else if ($arg->shouldWrite()) { + $printer->put("&`name`", "name", $arg->getName()); + } else if ($arg->isCallback()) { + $printer->put(""); + } else if (preg_match("/payload/", $arg->getName())) { + $printer->put("cb"); + } else { + $printer->put("`name`", "name", $arg->getName()); + } + + if ($i + 1 < $cnt) { + $printer->put(", "); + } + $i++; + } + $printer->put(");\n"); + + $this->generateCallbackFree($printer, $f); + if (preg_match("/_is_/", $f->getName())) { + $printer->put("RETURN_BOOL(`name`);\n", "name", "result"); + } else { + $printer->put("RETURN_LONG(`name`);\n", "name", "result"); + } + } else if ($f->isSavior()) { + + $first = $f->first(); + $printer->put("if (GIT2_SHOULD_FREE(_`name`)) {\n", + "name", $first->getName() + ); + $printer->block(function(Printer $printer) use ($f, $first) { + $printer->put("`function`", + "function", $f->getName() + ); + $printer->put("("); + $i = 0; + $cnt = count($f->getArguments()); + foreach ($f->getArguments() as $arg) { + /** @var Arg $arg */ + + if ($this->shouldResource($arg) && !$arg->shouldWrite()) { + $printer->put("PHP_GIT2_V(_`name`, `type`)", + "name", $arg->getName(), + "type", $this->getNormarizedTypeName($arg) + ); + } else if ($arg->shouldWrite()) { + $printer->put("&`name`", "name", $arg->getName()); + } else { + $printer->put("`name`", "name", $arg->getName()); + } + + if ($i + 1 < $cnt) { + $printer->put(", "); + } + $i++; + } + $printer->put(");\n"); + $printer->put("GIT2_SHOULD_FREE(_`name`) = 0;\n", "name", $first->getName()); + }); + $printer->put("};\n"); + + $printer->put("zval_ptr_dtor(&`name`);\n", "name", $first->getName()); + } else if ($f->isStringCreator()) { + $printer->put("result = `function`", + "function", $f->getName() + ); + $printer->put("("); + $i = 0; + $cnt = count($f->getArguments()); + foreach ($f->getArguments() as $arg) { + /** @var Arg $arg */ + + if ($this->shouldResource($arg) && !$arg->shouldWrite()) { + $printer->put("PHP_GIT2_V(_`name`, `type`)", + "name", $arg->getName(), + "type", $this->getNormarizedTypeName($arg) + ); + } else if ($arg->shouldWrite()) { + $printer->put("&`name`", "name", $arg->getName()); + } else { + $printer->put("`name`", "name", $arg->getName()); + } + + if ($i + 1 < $cnt) { + $printer->put(", "); + } + $i++; + } + $printer->put(");\n"); + $printer->put("RETURN_STRING(`name`, 1);\n", "name", "result"); + } else if ($f->isVoidCreator()) { + $printer->put("`function`", + "function", $f->getName() + ); + $printer->put("("); + $i = 0; + $cnt = count($f->getArguments()); + foreach ($f->getArguments() as $arg) { + /** @var Arg $arg */ + + if ($this->shouldResource($arg) && !$arg->shouldWrite()) { + $printer->put("PHP_GIT2_V(_`name`, `type`)", + "name", $arg->getName(), + "type", $this->getNormarizedTypeName($arg) + ); + } else if ($arg->shouldWrite()) { + $printer->put("&`name`", "name", $arg->getName()); + } else { + $printer->put("`name`", "name", $arg->getName()); + } + + if ($i + 1 < $cnt) { + $printer->put(", "); + } + $i++; + } + $printer->put(");\n"); + } else { + error_log(sprintf("# %s not supported (call function)", $f->getName())); + } + } + + public function generateCheckStatementIfNeeded(Printer $printer, Func $f) + { + if ($f->getReturnType() == "int" && $f->isResourceCreator()) { + $printer->put('if (php_git2_check_error(error, "`func`" TSRMLS_CC)) {', + "func", $f->getName() + ); + $printer->put("\n"); + $printer->block(function (Printer $printer) use ($f) { + $printer->put("RETURN_FALSE;\n"); + }); + $printer->put("}\n"); + } + } + + public function getNormarizedTypeName(Arg $arg) + { + $name = $arg->getType(); + return preg_replace("/^git_/", "", $name); + } + + public function generateMakeResourceIfNeeded(Printer $printer, Func $f, $name = "result", $force = 0) + { + if ($f->isResourceCreator() || $force) { + $arg = $f->first(); + $printer->put("if (php_git2_make_resource(&`name`, PHP_GIT2_TYPE_`type`, `target`, 1 TSRMLS_CC)) {\n", + "name", $name, + "type", strtoupper($this->getNormarizedTypeName($arg)), + "target", "out" + ); + $printer->block(function(Printer $printer) { + $printer->put("RETURN_FALSE;\n"); + }); + $printer->put("}\n"); + $printer->put("ZVAL_RESOURCE(return_value, GIT2_RVAL_P(`name`));\n", "name", $name); + } + } + + public function generateStrarrayConversion(Printer $printer, Func $f) + { + foreach ($f->getArguments() as $arg) { + /** @var Arg $arg */ + if ($arg->getType() == "git_strarray") { + $printer->put("php_git2_array_to_strarray(&_`name`, `name` TSRMLS_CC);\n", + "name", $arg->getName()); + } + } + } + + public function generateIncludes(Printer $printer, Func $f) + { + if ($this->flag) { + $printer->put("#include \"php_git2.h\"\n"); + $printer->put("#include \"php_git2_priv.h\"\n"); + $printer->put("#include \"`name`.h\"\n", "name", $this->name); + } + } + + public function out(Func $f) + { + $stream = new StringStream(); + $out = new ZeroCopyOutputStream($stream); + $printer = new Printer($out, "`"); + + $this->generateIncludes($printer, $f); + $this->generateProto($printer, $f); + $printer->put("PHP_FUNCTION(`function`)\n", + "function", $f->getName()); + $printer->put("{\n"); + $printer->block(function(Printer $printer) use ($f) { + $this->generateDeclarations($printer, $f); + $printer->put("\n"); + $this->generateParse($printer, $f); + $printer->put("\n"); + + $this->generateFetchResourceIfNeeded($printer, $f); + $this->generateStrarrayConversion($printer, $f); + $this->generateFunctionCall($printer, $f); + $this->generateCheckStatementIfNeeded($printer, $f); + $this->generateMakeResourceIfNeeded($printer, $f); + }); + $printer->put("}\n"); + $printer->put("/* }}} */\n"); + $printer->put("\n"); + + + return $stream->__toString(); + } +} + +class Header extends Fashion +{ + public function generateLicense(Printer $printer, Func $f) + { + if (!$this->flag) { + return; + } + $printer->put("/*\n"); + $printer->put(" * PHP Libgit2 Extension\n"); + $printer->put(" *\n"); + $printer->put(" * https://github.com/libgit2/php-git\n"); + $printer->put(" *\n"); + $printer->put(" * Copyright 2014 Shuhei Tanuma. All rights reserved.\n"); + $printer->put(" *\n"); + $printer->put(" * Permission is hereby granted, free of charge, to any person obtaining a copy\n"); + $printer->put(" * of this software and associated documentation files (the \"Software\"), to deal\n"); + $printer->put(" * in the Software without restriction, including without limitation the rights\n"); + $printer->put(" * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n"); + $printer->put(" * copies of the Software, and to permit persons to whom the Software is\n"); + $printer->put(" * furnished to do so, subject to the following conditions:\n"); + $printer->put(" *\n"); + $printer->put(" * The above copyright notice and this permission notice shall be included in\n"); + $printer->put(" * all copies or substantial portions of the Software.\n"); + $printer->put(" *\n"); + $printer->put(" * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n"); + $printer->put(" * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n"); + $printer->put(" * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n"); + $printer->put(" * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n"); + $printer->put(" * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n"); + $printer->put(" * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n"); + $printer->put(" * THE SOFTWARE.\n"); + $printer->put(" */\n"); + $printer->put("#ifndef PHP_GIT2_`file`_H\n", "file", strtoupper($this->name)); + $printer->put("#define PHP_GIT2_`file`_H\n", "file", strtoupper($this->name)); + $printer->put("\n"); + } + + public function generateArgInfo(Printer $printer, Func $f) + { + $printer->put("ZEND_BEGIN_ARG_INFO_EX(arginfo_`name`, `a`, `b`, `c`)\n", + "name", $f->getName(), + "a", 0, + "b", 0, + "c", count($f->getArguments()) + ); + foreach ($f->getArguments() as $arg) { + /** @var Arg $arg */ + $printer->put("\tZEND_ARG_INFO(`is_ref`, `name`)\n", + "is_ref", 0, + "name", $arg->getName()); + } + $printer->put("ZEND_END_ARG_INFO()\n"); + $printer->put("\n"); + } + + public function out(Func $f) + { + $stream = new StringStream(); + $out = new ZeroCopyOutputStream($stream); + $printer = new Printer($out, "`"); + + $this->generateLicense($printer, $f); + $this->generateArgInfo($printer, $f); + + return $stream->__toString(); + } +} + +class Header2 extends Header +{ + public function generateArgInfo(Printer $printer, Func $f) + { + $printer->put("ZEND_BEGIN_ARG_INFO_EX(arginfo_`name`, `a`, `b`, `c`)\n", + "name", $f->getName(), + "a", 0, + "b", 0, + "c", count($f->getArguments()) + ); + foreach ($f->getArguments() as $arg) { + /** @var Arg $arg */ + $printer->put("\tZEND_ARG_INFO(`is_ref`, `name`)\n", + "is_ref", 0, + "name", $arg->getName()); + } + $printer->put("ZEND_END_ARG_INFO()\n"); + $printer->put("\n"); + } + + public function out(Func $f) + { + $stream = new StringStream(); + $out = new ZeroCopyOutputStream($stream); + $printer = new Printer($out, "`"); + + $this->generateProto($printer, $f); + $printer->put("PHP_FUNCTION(`func`);\n", "func", $f->getName()); + $printer->put("\n"); + + return $stream->__toString(); + } +} + +$data = file_get_contents($_SERVER['argv'][1]); +$table = array(); +if (preg_match_all("/GIT_EXTERN\((.+?)\)\s*([a-zA-Z0-9_-]+)\((.+?)\);/s", $data, $match)) { + $cnt = count($match[0]); + + for ($i = 0; $i < $cnt; $i++) { + $func = new Func($match[2][$i], $match[1][$i]); + $args = explode(",", $match[3][$i]); + + foreach ($args as $arg) { + $arg = trim($arg); + $pos = strrpos($arg, " "); + $key = trim(substr($arg, $pos)); + $type = trim(substr($arg, 0, $pos)); + $func->addArgument(new Arg($type, $key)); + } + $table[$func->getName()] = $func; + } +} +if (getenv("PRINT_HEADER")) { + $flag = true; + foreach ($table as $name => $func) { + $printer = new Header($_SERVER['argv'][1], $flag); + echo $printer->out($func); + $flag = false; + } + + foreach ($table as $name => $func) { + $printer = new Header2($_SERVER['argv'][1], $flag); + echo $printer->out($func); + } + echo "#endif\n"; +} else { + if (isset($_SERVER['argv'][2])) { + $printer = new Fashion($_SERVER['argv'][1]); + echo $printer->out($table[$_SERVER['argv'][2]]); + } else { + $flag = true; + foreach ($table as $name => $func) { + $printer = new Fashion($_SERVER['argv'][1], $flag); + echo $printer->out($func); + $flag = false; + } + } +} + diff --git a/note.c b/note.c new file mode 100644 index 0000000000..595fb70ee2 --- /dev/null +++ b/note.c @@ -0,0 +1,268 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "note.h" + +/* {{{ proto resource git_note_iterator_new(resource $repo, string $notes_ref) + */ +PHP_FUNCTION(git_note_iterator_new) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_note_iterator *out = NULL; + zval *repo = NULL; + char *notes_ref = NULL; + int notes_ref_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repo, ¬es_ref, ¬es_ref_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_note_iterator_new(&out, PHP_GIT2_V(_repo, repository), notes_ref); + if (php_git2_check_error(error, "git_note_iterator_new" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_NOTE_ITERATOR, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto void git_note_iterator_free(resource $it) + */ +PHP_FUNCTION(git_note_iterator_free) +{ + zval *it = NULL; + php_git2_t *_it = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &it) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_it, php_git2_t*, &it, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_it)) { + git_note_iterator_free(PHP_GIT2_V(_it, note_iterator)); + GIT2_SHOULD_FREE(_it) = 0; + }; + zval_ptr_dtor(&it); +} +/* }}} */ + +/* {{{ proto long git_note_next(string $note_id, string $annotated_id, resource $it) + */ +PHP_FUNCTION(git_note_next) +{ + int result = 0, note_id_len = 0, annotated_id_len = 0; + char *note_id = NULL, *annotated_id = NULL; + zval *it = NULL; + php_git2_t *_it = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "ssr", ¬e_id, ¬e_id_len, &annotated_id, &annotated_id_len, &it) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_it, php_git2_t*, &it, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_note_next(note_id, annotated_id, PHP_GIT2_V(_it, note_iterator)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_note_read(resource $repo, string $notes_ref, string $oid) + */ +PHP_FUNCTION(git_note_read) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_note *out = NULL; + zval *repo = NULL; + char *notes_ref = NULL, *oid = NULL; + int notes_ref_len = 0, oid_len = 0, error = 0; + git_oid __oid = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rss", &repo, ¬es_ref, ¬es_ref_len, &oid, &oid_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__oid, oid, oid_len)) { + RETURN_FALSE; + } + error = git_note_read(&out, PHP_GIT2_V(_repo, repository), notes_ref, &__oid); + if (php_git2_check_error(error, "git_note_read" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_NOTE, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto string git_note_message(resource $note) + */ +PHP_FUNCTION(git_note_message) +{ + const char *result = NULL; + zval *note = NULL; + php_git2_t *_note = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", ¬e) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_note, php_git2_t*, ¬e, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_note_message(PHP_GIT2_V(_note, note)); + RETURN_STRING(result, 1); +} +/* }}} */ + +/* {{{ proto resource git_note_oid(resource $note) + */ +PHP_FUNCTION(git_note_oid) +{ + const git_oid *result = NULL; + zval *note = NULL; + php_git2_t *_note = NULL; + char __result[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", ¬e) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_note, php_git2_t*, ¬e, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_note_oid(PHP_GIT2_V(_note, note)); + git_oid_fmt(__result, result); + RETURN_STRING(__result, 1); +} +/* }}} */ + +/* {{{ proto resource git_note_create(resource $repo, array $author, array $committer, string $notes_ref, string $oid, string $note, long $force) + */ +PHP_FUNCTION(git_note_create) +{ + php_git2_t *_repo = NULL; + git_oid out = {0}, __oid = {0}; + zval *repo = NULL, *author = NULL, *committer = NULL; + char *notes_ref = NULL, *oid = NULL, *note = NULL; + int notes_ref_len = 0, oid_len = 0, note_len = 0, error = 0; + long force = 0; + char buf[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "raasssl", &repo, &author, &committer, ¬es_ref, ¬es_ref_len, &oid, &oid_len, ¬e, ¬e_len, &force) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__oid, oid, oid_len)) { + RETURN_FALSE; + } + error = git_note_create(&out, PHP_GIT2_V(_repo, repository), author, committer, notes_ref, &__oid, note, force); + if (php_git2_check_error(error, "git_note_create" TSRMLS_CC)) { + RETURN_FALSE; + } + git_oid_fmt(buf, &out); + RETURN_STRING(buf, 1); +} +/* }}} */ + +/* {{{ proto long git_note_remove(resource $repo, string $notes_ref, array $author, array $committer, string $oid) + */ +PHP_FUNCTION(git_note_remove) +{ + int result = 0, notes_ref_len = 0, oid_len = 0; + zval *repo = NULL, *author = NULL, *committer = NULL; + php_git2_t *_repo = NULL; + char *notes_ref = NULL, *oid = NULL; + git_oid __oid = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsaas", &repo, ¬es_ref, ¬es_ref_len, &author, &committer, &oid, &oid_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__oid, oid, oid_len)) { + RETURN_FALSE; + } + result = git_note_remove(PHP_GIT2_V(_repo, repository), notes_ref, author, committer, &__oid); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto void git_note_free(resource $note) + */ +PHP_FUNCTION(git_note_free) +{ + zval *note = NULL; + php_git2_t *_note = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", ¬e) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_note, php_git2_t*, ¬e, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_note)) { + git_note_free(PHP_GIT2_V(_note, note)); + GIT2_SHOULD_FREE(_note) = 0; + }; + zval_ptr_dtor(¬e); +} +/* }}} */ + +/* {{{ proto resource git_note_default_ref(resource $repo) + */ +PHP_FUNCTION(git_note_default_ref) +{ + php_git2_t *_repo = NULL; + char *out = NULL; + zval *repo = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_note_default_ref(&out, PHP_GIT2_V(_repo, repository)); + if (php_git2_check_error(error, "git_note_default_ref" TSRMLS_CC)) { + RETURN_FALSE; + } + RETURN_STRING(out, 1); +} +/* }}} */ + +/* {{{ proto long git_note_foreach(resource $repo, string $notes_ref, Callable $note_cb, $payload) + */ +PHP_FUNCTION(git_note_foreach) +{ + int result = 0, notes_ref_len = 0; + zval *repo = NULL, *payload = NULL; + php_git2_t *_repo = NULL; + char *notes_ref = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsfz", &repo, ¬es_ref, ¬es_ref_len, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + //result = git_note_foreach(PHP_GIT2_V(_repo, repository), notes_ref, , cb); + php_git2_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + diff --git a/note.h b/note.h new file mode 100644 index 0000000000..51de3a2a82 --- /dev/null +++ b/note.h @@ -0,0 +1,135 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_NOTE_H +#define PHP_GIT2_NOTE_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_note_iterator_new, 0, 0, 2) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, notes_ref) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_note_iterator_free, 0, 0, 1) + ZEND_ARG_INFO(0, it) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_note_next, 0, 0, 3) + ZEND_ARG_INFO(0, note_id) + ZEND_ARG_INFO(0, annotated_id) + ZEND_ARG_INFO(0, it) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_note_read, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, notes_ref) + ZEND_ARG_INFO(0, oid) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_note_message, 0, 0, 1) + ZEND_ARG_INFO(0, note) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_note_oid, 0, 0, 1) + ZEND_ARG_INFO(0, note) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_note_create, 0, 0, 7) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, author) + ZEND_ARG_INFO(0, committer) + ZEND_ARG_INFO(0, notes_ref) + ZEND_ARG_INFO(0, oid) + ZEND_ARG_INFO(0, note) + ZEND_ARG_INFO(0, force) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_note_remove, 0, 0, 5) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, notes_ref) + ZEND_ARG_INFO(0, author) + ZEND_ARG_INFO(0, committer) + ZEND_ARG_INFO(0, oid) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_note_free, 0, 0, 1) + ZEND_ARG_INFO(0, note) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_note_default_ref, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_note_foreach, 0, 0, 4) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, notes_ref) + ZEND_ARG_INFO(0, note_cb) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_note_iterator_new(repo, notes_ref) +*/ +PHP_FUNCTION(git_note_iterator_new); + +/* {{{ proto void git_note_iterator_free(it) +*/ +PHP_FUNCTION(git_note_iterator_free); + +/* {{{ proto long git_note_next(note_id, annotated_id, it) +*/ +PHP_FUNCTION(git_note_next); + +/* {{{ proto resource git_note_read(repo, notes_ref, oid) +*/ +PHP_FUNCTION(git_note_read); + +/* {{{ proto resource git_note_message(note) +*/ +PHP_FUNCTION(git_note_message); + +/* {{{ proto resource git_note_oid(note) +*/ +PHP_FUNCTION(git_note_oid); + +/* {{{ proto resource git_note_create(repo, author, committer, notes_ref, oid, note, force) +*/ +PHP_FUNCTION(git_note_create); + +/* {{{ proto long git_note_remove(repo, notes_ref, author, committer, oid) +*/ +PHP_FUNCTION(git_note_remove); + +/* {{{ proto void git_note_free(note) +*/ +PHP_FUNCTION(git_note_free); + +/* {{{ proto resource git_note_default_ref(repo) +*/ +PHP_FUNCTION(git_note_default_ref); + +/* {{{ proto long git_note_foreach(repo, notes_ref, note_cb, payload) +*/ +PHP_FUNCTION(git_note_foreach); + +#endif \ No newline at end of file diff --git a/object.c b/object.c new file mode 100644 index 0000000000..247d021031 --- /dev/null +++ b/object.c @@ -0,0 +1,284 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "object.h" + +/* {{{ proto long git_object_lookup(resource $repo, string $id, long $type) + */ +PHP_FUNCTION(git_object_lookup) +{ + int result = 0, id_len = 0; + git_object *object = NULL; + zval *repo = NULL; + php_git2_t *_repo = NULL; + char *id = NULL; + git_oid __id = {0}; + long type = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsl", &repo, &id, &id_len, &type) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__id, id, id_len)) { + RETURN_FALSE; + } + result = git_object_lookup(&object, PHP_GIT2_V(_repo, repository), &__id, type); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_object_lookup_prefix(resource $repo, string $id, long $len, long $type) + */ +PHP_FUNCTION(git_object_lookup_prefix) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_object *object_out = NULL; + zval *repo = NULL; + char *id = NULL; + int id_len = 0, error = 0; + git_oid __id = {0}; + long len = 0, type = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsll", &repo, &id, &id_len, &len, &type) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__id, id, id_len)) { + RETURN_FALSE; + } + error = git_object_lookup_prefix(&object_out, PHP_GIT2_V(_repo, repository), &__id, len, type); + if (php_git2_check_error(error, "git_object_lookup_prefix" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_OBJECT, object_out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_object_lookup_bypath(resource $treeish, string $path, long $type) + */ +PHP_FUNCTION(git_object_lookup_bypath) +{ + php_git2_t *result = NULL, *_treeish = NULL; + git_object *out = NULL; + zval *treeish = NULL; + char *path = NULL; + int path_len = 0, error = 0; + long type = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsl", &treeish, &path, &path_len, &type) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_treeish, php_git2_t*, &treeish, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_object_lookup_bypath(&out, PHP_GIT2_V(_treeish, object), path, type); + if (php_git2_check_error(error, "git_object_lookup_bypath" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_OBJECT, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_object_id(obj) +*/ +PHP_FUNCTION(git_object_id) +{ + zval *obj; + php_git2_t *_obj; + const git_oid *id; + char buf[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &obj) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_obj, php_git2_t*, &obj, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + id = git_object_id(PHP_GIT2_V(_obj, object)); + git_oid_fmt(buf, id); + RETURN_STRING(buf, 1); +} +/* }}} */ + +/* {{{ proto resource git_object_type(resource $obj) + */ +PHP_FUNCTION(git_object_type) +{ + git_otype result; + zval *obj = NULL; + php_git2_t *_obj = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &obj) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_obj, php_git2_t*, &obj, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_object_type(PHP_GIT2_V(_obj, object)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_object_owner(resource $obj) + */ +PHP_FUNCTION(git_object_owner) +{ + git_repository *result = NULL; + zval *obj = NULL; + php_git2_t *_obj = NULL, *__result = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &obj) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_obj, php_git2_t*, &obj, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_object_owner(PHP_GIT2_V(_obj, object)); + if (php_git2_make_resource(&__result, PHP_GIT2_TYPE_OBJECT, result, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(__result)); +} +/* }}} */ + +/* {{{ proto void git_object_free(resource $object) + */ +PHP_FUNCTION(git_object_free) +{ + zval *object = NULL; + php_git2_t *_object = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &object) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_object, php_git2_t*, &object, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_object)) { + git_object_free(PHP_GIT2_V(_object, object)); + GIT2_SHOULD_FREE(_object) = 0; + }; + zval_ptr_dtor(&object); +} +/* }}} */ + +/* {{{ proto string git_object_type2string(long $type) + */ +PHP_FUNCTION(git_object_type2string) +{ + const char *result = NULL; + long type = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "l", &type) == FAILURE) { + return; + } + + result = git_object_type2string(type); + RETURN_STRING(result, 1); +} +/* }}} */ + +/* {{{ proto resource git_object_string2type(str) +*/ +PHP_FUNCTION(git_object_string2type) +{ + char *str = {0}; + int str_len; + git_otype type; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "s", &str, &str_len) == FAILURE) { + return; + } + type = git_object_string2type(str); + RETURN_LONG(type); +} +/* }}} */ + +/* {{{ proto long git_object_typeisloose(long $type) + */ +PHP_FUNCTION(git_object_typeisloose) +{ + int result = 0; + long type = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "l", &type) == FAILURE) { + return; + } + + result = git_object_typeisloose(type); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_object__size(type) +*/ +PHP_FUNCTION(git_object__size) +{ + long type; + size_t size; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "l", &type) == FAILURE) { + return; + } + size = git_object__size(type); + RETURN_LONG(size); +} + +/* {{{ proto long git_object_peel(resource $object, long $target_type) + */ +PHP_FUNCTION(git_object_peel) +{ + int result = 0; + git_object *peeled = NULL; + zval *object = NULL; + php_git2_t *_object = NULL, *_result; + long target_type = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &object, &target_type) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_object, php_git2_t*, &object, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_object_peel(&peeled, PHP_GIT2_V(_object, object), target_type); + if (php_git2_make_resource(&_result, PHP_GIT2_TYPE_OBJECT, peeled, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(_result)); +} +/* }}} */ + +/* {{{ proto long git_object_dup(resource $source) + */ +PHP_FUNCTION(git_object_dup) +{ + int result = 0; + git_object *dest = NULL; + zval *source = NULL; + php_git2_t *_source = NULL, *_result = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &source) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_source, php_git2_t*, &source, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_object_dup(&dest, PHP_GIT2_V(_source, object)); + if (php_git2_make_resource(&_result, PHP_GIT2_TYPE_OBJECT, dest, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(_result)); +} +/* }}} */ diff --git a/object.h b/object.h new file mode 100644 index 0000000000..dc414ef3d1 --- /dev/null +++ b/object.h @@ -0,0 +1,141 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_OBJECT_H +#define PHP_GIT2_OBJECT_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_object_lookup, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, id) + ZEND_ARG_INFO(0, type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_object_lookup_prefix, 0, 0, 4) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, id) + ZEND_ARG_INFO(0, len) + ZEND_ARG_INFO(0, type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_object_lookup_bypath, 0, 0, 3) + ZEND_ARG_INFO(0, treeish) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_object_id, 0, 0, 1) + ZEND_ARG_INFO(0, obj) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_object_type, 0, 0, 1) + ZEND_ARG_INFO(0, obj) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_object_owner, 0, 0, 1) + ZEND_ARG_INFO(0, obj) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_object_free, 0, 0, 1) + ZEND_ARG_INFO(0, object) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_object_type2string, 0, 0, 1) + ZEND_ARG_INFO(0, type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_object_string2type, 0, 0, 1) + ZEND_ARG_INFO(0, str) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_object_typeisloose, 0, 0, 1) + ZEND_ARG_INFO(0, type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_object__size, 0, 0, 1) + ZEND_ARG_INFO(0, type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_object_peel, 0, 0, 2) + ZEND_ARG_INFO(0, object) + ZEND_ARG_INFO(0, target_type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_object_dup, 0, 0, 1) + ZEND_ARG_INFO(0, source) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_object_lookup(repo, id, type) +*/ +PHP_FUNCTION(git_object_lookup); + +/* {{{ proto resource git_object_lookup_prefix(repo, id, len, type) +*/ +PHP_FUNCTION(git_object_lookup_prefix); + +/* {{{ proto resource git_object_lookup_bypath(treeish, path, type) +*/ +PHP_FUNCTION(git_object_lookup_bypath); + +/* {{{ proto resource git_object_id(obj) +*/ +PHP_FUNCTION(git_object_id); + +/* {{{ proto resource git_object_type(obj) +*/ +PHP_FUNCTION(git_object_type); + +/* {{{ proto resource git_object_owner(obj) +*/ +PHP_FUNCTION(git_object_owner); + +/* {{{ proto void git_object_free(object) +*/ +PHP_FUNCTION(git_object_free); + +/* {{{ proto resource git_object_type2string(type) +*/ +PHP_FUNCTION(git_object_type2string); + +/* {{{ proto resource git_object_string2type(str) +*/ +PHP_FUNCTION(git_object_string2type); + +/* {{{ proto long git_object_typeisloose(type) +*/ +PHP_FUNCTION(git_object_typeisloose); + +/* {{{ proto resource git_object__size(type) +*/ +PHP_FUNCTION(git_object__size); + +/* {{{ proto resource git_object_peel(object, target_type) +*/ +PHP_FUNCTION(git_object_peel); + +/* {{{ proto resource git_object_dup(source) +*/ +PHP_FUNCTION(git_object_dup); + +#endif \ No newline at end of file diff --git a/odb.c b/odb.c new file mode 100644 index 0000000000..75be76cf12 --- /dev/null +++ b/odb.c @@ -0,0 +1,1109 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "odb.h" + +static int php_git2_git_odb_foreach_cb(const git_oid *id, void *payload) +{ + zval *param_oid, *retval_ptr = NULL; + php_git2_cb_t *p = (php_git2_cb_t*)payload; + long retval = 0; + char buf[41] = {0}; + GIT2_TSRMLS_SET(p->tsrm_ls) + + Z_ADDREF_P(p->payload); + MAKE_STD_ZVAL(param_oid); + + git_oid_fmt(buf, id); + ZVAL_STRING(param_oid, buf, 1); + + if (php_git2_call_function_v(p->fci, p->fcc TSRMLS_CC, &retval_ptr, 2, ¶m_oid, &p->payload)) { + return GIT_EUSER; + } + + retval = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + return retval; +} + +/* {{{ proto resource git_odb_new() + */ +PHP_FUNCTION(git_odb_new) +{ + php_git2_t *result = NULL; + git_odb *out = NULL; + int error = 0; + + error = git_odb_new(&out); + if (php_git2_check_error(error, "git_odb_new" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_ODB, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_odb_open(string $objects_dir) + */ +PHP_FUNCTION(git_odb_open) +{ + php_git2_t *result = NULL; + git_odb *out = NULL; + char *objects_dir = NULL; + int objects_dir_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "s", &objects_dir, &objects_dir_len) == FAILURE) { + return; + } + + error = git_odb_open(&out, objects_dir); + if (php_git2_check_error(error, "git_odb_open" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_ODB, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto long git_odb_add_disk_alternate(resource $odb, string $path) + */ +PHP_FUNCTION(git_odb_add_disk_alternate) +{ + int result = 0, path_len = 0; + zval *odb = NULL; + php_git2_t *_odb = NULL; + char *path = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &odb, &path, &path_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_odb, php_git2_t*, &odb, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_odb_add_disk_alternate(PHP_GIT2_V(_odb, odb), path); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto void git_odb_free(resource $db) + */ +PHP_FUNCTION(git_odb_free) +{ + zval *db = NULL; + php_git2_t *_db = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &db) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_db, php_git2_t*, &db, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_db)) { + git_odb_free(PHP_GIT2_V(_db, odb)); + GIT2_SHOULD_FREE(_db) = 0; + }; + zval_ptr_dtor(&db); +} +/* }}} */ + +/* {{{ proto resource git_odb_read(resource $db, string $id) + */ +PHP_FUNCTION(git_odb_read) +{ + php_git2_t *result = NULL, *_db = NULL; + git_odb_object *out = NULL; + zval *db = NULL; + char *id = NULL; + int id_len = 0, error = 0; + git_oid __id = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &db, &id, &id_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_db, php_git2_t*, &db, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__id, id, id_len)) { + RETURN_FALSE; + } + error = git_odb_read(&out, PHP_GIT2_V(_db, odb),&__id); + if (php_git2_check_error(error, "git_odb_read" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_ODB_OBJECT, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_odb_read_prefix(resource $db, string $short_id) + */ +PHP_FUNCTION(git_odb_read_prefix) +{ + php_git2_t *result = NULL, *_db = NULL; + git_odb_object *out = NULL; + zval *db = NULL; + char *short_id = NULL; + int short_id_len = 0, error = 0; + git_oid __short_id = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &db, &short_id, &short_id_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_db, php_git2_t*, &db, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__short_id, short_id, short_id_len)) { + RETURN_FALSE; + } + error = git_odb_read_prefix(&out, PHP_GIT2_V(_db, odb), &__short_id, short_id_len); + if (php_git2_check_error(error, "git_odb_read_prefix" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_ODB_OBJECT, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_odb_read_header( $type_out, resource $db, string $id) + */ +PHP_FUNCTION(git_odb_read_header) +{ + php_git2_t *_db = NULL; + size_t len_out = NULL; + zval *db = NULL, *_result = NULL; + git_otype type_out; + char *id = NULL; + int id_len = 0, error = 0; + git_oid __id = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &db, &id, &id_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_db, php_git2_t*, &db, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__id, id, id_len)) { + RETURN_FALSE; + } + error = git_odb_read_header(&len_out, &type_out, PHP_GIT2_V(_db, odb), &__id); + if (php_git2_check_error(error, "git_odb_read_header" TSRMLS_CC)) { + RETURN_FALSE; + } + MAKE_STD_ZVAL(_result); + array_init(_result); + add_next_index_long(_result, len_out); + add_next_index_long(_result, type_out); + RETURN_ZVAL(_result, 0, 1); +} +/* }}} */ + +/* {{{ proto long git_odb_exists(resource $db, string $id) + */ +PHP_FUNCTION(git_odb_exists) +{ + int result = 0, id_len = 0; + zval *db = NULL; + php_git2_t *_db = NULL; + char *id = NULL; + git_oid __id = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &db, &id, &id_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_db, php_git2_t*, &db, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__id, id, id_len)) { + RETURN_FALSE; + } + result = git_odb_exists(PHP_GIT2_V(_db, odb), &__id); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_odb_refresh(resource $db) + */ +PHP_FUNCTION(git_odb_refresh) +{ + int result = 0; + zval *db = NULL; + php_git2_t *_db = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &db) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_db, php_git2_t*, &db, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_odb_refresh(PHP_GIT2_V(_db, odb)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_odb_foreach(resource $db, Callable $cb, $payload) + */ +PHP_FUNCTION(git_odb_foreach) +{ + int result = 0; + zval *db = NULL, *payload = NULL; + php_git2_t *_db = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rfz", &db, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_db, php_git2_t*, &db, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_odb_foreach(PHP_GIT2_V(_db, odb), php_git2_git_odb_foreach_cb, cb); + php_git2_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_odb_write(resource $odb, $data, $type) + */ +PHP_FUNCTION(git_odb_write) +{ + php_git2_t *_odb = NULL; + git_oid out = {0}; + zval *odb = NULL; + zval *data = NULL; + long type = 0; + int error = 0, data_len = 0; + char buf[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsl", &odb, &data, &data_len, &type) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_odb, php_git2_t*, &odb, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_odb_write(&out, PHP_GIT2_V(_odb, odb), data, data_len, type); + if (php_git2_check_error(error, "git_odb_write" TSRMLS_CC)) { + RETURN_FALSE; + } + git_oid_fmt(buf, &out); + RETURN_STRING(buf, 1); +} +/* }}} */ + +/* {{{ proto resource git_odb_open_wstream(resource $db, long $size, $type) + */ +PHP_FUNCTION(git_odb_open_wstream) +{ + php_git2_t *result = NULL, *_db = NULL; + git_odb_stream *out = NULL; + zval *db = NULL; + long size = 0, type = 0; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rll", &db, &size, &type) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_db, php_git2_t*, &db, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_odb_open_wstream(&out, PHP_GIT2_V(_db, odb), size, type); + if (php_git2_check_error(error, "git_odb_open_wstream" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_ODB_STREAM, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto long git_odb_stream_write(resource $stream, string $buffer) + */ +PHP_FUNCTION(git_odb_stream_write) +{ + int result = 0, buffer_len = 0; + zval *stream = NULL; + php_git2_t *_stream = NULL; + char *buffer = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &stream, &buffer, &buffer_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_stream, php_git2_t*, &stream, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_odb_stream_write(PHP_GIT2_V(_stream, odb_stream), buffer, buffer_len); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_odb_stream_finalize_write(resource $stream) + */ +PHP_FUNCTION(git_odb_stream_finalize_write) +{ + php_git2_t *_stream = NULL; + git_oid out = {0}; + zval *stream = NULL; + int error = 0; + char buf[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &stream) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_stream, php_git2_t*, &stream, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_odb_stream_finalize_write(&out, PHP_GIT2_V(_stream, odb_stream)); + if (php_git2_check_error(error, "git_odb_stream_finalize_write" TSRMLS_CC)) { + RETURN_FALSE; + } + git_oid_fmt(buf, &out); + RETURN_STRING(buf, 1); +} +/* }}} */ + +/* {{{ proto long git_odb_stream_read(resource $stream, string $buffer, long $len) + */ +PHP_FUNCTION(git_odb_stream_read) +{ + int result = 0, buffer_len = 0; + zval *stream = NULL; + php_git2_t *_stream = NULL; + char *buffer = NULL; + long len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsl", &stream, &buffer, &buffer_len, &len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_stream, php_git2_t*, &stream, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_odb_stream_read(PHP_GIT2_V(_stream, odb_stream), buffer, len); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto void git_odb_stream_free(resource $stream) + */ +PHP_FUNCTION(git_odb_stream_free) +{ + zval *stream = NULL; + php_git2_t *_stream = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &stream) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_stream, php_git2_t*, &stream, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_stream)) { + git_odb_stream_free(PHP_GIT2_V(_stream, odb_stream)); + GIT2_SHOULD_FREE(_stream) = 0; + }; + zval_ptr_dtor(&stream); +} +/* }}} */ + +/* {{{ proto resource git_odb_open_rstream(resource $db, string $oid) + */ +PHP_FUNCTION(git_odb_open_rstream) +{ + php_git2_t *result = NULL, *_db = NULL; + git_odb_stream *out = NULL; + zval *db = NULL; + char *oid = NULL; + int oid_len = 0, error = 0; + git_oid __oid = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &db, &oid, &oid_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_db, php_git2_t*, &db, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__oid, oid, oid_len)) { + RETURN_FALSE; + } + error = git_odb_open_rstream(&out, PHP_GIT2_V(_db, odb), &__oid); + if (php_git2_check_error(error, "git_odb_open_rstream" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_ODB_STREAM, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_odb_write_pack(resource $db, $progress_cb, $progress_payload) + */ +PHP_FUNCTION(git_odb_write_pack) +{ + php_git2_t *result = NULL, *_db = NULL; + git_odb_writepack *out = NULL; + zval *db = NULL, *progress_cb = NULL, *progress_payload = NULL; + int error = 0; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rz", &db, &progress_cb, &progress_payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_db, php_git2_t*, &db, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_cb_init(&cb, &fci, &fcc, progress_payload TSRMLS_CC)) { + RETURN_FALSE; + } + error = git_odb_write_pack(&out, PHP_GIT2_V(_db, odb), progress_cb, cb); + if (php_git2_check_error(error, "git_odb_write_pack" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_ODB_WRITEPACK, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_odb_hash(string $data, long $type) + */ +PHP_FUNCTION(git_odb_hash) +{ + git_oid out = {0}; + zval *data = NULL; + int error = 0, data_len = 0; + long type = 0; + char buf[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "sl", &data, &data_len, &type) == FAILURE) { + return; + } + error = git_odb_hash(&out, data, data_len, type); + if (php_git2_check_error(error, "git_odb_hash" TSRMLS_CC)) { + RETURN_FALSE; + } + git_oid_fmt(buf, &out); + RETURN_STRING(buf, 1); +} +/* }}} */ + +/* {{{ proto resource git_odb_hashfile(string $path, $type) + */ +PHP_FUNCTION(git_odb_hashfile) +{ + git_oid out = {0}; + char *path = NULL; + int path_len = 0, error = 0; + char buf[GIT2_OID_HEXSIZE] = {0}; + long type = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "sl", &path, &path_len, &type) == FAILURE) { + return; + } + error = git_odb_hashfile(&out, path, type); + if (php_git2_check_error(error, "git_odb_hashfile" TSRMLS_CC)) { + RETURN_FALSE; + } + git_oid_fmt(buf, &out); + RETURN_STRING(buf, 1); +} +/* }}} */ + +/* {{{ proto long git_odb_object_dup(resource $source) + */ +PHP_FUNCTION(git_odb_object_dup) +{ + int result = 0; + git_odb_object *dest = NULL; + zval *source = NULL; + php_git2_t *_source = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &source) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_source, php_git2_t*, &source, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_odb_object_dup(&dest, PHP_GIT2_V(_source, odb_object)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto void git_odb_object_free(resource $object) + */ +PHP_FUNCTION(git_odb_object_free) +{ + zval *object = NULL; + php_git2_t *_object = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &object) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_object, php_git2_t*, &object, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_object)) { + git_odb_object_free(PHP_GIT2_V(_object, odb_object)); + GIT2_SHOULD_FREE(_object) = 0; + }; + zval_ptr_dtor(&object); +} +/* }}} */ + +/* {{{ proto resource git_odb_object_id(resource $object) + */ +PHP_FUNCTION(git_odb_object_id) +{ + const git_oid *result = NULL; + zval *object = NULL; + php_git2_t *_object = NULL; + char __result[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &object) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_object, php_git2_t*, &object, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_odb_object_id(PHP_GIT2_V(_object, odb_object)); + git_oid_fmt(__result, result); + RETURN_STRING(__result, 1); +} +/* }}} */ + +/* {{{ proto void git_odb_object_data(resource $object) + */ +PHP_FUNCTION(git_odb_object_data) +{ + zval *object = NULL; + php_git2_t *_object = NULL; + const char *buffer; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &object) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_object, php_git2_t*, &object, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + buffer = git_odb_object_data(PHP_GIT2_V(_object, odb_object)); + RETURN_STRINGL(buffer, git_odb_object_size(PHP_GIT2_V(_object, odb_object)), 1); +} +/* }}} */ + +/* {{{ proto long git_odb_object_size(resource $object) + */ +PHP_FUNCTION(git_odb_object_size) +{ + size_t result = 0; + zval *object = NULL; + php_git2_t *_object = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &object) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_object, php_git2_t*, &object, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_odb_object_size(PHP_GIT2_V(_object, odb_object)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_odb_object_type(resource $object) + */ +PHP_FUNCTION(git_odb_object_type) +{ + git_otype result; + zval *object = NULL; + php_git2_t *_object = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &object) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_object, php_git2_t*, &object, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_odb_object_type(PHP_GIT2_V(_object, odb_object)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_odb_add_backend(resource $odb, resource $backend, long $priority) + */ +PHP_FUNCTION(git_odb_add_backend) +{ + int result = 0; + zval *odb = NULL, *backend = NULL; + php_git2_t *_odb = NULL, *_backend = NULL; + long priority = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rrl", &odb, &backend, &priority) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_odb, php_git2_t*, &odb, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_backend, php_git2_t*, &backend, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_odb_add_backend(PHP_GIT2_V(_odb, odb), PHP_GIT2_V(_backend, odb_backend), priority); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_odb_add_alternate(resource $odb, resource $backend, long $priority) + */ +PHP_FUNCTION(git_odb_add_alternate) +{ + int result = 0; + zval *odb = NULL, *backend = NULL; + php_git2_t *_odb = NULL, *_backend = NULL; + long priority = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rrl", &odb, &backend, &priority) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_odb, php_git2_t*, &odb, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_backend, php_git2_t*, &backend, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_odb_add_alternate(PHP_GIT2_V(_odb, odb), PHP_GIT2_V(_backend, odb_backend), priority); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_odb_num_backends(resource $odb) + */ +PHP_FUNCTION(git_odb_num_backends) +{ + size_t result = 0; + zval *odb = NULL; + php_git2_t *_odb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &odb) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_odb, php_git2_t*, &odb, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_odb_num_backends(PHP_GIT2_V(_odb, odb)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_odb_get_backend(resource $odb, long $pos) + */ +PHP_FUNCTION(git_odb_get_backend) +{ + php_git2_t *result = NULL, *_odb = NULL; + git_odb_backend *out = NULL; + zval *odb = NULL; + long pos = 0; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &odb, &pos) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_odb, php_git2_t*, &odb, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_odb_get_backend(&out, PHP_GIT2_V(_odb, odb), pos); + if (php_git2_check_error(error, "git_odb_get_backend" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_ODB_BACKEND, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +static int php_git2_odb_backend_read(void **buffer, size_t *size, git_otype *type, git_odb_backend *backend, const git_oid *oid) +{ + php_git2_odb_backend *php_backend = (php_git2_odb_backend*)backend; + zval *param_oid = NULL, *retval_ptr = NULL; + php_git2_multi_cb_t *p = php_backend->multi; + int retval = 0; + GIT2_TSRMLS_SET(p->tsrm_ls); + char buf[41] = {0}; + + git_oid_fmt(buf, oid); + MAKE_STD_ZVAL(param_oid); + ZVAL_STRING(param_oid, buf, 1); + + if (php_git2_call_function_v(&p->callbacks[0].fci, &p->callbacks[0].fcc TSRMLS_CC, &retval_ptr, 1, ¶m_oid)) { + return GIT_EUSER; + } + if (Z_TYPE_P(retval_ptr) == IS_ARRAY) { + zval **value, **otype; + char *pp; + + if (zend_hash_num_elements(Z_ARRVAL_P(retval_ptr)) != 2) { + return GIT_ENOTFOUND; + } + + zend_hash_get_current_data(Z_ARRVAL_P(retval_ptr), (void **)&value); + pp = git_odb_backend_malloc(backend, Z_STRLEN_PP(value)); + memset(pp, '\0', Z_STRLEN_PP(value)); + memcpy(pp, Z_STRVAL_PP(value), Z_STRLEN_PP(value)); + + *buffer = pp; + *size = Z_STRLEN_PP(value); + + zend_hash_move_forward(Z_ARRVAL_P(retval_ptr)); + zend_hash_get_current_data(Z_ARRVAL_P(retval_ptr), (void **)&otype); + *type = Z_LVAL_PP(otype); + } else { + retval = GIT_ENOTFOUND; + } + + zval_ptr_dtor(&retval_ptr); + return retval; +} +static int php_git2_odb_backend_write(git_odb_backend *backend, const git_oid *oid, const void *buffer, size_t size, git_otype type) +{ + php_git2_odb_backend *php_backend = (php_git2_odb_backend*)backend; + zval *param_oid = NULL, *param_buffer = NULL, *param_otype = NULL, *retval_ptr = NULL; + php_git2_multi_cb_t *p = php_backend->multi; + int retval = 0; + GIT2_TSRMLS_SET(p->tsrm_ls); + char buf[41] = {0}; + + git_oid_fmt(buf, oid); + MAKE_STD_ZVAL(param_oid); + MAKE_STD_ZVAL(param_buffer); + MAKE_STD_ZVAL(param_otype); + + ZVAL_STRING(param_oid, buf, 1); + ZVAL_STRINGL(param_buffer, buffer, size, 1); + ZVAL_LONG(param_otype, type); + + if (php_git2_call_function_v(&p->callbacks[1].fci, &p->callbacks[1].fcc TSRMLS_CC, &retval_ptr, 3, + ¶m_oid, ¶m_buffer, ¶m_otype)) { + return GIT_EUSER; + } + + retval = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + return retval; +} +static int php_git2_odb_backend_read_prefix(git_oid *out_oid, + void **buffer_p, + size_t *len_p, + git_otype *type_p, + git_odb_backend *backend, + const git_oid *short_oid, + size_t len) +{ + php_git2_odb_backend *php_backend = (php_git2_odb_backend*)backend; + zval *param_short_oid = NULL, *retval_ptr = NULL; + php_git2_multi_cb_t *p = php_backend->multi; + int retval = 0; + GIT2_TSRMLS_SET(p->tsrm_ls); + char buf[41] = {0}; + + git_oid_nfmt(buf, len, short_oid); + MAKE_STD_ZVAL(param_short_oid); + ZVAL_STRING(param_short_oid, buf, 1); + + if (php_git2_call_function_v(&p->callbacks[2].fci, &p->callbacks[2].fcc TSRMLS_CC, &retval_ptr, 1, ¶m_short_oid)) { + return GIT_EUSER; + } + + if (Z_TYPE_P(retval_ptr) == IS_ARRAY) { + zval **value, **otype, **_oid; + char *pp; + + if (zend_hash_num_elements(Z_ARRVAL_P(retval_ptr)) != 3) { + return GIT_ENOTFOUND; + } + + zend_hash_get_current_data(Z_ARRVAL_P(retval_ptr), (void **)&value); + pp = git_odb_backend_malloc(backend, Z_STRLEN_PP(value)); + memset(pp, '\0', Z_STRLEN_PP(value)); + memcpy(pp, Z_STRVAL_PP(value), Z_STRLEN_PP(value)); + + *buffer_p = pp; + *len_p = Z_STRLEN_PP(value); + + zend_hash_move_forward(Z_ARRVAL_P(retval_ptr)); + zend_hash_get_current_data(Z_ARRVAL_P(retval_ptr), (void **)&otype); + *type_p = Z_LVAL_PP(otype); + + zend_hash_move_forward(Z_ARRVAL_P(retval_ptr)); + zend_hash_get_current_data(Z_ARRVAL_P(retval_ptr), (void **)&_oid); + if (git_oid_fromstrn(out_oid, Z_STRVAL_PP(_oid), Z_STRLEN_PP(_oid)) != GIT_OK) { + return GIT_EUSER; + } + } else { + retval = GIT_ENOTFOUND; + } + + zval_ptr_dtor(&retval_ptr); + return retval; +} + +static int php_git2_odb_backend_read_header(size_t *len_p, git_otype *type_p, git_odb_backend *backend, const git_oid *oid) +{ + php_git2_odb_backend *php_backend = (php_git2_odb_backend*)backend; + zval *param_oid = NULL, *retval_ptr = NULL; + php_git2_multi_cb_t *p = php_backend->multi; + int retval = 0; + GIT2_TSRMLS_SET(p->tsrm_ls); + char buf[41] = {0}; + + git_oid_fmt(buf, oid); + MAKE_STD_ZVAL(param_oid); + ZVAL_STRING(param_oid, buf, 1); + + if (php_git2_call_function_v(&p->callbacks[3].fci, &p->callbacks[3].fcc TSRMLS_CC, &retval_ptr, 1, ¶m_oid)) { + return GIT_EUSER; + } + if (Z_TYPE_P(retval_ptr) == IS_ARRAY) { + zval **value, **otype; + + if (zend_hash_num_elements(Z_ARRVAL_P(retval_ptr)) != 2) { + return GIT_ENOTFOUND; + } + + zend_hash_get_current_data(Z_ARRVAL_P(retval_ptr), (void **)&value); + *len_p = Z_LVAL_PP(value); + zend_hash_move_forward(Z_ARRVAL_P(retval_ptr)); + zend_hash_get_current_data(Z_ARRVAL_P(retval_ptr), (void **)&otype); + *type_p = Z_LVAL_PP(otype); + } else { + retval = GIT_ENOTFOUND; + } + + zval_ptr_dtor(&retval_ptr); + return retval; +} +static int php_git2_odb_backend_writestream(git_odb_stream **stream_out, git_odb_backend *_backend, size_t length, git_otype type) +{ + fprintf(stderr, "WRITES"); +} +static int php_git2_odb_backend_exists(git_odb_backend *backend, const git_oid *oid) +{ + php_git2_odb_backend *php_backend = (php_git2_odb_backend*)backend; + zval *param_oid = NULL, *retval_ptr = NULL; + php_git2_multi_cb_t *p = php_backend->multi; + int retval = 0; + GIT2_TSRMLS_SET(p->tsrm_ls); + char buf[41] = {0}; + + git_oid_fmt(buf, oid); + MAKE_STD_ZVAL(param_oid); + ZVAL_STRING(param_oid, buf, 1); + + if (php_git2_call_function_v(&p->callbacks[5].fci, &p->callbacks[5].fcc TSRMLS_CC, &retval_ptr, 1, + ¶m_oid)) { + return GIT_EUSER; + } + + retval = Z_LVAL_P(retval_ptr); + if (retval == 1) { + retval = 0; + } else { + retval = GIT_ENOTFOUND; + } + zval_ptr_dtor(&retval_ptr); + return !retval; +} + +static const zend_arg_info arginfo_git_odb_backend_foreach_callback[] = { + ZEND_ARG_INFO(0, oid) + ZEND_ARG_INFO(1, payload) +}; + +static void git_ex_cb(INTERNAL_FUNCTION_PARAMETERS) +{ + zval *payload, *this = getThis(); + php_git2_odb_backend_foreach_callback *_callback; + char *oid; + int oid_len, retval = 0; + git_oid _oid; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "sz", &oid, &oid_len, &payload) == FAILURE) { + return; + } + + if (git_oid_fromstrn(&_oid, oid, oid_len) != GIT_OK) { + return; + } + + _callback = (php_git2_odb_backend_foreach_callback*)zend_object_store_get_object(this TSRMLS_CC); + _callback->payload->payload = payload; + retval = _callback->callback(&_oid, _callback->payload); + RETURN_LONG(retval); +} + +static int php_git2_odb_backend_foreach(git_odb_backend *backend, git_odb_foreach_cb cb, void *data) +{ + php_git2_odb_backend *php_backend = (php_git2_odb_backend*)backend; + zval *param_callback = NULL, *callback = NULL, *retval_ptr = NULL; + php_git2_multi_cb_t *p = php_backend->multi; + zend_function function = {0}; + php_git2_odb_backend_foreach_callback *_callback; + php_git2_cb_t *__cb = (php_git2_cb_t*)data; + int retval = 0; + GIT2_TSRMLS_SET(p->tsrm_ls); + + MAKE_STD_ZVAL(callback); + object_init_ex(callback, php_git2_odb_backend_foreach_callback_class_entry); + _callback = (php_git2_odb_backend_foreach_callback*)zend_object_store_get_object(callback TSRMLS_CC); + _callback->callback = cb; + _callback->payload = __cb; + Z_ADDREF_P(callback); + + function.type = ZEND_INTERNAL_FUNCTION; + function.common.function_name = "callback"; + function.common.fn_flags = ZEND_ACC_CLOSURE; + function.common.num_args = 2; + function.common.required_num_args = 2; + function.common.arg_info = &arginfo_git_odb_backend_foreach_callback; + function.common.scope = php_git2_odb_backend_foreach_callback_class_entry; + function.internal_function.type = ZEND_INTERNAL_FUNCTION; + function.internal_function.scope = php_git2_odb_backend_foreach_callback_class_entry; + function.internal_function.fn_flags = ZEND_ACC_CLOSURE; + function.internal_function.handler = git_ex_cb; + function.internal_function.module = &git2_module_entry; + function.internal_function.num_args = 2; + function.internal_function.required_num_args = 2; + function.internal_function.arg_info = &arginfo_git_odb_backend_foreach_callback; + + MAKE_STD_ZVAL(param_callback); + zend_create_closure(param_callback, &function, php_git2_odb_backend_foreach_callback_class_entry, callback TSRMLS_CC); + Z_ADDREF_P(__cb->payload); + + if (php_git2_call_function_v(&p->callbacks[6].fci, &p->callbacks[6].fcc TSRMLS_CC, &retval_ptr, 2, + ¶m_callback, &__cb->payload)) { + return GIT_EUSER; + } + + retval = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + return retval; +} + +static void php_git2_odb_backend_free(git_odb_backend *_backend) +{ + php_git2_odb_backend *php_backend = (php_git2_odb_backend*)_backend; + zval *retval_ptr = NULL; + php_git2_multi_cb_t *p = php_backend->multi; + GIT2_TSRMLS_SET(p->tsrm_ls); + if (php_git2_call_function_v(&p->callbacks[7].fci, &p->callbacks[7].fcc TSRMLS_CC, &retval_ptr, 0)) { + return; + } + + zval_ptr_dtor(&retval_ptr); + return; +} + +static void php_git2_odb_refresh(git_odb_backend *_backend) +{ + php_git2_odb_backend *php_backend = (php_git2_odb_backend*)_backend; + zval *retval_ptr = NULL; + php_git2_multi_cb_t *p = php_backend->multi; + GIT2_TSRMLS_SET(p->tsrm_ls); + if (php_git2_call_function_v(&p->callbacks[8].fci, &p->callbacks[8].fcc TSRMLS_CC, &retval_ptr, 0)) { + return; + } + + zval_ptr_dtor(&retval_ptr); + return; +} +PHP_FUNCTION(git_odb_backend_new) +{ + php_git2_odb_backend *backend; + php_git2_t *result; + zval *callbacks, *tmp; + zend_fcall_info read_fci, write_fci, read_prefix_fci, read_header_fci, writestream_fci, + exists_fci, foreach_fci, free_fci, refresh_fci; + zend_fcall_info_cache read_fcc, write_fcc, read_prefix_fcc, read_header_fcc, writestream_fcc, + exists_fcc, foreach_fcc, free_fcc, refresh_fcc; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "a", &callbacks) == FAILURE) { + return; + } + + backend = ecalloc(1, sizeof(php_git2_odb_backend)); + + backend->parent.version = GIT_ODB_BACKEND_VERSION; + backend->parent.read = &php_git2_odb_backend_read; + backend->parent.write = &php_git2_odb_backend_write; + backend->parent.read_prefix = &php_git2_odb_backend_read_prefix; + backend->parent.read_header = &php_git2_odb_backend_read_header; + //backend->parent.writestream = &php_git2_odb_backend_writestream; + backend->parent.exists = &php_git2_odb_backend_exists; + backend->parent.foreach = &php_git2_odb_backend_foreach; + backend->parent.free = &php_git2_odb_backend_free; + backend->parent.refresh = &php_git2_odb_refresh; + + tmp = php_git2_read_arrval(callbacks, ZEND_STRS("read") TSRMLS_CC); + if (tmp) { + php_git2_fcall_info_wrapper2(tmp, &read_fci, &read_fcc TSRMLS_CC); + } + tmp = php_git2_read_arrval(callbacks, ZEND_STRS("write") TSRMLS_CC); + if (tmp) { + php_git2_fcall_info_wrapper2(tmp, &write_fci, &write_fcc TSRMLS_CC); + } + + tmp = php_git2_read_arrval(callbacks, ZEND_STRS("read_header") TSRMLS_CC); + if (tmp) { + php_git2_fcall_info_wrapper2(tmp, &read_header_fci, &read_header_fcc TSRMLS_CC); + } + tmp = php_git2_read_arrval(callbacks, ZEND_STRS("read_prefix") TSRMLS_CC); + if (tmp) { + php_git2_fcall_info_wrapper2(tmp, &read_prefix_fci, &read_prefix_fcc TSRMLS_CC); + } + tmp = php_git2_read_arrval(callbacks, ZEND_STRS("exists") TSRMLS_CC); + if (tmp) { + php_git2_fcall_info_wrapper2(tmp, &exists_fci, &exists_fcc TSRMLS_CC); + } + tmp = php_git2_read_arrval(callbacks, ZEND_STRS("foreach") TSRMLS_CC); + if (tmp) { + php_git2_fcall_info_wrapper2(tmp, &foreach_fci, &foreach_fcc TSRMLS_CC); + } + tmp = php_git2_read_arrval(callbacks, ZEND_STRS("free") TSRMLS_CC); + if (tmp) { + php_git2_fcall_info_wrapper2(tmp, &free_fci, &free_fcc TSRMLS_CC); + } + tmp = php_git2_read_arrval(callbacks, ZEND_STRS("refresh") TSRMLS_CC); + if (tmp) { + php_git2_fcall_info_wrapper2(tmp, &refresh_fci, &refresh_fcc TSRMLS_CC); + } + + Z_ADDREF_P(callbacks); + php_git2_multi_cb_init(&backend->multi, callbacks TSRMLS_CC, 9, + &read_fci, &read_fcc, + &write_fci, &write_fcc, + &read_prefix_fci, &read_prefix_fcc, + &read_header_fci, &read_header_fcc, + &writestream_fci, &writestream_fcc, + &exists_fci, &exists_fcc, + &foreach_fci, &foreach_fcc, + &free_fci, &free_fcc, + &refresh_fci, &refresh_fcc + ); + + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_ODB_BACKEND, backend, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} diff --git a/odb.h b/odb.h new file mode 100644 index 0000000000..0adbe34029 --- /dev/null +++ b/odb.h @@ -0,0 +1,302 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_ODB_H +#define PHP_GIT2_ODB_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_new, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_open, 0, 0, 1) + ZEND_ARG_INFO(0, objects_dir) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_add_disk_alternate, 0, 0, 2) + ZEND_ARG_INFO(0, odb) + ZEND_ARG_INFO(0, path) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_free, 0, 0, 1) + ZEND_ARG_INFO(0, db) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_read, 0, 0, 2) + ZEND_ARG_INFO(0, db) + ZEND_ARG_INFO(0, id) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_read_prefix, 0, 0, 3) + ZEND_ARG_INFO(0, db) + ZEND_ARG_INFO(0, short_id) + ZEND_ARG_INFO(0, len) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_read_header, 0, 0, 3) + ZEND_ARG_INFO(0, type_out) + ZEND_ARG_INFO(0, db) + ZEND_ARG_INFO(0, id) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_exists, 0, 0, 2) + ZEND_ARG_INFO(0, db) + ZEND_ARG_INFO(0, id) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_refresh, 0, 0, 1) + ZEND_ARG_INFO(0, db) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_foreach, 0, 0, 3) + ZEND_ARG_INFO(0, db) + ZEND_ARG_INFO(0, cb) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_write, 0, 0, 4) + ZEND_ARG_INFO(0, odb) + ZEND_ARG_INFO(0, data) + ZEND_ARG_INFO(0, len) + ZEND_ARG_INFO(0, type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_open_wstream, 0, 0, 3) + ZEND_ARG_INFO(0, db) + ZEND_ARG_INFO(0, size) + ZEND_ARG_INFO(0, type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_stream_write, 0, 0, 2) + ZEND_ARG_INFO(0, buffer) + ZEND_ARG_INFO(0, len) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_stream_finalize_write, 0, 0, 1) + ZEND_ARG_INFO(0, stream) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_stream_read, 0, 0, 3) + ZEND_ARG_INFO(0, stream) + ZEND_ARG_INFO(0, buffer) + ZEND_ARG_INFO(0, len) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_stream_free, 0, 0, 1) + ZEND_ARG_INFO(0, stream) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_open_rstream, 0, 0, 2) + ZEND_ARG_INFO(0, db) + ZEND_ARG_INFO(0, oid) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_write_pack, 0, 0, 3) + ZEND_ARG_INFO(0, db) + ZEND_ARG_INFO(0, progress_cb) + ZEND_ARG_INFO(0, progress_payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_hash, 0, 0, 3) + ZEND_ARG_INFO(0, data) + ZEND_ARG_INFO(0, len) + ZEND_ARG_INFO(0, type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_hashfile, 0, 0, 2) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_object_dup, 0, 0, 1) + ZEND_ARG_INFO(0, source) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_object_free, 0, 0, 1) + ZEND_ARG_INFO(0, object) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_object_id, 0, 0, 1) + ZEND_ARG_INFO(0, object) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_object_data, 0, 0, 1) + ZEND_ARG_INFO(0, object) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_object_size, 0, 0, 1) + ZEND_ARG_INFO(0, object) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_object_type, 0, 0, 1) + ZEND_ARG_INFO(0, object) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_add_backend, 0, 0, 3) + ZEND_ARG_INFO(0, odb) + ZEND_ARG_INFO(0, backend) + ZEND_ARG_INFO(0, priority) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_add_alternate, 0, 0, 3) + ZEND_ARG_INFO(0, odb) + ZEND_ARG_INFO(0, backend) + ZEND_ARG_INFO(0, priority) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_num_backends, 0, 0, 1) + ZEND_ARG_INFO(0, odb) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_get_backend, 0, 0, 2) + ZEND_ARG_INFO(0, odb) + ZEND_ARG_INFO(0, pos) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_odb_backend_new, 0, 0, 1) + ZEND_ARG_INFO(0, callbacks) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_odb_new() +*/ +PHP_FUNCTION(git_odb_new); + +/* {{{ proto resource git_odb_open(objects_dir) +*/ +PHP_FUNCTION(git_odb_open); + +/* {{{ proto long git_odb_add_disk_alternate(odb, path) +*/ +PHP_FUNCTION(git_odb_add_disk_alternate); + +/* {{{ proto void git_odb_free(db) +*/ +PHP_FUNCTION(git_odb_free); + +/* {{{ proto resource git_odb_read(db, id) +*/ +PHP_FUNCTION(git_odb_read); + +/* {{{ proto resource git_odb_read_prefix(db, short_id, len) +*/ +PHP_FUNCTION(git_odb_read_prefix); + +/* {{{ proto resource git_odb_read_header(type_out, db, id) +*/ +PHP_FUNCTION(git_odb_read_header); + +/* {{{ proto long git_odb_exists(db, id) +*/ +PHP_FUNCTION(git_odb_exists); + +/* {{{ proto long git_odb_refresh(db) +*/ +PHP_FUNCTION(git_odb_refresh); + +/* {{{ proto long git_odb_foreach(db, cb, payload) +*/ +PHP_FUNCTION(git_odb_foreach); + +/* {{{ proto resource git_odb_write(odb, data, len, type) +*/ +PHP_FUNCTION(git_odb_write); + +/* {{{ proto resource git_odb_open_wstream(db, size, type) +*/ +PHP_FUNCTION(git_odb_open_wstream); + +/* {{{ proto resource git_odb_stream_write(buffer, len) +*/ +PHP_FUNCTION(git_odb_stream_write); + +/* {{{ proto resource git_odb_stream_finalize_write(stream) +*/ +PHP_FUNCTION(git_odb_stream_finalize_write); + +/* {{{ proto long git_odb_stream_read(stream, buffer, len) +*/ +PHP_FUNCTION(git_odb_stream_read); + +/* {{{ proto void git_odb_stream_free(stream) +*/ +PHP_FUNCTION(git_odb_stream_free); + +/* {{{ proto resource git_odb_open_rstream(db, oid) +*/ +PHP_FUNCTION(git_odb_open_rstream); + +/* {{{ proto resource git_odb_write_pack(db, progress_cb, progress_payload) +*/ +PHP_FUNCTION(git_odb_write_pack); + +/* {{{ proto resource git_odb_hash(data, len, type) +*/ +PHP_FUNCTION(git_odb_hash); + +/* {{{ proto resource git_odb_hashfile(path, type) +*/ +PHP_FUNCTION(git_odb_hashfile); + +/* {{{ proto resource git_odb_object_dup(source) +*/ +PHP_FUNCTION(git_odb_object_dup); + +/* {{{ proto void git_odb_object_free(object) +*/ +PHP_FUNCTION(git_odb_object_free); + +/* {{{ proto resource git_odb_object_id(object) +*/ +PHP_FUNCTION(git_odb_object_id); + +/* {{{ proto resource git_odb_object_data(object) +*/ +PHP_FUNCTION(git_odb_object_data); + +/* {{{ proto resource git_odb_object_size(object) +*/ +PHP_FUNCTION(git_odb_object_size); + +/* {{{ proto resource git_odb_object_type(object) +*/ +PHP_FUNCTION(git_odb_object_type); + +/* {{{ proto long git_odb_add_backend(odb, backend, priority) +*/ +PHP_FUNCTION(git_odb_add_backend); + +/* {{{ proto long git_odb_add_alternate(odb, backend, priority) +*/ +PHP_FUNCTION(git_odb_add_alternate); + +/* {{{ proto resource git_odb_num_backends(odb) +*/ +PHP_FUNCTION(git_odb_num_backends); + +/* {{{ proto resource git_odb_get_backend(odb, pos) +*/ +PHP_FUNCTION(git_odb_get_backend); + +PHP_FUNCTION(git_odb_backend_new); + +#endif \ No newline at end of file diff --git a/packbuilder.c b/packbuilder.c new file mode 100644 index 0000000000..4fafa08cb3 --- /dev/null +++ b/packbuilder.c @@ -0,0 +1,368 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "packbuilder.h" + +static int php_git2_git_packbuilder_progress( + int stage, + unsigned int current, + unsigned int total, + void *payload) +{ + zval *param_stage = NULL, *param_current = NULL, *param_total = NULL, *retval_ptr = NULL; + php_git2_cb_t *p = (php_git2_cb_t*)payload; + long retval = 0; + GIT2_TSRMLS_SET(p->tsrm_ls) + + Z_ADDREF_P(p->payload); + MAKE_STD_ZVAL(param_stage); + MAKE_STD_ZVAL(param_current); + MAKE_STD_ZVAL(param_total); + ZVAL_LONG(param_stage, stage); + ZVAL_LONG(param_current, current); + ZVAL_LONG(param_total, total); + + if (php_git2_call_function_v(p->fci, p->fcc TSRMLS_CC, &retval_ptr, 4, + ¶m_stage, ¶m_current, ¶m_total, &p->payload)) { + return GIT_EUSER; + } + + if (retval_ptr) { + retval = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + } + return retval; +} + +static int php_git2_git_packbuilder_foreach_cb(void *buf, size_t size, void *payload) +{ + zval *param_buf= NULL, *param_size = NULL, *retval_ptr = NULL; + php_git2_cb_t *p = (php_git2_cb_t*)payload; + long retval = 0; + GIT2_TSRMLS_SET(p->tsrm_ls) + + Z_ADDREF_P(p->payload); + MAKE_STD_ZVAL(param_buf); + MAKE_STD_ZVAL(param_size); + ZVAL_STRINGL(param_buf, buf, size, 1); + ZVAL_LONG(param_size, size); + + if (php_git2_call_function_v(p->fci, p->fcc TSRMLS_CC, &retval_ptr, 3, + ¶m_buf, ¶m_size, &p->payload)) { + return GIT_EUSER; + } + + if (retval_ptr) { + retval = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + } + return retval; +} + + +static int php_git2_git_transfer_progress_callback(const git_transfer_progress *stats, void *payload) +{ + zval *param_stats = NULL, *retval_ptr = NULL; + php_git2_cb_t *p = (php_git2_cb_t*)payload; + long retval = 0; + GIT2_TSRMLS_SET(p->tsrm_ls) + + Z_ADDREF_P(p->payload); + php_git2_git_transfer_progress_to_array(stats, ¶m_stats TSRMLS_CC); + + + if (php_git2_call_function_v(p->fci, p->fcc TSRMLS_CC, &retval_ptr, 2, + ¶m_stats, &p->payload)) { + return GIT_EUSER; + } + + if (retval_ptr) { + retval = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + } + return retval; +} + +/* {{{ proto resource git_packbuilder_new(resource $repo) + */ +PHP_FUNCTION(git_packbuilder_new) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_packbuilder *out = NULL; + zval *repo = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_packbuilder_new(&out, PHP_GIT2_V(_repo, repository)); + if (php_git2_check_error(error, "git_packbuilder_new" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_PACKBUILDER, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto long git_packbuilder_set_threads(resource $pb, long $n) + */ +PHP_FUNCTION(git_packbuilder_set_threads) +{ + unsigned int result = 0; + zval *pb = NULL; + php_git2_t *_pb = NULL; + long n = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &pb, &n) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_pb, php_git2_t*, &pb, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_packbuilder_set_threads(PHP_GIT2_V(_pb, packbuilder), n); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_packbuilder_insert(resource $pb, string $id, string $name) + */ +PHP_FUNCTION(git_packbuilder_insert) +{ + int result = 0, id_len = 0, name_len = 0; + zval *pb = NULL; + php_git2_t *_pb = NULL; + char *id = NULL, *name = NULL; + git_oid __id = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rss", &pb, &id, &id_len, &name, &name_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_pb, php_git2_t*, &pb, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__id, id, id_len)) { + RETURN_FALSE; + } + result = git_packbuilder_insert(PHP_GIT2_V(_pb, packbuilder), &__id, name); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_packbuilder_insert_tree(resource $pb, string $id) + */ +PHP_FUNCTION(git_packbuilder_insert_tree) +{ + int result = 0, id_len = 0; + zval *pb = NULL; + php_git2_t *_pb = NULL; + char *id = NULL; + git_oid __id = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &pb, &id, &id_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_pb, php_git2_t*, &pb, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__id, id, id_len)) { + RETURN_FALSE; + } + result = git_packbuilder_insert_tree(PHP_GIT2_V(_pb, packbuilder), &__id); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_packbuilder_insert_commit(resource $pb, string $id) + */ +PHP_FUNCTION(git_packbuilder_insert_commit) +{ + int result = 0, id_len = 0; + zval *pb = NULL; + php_git2_t *_pb = NULL; + char *id = NULL; + git_oid __id = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &pb, &id, &id_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_pb, php_git2_t*, &pb, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__id, id, id_len)) { + RETURN_FALSE; + } + result = git_packbuilder_insert_commit(PHP_GIT2_V(_pb, packbuilder), &__id); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_packbuilder_write(resource $pb, string $path, long $mode, $progress_cb, $progress_cb_payload) + */ +PHP_FUNCTION(git_packbuilder_write) +{ + int result = 0, path_len = 0; + zval *pb = NULL, *progress_cb_payload = NULL; + php_git2_t *_pb = NULL; + char *path = NULL; + long mode = 0; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rslfz", &pb, &path, &path_len, &mode, &fci, &fcc, &progress_cb_payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_pb, php_git2_t*, &pb, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_cb_init(&cb, &fci, &fcc, progress_cb_payload TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_packbuilder_write(PHP_GIT2_V(_pb, packbuilder), path, mode, php_git2_git_transfer_progress_callback, cb); + php_git2_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_packbuilder_hash(resource $pb) + */ +PHP_FUNCTION(git_packbuilder_hash) +{ + const git_oid *result = NULL; + zval *pb = NULL; + php_git2_t *_pb = NULL; + char __result[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &pb) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_pb, php_git2_t*, &pb, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_packbuilder_hash(PHP_GIT2_V(_pb, packbuilder)); + git_oid_fmt(__result, result); + RETURN_STRING(__result, 1); +} +/* }}} */ + + +/* {{{ proto long git_packbuilder_foreach(resource $pb, Callable $cb, $payload) + */ +PHP_FUNCTION(git_packbuilder_foreach) +{ + int result = 0; + zval *pb = NULL, *payload = NULL; + php_git2_t *_pb = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rfz", &pb, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_pb, php_git2_t*, &pb, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_packbuilder_foreach(PHP_GIT2_V(_pb, packbuilder), php_git2_git_packbuilder_foreach_cb, cb); + php_git2_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_packbuilder_object_count(resource $pb) + */ +PHP_FUNCTION(git_packbuilder_object_count) +{ + uint32_t result = 0; + zval *pb = NULL; + php_git2_t *_pb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &pb) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_pb, php_git2_t*, &pb, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_packbuilder_object_count(PHP_GIT2_V(_pb, packbuilder)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_packbuilder_written(resource $pb) + */ +PHP_FUNCTION(git_packbuilder_written) +{ + uint32_t result = 0; + zval *pb = NULL; + php_git2_t *_pb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &pb) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_pb, php_git2_t*, &pb, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_packbuilder_written(PHP_GIT2_V(_pb, packbuilder)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_packbuilder_set_callbacks(resource $pb, $progress_cb, $progress_cb_payload) + */ +PHP_FUNCTION(git_packbuilder_set_callbacks) +{ + int result = 0; + zval *pb = NULL, *progress_cb_payload = NULL; + php_git2_t *_pb = NULL; + zend_fcall_info fci = empty_fcall_info, *_fci; + zend_fcall_info_cache fcc = empty_fcall_info_cache, *_fcc; + php_git2_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rfz", &pb, &fci, &fcc, &progress_cb_payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_pb, php_git2_t*, &pb, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + _fci = emalloc(sizeof(zend_fcall_info)); + _fcc = emalloc(sizeof(zend_fcall_info_cache)); + memcpy(_fci, &fci, sizeof(zend_fcall_info)); + memcpy(_fcc, &fcc, sizeof(zend_fcall_info_cache)); + + /* TODO(chobie): free memory when the resource removed */ + if (php_git2_cb_init(&cb, &_fci, &_fcc, progress_cb_payload TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_packbuilder_set_callbacks(PHP_GIT2_V(_pb, packbuilder), php_git2_git_packbuilder_progress, cb); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto void git_packbuilder_free(resource $pb) + */ +PHP_FUNCTION(git_packbuilder_free) +{ + zval *pb = NULL; + php_git2_t *_pb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &pb) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_pb, php_git2_t*, &pb, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_pb)) { + git_packbuilder_free(PHP_GIT2_V(_pb, packbuilder)); + GIT2_SHOULD_FREE(_pb) = 0; + }; + zval_ptr_dtor(&pb); +} +/* }}} */ + diff --git a/packbuilder.h b/packbuilder.h new file mode 100644 index 0000000000..5e8123f0de --- /dev/null +++ b/packbuilder.h @@ -0,0 +1,138 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_PACKBUILDER_H +#define PHP_GIT2_PACKBUILDER_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_packbuilder_new, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_packbuilder_set_threads, 0, 0, 2) + ZEND_ARG_INFO(0, pb) + ZEND_ARG_INFO(0, n) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_packbuilder_insert, 0, 0, 3) + ZEND_ARG_INFO(0, pb) + ZEND_ARG_INFO(0, id) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_packbuilder_insert_tree, 0, 0, 2) + ZEND_ARG_INFO(0, pb) + ZEND_ARG_INFO(0, id) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_packbuilder_insert_commit, 0, 0, 2) + ZEND_ARG_INFO(0, pb) + ZEND_ARG_INFO(0, id) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_packbuilder_write, 0, 0, 5) + ZEND_ARG_INFO(0, pb) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, mode) + ZEND_ARG_INFO(0, progress_cb) + ZEND_ARG_INFO(1, progress_cb_payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_packbuilder_hash, 0, 0, 1) + ZEND_ARG_INFO(0, pb) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_packbuilder_foreach, 0, 0, 3) + ZEND_ARG_INFO(0, pb) + ZEND_ARG_INFO(0, cb) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_packbuilder_object_count, 0, 0, 1) + ZEND_ARG_INFO(0, pb) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_packbuilder_written, 0, 0, 1) + ZEND_ARG_INFO(0, pb) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_packbuilder_set_callbacks, 0, 0, 3) + ZEND_ARG_INFO(0, pb) + ZEND_ARG_INFO(0, progress_cb) + ZEND_ARG_INFO(1, progress_cb_payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_packbuilder_free, 0, 0, 1) + ZEND_ARG_INFO(0, pb) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_packbuilder_new(repo) +*/ +PHP_FUNCTION(git_packbuilder_new); + +/* {{{ proto resource git_packbuilder_set_threads(pb, n) +*/ +PHP_FUNCTION(git_packbuilder_set_threads); + +/* {{{ proto long git_packbuilder_insert(pb, id, name) +*/ +PHP_FUNCTION(git_packbuilder_insert); + +/* {{{ proto long git_packbuilder_insert_tree(pb, id) +*/ +PHP_FUNCTION(git_packbuilder_insert_tree); + +/* {{{ proto long git_packbuilder_insert_commit(pb, id) +*/ +PHP_FUNCTION(git_packbuilder_insert_commit); + +/* {{{ proto resource git_packbuilder_write(path, mode, progress_cb, progress_cb_payload) +*/ +PHP_FUNCTION(git_packbuilder_write); + +/* {{{ proto resource git_packbuilder_hash(pb) +*/ +PHP_FUNCTION(git_packbuilder_hash); + +/* {{{ proto long git_packbuilder_foreach(pb, cb, payload) +*/ +PHP_FUNCTION(git_packbuilder_foreach); + +/* {{{ proto resource git_packbuilder_object_count(pb) +*/ +PHP_FUNCTION(git_packbuilder_object_count); + +/* {{{ proto resource git_packbuilder_written(pb) +*/ +PHP_FUNCTION(git_packbuilder_written); + +/* {{{ proto long git_packbuilder_set_callbacks(pb, progress_cb, progress_cb_payload) +*/ +PHP_FUNCTION(git_packbuilder_set_callbacks); + +/* {{{ proto void git_packbuilder_free(pb) +*/ +PHP_FUNCTION(git_packbuilder_free); + +#endif diff --git a/patch.c b/patch.c new file mode 100644 index 0000000000..267025424c --- /dev/null +++ b/patch.c @@ -0,0 +1,327 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "patch.h" + +/* {{{ proto resource git_patch_from_diff(resource $diff, long $idx) + */ +PHP_FUNCTION(git_patch_from_diff) +{ + php_git2_t *result = NULL, *_diff = NULL; + git_patch *out = NULL; + zval *diff = NULL; + long idx = 0; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &diff, &idx) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_diff, php_git2_t*, &diff, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_patch_from_diff(&out, PHP_GIT2_V(_diff, diff), idx); + if (php_git2_check_error(error, "git_patch_from_diff" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_PATCH, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_patch_from_blobs(resource $old_blob, string $old_as_path, resource $new_blob, string $new_as_path, $opts) + */ +PHP_FUNCTION(git_patch_from_blobs) +{ + php_git2_t *result = NULL, *_old_blob = NULL, *_new_blob = NULL; + git_patch *out = NULL; + git_diff_options options = GIT_DIFF_OPTIONS_INIT; + zval *old_blob = NULL, *new_blob = NULL, *opts = NULL; + char *old_as_path = NULL, *new_as_path = NULL; + int old_as_path_len = 0, new_as_path_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsrsa", &old_blob, &old_as_path, &old_as_path_len, &new_blob, &new_as_path, &new_as_path_len, &opts) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_old_blob, php_git2_t*, &old_blob, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_new_blob, php_git2_t*, &new_blob, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + php_git2_array_to_git_diff_options(&options, opts TSRMLS_CC); + error = git_patch_from_blobs(&out, PHP_GIT2_V(_old_blob, blob), old_as_path, PHP_GIT2_V(_new_blob, blob), new_as_path, &options); + php_git2_git_diff_options_free(&options); + if (php_git2_check_error(error, "git_patch_from_blobs" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_PATCH, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto resource git_patch_from_blob_and_buffer(resource $old_blob, string $old_as_path, string $buffer, string $buffer_as_path, $opts) + */ +PHP_FUNCTION(git_patch_from_blob_and_buffer) +{ + php_git2_t *result = NULL, *_old_blob = NULL; + git_patch *out = NULL; + zval *old_blob = NULL, *opts = NULL; + char *old_as_path = NULL, *buffer = NULL, *buffer_as_path = NULL; + int old_as_path_len = 0, buffer_len = 0, buffer_as_path_len = 0, error = 0; + git_diff_options options = GIT_DIFF_OPTIONS_INIT; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsslsa", &old_blob, &old_as_path, &old_as_path_len, &buffer, &buffer_len, &buffer_len, &buffer_as_path, &buffer_as_path_len, &opts) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_old_blob, php_git2_t*, &old_blob, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + php_git2_array_to_git_diff_options(&options, opts TSRMLS_CC); + error = git_patch_from_blob_and_buffer(&out, PHP_GIT2_V(_old_blob, blob), old_as_path, buffer, buffer_len, buffer_as_path, &options); + php_git2_git_diff_options_free(&options); + if (php_git2_check_error(error, "git_patch_from_blob_and_buffer" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_PATCH, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto void git_patch_free(resource $patch) + */ +PHP_FUNCTION(git_patch_free) +{ + zval *patch = NULL; + php_git2_t *_patch = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &patch) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_patch, php_git2_t*, &patch, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_patch)) { + git_patch_free(PHP_GIT2_V(_patch, patch)); + GIT2_SHOULD_FREE(_patch) = 0; + }; + zval_ptr_dtor(&patch); +} +/* }}} */ + + +/* {{{ proto resource git_patch_get_delta(resource $patch) + */ +PHP_FUNCTION(git_patch_get_delta) +{ + const git_diff_delta *result = NULL; + zval *patch = NULL, *out = NULL; + php_git2_t *_patch = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &patch) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_patch, php_git2_t*, &patch, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_patch_get_delta(PHP_GIT2_V(_patch, patch)); + php_git2_diff_delta_to_array(result, &out TSRMLS_CC); + RETURN_ZVAL(out, 0, 1); +} +/* }}} */ + +/* {{{ proto long git_patch_num_hunks(resource $patch) + */ +PHP_FUNCTION(git_patch_num_hunks) +{ + size_t result = 0; + zval *patch = NULL; + php_git2_t *_patch = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &patch) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_patch, php_git2_t*, &patch, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_patch_num_hunks(PHP_GIT2_V(_patch, patch)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_patch_line_stats(resource $patch) + */ +PHP_FUNCTION(git_patch_line_stats) +{ + int result = 0; + size_t total_context = 0, total_additions = 0, total_deletions = 0; + zval *patch = NULL, *out = NULL; + php_git2_t *_patch = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &patch) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_patch, php_git2_t*, &patch, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_patch_line_stats(&total_context, &total_additions, &total_deletions, PHP_GIT2_V(_patch, patch)); + MAKE_STD_ZVAL(out); + array_init(out); + add_assoc_long_ex(out, ZEND_STRS("total_context"), total_context); + add_assoc_long_ex(out, ZEND_STRS("total_additions"), total_additions); + add_assoc_long_ex(out, ZEND_STRS("total_deletions"), total_deletions); + RETURN_ZVAL(out, 0, 1); +} +/* }}} */ + +/* {{{ proto resource git_patch_get_hunk(long $lines_in_hunk, resource $patch, long $hunk_idx) + */ +PHP_FUNCTION(git_patch_get_hunk) +{ + php_git2_t *result = NULL, *_patch = NULL; + git_diff_hunk *out = NULL; + long lines_in_hunk = 0, hunk_idx = 0; + zval *patch = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "lrl", &lines_in_hunk, &patch, &hunk_idx) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_patch, php_git2_t*, &patch, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_patch_get_hunk(&out, lines_in_hunk, PHP_GIT2_V(_patch, patch), hunk_idx); + if (php_git2_check_error(error, "git_patch_get_hunk" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_DIFF_HUNK, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto long git_patch_num_lines_in_hunk(resource $patch, long $hunk_idx) + */ +PHP_FUNCTION(git_patch_num_lines_in_hunk) +{ + int result = 0; + zval *patch = NULL; + php_git2_t *_patch = NULL; + long hunk_idx = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &patch, &hunk_idx) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_patch, php_git2_t*, &patch, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_patch_num_lines_in_hunk(PHP_GIT2_V(_patch, patch), hunk_idx); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_patch_get_line_in_hunk(resource $patch, long $hunk_idx, long $line_of_hunk) + */ +PHP_FUNCTION(git_patch_get_line_in_hunk) +{ + php_git2_t *result = NULL, *_patch = NULL; + git_diff_line *out = NULL; + zval *patch = NULL; + long hunk_idx = 0, line_of_hunk = 0; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rll", &patch, &hunk_idx, &line_of_hunk) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_patch, php_git2_t*, &patch, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_patch_get_line_in_hunk(&out, PHP_GIT2_V(_patch, patch), hunk_idx, line_of_hunk); + if (php_git2_check_error(error, "git_patch_get_line_in_hunk" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_DIFF_LINE, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto long git_patch_size(resource $patch, long $include_context, long $include_hunk_headers, long $include_file_headers) + */ +PHP_FUNCTION(git_patch_size) +{ + size_t result = 0; + zval *patch = NULL; + php_git2_t *_patch = NULL; + long include_context = 0, include_hunk_headers = 0, include_file_headers = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rlll", &patch, &include_context, &include_hunk_headers, &include_file_headers) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_patch, php_git2_t*, &patch, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_patch_size(PHP_GIT2_V(_patch, patch), include_context, include_hunk_headers, include_file_headers); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_patch_print(resource $patch, Callable $print_cb, $payload) + */ +PHP_FUNCTION(git_patch_print) +{ + int result = 0; + zval *patch = NULL, *payload = NULL; + php_git2_t *_patch = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_multi_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rfz", &patch, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_patch, php_git2_t*, &patch, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + php_git2_multi_cb_init(&cb, payload TSRMLS_CC, 3, + &empty_fcall_info, &empty_fcall_info_cache, + &empty_fcall_info, &empty_fcall_info_cache, + &fci, &fcc + ); + result = git_patch_print(PHP_GIT2_V(_patch, patch), php_git2_git_diff_line_cb, cb); + php_git2_multi_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto long git_patch_to_str(resource $patch) + */ +PHP_FUNCTION(git_patch_to_str) +{ + int result = 0; + char *string = NULL; + zval *patch = NULL; + php_git2_t *_patch = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &patch) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_patch, php_git2_t*, &patch, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_patch_to_str(&string, PHP_GIT2_V(_patch, patch)); + if (result != 0) { + RETURN_FALSE; + } + + RETVAL_STRING(string, 1); + free(string); +} +/* }}} */ diff --git a/patch.h b/patch.h new file mode 100644 index 0000000000..2e666d9d22 --- /dev/null +++ b/patch.h @@ -0,0 +1,156 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_PATCH_H +#define PHP_GIT2_PATCH_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_patch_from_diff, 0, 0, 2) + ZEND_ARG_INFO(0, diff) + ZEND_ARG_INFO(0, idx) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_patch_from_blobs, 0, 0, 5) + ZEND_ARG_INFO(0, old_blob) + ZEND_ARG_INFO(0, old_as_path) + ZEND_ARG_INFO(0, new_blob) + ZEND_ARG_INFO(0, new_as_path) + ZEND_ARG_INFO(0, opts) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_patch_from_blob_and_buffer, 0, 0, 6) + ZEND_ARG_INFO(0, old_blob) + ZEND_ARG_INFO(0, old_as_path) + ZEND_ARG_INFO(0, buffer) + ZEND_ARG_INFO(0, buffer_len) + ZEND_ARG_INFO(0, buffer_as_path) + ZEND_ARG_INFO(0, opts) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_patch_free, 0, 0, 1) + ZEND_ARG_INFO(0, patch) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_patch_get_delta, 0, 0, 1) + ZEND_ARG_INFO(0, patch) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_patch_num_hunks, 0, 0, 1) + ZEND_ARG_INFO(0, patch) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_patch_line_stats, 0, 0, 4) + ZEND_ARG_INFO(0, total_context) + ZEND_ARG_INFO(0, total_additions) + ZEND_ARG_INFO(0, total_deletions) + ZEND_ARG_INFO(0, patch) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_patch_get_hunk, 0, 0, 3) + ZEND_ARG_INFO(0, lines_in_hunk) + ZEND_ARG_INFO(0, patch) + ZEND_ARG_INFO(0, hunk_idx) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_patch_num_lines_in_hunk, 0, 0, 2) + ZEND_ARG_INFO(0, patch) + ZEND_ARG_INFO(0, hunk_idx) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_patch_get_line_in_hunk, 0, 0, 3) + ZEND_ARG_INFO(0, patch) + ZEND_ARG_INFO(0, hunk_idx) + ZEND_ARG_INFO(0, line_of_hunk) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_patch_size, 0, 0, 4) + ZEND_ARG_INFO(0, patch) + ZEND_ARG_INFO(0, include_context) + ZEND_ARG_INFO(0, include_hunk_headers) + ZEND_ARG_INFO(0, include_file_headers) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_patch_print, 0, 0, 3) + ZEND_ARG_INFO(0, patch) + ZEND_ARG_INFO(0, print_cb) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_patch_to_str, 0, 0, 1) + ZEND_ARG_INFO(0, patch) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_patch_from_diff(diff, idx) +*/ +PHP_FUNCTION(git_patch_from_diff); + +/* {{{ proto resource git_patch_from_blobs(old_blob, old_as_path, new_blob, new_as_path, opts) +*/ +PHP_FUNCTION(git_patch_from_blobs); + +/* {{{ proto resource git_patch_from_blob_and_buffer(old_blob, old_as_path, buffer, buffer_len, buffer_as_path, opts) +*/ +PHP_FUNCTION(git_patch_from_blob_and_buffer); + +/* {{{ proto void git_patch_free(patch) +*/ +PHP_FUNCTION(git_patch_free); + +/* {{{ proto resource git_patch_get_delta(patch) +*/ +PHP_FUNCTION(git_patch_get_delta); + +/* {{{ proto resource git_patch_num_hunks(patch) +*/ +PHP_FUNCTION(git_patch_num_hunks); + +/* {{{ proto long git_patch_line_stats(total_context, total_additions, total_deletions, patch) +*/ +PHP_FUNCTION(git_patch_line_stats); + +/* {{{ proto resource git_patch_get_hunk(lines_in_hunk, patch, hunk_idx) +*/ +PHP_FUNCTION(git_patch_get_hunk); + +/* {{{ proto long git_patch_num_lines_in_hunk(patch, hunk_idx) +*/ +PHP_FUNCTION(git_patch_num_lines_in_hunk); + +/* {{{ proto resource git_patch_get_line_in_hunk(patch, hunk_idx, line_of_hunk) +*/ +PHP_FUNCTION(git_patch_get_line_in_hunk); + +/* {{{ proto resource git_patch_size(patch, include_context, include_hunk_headers, include_file_headers) +*/ +PHP_FUNCTION(git_patch_size); + +/* {{{ proto long git_patch_print(patch, print_cb, payload) +*/ +PHP_FUNCTION(git_patch_print); + +/* {{{ proto resource git_patch_to_str(patch) +*/ +PHP_FUNCTION(git_patch_to_str); + +#endif \ No newline at end of file diff --git a/pathspec.c b/pathspec.c new file mode 100644 index 0000000000..05bc5b0470 --- /dev/null +++ b/pathspec.c @@ -0,0 +1,316 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "pathspec.h" + +/* {{{ proto resource git_pathspec_new(array $pathspec) + */ +PHP_FUNCTION(git_pathspec_new) +{ + php_git2_t *result = NULL; + git_pathspec *out = NULL; + zval *pathspec = NULL; + git_strarray _pathspec = {0}; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "a", &pathspec) == FAILURE) { + return; + } + + php_git2_array_to_strarray(&_pathspec, pathspec TSRMLS_CC); + error = git_pathspec_new(&out, &_pathspec); + php_git2_strarray_free(&_pathspec); + if (php_git2_check_error(error, "git_pathspec_new" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_PATHSPEC, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto void git_pathspec_free(resource $ps) + */ +PHP_FUNCTION(git_pathspec_free) +{ + zval *ps = NULL; + php_git2_t *_ps = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &ps) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_ps, php_git2_t*, &ps, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_ps)) { + git_pathspec_free(PHP_GIT2_V(_ps, pathspec)); + GIT2_SHOULD_FREE(_ps) = 0; + }; + zval_ptr_dtor(&ps); +} +/* }}} */ + + +/* {{{ proto long git_pathspec_matches_path(resource $ps, long $flags, string $path) + */ +PHP_FUNCTION(git_pathspec_matches_path) +{ + int result = 0, path_len = 0; + zval *ps = NULL; + php_git2_t *_ps = NULL; + long flags = 0; + char *path = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rls", &ps, &flags, &path, &path_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_ps, php_git2_t*, &ps, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_pathspec_matches_path(PHP_GIT2_V(_ps, pathspec), flags, path); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto resource git_pathspec_match_workdir(resource $repo, long $flags, resource $ps) + */ +PHP_FUNCTION(git_pathspec_match_workdir) +{ + php_git2_t *result = NULL, *_repo = NULL, *_ps = NULL; + git_pathspec_match_list *out; + zval *repo = NULL, *ps = NULL; + long flags = 0; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rlr", &repo, &flags, &ps) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_ps, php_git2_t*, &ps, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_pathspec_match_workdir(&out, PHP_GIT2_V(_repo, repository), flags, PHP_GIT2_V(_ps, pathspec)); + if (php_git2_check_error(error, "git_pathspec_match_workdir" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_PATHSPEC_MATCH_LIST, out, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_pathspec_match_index(resource $index, long $flags, resource $ps) + */ +PHP_FUNCTION(git_pathspec_match_index) +{ + php_git2_t *result = NULL, *_index = NULL, *_ps = NULL; + git_pathspec_match_list *out = NULL; + zval *index = NULL, *ps = NULL; + long flags = 0; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rlr", &index, &flags, &ps) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_index, php_git2_t*, &index, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_ps, php_git2_t*, &ps, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_pathspec_match_index(&out, PHP_GIT2_V(_index, index), flags, PHP_GIT2_V(_ps, pathspec)); + if (php_git2_check_error(error, "git_pathspec_match_index" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_PATHSPEC_MATCH_LIST, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_pathspec_match_tree(resource $tree, long $flags, resource $ps) + */ +PHP_FUNCTION(git_pathspec_match_tree) +{ + php_git2_t *result = NULL, *_tree = NULL, *_ps = NULL; + git_pathspec_match_list *out = NULL; + zval *tree = NULL, *ps = NULL; + long flags = 0; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rlr", &tree, &flags, &ps) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_tree, php_git2_t*, &tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_ps, php_git2_t*, &ps, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_pathspec_match_tree(&out, PHP_GIT2_V(_tree, tree), flags, PHP_GIT2_V(_ps, pathspec)); + if (php_git2_check_error(error, "git_pathspec_match_tree" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_PATHSPEC_MATCH_LIST, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_pathspec_match_diff(resource $diff, long $flags, resource $ps) + */ +PHP_FUNCTION(git_pathspec_match_diff) +{ + php_git2_t *result = NULL, *_diff = NULL, *_ps = NULL; + git_pathspec_match_list *out = NULL; + zval *diff = NULL, *ps = NULL; + long flags = 0; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rlr", &diff, &flags, &ps) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_diff, php_git2_t*, &diff, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_ps, php_git2_t*, &ps, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_pathspec_match_diff(&out, PHP_GIT2_V(_diff, diff), flags, PHP_GIT2_V(_ps, pathspec)); + if (php_git2_check_error(error, "git_pathspec_match_diff" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_PATHSPEC_MATCH_LIST, out, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto void git_pathspec_match_list_free(resource $m) + */ +PHP_FUNCTION(git_pathspec_match_list_free) +{ + zval *m = NULL; + php_git2_t *_m = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &m) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_m, php_git2_t*, &m, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_m)) { + git_pathspec_match_list_free(PHP_GIT2_V(_m, pathspec_match_list)); + GIT2_SHOULD_FREE(_m) = 0; + }; + zval_ptr_dtor(&m); +} +/* }}} */ + + +/* {{{ proto long git_pathspec_match_list_entrycount(resource $m) + */ +PHP_FUNCTION(git_pathspec_match_list_entrycount) +{ + size_t result = 0; + zval *m = NULL; + php_git2_t *_m = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &m) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_m, php_git2_t*, &m, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_pathspec_match_list_entrycount(PHP_GIT2_V(_m, pathspec_match_list)); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto string git_pathspec_match_list_entry(resource $m, long $pos) + */ +PHP_FUNCTION(git_pathspec_match_list_entry) +{ + const char *result = NULL; + zval *m = NULL; + php_git2_t *_m = NULL; + long pos = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &m, &pos) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_m, php_git2_t*, &m, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_pathspec_match_list_entry(PHP_GIT2_V(_m, pathspec_match_list), pos); + RETURN_STRING(result, 1); +} +/* }}} */ + + +/* {{{ proto resource git_pathspec_match_list_diff_entry(resource $m, long $pos) + */ +PHP_FUNCTION(git_pathspec_match_list_diff_entry) +{ + const git_diff_delta *result = NULL; + zval *m = NULL, *_result = NULL; + php_git2_t *_m = NULL; + long pos = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &m, &pos) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_m, php_git2_t*, &m, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_pathspec_match_list_diff_entry(PHP_GIT2_V(_m, pathspec_match_list), pos); + if (result == NULL) { + RETURN_FALSE; + } + php_git2_diff_delta_to_array(result, &_result TSRMLS_CC); + RETURN_ZVAL(_result, 0, 1); +} +/* }}} */ + + +/* {{{ proto long git_pathspec_match_list_failed_entrycount(resource $m) + */ +PHP_FUNCTION(git_pathspec_match_list_failed_entrycount) +{ + size_t result = 0; + zval *m = NULL; + php_git2_t *_m = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &m) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_m, php_git2_t*, &m, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_pathspec_match_list_failed_entrycount(PHP_GIT2_V(_m, pathspec_match_list)); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto string git_pathspec_match_list_failed_entry(resource $m, long $pos) + */ +PHP_FUNCTION(git_pathspec_match_list_failed_entry) +{ + const char *result = NULL; + zval *m = NULL; + php_git2_t *_m = NULL; + long pos = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &m, &pos) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_m, php_git2_t*, &m, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_pathspec_match_list_failed_entry(PHP_GIT2_V(_m, pathspec_match_list), pos); + RETURN_STRING(result, 1); +} +/* }}} */ + diff --git a/pathspec.h b/pathspec.h new file mode 100644 index 0000000000..bc57b43009 --- /dev/null +++ b/pathspec.h @@ -0,0 +1,146 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_PATHSPEC_H +#define PHP_GIT2_PATHSPEC_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_pathspec_new, 0, 0, 1) + ZEND_ARG_INFO(0, pathspec) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_pathspec_free, 0, 0, 1) + ZEND_ARG_INFO(0, ps) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_pathspec_matches_path, 0, 0, 3) + ZEND_ARG_INFO(0, ps) + ZEND_ARG_INFO(0, flags) + ZEND_ARG_INFO(0, path) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_pathspec_match_workdir, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, flags) + ZEND_ARG_INFO(0, ps) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_pathspec_match_index, 0, 0, 3) + ZEND_ARG_INFO(0, index) + ZEND_ARG_INFO(0, flags) + ZEND_ARG_INFO(0, ps) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_pathspec_match_tree, 0, 0, 3) + ZEND_ARG_INFO(0, tree) + ZEND_ARG_INFO(0, flags) + ZEND_ARG_INFO(0, ps) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_pathspec_match_diff, 0, 0, 3) + ZEND_ARG_INFO(0, diff) + ZEND_ARG_INFO(0, flags) + ZEND_ARG_INFO(0, ps) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_pathspec_match_list_free, 0, 0, 1) + ZEND_ARG_INFO(0, m) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_pathspec_match_list_entrycount, 0, 0, 1) + ZEND_ARG_INFO(0, m) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_pathspec_match_list_entry, 0, 0, 2) + ZEND_ARG_INFO(0, m) + ZEND_ARG_INFO(0, pos) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_pathspec_match_list_diff_entry, 0, 0, 2) + ZEND_ARG_INFO(0, m) + ZEND_ARG_INFO(0, pos) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_pathspec_match_list_failed_entrycount, 0, 0, 1) + ZEND_ARG_INFO(0, m) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_pathspec_match_list_failed_entry, 0, 0, 2) + ZEND_ARG_INFO(0, m) + ZEND_ARG_INFO(0, pos) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_pathspec_new(pathspec) +*/ +PHP_FUNCTION(git_pathspec_new); + +/* {{{ proto void git_pathspec_free(ps) +*/ +PHP_FUNCTION(git_pathspec_free); + +/* {{{ proto long git_pathspec_matches_path(ps, flags, path) +*/ +PHP_FUNCTION(git_pathspec_matches_path); + +/* {{{ proto resource git_pathspec_match_workdir(repo, flags, ps) +*/ +PHP_FUNCTION(git_pathspec_match_workdir); + +/* {{{ proto resource git_pathspec_match_index(index, flags, ps) +*/ +PHP_FUNCTION(git_pathspec_match_index); + +/* {{{ proto resource git_pathspec_match_tree(tree, flags, ps) +*/ +PHP_FUNCTION(git_pathspec_match_tree); + +/* {{{ proto resource git_pathspec_match_diff(diff, flags, ps) +*/ +PHP_FUNCTION(git_pathspec_match_diff); + +/* {{{ proto void git_pathspec_match_list_free(m) +*/ +PHP_FUNCTION(git_pathspec_match_list_free); + +/* {{{ proto resource git_pathspec_match_list_entrycount(m) +*/ +PHP_FUNCTION(git_pathspec_match_list_entrycount); + +/* {{{ proto resource git_pathspec_match_list_entry(m, pos) +*/ +PHP_FUNCTION(git_pathspec_match_list_entry); + +/* {{{ proto resource git_pathspec_match_list_diff_entry(m, pos) +*/ +PHP_FUNCTION(git_pathspec_match_list_diff_entry); + +/* {{{ proto resource git_pathspec_match_list_failed_entrycount(m) +*/ +PHP_FUNCTION(git_pathspec_match_list_failed_entrycount); + +/* {{{ proto resource git_pathspec_match_list_failed_entry(m, pos) +*/ +PHP_FUNCTION(git_pathspec_match_list_failed_entry); + +#endif \ No newline at end of file diff --git a/php_git2.c b/php_git2.c new file mode 100644 index 0000000000..033a987a8e --- /dev/null +++ b/php_git2.c @@ -0,0 +1,1534 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "repository.h" +#include "commit.h" +#include "tree.h" +#include "clone.h" +#include "blob.h" +#include "revwalk.h" +#include "treebuilder.h" +#include "reference.h" +#include "g_config.h" +#include "object.h" +#include "index.h" +#include "revparse.h" +#include "branch.h" +#include "tag.h" +#include "status.h" +#include "cred.h" +#include "remote.h" +#include "transport.h" +#include "diff.h" +#include "checkout.h" +#include "filter.h" +#include "ignore.h" +#include "indexer.h" +#include "pathspec.h" +#include "patch.h" +#include "merge.h" +#include "note.h" +#include "odb.h" +#include "reflog.h" +#include "blame.h" +#include "packbuilder.h" +#include "stash.h" +#include "signature.h" +#include "reset.h" +#include "message.h" +#include "submodule.h" +#include "attr.h" +#include "giterr.h" +#include "push.h" +#include "refspec.h" +#include "graph.h" +#include "blame.h" + +int git2_resource_handle; + +zend_class_entry *php_git2_odb_backend_foreach_callback_class_entry; + +void static destruct_git2(zend_rsrc_list_entry *rsrc TSRMLS_DC) +{ + php_git2_t *resource = (php_git2_t *)rsrc->ptr; + if (resource->should_free_v) { + switch (resource->type) { + case PHP_GIT2_TYPE_REPOSITORY: + git_repository_free(PHP_GIT2_V(resource, repository)); + break; + case PHP_GIT2_TYPE_COMMIT: + git_commit_free(PHP_GIT2_V(resource, commit)); + break; + case PHP_GIT2_TYPE_TREE: + git_tree_free(PHP_GIT2_V(resource, tree)); + break; + case PHP_GIT2_TYPE_TREE_ENTRY: + git_tree_entry_free(PHP_GIT2_V(resource, tree_entry)); + break; + case PHP_GIT2_TYPE_BLOB: + git_blob_free(PHP_GIT2_V(resource, blob)); + break; + case PHP_GIT2_TYPE_REVWALK: + git_revwalk_free(PHP_GIT2_V(resource, revwalk)); + break; + case PHP_GIT2_TYPE_TREEBUILDER: + git_treebuilder_free(PHP_GIT2_V(resource, treebuilder)); + break; + case PHP_GIT2_TYPE_REFERENCE: + git_reference_free(PHP_GIT2_V(resource, reference)); + break; + case PHP_GIT2_TYPE_CONFIG: + git_config_free(PHP_GIT2_V(resource, config)); + break; + case PHP_GIT2_TYPE_OBJECT: + git_object_free(PHP_GIT2_V(resource, object)); + break; + case PHP_GIT2_TYPE_FILTER: + { + php_git2_filter *filter = (php_git2_filter*)PHP_GIT2_V(resource, filter); + zval_ptr_dtor(&filter->multi->payload); + php_git2_multi_cb_free(filter->multi); + efree(filter); + break; + } + case PHP_GIT2_TYPE_FILTER_LIST: + git_filter_list_free(PHP_GIT2_V(resource, filter_list)); + break; + case PHP_GIT2_TYPE_ODB_BACKEND: + { + php_git2_odb_backend *backend = (php_git2_odb_backend*)PHP_GIT2_V(resource, odb_backend); + zval_ptr_dtor(&backend->multi->payload); + php_git2_multi_cb_free(backend->multi); + efree(PHP_GIT2_V(resource, odb_backend)); + break; + } + } + } + + efree(resource); +} + +ZEND_DECLARE_MODULE_GLOBALS(git2); + +static zend_class_entry *php_git2_get_exception_base(TSRMLS_D) +{ +#if (PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION < 2) + return zend_exception_get_default(); +#else + return zend_exception_get_default(TSRMLS_C); +#endif +} + +int php_git2_make_resource(php_git2_t **out, enum php_git2_resource_type type, void *resource, int should_free TSRMLS_DC) +{ + php_git2_t *result = NULL; + + PHP_GIT2_MAKE_RESOURCE_NOCHECK(result); + if (result == NULL) { + return 1; + } + + switch (type) { + case PHP_GIT2_TYPE_REPOSITORY: + PHP_GIT2_V(result, repository) = (git_repository*)resource; + break; + case PHP_GIT2_TYPE_COMMIT: + PHP_GIT2_V(result, commit) = (git_commit*)resource; + break; + case PHP_GIT2_TYPE_TREE: + PHP_GIT2_V(result, tree) = (git_tree*)resource; + break; + case PHP_GIT2_TYPE_TREE_ENTRY: + PHP_GIT2_V(result, tree_entry) = (git_tree_entry*)resource; + break; + case PHP_GIT2_TYPE_BLOB: + PHP_GIT2_V(result, blob) = (git_blob*)resource; + break; + case PHP_GIT2_TYPE_REVWALK: + PHP_GIT2_V(result, revwalk) = (git_revwalk*)resource; + break; + case PHP_GIT2_TYPE_TREEBUILDER: + PHP_GIT2_V(result, treebuilder) = (git_treebuilder*)resource; + break; + case PHP_GIT2_TYPE_REFERENCE: + PHP_GIT2_V(result, reference) = (git_reference*)resource; + break; + case PHP_GIT2_TYPE_REFERENCE_ITERATOR: + PHP_GIT2_V(result, reference_iterator) = (git_reference_iterator*)resource; + break; + case PHP_GIT2_TYPE_CONFIG: + PHP_GIT2_V(result, config) = (git_config*)resource; + break; + case PHP_GIT2_TYPE_CONFIG_ITERATOR: + PHP_GIT2_V(result, config_iterator) = (git_config_iterator*)resource; + break; + case PHP_GIT2_TYPE_OBJECT: + PHP_GIT2_V(result, object) = (git_object*)resource; + break; + case PHP_GIT2_TYPE_INDEX: + PHP_GIT2_V(result, index) = (git_index*)resource; + break; + case PHP_GIT2_TYPE_ODB: + PHP_GIT2_V(result, odb) = (git_odb*)resource; + break; + case PHP_GIT2_TYPE_REFDB: + PHP_GIT2_V(result, refdb) = (git_refdb*)resource; + break; + case PHP_GIT2_TYPE_STATUS_LIST: + PHP_GIT2_V(result, status_list) = (git_status_list*)resource; + break; + case PHP_GIT2_TYPE_BRANCH_ITERATOR: + PHP_GIT2_V(result, branch_iterator) = (git_branch_iterator*)resource; + break; + case PHP_GIT2_TYPE_TAG: + PHP_GIT2_V(result, tag) = (git_tag*)resource; + break; + case PHP_GIT2_TYPE_CRED: + PHP_GIT2_V(result, cred) = (git_cred*)resource; + break; + case PHP_GIT2_TYPE_TRANSPORT: + PHP_GIT2_V(result, transport) = (git_transport*)resource; + break; + case PHP_GIT2_TYPE_REMOTE: + PHP_GIT2_V(result, remote) = (git_remote*)resource; + break; + case PHP_GIT2_TYPE_DIFF: + PHP_GIT2_V(result, diff) = (git_diff*)resource; + break; + case PHP_GIT2_TYPE_MERGE_RESULT: + PHP_GIT2_V(result, merge_result) = (git_merge_result*)resource; + break; + case PHP_GIT2_TYPE_MERGE_HEAD: + PHP_GIT2_V(result, merge_head) = (git_merge_head*)resource; + break; + case PHP_GIT2_TYPE_PATHSPEC: + PHP_GIT2_V(result, pathspec) = (git_pathspec*)resource; + break; + case PHP_GIT2_TYPE_PATHSPEC_MATCH_LIST: + PHP_GIT2_V(result, pathspec_match_list) = (git_pathspec_match_list*)resource; + break; + case PHP_GIT2_TYPE_PATCH: + PHP_GIT2_V(result, patch) = (git_patch*)resource; + break; + case PHP_GIT2_TYPE_DIFF_HUNK: + PHP_GIT2_V(result, diff_hunk) = (git_diff_hunk*)resource; + break; + case PHP_GIT2_TYPE_BUF: + PHP_GIT2_V(result, buf) = (git_buf*)resource; + break; + case PHP_GIT2_TYPE_FILTER_LIST: + PHP_GIT2_V(result, filter_list) = (git_filter_list*)resource; + break; + case PHP_GIT2_TYPE_FILTER_SOURCE: + PHP_GIT2_V(result, filter_source) = (git_filter_source*)resource; + break; + case PHP_GIT2_TYPE_DIFF_LINE: + PHP_GIT2_V(result, diff_line) = (git_diff_line*)resource; + break; + case PHP_GIT2_TYPE_INDEX_CONFLICT_ITERATOR: + PHP_GIT2_V(result, index_conflict_iterator) = (git_index_conflict_iterator*)resource; + break; + case PHP_GIT2_TYPE_SMART_SUBTRANSPORT: + PHP_GIT2_V(result, smart_subtransport) = (git_smart_subtransport*)resource; + break; + case PHP_GIT2_TYPE_NOTE: + PHP_GIT2_V(result, note) = (git_note*)resource; + break; + case PHP_GIT2_TYPE_NOTE_ITERATOR: + PHP_GIT2_V(result, note_iterator) = (git_note_iterator*)resource; + break; + case PHP_GIT2_TYPE_ODB_STREAM: + PHP_GIT2_V(result, odb_stream) = (git_odb_stream*)resource; + break; + case PHP_GIT2_TYPE_ODB_OBJECT: + PHP_GIT2_V(result, odb_object) = (git_odb_object*)resource; + break; + case PHP_GIT2_TYPE_ODB_WRITEPACK: + PHP_GIT2_V(result, odb_writepack) = (git_odb_writepack*)resource; + break; + case PHP_GIT2_TYPE_ODB_BACKEND: + PHP_GIT2_V(result, odb_backend) = (git_odb_backend*)resource; + break; + case PHP_GIT2_TYPE_REFLOG: + PHP_GIT2_V(result, reflog) = (git_reflog*)resource; + break; + case PHP_GIT2_TYPE_REFLOG_ENTRY: + PHP_GIT2_V(result, reflog_entry) = (git_reflog_entry*)resource; + break; + case PHP_GIT2_TYPE_BLAME: + PHP_GIT2_V(result, blame) = (git_blame*)resource; + break; + case PHP_GIT2_TYPE_PACKBUILDER: + PHP_GIT2_V(result, packbuilder) = (git_packbuilder*)resource; + break; + case PHP_GIT2_TYPE_SUBMODULE: + PHP_GIT2_V(result, submodule) = (git_submodule*)resource; + break; + case PHP_GIT2_TYPE_PUSH: + PHP_GIT2_V(result, push) = (git_push*)resource; + break; + case PHP_GIT2_TYPE_FILTER: + PHP_GIT2_V(result, filter) = (git_filter*)resource; + break; + default: + php_error_docref(NULL TSRMLS_CC, E_ERROR, "passed resource type does not support. probably bug."); + } + + result->type = type; + result->resource_id = PHP_GIT2_LIST_INSERT(result, git2_resource_handle); + result->should_free_v = should_free; + + *out = result; + return 0; +} + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_resource_type, 0, 0, 1) + ZEND_ARG_INFO(0, resource) +ZEND_END_ARG_INFO() + +/* {{{ proto long git_resource_type(resource $git) + */ +PHP_FUNCTION(git_resource_type) +{ + zval *resource = NULL; + php_git2_t *_resource= NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &resource) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_resource, php_git2_t*, &resource, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + RETURN_LONG(_resource->type); +} +/* }}} */ + +PHP_FUNCTION(git_checkout_opts_new) +{ + zval *tmp; + git_checkout_opts opt = GIT_CHECKOUT_OPTS_INIT; + + php_git2_git_checkout_opts_to_array(&opt, &tmp TSRMLS_CC); + RETURN_ZVAL(tmp, 0, 1); +} + +PHP_FUNCTION(git_libgit2_capabilities) +{ + RETURN_LONG(git_libgit2_capabilities()); +} + + +PHP_FUNCTION(git_libgit2_version) +{ + char buf[32] = {0}; + int major, minor, rev; + + git_libgit2_version(&major, &minor, &rev); + snprintf(buf, 32, "%d.%d.%d", major, minor, rev); + + RETURN_STRING(buf, 1); +} + +static zend_function_entry php_git2_functions[] = { + /* repository */ + PHP_FE(git_repository_new, arginfo_git_repository_new) + PHP_FE(git_repository_init, arginfo_git_repository_init) + PHP_FE(git_repository_open_bare, arginfo_git_repository_open_bare) + PHP_FE(git_repository_open, arginfo_git_repository_open) + PHP_FE(git_repository_get_namespace, arginfo_git_repository_get_namespace) + PHP_FE(git_repository_workdir, arginfo_git_repository_workdir) + PHP_FE(git_repository_wrap_odb, arginfo_git_repository_wrap_odb) + PHP_FE(git_repository_discover, arginfo_git_repository_discover) + PHP_FE(git_repository_open_ext, arginfo_git_repository_open_ext) + PHP_FE(git_repository_free, arginfo_git_repository_free) + PHP_FE(git_repository_init_ext, arginfo_git_repository_init_ext) + PHP_FE(git_repository_head, arginfo_git_repository_head) + PHP_FE(git_repository_head_detached, arginfo_git_repository_head_detached) + PHP_FE(git_repository_head_unborn, arginfo_git_repository_head_unborn) + PHP_FE(git_repository_is_empty, arginfo_git_repository_is_empty) + PHP_FE(git_repository_path, arginfo_git_repository_path) + PHP_FE(git_repository_set_workdir, arginfo_git_repository_set_workdir) + PHP_FE(git_repository_is_bare, arginfo_git_repository_is_bare) + PHP_FE(git_repository_config, arginfo_git_repository_config) + PHP_FE(git_repository_odb, arginfo_git_repository_odb) + PHP_FE(git_repository_refdb, arginfo_git_repository_refdb) + PHP_FE(git_repository_index, arginfo_git_repository_index) + PHP_FE(git_repository_message, arginfo_git_repository_message) + PHP_FE(git_repository_message_remove, arginfo_git_repository_message_remove) + PHP_FE(git_repository_merge_cleanup, arginfo_git_repository_merge_cleanup) + PHP_FE(git_repository_fetchhead_foreach, arginfo_git_repository_fetchhead_foreach) + PHP_FE(git_repository_mergehead_foreach, arginfo_git_repository_mergehead_foreach) + PHP_FE(git_repository_hashfile, arginfo_git_repository_hashfile) + PHP_FE(git_repository_set_head, arginfo_git_repository_set_head) + PHP_FE(git_repository_set_head_detached, arginfo_git_repository_set_head_detached) + PHP_FE(git_repository_detach_head, arginfo_git_repository_detach_head) + PHP_FE(git_repository_state, arginfo_git_repository_state) + PHP_FE(git_repository_set_namespace, arginfo_git_repository_set_namespace) + PHP_FE(git_repository_is_shallow, arginfo_git_repository_is_shallow) + PHP_FE(git_repository_init_options_new, NULL) + + /* index */ + PHP_FE(git_index_open, arginfo_git_index_open) + PHP_FE(git_index_new, arginfo_git_index_new) + PHP_FE(git_index_free, arginfo_git_index_free) + PHP_FE(git_index_owner, arginfo_git_index_owner) + PHP_FE(git_index_caps, arginfo_git_index_caps) + PHP_FE(git_index_set_caps, arginfo_git_index_set_caps) + PHP_FE(git_index_read, arginfo_git_index_read) + PHP_FE(git_index_write, arginfo_git_index_write) + PHP_FE(git_index_path, arginfo_git_index_path) + PHP_FE(git_index_read_tree, arginfo_git_index_read_tree) + PHP_FE(git_index_write_tree, arginfo_git_index_write_tree) + PHP_FE(git_index_write_tree_to, arginfo_git_index_write_tree_to) + PHP_FE(git_index_entrycount, arginfo_git_index_entrycount) + PHP_FE(git_index_clear, arginfo_git_index_clear) + PHP_FE(git_index_get_byindex, arginfo_git_index_get_byindex) + PHP_FE(git_index_get_bypath, arginfo_git_index_get_bypath) + PHP_FE(git_index_remove, arginfo_git_index_remove) + PHP_FE(git_index_remove_directory, arginfo_git_index_remove_directory) + PHP_FE(git_index_add, arginfo_git_index_add) + PHP_FE(git_index_entry_stage, arginfo_git_index_entry_stage) + PHP_FE(git_index_add_bypath, arginfo_git_index_add_bypath) + PHP_FE(git_index_remove_bypath, arginfo_git_index_remove_bypath) + PHP_FE(git_index_add_all, arginfo_git_index_add_all) + PHP_FE(git_index_remove_all, arginfo_git_index_remove_all) + PHP_FE(git_index_update_all, arginfo_git_index_update_all) + PHP_FE(git_index_find, arginfo_git_index_find) + PHP_FE(git_index_conflict_add, arginfo_git_index_conflict_add) + PHP_FE(git_index_conflict_get, arginfo_git_index_conflict_get) + PHP_FE(git_index_conflict_remove, arginfo_git_index_conflict_remove) + PHP_FE(git_index_conflict_cleanup, arginfo_git_index_conflict_cleanup) + PHP_FE(git_index_has_conflicts, arginfo_git_index_has_conflicts) + PHP_FE(git_index_conflict_iterator_new, arginfo_git_index_conflict_iterator_new) + PHP_FE(git_index_conflict_next, arginfo_git_index_conflict_next) + PHP_FE(git_index_conflict_iterator_free, arginfo_git_index_conflict_iterator_free) + + /* object */ + PHP_FE(git_object_lookup, arginfo_git_object_lookup) + PHP_FE(git_object_lookup_prefix, arginfo_git_object_lookup_prefix) + PHP_FE(git_object_lookup_bypath, arginfo_git_object_lookup_bypath) + PHP_FE(git_object_id, arginfo_git_object_id) + PHP_FE(git_object_type, arginfo_git_object_type) + PHP_FE(git_object_owner, arginfo_git_object_owner) + PHP_FE(git_object_free, arginfo_git_object_free) + PHP_FE(git_object_type2string, arginfo_git_object_type2string) + PHP_FE(git_object_string2type, arginfo_git_object_string2type) + PHP_FE(git_object_typeisloose, arginfo_git_object_typeisloose) + PHP_FE(git_object__size, arginfo_git_object__size) + PHP_FE(git_object_peel, arginfo_git_object_peel) + PHP_FE(git_object_dup, arginfo_git_object_dup) + + /* clone */ + PHP_FE(git_clone, arginfo_git_clone) + + /* reference */ + PHP_FE(git_reference_lookup, arginfo_git_reference_lookup) + PHP_FE(git_reference_name_to_id, arginfo_git_reference_name_to_id) + PHP_FE(git_reference_dwim, arginfo_git_reference_dwim) + PHP_FE(git_reference_symbolic_create, arginfo_git_reference_symbolic_create) + PHP_FE(git_reference_create, arginfo_git_reference_create) + PHP_FE(git_reference_target, arginfo_git_reference_target) + PHP_FE(git_reference_target_peel, arginfo_git_reference_target_peel) + PHP_FE(git_reference_symbolic_target, arginfo_git_reference_symbolic_target) + PHP_FE(git_reference_type, arginfo_git_reference_type) + PHP_FE(git_reference_name, arginfo_git_reference_name) + PHP_FE(git_reference_resolve, arginfo_git_reference_resolve) + PHP_FE(git_reference_owner, arginfo_git_reference_owner) + PHP_FE(git_reference_symbolic_set_target, arginfo_git_reference_symbolic_set_target) + PHP_FE(git_reference_set_target, arginfo_git_reference_set_target) + PHP_FE(git_reference_rename, arginfo_git_reference_rename) + PHP_FE(git_reference_delete, arginfo_git_reference_delete) + PHP_FE(git_reference_list, arginfo_git_reference_list) + PHP_FE(git_reference_foreach, arginfo_git_reference_foreach) + PHP_FE(git_reference_foreach_name, arginfo_git_reference_foreach_name) + PHP_FE(git_reference_free, arginfo_git_reference_free) + PHP_FE(git_reference_cmp, arginfo_git_reference_cmp) + PHP_FE(git_reference_iterator_new, arginfo_git_reference_iterator_new) + PHP_FE(git_reference_iterator_glob_new, arginfo_git_reference_iterator_glob_new) + PHP_FE(git_reference_next, arginfo_git_reference_next) + PHP_FE(git_reference_next_name, arginfo_git_reference_next_name) + PHP_FE(git_reference_iterator_free, arginfo_git_reference_iterator_free) + PHP_FE(git_reference_foreach_glob, arginfo_git_reference_foreach_glob) + PHP_FE(git_reference_has_log, arginfo_git_reference_has_log) + PHP_FE(git_reference_is_branch, arginfo_git_reference_is_branch) + PHP_FE(git_reference_is_remote, arginfo_git_reference_is_remote) + PHP_FE(git_reference_is_tag, arginfo_git_reference_is_tag) + PHP_FE(git_reference_normalize_name, arginfo_git_reference_normalize_name) + PHP_FE(git_reference_peel, arginfo_git_reference_peel) + PHP_FE(git_reference_is_valid_name, arginfo_git_reference_is_valid_name) + PHP_FE(git_reference_shorthand, arginfo_git_reference_shorthand) + + /* commit */ + PHP_FE(git_commit_lookup, arginfo_git_commit_lookup) + PHP_FE(git_commit_author, arginfo_git_commit_author) + PHP_FE(git_commit_tree, arginfo_git_commit_tree) + PHP_FE(git_commit_lookup_prefix, arginfo_git_commit_lookup_prefix) + PHP_FE(git_commit_id, arginfo_git_commit_id) + PHP_FE(git_commit_owner, arginfo_git_commit_owner) + PHP_FE(git_commit_message_encoding, arginfo_git_commit_message_encoding) + PHP_FE(git_commit_message, arginfo_git_commit_message) + PHP_FE(git_commit_message_raw, arginfo_git_commit_message_raw) + PHP_FE(git_commit_time, arginfo_git_commit_time) + PHP_FE(git_commit_time_offset, arginfo_git_commit_time_offset) + PHP_FE(git_commit_committer, arginfo_git_commit_committer) + PHP_FE(git_commit_raw_header, arginfo_git_commit_raw_header) + PHP_FE(git_commit_tree_id, arginfo_git_commit_tree_id) + PHP_FE(git_commit_parentcount, arginfo_git_commit_parentcount) + PHP_FE(git_commit_parent, arginfo_git_commit_parent) + PHP_FE(git_commit_parent_id, arginfo_git_commit_parent_id) + PHP_FE(git_commit_nth_gen_ancestor, arginfo_git_commit_nth_gen_ancestor) + PHP_FE(git_commit_create, arginfo_git_commit_create) + + /* tree */ + PHP_FE(git_tree_free, arginfo_git_tree_free) + PHP_FE(git_tree_id, arginfo_git_tree_id) + PHP_FE(git_tree_lookup, arginfo_git_tree_lookup) + PHP_FE(git_tree_owner, arginfo_git_tree_owner) + PHP_FE(git_tree_walk, arginfo_git_tree_walk) + + PHP_FE(git_tree_entry_byoid, arginfo_git_tree_entry_byoid) + PHP_FE(git_tree_entry_byindex, arginfo_git_tree_entry_byindex) + PHP_FE(git_tree_entry_byname, arginfo_git_tree_entry_byname) + PHP_FE(git_tree_entry_bypath, arginfo_git_tree_entry_bypath) + PHP_FE(git_tree_entry_id, arginfo_git_tree_entry_id) + PHP_FE(git_tree_entry_name, arginfo_git_tree_entry_name) + PHP_FE(git_tree_entry_type, arginfo_git_tree_entry_type) + PHP_FE(git_tree_entrycount, arginfo_git_tree_entrycount) + PHP_FE(git_tree_entry_filemode, arginfo_git_tree_entry_filemode) + PHP_FE(git_tree_entry_filemode_raw, arginfo_git_tree_entry_filemode_raw) + PHP_FE(git_tree_entry_cmp, arginfo_git_tree_entry_cmp) + PHP_FE(git_tree_entry_free, arginfo_git_tree_entry_free) + PHP_FE(git_tree_entry_dup, arginfo_git_tree_entry_dup) + + /* treebuilder */ + PHP_FE(git_treebuilder_create, arginfo_git_treebuilder_create) + PHP_FE(git_treebuilder_clear, arginfo_git_treebuilder_clear) + PHP_FE(git_treebuilder_entrycount, arginfo_git_treebuilder_entrycount) + PHP_FE(git_treebuilder_free, arginfo_git_treebuilder_free) + PHP_FE(git_treebuilder_get, arginfo_git_treebuilder_get) + PHP_FE(git_treebuilder_insert, arginfo_git_treebuilder_insert) + PHP_FE(git_treebuilder_remove, arginfo_git_treebuilder_remove) + PHP_FE(git_treebuilder_filter, arginfo_git_treebuilder_filter) + PHP_FE(git_treebuilder_write, arginfo_git_treebuilder_write) + + /* blob */ + PHP_FE(git_blob_create_frombuffer, arginfo_git_blob_create_frombuffer) + PHP_FE(git_blob_create_fromchunks, arginfo_git_blob_create_fromchunks) + PHP_FE(git_blob_create_fromdisk, arginfo_git_blob_create_fromdisk) + PHP_FE(git_blob_create_fromworkdir, arginfo_git_blob_create_fromworkdir) + PHP_FE(git_blob_filtered_content, arginfo_git_blob_filtered_content) + PHP_FE(git_blob_free, arginfo_git_blob_free) + PHP_FE(git_blob_id, arginfo_git_blob_id) + PHP_FE(git_blob_is_binary, arginfo_git_blob_is_binary) + PHP_FE(git_blob_lookup, arginfo_git_blob_lookup) + PHP_FE(git_blob_lookup_prefix, arginfo_git_blob_lookup_prefix) + PHP_FE(git_blob_owner, arginfo_git_blob_owner) + PHP_FE(git_blob_rawcontent, arginfo_git_blob_rawcontent) + PHP_FE(git_blob_rawsize, arginfo_git_blob_rawsize) + + /* revwalk */ + PHP_FE(git_revwalk_new, arginfo_git_revwalk_new) + PHP_FE(git_revwalk_reset, arginfo_git_revwalk_reset) + PHP_FE(git_revwalk_push, arginfo_git_revwalk_push) + PHP_FE(git_revwalk_push_glob, arginfo_git_revwalk_push_glob) + PHP_FE(git_revwalk_push_head, arginfo_git_revwalk_push_head) + PHP_FE(git_revwalk_hide, arginfo_git_revwalk_hide) + PHP_FE(git_revwalk_hide_glob, arginfo_git_revwalk_hide_glob) + PHP_FE(git_revwalk_hide_head, arginfo_git_revwalk_hide_head) + PHP_FE(git_revwalk_push_ref, arginfo_git_revwalk_push_ref) + PHP_FE(git_revwalk_hide_ref, arginfo_git_revwalk_hide_ref) + PHP_FE(git_revwalk_next, arginfo_git_revwalk_next) + PHP_FE(git_revwalk_sorting, arginfo_git_revwalk_sorting) + PHP_FE(git_revwalk_push_range, arginfo_git_revwalk_push_range) + PHP_FE(git_revwalk_simplify_first_parent, arginfo_git_revwalk_simplify_first_parent) + PHP_FE(git_revwalk_free, arginfo_git_revwalk_free) + PHP_FE(git_revwalk_repository, arginfo_git_revwalk_repository) + + /* config */ + PHP_FE(git_config_find_global, arginfo_git_config_find_global) + PHP_FE(git_config_find_xdg, arginfo_git_config_find_xdg) + PHP_FE(git_config_find_system, arginfo_git_config_find_system) + PHP_FE(git_config_open_default, arginfo_git_config_open_default) + PHP_FE(git_config_new, arginfo_git_config_new) + PHP_FE(git_config_add_file_ondisk, arginfo_git_config_add_file_ondisk) + PHP_FE(git_config_open_ondisk, arginfo_git_config_open_ondisk) + PHP_FE(git_config_open_level, arginfo_git_config_open_level) + PHP_FE(git_config_open_global, arginfo_git_config_open_global) + PHP_FE(git_config_refresh, arginfo_git_config_refresh) + PHP_FE(git_config_free, arginfo_git_config_free) + PHP_FE(git_config_get_entry, arginfo_git_config_get_entry) + PHP_FE(git_config_get_int32, arginfo_git_config_get_int32) + PHP_FE(git_config_get_int64, arginfo_git_config_get_int64) + PHP_FE(git_config_get_bool, arginfo_git_config_get_bool) + PHP_FE(git_config_get_string, arginfo_git_config_get_string) + PHP_FE(git_config_get_multivar_foreach, arginfo_git_config_get_multivar_foreach) + PHP_FE(git_config_multivar_iterator_new, arginfo_git_config_multivar_iterator_new) + PHP_FE(git_config_next, arginfo_git_config_next) + PHP_FE(git_config_iterator_free, arginfo_git_config_iterator_free) + PHP_FE(git_config_set_int32, arginfo_git_config_set_int32) + PHP_FE(git_config_set_int64, arginfo_git_config_set_int64) + PHP_FE(git_config_set_bool, arginfo_git_config_set_bool) + PHP_FE(git_config_set_string, arginfo_git_config_set_string) + PHP_FE(git_config_set_multivar, arginfo_git_config_set_multivar) + PHP_FE(git_config_delete_entry, arginfo_git_config_delete_entry) + PHP_FE(git_config_delete_multivar, arginfo_git_config_delete_multivar) + PHP_FE(git_config_foreach, arginfo_git_config_foreach) + PHP_FE(git_config_iterator_new, arginfo_git_config_iterator_new) + PHP_FE(git_config_iterator_glob_new, arginfo_git_config_iterator_glob_new) + PHP_FE(git_config_foreach_match, arginfo_git_config_foreach_match) + PHP_FE(git_config_get_mapped, arginfo_git_config_get_mapped) + PHP_FE(git_config_lookup_map_value, arginfo_git_config_lookup_map_value) + PHP_FE(git_config_parse_bool, arginfo_git_config_parse_bool) + PHP_FE(git_config_parse_int32, arginfo_git_config_parse_int32) + PHP_FE(git_config_parse_int64, arginfo_git_config_parse_int64) + PHP_FE(git_config_backend_foreach_match, arginfo_git_config_backend_foreach_match) + + /* revparse */ + PHP_FE(git_revparse_single, arginfo_git_revparse_single) + PHP_FE(git_revparse_ext, arginfo_git_revparse_ext) + PHP_FE(git_revparse, arginfo_git_revparse) + + /* remote */ + PHP_FE(git_remote_create, arginfo_git_remote_create) + PHP_FE(git_remote_create_with_fetchspec, arginfo_git_remote_create_with_fetchspec) + PHP_FE(git_remote_create_inmemory, arginfo_git_remote_create_inmemory) + PHP_FE(git_remote_load, arginfo_git_remote_load) + PHP_FE(git_remote_save, arginfo_git_remote_save) + PHP_FE(git_remote_owner, arginfo_git_remote_owner) + PHP_FE(git_remote_name, arginfo_git_remote_name) + PHP_FE(git_remote_url, arginfo_git_remote_url) + PHP_FE(git_remote_pushurl, arginfo_git_remote_pushurl) + PHP_FE(git_remote_set_url, arginfo_git_remote_set_url) + PHP_FE(git_remote_set_pushurl, arginfo_git_remote_set_pushurl) + PHP_FE(git_remote_add_fetch, arginfo_git_remote_add_fetch) + PHP_FE(git_remote_get_fetch_refspecs, arginfo_git_remote_get_fetch_refspecs) + PHP_FE(git_remote_set_fetch_refspecs, arginfo_git_remote_set_fetch_refspecs) + PHP_FE(git_remote_add_push, arginfo_git_remote_add_push) + PHP_FE(git_remote_get_push_refspecs, arginfo_git_remote_get_push_refspecs) + PHP_FE(git_remote_set_push_refspecs, arginfo_git_remote_set_push_refspecs) + PHP_FE(git_remote_clear_refspecs, arginfo_git_remote_clear_refspecs) + PHP_FE(git_remote_refspec_count, arginfo_git_remote_refspec_count) + PHP_FE(git_remote_get_refspec, arginfo_git_remote_get_refspec) + PHP_FE(git_remote_connect, arginfo_git_remote_connect) + PHP_FE(git_remote_ls, arginfo_git_remote_ls) + PHP_FE(git_remote_download, arginfo_git_remote_download) + PHP_FE(git_remote_connected, arginfo_git_remote_connected) + PHP_FE(git_remote_stop, arginfo_git_remote_stop) + PHP_FE(git_remote_disconnect, arginfo_git_remote_disconnect) + PHP_FE(git_remote_free, arginfo_git_remote_free) + PHP_FE(git_remote_update_tips, arginfo_git_remote_update_tips) + PHP_FE(git_remote_fetch, arginfo_git_remote_fetch) + PHP_FE(git_remote_valid_url, arginfo_git_remote_valid_url) + PHP_FE(git_remote_supported_url, arginfo_git_remote_supported_url) + PHP_FE(git_remote_list, arginfo_git_remote_list) + PHP_FE(git_remote_check_cert, arginfo_git_remote_check_cert) + PHP_FE(git_remote_set_transport, arginfo_git_remote_set_transport) + PHP_FE(git_remote_set_callbacks, arginfo_git_remote_set_callbacks) + PHP_FE(git_remote_stats, arginfo_git_remote_stats) + PHP_FE(git_remote_autotag, arginfo_git_remote_autotag) + PHP_FE(git_remote_set_autotag, arginfo_git_remote_set_autotag) + PHP_FE(git_remote_rename, arginfo_git_remote_rename) + PHP_FE(git_remote_update_fetchhead, arginfo_git_remote_update_fetchhead) + PHP_FE(git_remote_set_update_fetchhead, arginfo_git_remote_set_update_fetchhead) + PHP_FE(git_remote_is_valid_name, arginfo_git_remote_is_valid_name) + + /* cred */ + PHP_FE(git_cred_has_username, arginfo_git_cred_has_username) + PHP_FE(git_cred_userpass_plaintext_new, arginfo_git_cred_userpass_plaintext_new) + PHP_FE(git_cred_ssh_key_new, arginfo_git_cred_ssh_key_new) + PHP_FE(git_cred_ssh_custom_new, arginfo_git_cred_ssh_custom_new) + PHP_FE(git_cred_default_new, arginfo_git_cred_default_new) + PHP_FE(git_cred_userpass, arginfo_git_cred_userpass) + + /* status */ + PHP_FE(git_status_foreach, arginfo_git_status_foreach) + PHP_FE(git_status_foreach_ext, arginfo_git_status_foreach_ext) + PHP_FE(git_status_file, arginfo_git_status_file) + PHP_FE(git_status_list_new, arginfo_git_status_list_new) + PHP_FE(git_status_list_entrycount, arginfo_git_status_list_entrycount) + PHP_FE(git_status_byindex, arginfo_git_status_byindex) + PHP_FE(git_status_list_free, arginfo_git_status_list_free) + PHP_FE(git_status_should_ignore, arginfo_git_status_should_ignore) + PHP_FE(git_status_options_new, NULL) + + /* transport */ + PHP_FE(git_transport_new, arginfo_git_transport_new) + PHP_FE(git_transport_register, arginfo_git_transport_register) + PHP_FE(git_transport_unregister, arginfo_git_transport_unregister) + PHP_FE(git_transport_dummy, arginfo_git_transport_dummy) + PHP_FE(git_transport_local, arginfo_git_transport_local) + PHP_FE(git_transport_smart, arginfo_git_transport_smart) + PHP_FE(git_smart_subtransport_http, arginfo_git_smart_subtransport_http) + PHP_FE(git_smart_subtransport_git, arginfo_git_smart_subtransport_git) + PHP_FE(git_smart_subtransport_ssh, arginfo_git_smart_subtransport_ssh) + + /* diff */ + PHP_FE(git_diff_free, arginfo_git_diff_free) + PHP_FE(git_diff_tree_to_tree, arginfo_git_diff_tree_to_tree) + PHP_FE(git_diff_tree_to_index, arginfo_git_diff_tree_to_index) + PHP_FE(git_diff_index_to_workdir, arginfo_git_diff_index_to_workdir) + PHP_FE(git_diff_tree_to_workdir, arginfo_git_diff_tree_to_workdir) + PHP_FE(git_diff_tree_to_workdir_with_index, arginfo_git_diff_tree_to_workdir_with_index) + PHP_FE(git_diff_merge, arginfo_git_diff_merge) + PHP_FE(git_diff_find_similar, arginfo_git_diff_find_similar) + PHP_FE(git_diff_options_init, arginfo_git_diff_options_init) + PHP_FE(git_diff_num_deltas, arginfo_git_diff_num_deltas) + PHP_FE(git_diff_num_deltas_of_type, arginfo_git_diff_num_deltas_of_type) + PHP_FE(git_diff_get_delta, arginfo_git_diff_get_delta) + PHP_FE(git_diff_is_sorted_icase, arginfo_git_diff_is_sorted_icase) + PHP_FE(git_diff_foreach, arginfo_git_diff_foreach) + PHP_FE(git_diff_status_char, arginfo_git_diff_status_char) + PHP_FE(git_diff_print, arginfo_git_diff_print) + PHP_FE(git_diff_blobs, arginfo_git_diff_blobs) + PHP_FE(git_diff_blob_to_buffer, arginfo_git_diff_blob_to_buffer) + + /* checkout */ + PHP_FE(git_checkout_head, arginfo_git_checkout_head) + PHP_FE(git_checkout_index, arginfo_git_checkout_index) + PHP_FE(git_checkout_tree, arginfo_git_checkout_tree) + + PHP_FE(git_checkout_opts_new, NULL) /* convention function */ + + /* filter */ + PHP_FE(git_filter_list_load, arginfo_git_filter_list_load) + PHP_FE(git_filter_list_apply_to_data, arginfo_git_filter_list_apply_to_data) + PHP_FE(git_filter_list_apply_to_file, arginfo_git_filter_list_apply_to_file) + PHP_FE(git_filter_list_apply_to_blob, arginfo_git_filter_list_apply_to_blob) + PHP_FE(git_filter_list_free, arginfo_git_filter_list_free) + PHP_FE(git_filter_lookup, arginfo_git_filter_lookup) + PHP_FE(git_filter_list_new, arginfo_git_filter_list_new) + PHP_FE(git_filter_list_push, arginfo_git_filter_list_push) + PHP_FE(git_filter_list_length, arginfo_git_filter_list_length) + PHP_FE(git_filter_source_repo, arginfo_git_filter_source_repo) + PHP_FE(git_filter_source_path, arginfo_git_filter_source_path) + PHP_FE(git_filter_source_filemode, arginfo_git_filter_source_filemode) + PHP_FE(git_filter_source_id, arginfo_git_filter_source_id) + PHP_FE(git_filter_source_mode, arginfo_git_filter_source_mode) + PHP_FE(git_filter_register, arginfo_git_filter_register) + PHP_FE(git_filter_unregister, arginfo_git_filter_unregister) + PHP_FE(git_filter_new, arginfo_git_filter_new) + + /* ignore */ + PHP_FE(git_ignore_add_rule, arginfo_git_ignore_add_rule) + PHP_FE(git_ignore_clear_internal_rules, arginfo_git_ignore_clear_internal_rules) + PHP_FE(git_ignore_path_is_ignored, arginfo_git_ignore_path_is_ignored) + + /* indexer */ + PHP_FE(git_indexer_new, arginfo_git_indexer_new) + PHP_FE(git_indexer_append, arginfo_git_indexer_append) + PHP_FE(git_indexer_commit, arginfo_git_indexer_commit) + PHP_FE(git_indexer_hash, arginfo_git_indexer_hash) + PHP_FE(git_indexer_free, arginfo_git_indexer_free) + + /* pathspec */ + PHP_FE(git_pathspec_new, arginfo_git_pathspec_new) + PHP_FE(git_pathspec_free, arginfo_git_pathspec_free) + PHP_FE(git_pathspec_matches_path, arginfo_git_pathspec_matches_path) + PHP_FE(git_pathspec_match_workdir, arginfo_git_pathspec_match_workdir) + PHP_FE(git_pathspec_match_index, arginfo_git_pathspec_match_index) + PHP_FE(git_pathspec_match_tree, arginfo_git_pathspec_match_tree) + PHP_FE(git_pathspec_match_diff, arginfo_git_pathspec_match_diff) + PHP_FE(git_pathspec_match_list_free, arginfo_git_pathspec_match_list_free) + PHP_FE(git_pathspec_match_list_entrycount, arginfo_git_pathspec_match_list_entrycount) + PHP_FE(git_pathspec_match_list_entry, arginfo_git_pathspec_match_list_entry) + PHP_FE(git_pathspec_match_list_diff_entry, arginfo_git_pathspec_match_list_diff_entry) + PHP_FE(git_pathspec_match_list_failed_entrycount, arginfo_git_pathspec_match_list_failed_entrycount) + PHP_FE(git_pathspec_match_list_failed_entry, arginfo_git_pathspec_match_list_failed_entry) + + /* patch */ + PHP_FE(git_patch_from_diff, arginfo_git_patch_from_diff) + PHP_FE(git_patch_from_blobs, arginfo_git_patch_from_blobs) + PHP_FE(git_patch_from_blob_and_buffer, arginfo_git_patch_from_blob_and_buffer) + PHP_FE(git_patch_free, arginfo_git_patch_free) + PHP_FE(git_patch_get_delta, arginfo_git_patch_get_delta) + PHP_FE(git_patch_num_hunks, arginfo_git_patch_num_hunks) + PHP_FE(git_patch_line_stats, arginfo_git_patch_line_stats) + PHP_FE(git_patch_get_hunk, arginfo_git_patch_get_hunk) + PHP_FE(git_patch_num_lines_in_hunk, arginfo_git_patch_num_lines_in_hunk) + PHP_FE(git_patch_get_line_in_hunk, arginfo_git_patch_get_line_in_hunk) + PHP_FE(git_patch_size, arginfo_git_patch_size) + PHP_FE(git_patch_print, arginfo_git_patch_print) + PHP_FE(git_patch_to_str, arginfo_git_patch_to_str) + + /* merge */ + PHP_FE(git_merge_base, arginfo_git_merge_base) + PHP_FE(git_merge_base_many, arginfo_git_merge_base_many) + PHP_FE(git_merge_head_from_ref, arginfo_git_merge_head_from_ref) + PHP_FE(git_merge_head_from_fetchhead, arginfo_git_merge_head_from_fetchhead) + PHP_FE(git_merge_head_from_oid, arginfo_git_merge_head_from_oid) + PHP_FE(git_merge_head_free, arginfo_git_merge_head_free) + PHP_FE(git_merge_trees, arginfo_git_merge_trees) + PHP_FE(git_merge, arginfo_git_merge) + PHP_FE(git_merge_result_is_uptodate, arginfo_git_merge_result_is_uptodate) + PHP_FE(git_merge_result_is_fastforward, arginfo_git_merge_result_is_fastforward) + PHP_FE(git_merge_result_fastforward_oid, arginfo_git_merge_result_fastforward_oid) + PHP_FE(git_merge_result_free, arginfo_git_merge_result_free) + + /* tag */ + PHP_FE(git_tag_lookup, arginfo_git_tag_lookup) + PHP_FE(git_tag_lookup_prefix, arginfo_git_tag_lookup_prefix) + PHP_FE(git_tag_free, arginfo_git_tag_free) + PHP_FE(git_tag_id, arginfo_git_tag_id) + PHP_FE(git_tag_owner, arginfo_git_tag_owner) + PHP_FE(git_tag_target, arginfo_git_tag_target) + PHP_FE(git_tag_target_id, arginfo_git_tag_target_id) + PHP_FE(git_tag_target_type, arginfo_git_tag_target_type) + PHP_FE(git_tag_name, arginfo_git_tag_name) + PHP_FE(git_tag_tagger, arginfo_git_tag_tagger) + PHP_FE(git_tag_message, arginfo_git_tag_message) + PHP_FE(git_tag_create, arginfo_git_tag_create) + PHP_FE(git_tag_annotation_create, arginfo_git_tag_annotation_create) + PHP_FE(git_tag_create_frombuffer, arginfo_git_tag_create_frombuffer) + PHP_FE(git_tag_create_lightweight, arginfo_git_tag_create_lightweight) + PHP_FE(git_tag_delete, arginfo_git_tag_delete) + PHP_FE(git_tag_list, arginfo_git_tag_list) + PHP_FE(git_tag_list_match, arginfo_git_tag_list_match) + PHP_FE(git_tag_foreach, arginfo_git_tag_foreach) + PHP_FE(git_tag_peel, arginfo_git_tag_peel) + + /* note */ + PHP_FE(git_note_iterator_new, arginfo_git_note_iterator_new) + PHP_FE(git_note_iterator_free, arginfo_git_note_iterator_free) + PHP_FE(git_note_next, arginfo_git_note_next) + PHP_FE(git_note_read, arginfo_git_note_read) + PHP_FE(git_note_message, arginfo_git_note_message) + PHP_FE(git_note_oid, arginfo_git_note_oid) + PHP_FE(git_note_create, arginfo_git_note_create) + PHP_FE(git_note_remove, arginfo_git_note_remove) + PHP_FE(git_note_free, arginfo_git_note_free) + PHP_FE(git_note_default_ref, arginfo_git_note_default_ref) + PHP_FE(git_note_foreach, arginfo_git_note_foreach) + + /* odb */ + PHP_FE(git_odb_new, arginfo_git_odb_new) + PHP_FE(git_odb_open, arginfo_git_odb_open) + PHP_FE(git_odb_add_disk_alternate, arginfo_git_odb_add_disk_alternate) + PHP_FE(git_odb_free, arginfo_git_odb_free) + PHP_FE(git_odb_read, arginfo_git_odb_read) + PHP_FE(git_odb_read_prefix, arginfo_git_odb_read_prefix) + PHP_FE(git_odb_read_header, arginfo_git_odb_read_header) + PHP_FE(git_odb_exists, arginfo_git_odb_exists) + PHP_FE(git_odb_refresh, arginfo_git_odb_refresh) + PHP_FE(git_odb_foreach, arginfo_git_odb_foreach) + PHP_FE(git_odb_write, arginfo_git_odb_write) + PHP_FE(git_odb_open_wstream, arginfo_git_odb_open_wstream) + PHP_FE(git_odb_stream_write, arginfo_git_odb_stream_write) + PHP_FE(git_odb_stream_finalize_write, arginfo_git_odb_stream_finalize_write) + PHP_FE(git_odb_stream_read, arginfo_git_odb_stream_read) + PHP_FE(git_odb_stream_free, arginfo_git_odb_stream_free) + PHP_FE(git_odb_open_rstream, arginfo_git_odb_open_rstream) + PHP_FE(git_odb_write_pack, arginfo_git_odb_write_pack) + PHP_FE(git_odb_hash, arginfo_git_odb_hash) + PHP_FE(git_odb_hashfile, arginfo_git_odb_hashfile) + PHP_FE(git_odb_object_dup, arginfo_git_odb_object_dup) + PHP_FE(git_odb_object_free, arginfo_git_odb_object_free) + PHP_FE(git_odb_object_id, arginfo_git_odb_object_id) + PHP_FE(git_odb_object_data, arginfo_git_odb_object_data) + PHP_FE(git_odb_object_size, arginfo_git_odb_object_size) + PHP_FE(git_odb_object_type, arginfo_git_odb_object_type) + PHP_FE(git_odb_add_backend, arginfo_git_odb_add_backend) + PHP_FE(git_odb_add_alternate, arginfo_git_odb_add_alternate) + PHP_FE(git_odb_num_backends, arginfo_git_odb_num_backends) + PHP_FE(git_odb_get_backend, arginfo_git_odb_get_backend) + + PHP_FE(git_odb_backend_new, arginfo_git_odb_backend_new) + + /* reflog */ + PHP_FE(git_reflog_read, arginfo_git_reflog_read) + PHP_FE(git_reflog_write, arginfo_git_reflog_write) + PHP_FE(git_reflog_append, arginfo_git_reflog_append) + PHP_FE(git_reflog_append_to, arginfo_git_reflog_append_to) + PHP_FE(git_reflog_rename, arginfo_git_reflog_rename) + PHP_FE(git_reflog_delete, arginfo_git_reflog_delete) + PHP_FE(git_reflog_entrycount, arginfo_git_reflog_entrycount) + PHP_FE(git_reflog_entry_byindex, arginfo_git_reflog_entry_byindex) + PHP_FE(git_reflog_drop, arginfo_git_reflog_drop) + PHP_FE(git_reflog_entry_id_old, arginfo_git_reflog_entry_id_old) + PHP_FE(git_reflog_entry_id_new, arginfo_git_reflog_entry_id_new) + PHP_FE(git_reflog_entry_committer, arginfo_git_reflog_entry_committer) + PHP_FE(git_reflog_entry_message, arginfo_git_reflog_entry_message) + PHP_FE(git_reflog_free, arginfo_git_reflog_free) + + /* packbuilder */ + PHP_FE(git_packbuilder_new, arginfo_git_packbuilder_new) + PHP_FE(git_packbuilder_set_threads, arginfo_git_packbuilder_set_threads) + PHP_FE(git_packbuilder_insert, arginfo_git_packbuilder_insert) + PHP_FE(git_packbuilder_insert_tree, arginfo_git_packbuilder_insert_tree) + PHP_FE(git_packbuilder_insert_commit, arginfo_git_packbuilder_insert_commit) + PHP_FE(git_packbuilder_write, arginfo_git_packbuilder_write) + PHP_FE(git_packbuilder_hash, arginfo_git_packbuilder_hash) + PHP_FE(git_packbuilder_foreach, arginfo_git_packbuilder_foreach) + PHP_FE(git_packbuilder_object_count, arginfo_git_packbuilder_object_count) + PHP_FE(git_packbuilder_written, arginfo_git_packbuilder_written) + PHP_FE(git_packbuilder_set_callbacks, arginfo_git_packbuilder_set_callbacks) + PHP_FE(git_packbuilder_free, arginfo_git_packbuilder_free) + + /* stash */ + PHP_FE(git_stash_save, arginfo_git_stash_save) + PHP_FE(git_stash_foreach, arginfo_git_stash_foreach) + PHP_FE(git_stash_drop, arginfo_git_stash_drop) + + /* signature */ + PHP_FE(git_signature_new, arginfo_git_signature_new) + PHP_FE(git_signature_now, arginfo_git_signature_now) + PHP_FE(git_signature_default, arginfo_git_signature_default) + + /* reset */ + PHP_FE(git_reset, arginfo_git_reset) + PHP_FE(git_reset_default, arginfo_git_reset_default) + + /* message */ + PHP_FE(git_message_prettify, arginfo_git_message_prettify) + + /* submodule */ + PHP_FE(git_submodule_lookup, arginfo_git_submodule_lookup) + PHP_FE(git_submodule_foreach, arginfo_git_submodule_foreach) + PHP_FE(git_submodule_add_setup, arginfo_git_submodule_add_setup) + PHP_FE(git_submodule_add_finalize, arginfo_git_submodule_add_finalize) + PHP_FE(git_submodule_add_to_index, arginfo_git_submodule_add_to_index) + PHP_FE(git_submodule_save, arginfo_git_submodule_save) + PHP_FE(git_submodule_owner, arginfo_git_submodule_owner) + PHP_FE(git_submodule_name, arginfo_git_submodule_name) + PHP_FE(git_submodule_path, arginfo_git_submodule_path) + PHP_FE(git_submodule_url, arginfo_git_submodule_url) + PHP_FE(git_submodule_set_url, arginfo_git_submodule_set_url) + PHP_FE(git_submodule_index_id, arginfo_git_submodule_index_id) + PHP_FE(git_submodule_head_id, arginfo_git_submodule_head_id) + PHP_FE(git_submodule_wd_id, arginfo_git_submodule_wd_id) + PHP_FE(git_submodule_ignore, arginfo_git_submodule_ignore) + PHP_FE(git_submodule_set_ignore, arginfo_git_submodule_set_ignore) + PHP_FE(git_submodule_update, arginfo_git_submodule_update) + PHP_FE(git_submodule_set_update, arginfo_git_submodule_set_update) + PHP_FE(git_submodule_fetch_recurse_submodules, arginfo_git_submodule_fetch_recurse_submodules) + PHP_FE(git_submodule_set_fetch_recurse_submodules, arginfo_git_submodule_set_fetch_recurse_submodules) + PHP_FE(git_submodule_init, arginfo_git_submodule_init) + PHP_FE(git_submodule_sync, arginfo_git_submodule_sync) + PHP_FE(git_submodule_open, arginfo_git_submodule_open) + PHP_FE(git_submodule_reload, arginfo_git_submodule_reload) + PHP_FE(git_submodule_reload_all, arginfo_git_submodule_reload_all) + PHP_FE(git_submodule_status, arginfo_git_submodule_status) + PHP_FE(git_submodule_location, arginfo_git_submodule_location) + + /* attr */ + PHP_FE(git_attr_value, arginfo_git_attr_value) + PHP_FE(git_attr_get, arginfo_git_attr_get) + PHP_FE(git_attr_get_many, arginfo_git_attr_get_many) + PHP_FE(git_attr_foreach, arginfo_git_attr_foreach) + PHP_FE(git_attr_cache_flush, arginfo_git_attr_cache_flush) + PHP_FE(git_attr_add_macro, arginfo_git_attr_add_macro) + + /* giterr */ + PHP_FE(giterr_last, arginfo_giterr_last) + PHP_FE(giterr_clear, arginfo_giterr_clear) + PHP_FE(giterr_detach, arginfo_giterr_detach) + PHP_FE(giterr_set_str, arginfo_giterr_set_str) + PHP_FE(giterr_set_oom, arginfo_giterr_set_oom) + + /* push */ + PHP_FE(git_push_new, arginfo_git_push_new) + PHP_FE(git_push_set_options, arginfo_git_push_set_options) + PHP_FE(git_push_set_callbacks, arginfo_git_push_set_callbacks) + PHP_FE(git_push_add_refspec, arginfo_git_push_add_refspec) + PHP_FE(git_push_update_tips, arginfo_git_push_update_tips) + PHP_FE(git_push_finish, arginfo_git_push_finish) + PHP_FE(git_push_unpack_ok, arginfo_git_push_unpack_ok) + PHP_FE(git_push_status_foreach, arginfo_git_push_status_foreach) + PHP_FE(git_push_free, arginfo_git_push_free) + + /* refspec */ + PHP_FE(git_refspec_src, arginfo_git_refspec_src) + PHP_FE(git_refspec_dst, arginfo_git_refspec_dst) + PHP_FE(git_refspec_string, arginfo_git_refspec_string) + PHP_FE(git_refspec_force, arginfo_git_refspec_force) + PHP_FE(git_refspec_direction, arginfo_git_refspec_direction) + PHP_FE(git_refspec_src_matches, arginfo_git_refspec_src_matches) + PHP_FE(git_refspec_dst_matches, arginfo_git_refspec_dst_matches) + PHP_FE(git_refspec_transform, arginfo_git_refspec_transform) + PHP_FE(git_refspec_rtransform, arginfo_git_refspec_rtransform) + + /* graph */ + PHP_FE(git_graph_ahead_behind, arginfo_git_graph_ahead_behind) + + /* blame */ + PHP_FE(git_blame_get_hunk_count, arginfo_git_blame_get_hunk_count) + PHP_FE(git_blame_get_hunk_byindex, arginfo_git_blame_get_hunk_byindex) + PHP_FE(git_blame_get_hunk_byline, arginfo_git_blame_get_hunk_byline) + PHP_FE(git_blame_file, arginfo_git_blame_file) + PHP_FE(git_blame_buffer, arginfo_git_blame_buffer) + PHP_FE(git_blame_free, arginfo_git_blame_free) + PHP_FE(git_blame_options_new, arginfo_git_blame_options_new) + + /* misc */ + PHP_FE(git_resource_type, arginfo_git_resource_type) + PHP_FE(git_libgit2_capabilities, NULL) + PHP_FE(git_libgit2_version, NULL) + PHP_FE_END +}; + +PHP_MINFO_FUNCTION(git2) +{ + char buf[32] = {0}; + int major, minor, rev; + + php_printf("PHP Git2 Extension\n"); + + git_libgit2_version(&major, &minor, &rev); + snprintf(buf, 32, "%d.%d.%d", major, minor, rev); + + php_info_print_table_start(); + php_info_print_table_header(2, "Git2 Support", "enabled"); + php_info_print_table_header(2, "libgit2 version", buf); + php_info_print_table_end(); +} + +PHP_INI_BEGIN() + STD_PHP_INI_BOOLEAN("git2.dummy", "1", PHP_INI_ALL, OnUpdateLong, dummy, zend_git2_globals, git2_globals) +PHP_INI_END() + +static PHP_GINIT_FUNCTION(git2) +{ +} + +static PHP_GSHUTDOWN_FUNCTION(git2) +{ +} + + +static void php_git2_odb_backend_foreach_callback_free_storage(php_git2_odb_backend_foreach_callback *object TSRMLS_DC) +{ + zend_object_std_dtor(&object->zo TSRMLS_CC); + efree(object); +} + +zend_object_value php_git2_odb_backend_foreach_callback_new(zend_class_entry *ce TSRMLS_DC) +{ + zend_object_value retval; + PHP_GIT2_STD_CREATE_OBJECT(php_git2_odb_backend_foreach_callback); + return retval; +} + +PHP_MINIT_FUNCTION(git2) +{ + zend_class_entry ce; + REGISTER_INI_ENTRIES(); + + + INIT_CLASS_ENTRY(ce, "Git2ODBBackendForeachCallback", 0); + php_git2_odb_backend_foreach_callback_class_entry = zend_register_internal_class(&ce TSRMLS_CC); + zend_register_class_alias_ex(ZEND_NS_NAME("Git2\\ODB\\Backend", "ForeachCallback"), sizeof(ZEND_NS_NAME("Git2\\ODB\\Backend", "ForeachCallback"))-1, php_git2_odb_backend_foreach_callback_class_entry TSRMLS_CC); + php_git2_odb_backend_foreach_callback_class_entry->create_object = php_git2_odb_backend_foreach_callback_new; + + git2_resource_handle = zend_register_list_destructors_ex(destruct_git2, NULL, PHP_GIT2_RESOURCE_NAME, module_number); + + REGISTER_LONG_CONSTANT("GIT_TYPE_REPOSITORY", PHP_GIT2_TYPE_REPOSITORY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_COMMIT", PHP_GIT2_TYPE_COMMIT,CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_TREE", PHP_GIT2_TYPE_TREE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_TREE_ENTRY", PHP_GIT2_TYPE_TREE_ENTRY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_BLOB", PHP_GIT2_TYPE_BLOB, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_REVWALK", PHP_GIT2_TYPE_REVWALK, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_TREEBUILDER", PHP_GIT2_TYPE_TREEBUILDER, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_REFERENCE", PHP_GIT2_TYPE_REFERENCE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_CONFIG", PHP_GIT2_TYPE_CONFIG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_OBJECT", PHP_GIT2_TYPE_OBJECT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_INDEX", PHP_GIT2_TYPE_INDEX, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_ODB", PHP_GIT2_TYPE_ODB, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_REFDB", PHP_GIT2_TYPE_REFDB, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_BRANCH_ITERATOR", PHP_GIT2_TYPE_BRANCH_ITERATOR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_TAG", PHP_GIT2_TYPE_TAG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_CRED", PHP_GIT2_TYPE_CRED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_TRANSPORT", PHP_GIT2_TYPE_TRANSPORT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_REMOTE", PHP_GIT2_TYPE_REMOTE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_DIFF", PHP_GIT2_TYPE_DIFF, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_MERGE_RESULT", PHP_GIT2_TYPE_MERGE_RESULT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_MERGE_HEAD", PHP_GIT2_TYPE_MERGE_HEAD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_PATHSPEC", PHP_GIT2_TYPE_PATHSPEC, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_PATHSPEC_MATCH_LIST", PHP_GIT2_TYPE_PATHSPEC_MATCH_LIST, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_PATCH", PHP_GIT2_TYPE_PATCH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_DIFF_HUNK", PHP_GIT2_TYPE_DIFF_HUNK, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_STATUS_LIST", PHP_GIT2_TYPE_STATUS_LIST, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_BUF", PHP_GIT2_TYPE_BUF, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_FILTER_LIST", PHP_GIT2_TYPE_FILTER_LIST, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_FILTER_SOURCE", PHP_GIT2_TYPE_FILTER_SOURCE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TYPE_DIFF_LINE", PHP_GIT2_TYPE_DIFF_LINE, CONST_CS | CONST_PERSISTENT); + + /* git_ref_t */ + REGISTER_LONG_CONSTANT("GIT_REF_INVALID", GIT_REF_INVALID, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REF_OID", GIT_REF_OID, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REF_SYMBOLIC", GIT_REF_SYMBOLIC, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REF_LISTALL", GIT_REF_LISTALL, CONST_CS | CONST_PERSISTENT); + /* git_branch_t */ + REGISTER_LONG_CONSTANT("GIT_BRANCH_LOCAL", GIT_BRANCH_LOCAL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_BRANCH_REMOTE", GIT_BRANCH_REMOTE, CONST_CS | CONST_PERSISTENT); + /* git_filemode_t */ + REGISTER_LONG_CONSTANT("GIT_FILEMODE_NEW", GIT_FILEMODE_NEW, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_FILEMODE_TREE", GIT_FILEMODE_TREE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_FILEMODE_BLOB", GIT_FILEMODE_BLOB, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_FILEMODE_BLOB_EXECUTABLE", GIT_FILEMODE_BLOB_EXECUTABLE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_FILEMODE_LINK", GIT_FILEMODE_LINK, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_FILEMODE_COMMIT", GIT_FILEMODE_COMMIT, CONST_CS | CONST_PERSISTENT); + /* git_submodule_update_t */ + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_UPDATE_RESET", GIT_SUBMODULE_UPDATE_RESET, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_UPDATE_CHECKOUT", GIT_SUBMODULE_UPDATE_CHECKOUT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_UPDATE_REBASE", GIT_SUBMODULE_UPDATE_REBASE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_UPDATE_MERGE", GIT_SUBMODULE_UPDATE_MERGE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_UPDATE_NONE", GIT_SUBMODULE_UPDATE_NONE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_UPDATE_DEFAULT", GIT_SUBMODULE_UPDATE_DEFAULT, CONST_CS | CONST_PERSISTENT); + /* git_submodule_ignore_t */ + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_IGNORE_RESET", GIT_SUBMODULE_IGNORE_RESET, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_IGNORE_NONE", GIT_SUBMODULE_IGNORE_NONE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_IGNORE_UNTRACKED", GIT_SUBMODULE_IGNORE_UNTRACKED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_IGNORE_DIRTY", GIT_SUBMODULE_IGNORE_DIRTY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_IGNORE_ALL", GIT_SUBMODULE_IGNORE_ALL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_IGNORE_DEFAULT", GIT_SUBMODULE_IGNORE_DEFAULT, CONST_CS | CONST_PERSISTENT); + + /* git_attr_t */ + REGISTER_LONG_CONSTANT("GIT_ATTR_UNSPECIFIED_T", GIT_ATTR_UNSPECIFIED_T, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_ATTR_TRUE_T", GIT_ATTR_TRUE_T, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_ATTR_FALSE_T", GIT_ATTR_FALSE_T, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_ATTR_VALUE_T", GIT_ATTR_VALUE_T, CONST_CS | CONST_PERSISTENT); + + /* git_blame_flag_t */ + REGISTER_LONG_CONSTANT("GIT_BLAME_NORMAL", GIT_BLAME_NORMAL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_BLAME_TRACK_COPIES_SAME_FILE", GIT_BLAME_TRACK_COPIES_SAME_FILE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES", GIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES", GIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES", GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES, CONST_CS | CONST_PERSISTENT); + + /* git_checkout_strategy_t */ + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_NONE", GIT_CHECKOUT_NONE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_SAFE", GIT_CHECKOUT_SAFE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_SAFE_CREATE", GIT_CHECKOUT_SAFE_CREATE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_FORCE", GIT_CHECKOUT_FORCE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_ALLOW_CONFLICTS", GIT_CHECKOUT_ALLOW_CONFLICTS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_REMOVE_UNTRACKED", GIT_CHECKOUT_REMOVE_UNTRACKED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_REMOVE_IGNORED", GIT_CHECKOUT_REMOVE_IGNORED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_UPDATE_ONLY", GIT_CHECKOUT_UPDATE_ONLY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_DONT_UPDATE_INDEX", GIT_CHECKOUT_DONT_UPDATE_INDEX, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_NO_REFRESH", GIT_CHECKOUT_NO_REFRESH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_SKIP_UNMERGED", GIT_CHECKOUT_SKIP_UNMERGED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_USE_OURS", GIT_CHECKOUT_USE_OURS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_USE_THEIRS", GIT_CHECKOUT_USE_THEIRS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH", GIT_CHECKOUT_DISABLE_PATHSPEC_MATCH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES", GIT_CHECKOUT_SKIP_LOCKED_DIRECTORIES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_UPDATE_SUBMODULES", GIT_CHECKOUT_UPDATE_SUBMODULES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED", GIT_CHECKOUT_UPDATE_SUBMODULES_IF_CHANGED, CONST_CS | CONST_PERSISTENT); + + /* git_checkout_notify_t */ + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_NOTIFY_NONE", GIT_CHECKOUT_NOTIFY_NONE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_NOTIFY_CONFLICT", GIT_CHECKOUT_NOTIFY_CONFLICT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_NOTIFY_DIRTY", GIT_CHECKOUT_NOTIFY_DIRTY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_NOTIFY_UPDATED", GIT_CHECKOUT_NOTIFY_UPDATED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_NOTIFY_UNTRACKED", GIT_CHECKOUT_NOTIFY_UNTRACKED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_NOTIFY_IGNORED", GIT_CHECKOUT_NOTIFY_IGNORED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CHECKOUT_NOTIFY_ALL", GIT_CHECKOUT_NOTIFY_ALL, CONST_CS | CONST_PERSISTENT); + + /* git_cap_t */ + REGISTER_LONG_CONSTANT("GIT_CAP_THREADS", GIT_CAP_THREADS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CAP_HTTPS", GIT_CAP_HTTPS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CAP_SSH", GIT_CAP_SSH, CONST_CS | CONST_PERSISTENT); + + /* git_libgit2_opt_t */ + REGISTER_LONG_CONSTANT("GIT_OPT_GET_MWINDOW_SIZE", GIT_OPT_GET_MWINDOW_SIZE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_OPT_SET_MWINDOW_SIZE", GIT_OPT_SET_MWINDOW_SIZE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_OPT_GET_MWINDOW_MAPPED_LIMIT", GIT_OPT_GET_MWINDOW_MAPPED_LIMIT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_OPT_SET_MWINDOW_MAPPED_LIMIT", GIT_OPT_SET_MWINDOW_MAPPED_LIMIT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_OPT_GET_SEARCH_PATH", GIT_OPT_GET_SEARCH_PATH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_OPT_SET_SEARCH_PATH", GIT_OPT_SET_SEARCH_PATH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_OPT_SET_CACHE_OBJECT_LIMIT", GIT_OPT_SET_CACHE_OBJECT_LIMIT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_OPT_SET_CACHE_MAX_SIZE", GIT_OPT_SET_CACHE_MAX_SIZE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_OPT_ENABLE_CACHING", GIT_OPT_ENABLE_CACHING, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_OPT_GET_CACHED_MEMORY", GIT_OPT_GET_CACHED_MEMORY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_OPT_GET_TEMPLATE_PATH", GIT_OPT_GET_TEMPLATE_PATH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_OPT_SET_TEMPLATE_PATH", GIT_OPT_SET_TEMPLATE_PATH, CONST_CS | CONST_PERSISTENT); + + /* git_config_level_t */ + REGISTER_LONG_CONSTANT("GIT_CONFIG_LEVEL_SYSTEM", GIT_CONFIG_LEVEL_SYSTEM, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CONFIG_LEVEL_XDG", GIT_CONFIG_LEVEL_XDG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CONFIG_LEVEL_GLOBAL", GIT_CONFIG_LEVEL_GLOBAL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CONFIG_LEVEL_LOCAL", GIT_CONFIG_LEVEL_LOCAL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CONFIG_LEVEL_APP", GIT_CONFIG_LEVEL_APP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CONFIG_HIGHEST_LEVEL", GIT_CONFIG_HIGHEST_LEVEL, CONST_CS | CONST_PERSISTENT); + + /* git_cvar_t */ + REGISTER_LONG_CONSTANT("GIT_CVAR_FALSE", GIT_CVAR_FALSE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CVAR_TRUE", GIT_CVAR_TRUE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CVAR_INT32", GIT_CVAR_INT32, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CVAR_STRING", GIT_CVAR_STRING, CONST_CS | CONST_PERSISTENT); + + /* git_diff_option_t */ + REGISTER_LONG_CONSTANT("GIT_DIFF_NORMAL", GIT_DIFF_NORMAL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_REVERSE", GIT_DIFF_REVERSE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_INCLUDE_IGNORED", GIT_DIFF_INCLUDE_IGNORED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_RECURSE_IGNORED_DIRS", GIT_DIFF_RECURSE_IGNORED_DIRS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_INCLUDE_UNTRACKED", GIT_DIFF_INCLUDE_UNTRACKED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_RECURSE_UNTRACKED_DIRS", GIT_DIFF_RECURSE_UNTRACKED_DIRS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_INCLUDE_UNMODIFIED", GIT_DIFF_INCLUDE_UNMODIFIED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_INCLUDE_TYPECHANGE", GIT_DIFF_INCLUDE_TYPECHANGE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_INCLUDE_TYPECHANGE_TREES", GIT_DIFF_INCLUDE_TYPECHANGE_TREES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_IGNORE_FILEMODE", GIT_DIFF_IGNORE_FILEMODE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_IGNORE_SUBMODULES", GIT_DIFF_IGNORE_SUBMODULES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_IGNORE_CASE", GIT_DIFF_IGNORE_CASE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_DISABLE_PATHSPEC_MATCH", GIT_DIFF_DISABLE_PATHSPEC_MATCH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_SKIP_BINARY_CHECK", GIT_DIFF_SKIP_BINARY_CHECK, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS", GIT_DIFF_ENABLE_FAST_UNTRACKED_DIRS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_FORCE_TEXT", GIT_DIFF_FORCE_TEXT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_FORCE_BINARY", GIT_DIFF_FORCE_BINARY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_IGNORE_WHITESPACE", GIT_DIFF_IGNORE_WHITESPACE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_IGNORE_WHITESPACE_CHANGE", GIT_DIFF_IGNORE_WHITESPACE_CHANGE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_IGNORE_WHITESPACE_EOL", GIT_DIFF_IGNORE_WHITESPACE_EOL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_SHOW_UNTRACKED_CONTENT", GIT_DIFF_SHOW_UNTRACKED_CONTENT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_SHOW_UNMODIFIED", GIT_DIFF_SHOW_UNMODIFIED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_PATIENCE", GIT_DIFF_PATIENCE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_MINIMAL", GIT_DIFF_MINIMAL, CONST_CS | CONST_PERSISTENT); + /* git_diff_flag_t */ + REGISTER_LONG_CONSTANT("GIT_DIFF_FLAG_BINARY", GIT_DIFF_FLAG_BINARY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_FLAG_NOT_BINARY", GIT_DIFF_FLAG_NOT_BINARY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_FLAG_VALID_OID", GIT_DIFF_FLAG_VALID_OID, CONST_CS | CONST_PERSISTENT); + /* git_delta_t */ + REGISTER_LONG_CONSTANT("GIT_DELTA_UNMODIFIED", GIT_DELTA_UNMODIFIED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DELTA_ADDED", GIT_DELTA_ADDED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DELTA_DELETED", GIT_DELTA_DELETED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DELTA_MODIFIED", GIT_DELTA_MODIFIED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DELTA_RENAMED", GIT_DELTA_RENAMED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DELTA_COPIED", GIT_DELTA_COPIED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DELTA_IGNORED", GIT_DELTA_IGNORED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DELTA_UNTRACKED", GIT_DELTA_UNTRACKED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DELTA_TYPECHANGE", GIT_DELTA_TYPECHANGE, CONST_CS | CONST_PERSISTENT); + /* git_diff_line_t */ + REGISTER_LONG_CONSTANT("GIT_DIFF_LINE_CONTEXT", GIT_DIFF_LINE_CONTEXT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_LINE_ADDITION", GIT_DIFF_LINE_ADDITION, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_LINE_DELETION", GIT_DIFF_LINE_DELETION, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_LINE_CONTEXT_EOFNL", GIT_DIFF_LINE_CONTEXT_EOFNL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_LINE_ADD_EOFNL", GIT_DIFF_LINE_ADD_EOFNL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_LINE_DEL_EOFNL", GIT_DIFF_LINE_DEL_EOFNL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_LINE_FILE_HDR", GIT_DIFF_LINE_FILE_HDR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_LINE_HUNK_HDR", GIT_DIFF_LINE_HUNK_HDR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_LINE_BINARY", GIT_DIFF_LINE_BINARY, CONST_CS | CONST_PERSISTENT); + /* git_diff_find_t */ + REGISTER_LONG_CONSTANT("GIT_DIFF_FIND_RENAMES", GIT_DIFF_FIND_RENAMES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_FIND_RENAMES_FROM_REWRITES", GIT_DIFF_FIND_RENAMES_FROM_REWRITES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_FIND_COPIES", GIT_DIFF_FIND_COPIES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED", GIT_DIFF_FIND_COPIES_FROM_UNMODIFIED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_FIND_REWRITES", GIT_DIFF_FIND_REWRITES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_BREAK_REWRITES", GIT_DIFF_BREAK_REWRITES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_FIND_AND_BREAK_REWRITES", GIT_DIFF_FIND_AND_BREAK_REWRITES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("(GIT_DIFF_FIND_REWRITES | GIT_DIFF_BREAK_REWRITES)", (GIT_DIFF_FIND_REWRITES | GIT_DIFF_BREAK_REWRITES), CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_FIND_FOR_UNTRACKED", GIT_DIFF_FIND_FOR_UNTRACKED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_FIND_ALL", GIT_DIFF_FIND_ALL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_FIND_IGNORE_LEADING_WHITESPACE", GIT_DIFF_FIND_IGNORE_LEADING_WHITESPACE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_FIND_IGNORE_WHITESPACE", GIT_DIFF_FIND_IGNORE_WHITESPACE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE", GIT_DIFF_FIND_DONT_IGNORE_WHITESPACE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_FIND_EXACT_MATCH_ONLY", GIT_DIFF_FIND_EXACT_MATCH_ONLY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY", GIT_DIFF_BREAK_REWRITES_FOR_RENAMES_ONLY, CONST_CS | CONST_PERSISTENT); + /* git_diff_format_t */ + REGISTER_LONG_CONSTANT("GIT_DIFF_FORMAT_PATCH", GIT_DIFF_FORMAT_PATCH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_FORMAT_PATCH_HEADER", GIT_DIFF_FORMAT_PATCH_HEADER, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_FORMAT_RAW", GIT_DIFF_FORMAT_RAW, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_FORMAT_NAME_ONLY", GIT_DIFF_FORMAT_NAME_ONLY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIFF_FORMAT_NAME_STATUS", GIT_DIFF_FORMAT_NAME_STATUS, CONST_CS | CONST_PERSISTENT); + + /* git_error_code */ + REGISTER_LONG_CONSTANT("GIT_OK", GIT_OK, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_ERROR", GIT_ERROR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_ENOTFOUND", GIT_ENOTFOUND, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_EEXISTS", GIT_EEXISTS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_EAMBIGUOUS", GIT_EAMBIGUOUS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_EBUFS", GIT_EBUFS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_EUSER", GIT_EUSER, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_EBAREREPO", GIT_EBAREREPO, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_EUNBORNBRANCH", GIT_EUNBORNBRANCH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_EUNMERGED", GIT_EUNMERGED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_ENONFASTFORWARD", GIT_ENONFASTFORWARD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_EINVALIDSPEC", GIT_EINVALIDSPEC, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_EMERGECONFLICT", GIT_EMERGECONFLICT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_ELOCKED", GIT_ELOCKED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_PASSTHROUGH", GIT_PASSTHROUGH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_ITEROVER", GIT_ITEROVER, CONST_CS | CONST_PERSISTENT); + + /* git_error_t */ + REGISTER_LONG_CONSTANT("GITERR_NONE", GITERR_NONE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_NOMEMORY", GITERR_NOMEMORY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_OS", GITERR_OS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_INVALID", GITERR_INVALID, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_REFERENCE", GITERR_REFERENCE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_ZLIB", GITERR_ZLIB, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_REPOSITORY", GITERR_REPOSITORY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_CONFIG", GITERR_CONFIG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_REGEX", GITERR_REGEX, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_ODB", GITERR_ODB, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_INDEX", GITERR_INDEX, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_OBJECT", GITERR_OBJECT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_NET", GITERR_NET, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_TAG", GITERR_TAG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_TREE", GITERR_TREE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_INDEXER", GITERR_INDEXER, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_SSL", GITERR_SSL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_SUBMODULE", GITERR_SUBMODULE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_THREAD", GITERR_THREAD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_STASH", GITERR_STASH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_CHECKOUT", GITERR_CHECKOUT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_FETCHHEAD", GITERR_FETCHHEAD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_MERGE", GITERR_MERGE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_SSH", GITERR_SSH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GITERR_FILTER", GITERR_FILTER, CONST_CS | CONST_PERSISTENT); + + /* git_filter_mode_t */ + REGISTER_LONG_CONSTANT("GIT_FILTER_TO_WORKTREE", GIT_FILTER_TO_WORKTREE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_FILTER_SMUDGE", GIT_FILTER_SMUDGE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_FILTER_TO_ODB", GIT_FILTER_TO_ODB, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_FILTER_CLEAN", GIT_FILTER_CLEAN, CONST_CS | CONST_PERSISTENT); + + /* git_indexcap_t */ + REGISTER_LONG_CONSTANT("GIT_INDEXCAP_IGNORE_CASE", GIT_INDEXCAP_IGNORE_CASE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_INDEXCAP_NO_FILEMODE", GIT_INDEXCAP_NO_FILEMODE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_INDEXCAP_NO_SYMLINKS", GIT_INDEXCAP_NO_SYMLINKS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_INDEXCAP_FROM_OWNER", GIT_INDEXCAP_FROM_OWNER, CONST_CS | CONST_PERSISTENT); + /* git_index_add_option_t */ + REGISTER_LONG_CONSTANT("GIT_INDEX_ADD_DEFAULT", GIT_INDEX_ADD_DEFAULT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_INDEX_ADD_FORCE", GIT_INDEX_ADD_FORCE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH", GIT_INDEX_ADD_DISABLE_PATHSPEC_MATCH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_INDEX_ADD_CHECK_PATHSPEC", GIT_INDEX_ADD_CHECK_PATHSPEC, CONST_CS | CONST_PERSISTENT); + + /* git_merge_tree_flag_t */ + REGISTER_LONG_CONSTANT("GIT_MERGE_TREE_FIND_RENAMES", GIT_MERGE_TREE_FIND_RENAMES, CONST_CS | CONST_PERSISTENT); + /* git_merge_automerge_flags */ + REGISTER_LONG_CONSTANT("GIT_MERGE_AUTOMERGE_NORMAL", GIT_MERGE_AUTOMERGE_NORMAL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_MERGE_AUTOMERGE_NONE", GIT_MERGE_AUTOMERGE_NONE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_MERGE_AUTOMERGE_FAVOR_OURS", GIT_MERGE_AUTOMERGE_FAVOR_OURS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_MERGE_AUTOMERGE_FAVOR_THEIRS", GIT_MERGE_AUTOMERGE_FAVOR_THEIRS, CONST_CS | CONST_PERSISTENT); + /* git_merge_flags_t */ + REGISTER_LONG_CONSTANT("GIT_MERGE_NO_FASTFORWARD", GIT_MERGE_NO_FASTFORWARD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_MERGE_FASTFORWARD_ONLY", GIT_MERGE_FASTFORWARD_ONLY, CONST_CS | CONST_PERSISTENT); + + /* git_direction */ + REGISTER_LONG_CONSTANT("GIT_DIRECTION_FETCH", GIT_DIRECTION_FETCH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_DIRECTION_PUSH", GIT_DIRECTION_PUSH, CONST_CS | CONST_PERSISTENT); + + /* git_odb_stream_t */ + REGISTER_LONG_CONSTANT("GIT_STREAM_RDONLY", GIT_STREAM_RDONLY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STREAM_WRONLY", GIT_STREAM_WRONLY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STREAM_RW", GIT_STREAM_RW, CONST_CS | CONST_PERSISTENT); + + /* git_packbuilder_stage_t */ + REGISTER_LONG_CONSTANT("GIT_PACKBUILDER_ADDING_OBJECTS", GIT_PACKBUILDER_ADDING_OBJECTS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_PACKBUILDER_DELTAFICATION", GIT_PACKBUILDER_DELTAFICATION, CONST_CS | CONST_PERSISTENT); + + /* git_pathspec_flag_t */ + REGISTER_LONG_CONSTANT("GIT_PATHSPEC_DEFAULT", GIT_PATHSPEC_DEFAULT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_PATHSPEC_IGNORE_CASE", GIT_PATHSPEC_IGNORE_CASE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_PATHSPEC_USE_CASE", GIT_PATHSPEC_USE_CASE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_PATHSPEC_NO_GLOB", GIT_PATHSPEC_NO_GLOB, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_PATHSPEC_NO_MATCH_ERROR", GIT_PATHSPEC_NO_MATCH_ERROR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_PATHSPEC_FIND_FAILURES", GIT_PATHSPEC_FIND_FAILURES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_PATHSPEC_FAILURES_ONLY", GIT_PATHSPEC_FAILURES_ONLY, CONST_CS | CONST_PERSISTENT); + + /* git_reference_normalize_t */ + REGISTER_LONG_CONSTANT("GIT_REF_FORMAT_NORMAL", GIT_REF_FORMAT_NORMAL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REF_FORMAT_ALLOW_ONELEVEL", GIT_REF_FORMAT_ALLOW_ONELEVEL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REF_FORMAT_REFSPEC_PATTERN", GIT_REF_FORMAT_REFSPEC_PATTERN, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REF_FORMAT_REFSPEC_SHORTHAND", GIT_REF_FORMAT_REFSPEC_SHORTHAND, CONST_CS | CONST_PERSISTENT); + + /* git_remote_autotag_option_t */ + REGISTER_LONG_CONSTANT("GIT_REMOTE_DOWNLOAD_TAGS_AUTO", GIT_REMOTE_DOWNLOAD_TAGS_AUTO, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REMOTE_DOWNLOAD_TAGS_NONE", GIT_REMOTE_DOWNLOAD_TAGS_NONE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REMOTE_DOWNLOAD_TAGS_ALL", GIT_REMOTE_DOWNLOAD_TAGS_ALL, CONST_CS | CONST_PERSISTENT); + + /* git_repository_open_flag_t */ + REGISTER_LONG_CONSTANT("GIT_REPOSITORY_OPEN_NO_SEARCH", GIT_REPOSITORY_OPEN_NO_SEARCH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REPOSITORY_OPEN_CROSS_FS", GIT_REPOSITORY_OPEN_CROSS_FS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REPOSITORY_OPEN_BARE", GIT_REPOSITORY_OPEN_BARE, CONST_CS | CONST_PERSISTENT); + /* git_repository_init_flag_t */ + REGISTER_LONG_CONSTANT("GIT_REPOSITORY_INIT_BARE", GIT_REPOSITORY_INIT_BARE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REPOSITORY_INIT_NO_REINIT", GIT_REPOSITORY_INIT_NO_REINIT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REPOSITORY_INIT_NO_DOTGIT_DIR", GIT_REPOSITORY_INIT_NO_DOTGIT_DIR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REPOSITORY_INIT_MKDIR", GIT_REPOSITORY_INIT_MKDIR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REPOSITORY_INIT_MKPATH", GIT_REPOSITORY_INIT_MKPATH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE", GIT_REPOSITORY_INIT_EXTERNAL_TEMPLATE, CONST_CS | CONST_PERSISTENT); + /* git_repository_init_mode_t */ + REGISTER_LONG_CONSTANT("GIT_REPOSITORY_INIT_SHARED_UMASK", GIT_REPOSITORY_INIT_SHARED_UMASK, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REPOSITORY_INIT_SHARED_GROUP", GIT_REPOSITORY_INIT_SHARED_GROUP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REPOSITORY_INIT_SHARED_ALL", GIT_REPOSITORY_INIT_SHARED_ALL, CONST_CS | CONST_PERSISTENT); + /* git_repository_state_t */ + REGISTER_LONG_CONSTANT("GIT_REPOSITORY_STATE_NONE", GIT_REPOSITORY_STATE_NONE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REPOSITORY_STATE_MERGE", GIT_REPOSITORY_STATE_MERGE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REPOSITORY_STATE_REVERT", GIT_REPOSITORY_STATE_REVERT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REPOSITORY_STATE_CHERRY_PICK", GIT_REPOSITORY_STATE_CHERRY_PICK, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REPOSITORY_STATE_BISECT", GIT_REPOSITORY_STATE_BISECT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REPOSITORY_STATE_REBASE", GIT_REPOSITORY_STATE_REBASE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REPOSITORY_STATE_REBASE_INTERACTIVE", GIT_REPOSITORY_STATE_REBASE_INTERACTIVE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REPOSITORY_STATE_REBASE_MERGE", GIT_REPOSITORY_STATE_REBASE_MERGE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REPOSITORY_STATE_APPLY_MAILBOX", GIT_REPOSITORY_STATE_APPLY_MAILBOX, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE", GIT_REPOSITORY_STATE_APPLY_MAILBOX_OR_REBASE, CONST_CS | CONST_PERSISTENT); + + /* git_reset_t */ + REGISTER_LONG_CONSTANT("GIT_RESET_SOFT", GIT_RESET_SOFT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_RESET_MIXED", GIT_RESET_MIXED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_RESET_HARD", GIT_RESET_HARD, CONST_CS | CONST_PERSISTENT); + + /* git_revparse_mode_t */ + REGISTER_LONG_CONSTANT("GIT_REVPARSE_SINGLE", GIT_REVPARSE_SINGLE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REVPARSE_RANGE", GIT_REVPARSE_RANGE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_REVPARSE_MERGE_BASE", GIT_REVPARSE_MERGE_BASE, CONST_CS | CONST_PERSISTENT); + + /* git_stash_flags */ + REGISTER_LONG_CONSTANT("GIT_STASH_DEFAULT", GIT_STASH_DEFAULT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STASH_KEEP_INDEX", GIT_STASH_KEEP_INDEX, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STASH_INCLUDE_UNTRACKED", GIT_STASH_INCLUDE_UNTRACKED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STASH_INCLUDE_IGNORED", GIT_STASH_INCLUDE_IGNORED, CONST_CS | CONST_PERSISTENT); + + /* git_status_t */ + REGISTER_LONG_CONSTANT("GIT_STATUS_CURRENT", GIT_STATUS_CURRENT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_INDEX_NEW", GIT_STATUS_INDEX_NEW, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_INDEX_MODIFIED", GIT_STATUS_INDEX_MODIFIED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_INDEX_DELETED", GIT_STATUS_INDEX_DELETED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_INDEX_RENAMED", GIT_STATUS_INDEX_RENAMED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_INDEX_TYPECHANGE", GIT_STATUS_INDEX_TYPECHANGE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_WT_NEW", GIT_STATUS_WT_NEW, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_WT_MODIFIED", GIT_STATUS_WT_MODIFIED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_WT_DELETED", GIT_STATUS_WT_DELETED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_WT_TYPECHANGE", GIT_STATUS_WT_TYPECHANGE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_WT_RENAMED", GIT_STATUS_WT_RENAMED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_IGNORED", GIT_STATUS_IGNORED, CONST_CS | CONST_PERSISTENT); + /* git_status_show_t */ + REGISTER_LONG_CONSTANT("GIT_STATUS_SHOW_INDEX_AND_WORKDIR", GIT_STATUS_SHOW_INDEX_AND_WORKDIR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_SHOW_INDEX_ONLY", GIT_STATUS_SHOW_INDEX_ONLY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_SHOW_WORKDIR_ONLY", GIT_STATUS_SHOW_WORKDIR_ONLY, CONST_CS | CONST_PERSISTENT); + /* git_status_opt_t */ + REGISTER_LONG_CONSTANT("GIT_STATUS_OPT_INCLUDE_UNTRACKED", GIT_STATUS_OPT_INCLUDE_UNTRACKED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_OPT_INCLUDE_IGNORED", GIT_STATUS_OPT_INCLUDE_IGNORED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_OPT_INCLUDE_UNMODIFIED", GIT_STATUS_OPT_INCLUDE_UNMODIFIED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_OPT_EXCLUDE_SUBMODULES", GIT_STATUS_OPT_EXCLUDE_SUBMODULES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS", GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH", GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_OPT_RECURSE_IGNORED_DIRS", GIT_STATUS_OPT_RECURSE_IGNORED_DIRS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX", GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR", GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_OPT_SORT_CASE_SENSITIVELY", GIT_STATUS_OPT_SORT_CASE_SENSITIVELY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY", GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_OPT_RENAMES_FROM_REWRITES", GIT_STATUS_OPT_RENAMES_FROM_REWRITES, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_STATUS_OPT_NO_REFRESH", GIT_STATUS_OPT_NO_REFRESH, CONST_CS | CONST_PERSISTENT); + + /* git_submodule_status_t */ + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_STATUS_IN_HEAD", GIT_SUBMODULE_STATUS_IN_HEAD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_STATUS_IN_INDEX", GIT_SUBMODULE_STATUS_IN_INDEX, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_STATUS_IN_CONFIG", GIT_SUBMODULE_STATUS_IN_CONFIG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_STATUS_IN_WD", GIT_SUBMODULE_STATUS_IN_WD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_STATUS_INDEX_ADDED", GIT_SUBMODULE_STATUS_INDEX_ADDED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_STATUS_INDEX_DELETED", GIT_SUBMODULE_STATUS_INDEX_DELETED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_STATUS_INDEX_MODIFIED", GIT_SUBMODULE_STATUS_INDEX_MODIFIED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_STATUS_WD_UNINITIALIZED", GIT_SUBMODULE_STATUS_WD_UNINITIALIZED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_STATUS_WD_ADDED", GIT_SUBMODULE_STATUS_WD_ADDED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_STATUS_WD_DELETED", GIT_SUBMODULE_STATUS_WD_DELETED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_STATUS_WD_MODIFIED", GIT_SUBMODULE_STATUS_WD_MODIFIED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED", GIT_SUBMODULE_STATUS_WD_INDEX_MODIFIED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_STATUS_WD_WD_MODIFIED", GIT_SUBMODULE_STATUS_WD_WD_MODIFIED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SUBMODULE_STATUS_WD_UNTRACKED", GIT_SUBMODULE_STATUS_WD_UNTRACKED, CONST_CS | CONST_PERSISTENT); + + /* git_trace_level_t */ + REGISTER_LONG_CONSTANT("GIT_TRACE_NONE", GIT_TRACE_NONE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TRACE_FATAL", GIT_TRACE_FATAL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TRACE_ERROR", GIT_TRACE_ERROR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TRACE_WARN", GIT_TRACE_WARN, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TRACE_INFO", GIT_TRACE_INFO, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TRACE_DEBUG", GIT_TRACE_DEBUG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TRACE_TRACE", GIT_TRACE_TRACE, CONST_CS | CONST_PERSISTENT); + + /* git_credtype_t */ + REGISTER_LONG_CONSTANT("GIT_CREDTYPE_USERPASS_PLAINTEXT", GIT_CREDTYPE_USERPASS_PLAINTEXT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CREDTYPE_SSH_KEY", GIT_CREDTYPE_SSH_KEY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CREDTYPE_SSH_CUSTOM", GIT_CREDTYPE_SSH_CUSTOM, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_CREDTYPE_DEFAULT", GIT_CREDTYPE_DEFAULT, CONST_CS | CONST_PERSISTENT); + /* git_transport_flags_t */ + REGISTER_LONG_CONSTANT("GIT_TRANSPORTFLAGS_NONE", GIT_TRANSPORTFLAGS_NONE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TRANSPORTFLAGS_NO_CHECK_CERT", GIT_TRANSPORTFLAGS_NO_CHECK_CERT, CONST_CS | CONST_PERSISTENT); + /* git_smart_service_t */ + REGISTER_LONG_CONSTANT("GIT_SERVICE_UPLOADPACK_LS", GIT_SERVICE_UPLOADPACK_LS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SERVICE_UPLOADPACK", GIT_SERVICE_UPLOADPACK, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SERVICE_RECEIVEPACK_LS", GIT_SERVICE_RECEIVEPACK_LS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_SERVICE_RECEIVEPACK", GIT_SERVICE_RECEIVEPACK, CONST_CS | CONST_PERSISTENT); + + /* git_treewalk_mode */ + REGISTER_LONG_CONSTANT("GIT_TREEWALK_PRE", GIT_TREEWALK_PRE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_TREEWALK_POST", GIT_TREEWALK_POST, CONST_CS | CONST_PERSISTENT); + + /* git_otype */ + REGISTER_LONG_CONSTANT("GIT_OBJ_ANY", GIT_OBJ_ANY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_OBJ_BAD", GIT_OBJ_BAD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_OBJ__EXT1", GIT_OBJ__EXT1, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_OBJ_COMMIT", GIT_OBJ_COMMIT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_OBJ_TREE", GIT_OBJ_TREE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_OBJ_BLOB", GIT_OBJ_BLOB, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_OBJ_TAG", GIT_OBJ_TAG, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_OBJ__EXT2", GIT_OBJ__EXT2, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_OBJ_OFS_DELTA", GIT_OBJ_OFS_DELTA, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("GIT_OBJ_REF_DELTA", GIT_OBJ_REF_DELTA, CONST_CS | CONST_PERSISTENT); + + return SUCCESS; +} + +PHP_RINIT_FUNCTION(git2) +{ + git_threads_init(); + return SUCCESS; +} + +PHP_MSHUTDOWN_FUNCTION(git2) +{ + UNREGISTER_INI_ENTRIES(); + return SUCCESS; +} + +PHP_RSHUTDOWN_FUNCTION(git2) +{ + git_threads_shutdown(); + return SUCCESS; +} + +zend_module_entry git2_module_entry = { +#if ZEND_MODULE_API_NO >= 20010901 + STANDARD_MODULE_HEADER, +#endif + PHP_GIT2_EXTNAME, + php_git2_functions, /* Functions */ + PHP_MINIT(git2), /* MINIT */ + PHP_MSHUTDOWN(git2), /* MSHUTDOWN */ + PHP_RINIT(git2), /* RINIT */ + PHP_RSHUTDOWN(git2), /* RSHUTDOWN */ + PHP_MINFO(git2), /* MINFO */ +#if ZEND_MODULE_API_NO >= 20010901 + PHP_GIT2_EXTVER, +#endif + PHP_MODULE_GLOBALS(git2), + PHP_GINIT(git2), + PHP_GSHUTDOWN(git2), + NULL, + STANDARD_MODULE_PROPERTIES_EX +}; + +#ifdef COMPILE_DL_GIT2 +ZEND_GET_MODULE(git2) +#endif \ No newline at end of file diff --git a/php_git2.h b/php_git2.h index d8e19e5bc7..4c5493a976 100644 --- a/php_git2.h +++ b/php_git2.h @@ -1,18 +1,20 @@ /* - * The MIT License + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. All rights reserved. * - * Copyright (c) 2010 - 2012 Shuhei Tanuma - * * 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 @@ -21,213 +23,218 @@ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. */ - #ifndef PHP_GIT2_H -# define PHP_GIT2_H - -# define PHP_GIT2_EXTNAME "git2" -# define PHP_GIT2_EXTVER "0.2.1" - -# ifdef HAVE_CONFIG_H -# include "config.h" -# endif - -# include "php.h" -# include "ext/spl/spl_exceptions.h" -# include -# include -# include - +#define PHP_GIT2_H + +#define PHP_GIT2_EXTNAME "git2" +#define PHP_GIT2_EXTVER "0.3.0" + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" +#include "php_ini.h" +#include "zend.h" +#include "zend_interfaces.h" +#include "zend_exceptions.h" +#include "ext/standard/php_smart_str.h" +#include "ext/spl/spl_exceptions.h" +#include "ext/standard/php_var.h" +#include "ext/standard/php_string.h" +#include "ext/standard/php_incomplete_class.h" +#include "ext/standard/info.h" +#include "ext/standard/php_array.h" +#include "limits.h" + +#include "git2.h" +#include "git2/odb.h" +#include "git2/odb_backend.h" +#include "git2/trace.h" +#include "git2/sys/filter.h" +#include "git2/sys/odb_backend.h" + +#include "date/php_date.h" + +#include + +/* Define the entry point symbol + * Zend will use when loading this module + */ extern zend_module_entry git2_module_entry; - -# define phpext_git2_ptr &git_module_entry; -# define PHP_GIT2_NS "Git2" - -extern PHPAPI zend_class_entry *git2_repository_class_entry; -extern PHPAPI zend_class_entry *git2_commit_class_entry; -extern PHPAPI zend_class_entry *git2_blob_class_entry; -extern PHPAPI zend_class_entry *git2_tree_class_entry; -extern PHPAPI zend_class_entry *git2_tree_builder_class_entry; -extern PHPAPI zend_class_entry *git2_tree_entry_class_entry; -extern PHPAPI zend_class_entry *git2_signature_class_entry; -extern PHPAPI zend_class_entry *git2_walker_class_entry; -extern PHPAPI zend_class_entry *git2_reference_class_entry; -extern PHPAPI zend_class_entry *git2_index_class_entry; -extern PHPAPI zend_class_entry *git2_index_entry_class_entry; - -typedef struct{ +#define phpext_git2_ptr &git2_module_entry + +ZEND_BEGIN_MODULE_GLOBALS(git2) + long dummy; +ZEND_END_MODULE_GLOBALS(git2) + +ZEND_EXTERN_MODULE_GLOBALS(git2) + +#ifdef ZTS +#define GIT2G(v) TSRMG(git2_globals_id, zend_git2_globals *, v) +#else +#define GIT2G(v) (git2_globals.v) +#endif + +#define PHP_GIT2_RESOURCE_NAME "git2" + + +#ifdef ZTS +#define GIT2_TSRMLS_SET(target) void ***tsrm_ls = target; +#define GIT2_TSRMLS_DECL void ***tsrm_ls; +#define GIT2_TSRMLS_SET2(target, value) target->tsrm_ls = value; +#else +#define GIT2_TSRMLS_SET(target) +#define GIT2_TSRMLS_SET2(target, value) +#define GIT2_TSRMLS_DECL +#endif + +enum php_git2_resource_type { + PHP_GIT2_TYPE_REPOSITORY, + PHP_GIT2_TYPE_COMMIT, + PHP_GIT2_TYPE_TREE, + PHP_GIT2_TYPE_TREE_ENTRY, + PHP_GIT2_TYPE_BLOB, + PHP_GIT2_TYPE_REVWALK, + PHP_GIT2_TYPE_TREEBUILDER, + PHP_GIT2_TYPE_REFERENCE, + PHP_GIT2_TYPE_REFERENCE_ITERATOR, + PHP_GIT2_TYPE_CONFIG, + PHP_GIT2_TYPE_CONFIG_ITERATOR, + PHP_GIT2_TYPE_OBJECT, + PHP_GIT2_TYPE_INDEX, + PHP_GIT2_TYPE_ODB, + PHP_GIT2_TYPE_REFDB, + PHP_GIT2_TYPE_STATUS_LIST, + PHP_GIT2_TYPE_BRANCH_ITERATOR, + PHP_GIT2_TYPE_TAG, + PHP_GIT2_TYPE_CRED, + PHP_GIT2_TYPE_TRANSPORT, + PHP_GIT2_TYPE_REMOTE, + PHP_GIT2_TYPE_DIFF, + PHP_GIT2_TYPE_MERGE_RESULT, + PHP_GIT2_TYPE_MERGE_HEAD, + PHP_GIT2_TYPE_PATHSPEC, + PHP_GIT2_TYPE_PATHSPEC_MATCH_LIST, + PHP_GIT2_TYPE_PATCH, + PHP_GIT2_TYPE_DIFF_HUNK, + PHP_GIT2_TYPE_BUF, + PHP_GIT2_TYPE_FILTER_LIST, + PHP_GIT2_TYPE_FILTER_SOURCE, + PHP_GIT2_TYPE_DIFF_LINE, + PHP_GIT2_TYPE_INDEX_CONFLICT_ITERATOR, + PHP_GIT2_TYPE_SMART_SUBTRANSPORT, + PHP_GIT2_TYPE_NOTE, + PHP_GIT2_TYPE_NOTE_ITERATOR, + PHP_GIT2_TYPE_ODB_STREAM, + PHP_GIT2_TYPE_ODB_OBJECT, + PHP_GIT2_TYPE_ODB_WRITEPACK, + PHP_GIT2_TYPE_ODB_BACKEND, + PHP_GIT2_TYPE_REFLOG, + PHP_GIT2_TYPE_REFLOG_ENTRY, + PHP_GIT2_TYPE_BLAME, + PHP_GIT2_TYPE_PACKBUILDER, + PHP_GIT2_TYPE_SUBMODULE, + PHP_GIT2_TYPE_PUSH, + PHP_GIT2_TYPE_REFSPEC, + PHP_GIT2_TYPE_INDEXER, + PHP_GIT2_TYPE_FILTER, /* for conventional reason */ +}; + +typedef struct php_git2_t { + enum php_git2_resource_type type; + union { + git_repository *repository; + git_commit *commit; + git_tree *tree; + git_tree_entry *tree_entry; + git_blob *blob; + git_revwalk *revwalk; + git_treebuilder *treebuilder; + git_reference *reference; + git_reference_iterator *reference_iterator; + git_config *config; + git_config_iterator *config_iterator; + git_object *object; + git_index *index; + git_odb *odb; + git_refdb *refdb; + git_status_list *status_list; + git_branch_iterator *branch_iterator; + git_tag *tag; + git_cred *cred; + git_transport *transport; + git_remote *remote; + git_diff *diff; + git_merge_result *merge_result; + git_merge_head *merge_head; + git_pathspec *pathspec; + git_pathspec_match_list *pathspec_match_list; + git_patch *patch; + git_diff_hunk *diff_hunk; + git_buf *buf; + git_filter_list *filter_list; + git_filter_source *filter_source; + git_diff_line *diff_line; + git_index_conflict_iterator *index_conflict_iterator; + git_smart_subtransport *smart_subtransport; + git_note *note; + git_note_iterator *note_iterator; + git_odb_stream *odb_stream; + git_odb_object *odb_object; + git_odb_writepack *odb_writepack; + git_odb_backend *odb_backend; + git_reflog *reflog; + git_reflog_entry *reflog_entry; + git_blame *blame; + git_packbuilder *packbuilder; + git_submodule *submodule; + git_push *push; + git_refspec *refspec; + git_indexer *indexer; + git_filter *filter; + } v; + int should_free_v; + int resource_id; + int mutable; +} php_git2_t; + +typedef struct php_git2_cb_t { + zval *payload; + zend_fcall_info *fci; + zend_fcall_info_cache *fcc; + GIT2_TSRMLS_DECL +} php_git2_cb_t; + +typedef struct php_git2_fcall_t { + zend_fcall_info fci; + zend_fcall_info_cache fcc; + zval *value; +} php_git2_fcall_t; + +typedef struct php_git2_multi_cb_t { + int num_callbacks; + php_git2_fcall_t *callbacks; + zval *payload; + GIT2_TSRMLS_DECL +} php_git2_multi_cb_t; + +typedef struct php_git2_filter { + git_filter super; + php_git2_multi_cb_t *multi; +} php_git2_filter; + +typedef struct php_git2_odb_backend { + git_odb_backend parent; + php_git2_multi_cb_t *multi; +} php_git2_odb_backend; + +typedef struct php_git2_odb_backend_foreach_callback { zend_object zo; - git_repository *repository; -} php_git2_repository; + git_odb_foreach_cb callback; + php_git2_cb_t *payload; +} php_git2_odb_backend_foreach_callback; -typedef struct{ - zend_object zo; - git_commit *commit; -} php_git2_commit; +extern zend_class_entry *php_git2_odb_backend_foreach_callback_class_entry; -typedef struct{ - zend_object zo; - git_blob *blob; -} php_git2_blob; - -typedef struct{ - zend_object zo; - git_tree *tree; - unsigned int offset; - git_repository *repository; -} php_git2_tree; - -typedef struct{ - zend_object zo; - git_tree_entry *entry; -} php_git2_tree_entry; - -typedef struct{ - zend_object zo; - git_treebuilder *builder; -} php_git2_tree_builder; - -typedef struct{ - zend_object zo; - git_signature *signature; -} php_git2_signature; - -typedef struct{ - zend_object zo; - git_reference *reference; -} php_git2_reference; - -typedef struct{ - zend_object zo; - git_revwalk *walker; - git_oid *current; - git_repository *repository; -} php_git2_walker; - -typedef struct{ - zend_object zo; - git_index *index; - unsigned int offset; -} php_git2_index; - -typedef struct{ - zend_object zo; - git_index_entry *entry; -} php_git2_index_entry; - - -# define PHP_GIT2_GET_OBJECT(STRUCT_NAME, OBJECT) (STRUCT_NAME *) zend_object_store_get_object(OBJECT TSRMLS_CC); - -# if ZEND_MODULE_API_NO >= 20100525 -# define PHP_GIT2_STD_CREATE_OBJECT(STRUCT_NAME) \ - STRUCT_NAME *object;\ - \ - object = ecalloc(1, sizeof(*object));\ - zend_object_std_init(&object->zo, ce TSRMLS_CC);\ - object_properties_init(&object->zo, ce); - \ - retval.handle = zend_objects_store_put(object,\ - (zend_objects_store_dtor_t)zend_objects_destroy_object,\ - (zend_objects_free_object_storage_t) STRUCT_NAME##_free_storage ,\ - NULL TSRMLS_CC);\ - retval.handlers = zend_get_std_object_handlers(); -# else -# define PHP_GIT2_STD_CREATE_OBJECT(STRUCT_NAME) \ - STRUCT_NAME *object;\ - zval *tmp = NULL;\ - \ - object = ecalloc(1, sizeof(*object));\ - zend_object_std_init(&object->zo, ce TSRMLS_CC);\ - zend_hash_copy(object->zo.properties, &ce->default_properties, (copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *)); \ - \ - retval.handle = zend_objects_store_put(object,\ - (zend_objects_store_dtor_t)zend_objects_destroy_object,\ - (zend_objects_free_object_storage_t) STRUCT_NAME##_free_storage ,\ - NULL TSRMLS_CC);\ - retval.handlers = zend_get_std_object_handlers(); -# endif - -extern int php_git2_add_protected_property_string_ex(zval *object, char *name, int name_length, char *data, zend_bool duplicate TSRMLS_DC); -extern zval* php_git2_object_new(git_repository *repository, git_object *object TSRMLS_DC); -extern int php_git2_call_user_function_v(zval **retval, zval *obj, char *method, unsigned int method_len, unsigned int param_count, ...); - -extern inline void php_git2_create_signature(zval *object, char *name, int name_len, char *email, int email_len, zval *date TSRMLS_DC); - - -static inline php_git2_create_signature_from_commit(zval **object, git_commit *commit, int type TSRMLS_DC) -{ - zval *ret; - zval *z_signature, *date; - char time_str[12] = {0}; - const git_signature *author; - php_git2_signature *m_signature; - - if (type == 0) { - author = git_commit_author(commit); - } else { - author = git_commit_committer(commit); - } - - MAKE_STD_ZVAL(ret); - MAKE_STD_ZVAL(date); - - object_init_ex(ret,git2_signature_class_entry); - m_signature = PHP_GIT2_GET_OBJECT(php_git2_signature, ret); - add_property_string_ex(ret,"name",sizeof("name"), author->name,1 TSRMLS_CC); - add_property_string_ex(ret,"email",sizeof("email"),author->email,1 TSRMLS_CC); - - php_date_instantiate(php_date_get_date_ce(), date TSRMLS_CC); - snprintf(time_str,12,"%c%ld",'@',author->when.time); - php_date_initialize(zend_object_store_get_object(date TSRMLS_CC), time_str, strlen(time_str), NULL, NULL, 0 TSRMLS_CC); - - add_property_zval(ret,"time",date); - zval_ptr_dtor(&date); - *object = ret; -} - -static inline void create_tree_entry_from_entry(zval **object, git_tree_entry *entry, git_repository *repository) -{ - TSRMLS_FETCH(); - char buf[GIT_OID_HEXSZ] = {0}; - const git_oid *oid; - php_git2_tree_entry *m_entry; - - MAKE_STD_ZVAL(*object); - object_init_ex(*object, git2_tree_entry_class_entry); - m_entry = PHP_GIT2_GET_OBJECT(php_git2_tree_entry, *object); - - m_entry->entry = entry; - oid = git_tree_entry_id(entry); - git_oid_to_string(buf,GIT_OID_HEXSZ,oid); - - add_property_string(*object, "name", (char *)git_tree_entry_name(entry), 1); - add_property_string(*object, "oid", buf, 1); - add_property_long(*object, "attributes", git_tree_entry_attributes(entry)); -} - -static inline void php_git2_create_index_entry(zval **object, git_index_entry *entry TSRMLS_DC) -{ - zval *tmp = NULL; - char oid_out[GIT_OID_HEXSZ] = {0}; - - MAKE_STD_ZVAL(tmp); - object_init_ex(tmp, git2_index_entry_class_entry); - git_oid_fmt(oid_out, &entry->oid); - - add_property_string_ex(tmp, "path", sizeof("path"), entry->path, 1 TSRMLS_CC); - add_property_stringl_ex(tmp, "oid", sizeof("oid"), oid_out,GIT_OID_HEXSZ, 1 TSRMLS_CC); - add_property_long(tmp, "dev", entry->dev); - add_property_long(tmp, "ino", entry->ino); - add_property_long(tmp, "mode", entry->mode); - add_property_long(tmp, "uid", entry->uid); - add_property_long(tmp, "gid", entry->gid); - add_property_long(tmp, "file_size", entry->file_size); - add_property_long(tmp, "flags", entry->flags); - add_property_long(tmp, "flags_extended", entry->flags_extended); - add_property_long(tmp, "ctime", entry->ctime.seconds); - add_property_long(tmp, "mtime", entry->mtime.seconds); - - *object = tmp; -} - -#endif /* PHP_GIT2_H */ \ No newline at end of file +#endif /* PHP_GIT2_H */ diff --git a/php_git2_priv.h b/php_git2_priv.h new file mode 100644 index 0000000000..31bd3f2b30 --- /dev/null +++ b/php_git2_priv.h @@ -0,0 +1,98 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_PRIV_H +#define PHP_GIT2_PRIV_H + +extern int git2_resource_handle; + +#if PHP_VERSION_ID>=50399 +#define PHP_GIT2_LIST_INSERT(type, handle) zend_list_insert(type, handle TSRMLS_CC) +#else +#define PHP_GIT2_LIST_INSERT(type, handle) zend_list_insert(type, handle) +#endif + +# if ZEND_MODULE_API_NO >= 20100525 +# define PHP_GIT2_STD_CREATE_OBJECT(STRUCT_NAME) \ + STRUCT_NAME *object;\ + \ + object = (STRUCT_NAME*)ecalloc(1, sizeof(*object));\ + zend_object_std_init(&object->zo, ce TSRMLS_CC);\ + object_properties_init(&object->zo, ce);\ + \ + retval.handle = zend_objects_store_put(object,\ + (zend_objects_store_dtor_t)zend_objects_destroy_object,\ + (zend_objects_free_object_storage_t) STRUCT_NAME##_free_storage ,\ + NULL TSRMLS_CC);\ + retval.handlers = zend_get_std_object_handlers(); +# else +# define PHP_GIT2_STD_CREATE_OBJECT(STRUCT_NAME) \ + STRUCT_NAME *object;\ + zval *tmp = NULL;\ + \ + object = (STRUCT_NAME*)ecalloc(1, sizeof(*object));\ + zend_object_std_init(&object->zo, ce TSRMLS_CC);\ + zend_hash_copy(object->zo.properties, &ce->default_properties, (copy_ctor_func_t)zval_add_ref, (void *)&tmp, sizeof(zval *)); \ + \ + retval.handle = zend_objects_store_put(object,\ + (zend_objects_store_dtor_t)zend_objects_destroy_object,\ + (zend_objects_free_object_storage_t) STRUCT_NAME##_free_storage ,\ + NULL TSRMLS_CC);\ + retval.handlers = zend_get_std_object_handlers(); +# endif + +#define PHP_GIT2_V(git2, type) git2->v.type +#define GIT2_RVAL_P(git2) git2->resource_id +#define GIT2_SHOULD_FREE(git2) git2->should_free_v + +#define PHP_GIT2_MAKE_RESOURCE(val) \ +do {\ + val = (php_git2_t *)emalloc(sizeof(php_git2_t));\ + if (!val) {\ + php_error_docref(NULL TSRMLS_CC, E_ERROR, "emalloc failed");\ + RETURN_FALSE;\ + }\ + val->should_free_v = 0;\ + val->type = 0;\ + val->mutable = 0;\ +} while (0);\ + + +#define PHP_GIT2_MAKE_RESOURCE_NOCHECK(val) \ +do {\ + val = (php_git2_t *)emalloc(sizeof(php_git2_t));\ + val->should_free_v = 0;\ + val->type = 0;\ + val->mutable = 0;\ +} while (0);\ + +#define GIT2_OID_HEXSIZE (GIT_OID_HEXSZ+1) +#define GIT2_BUFFER_SIZE 512 + +int php_git2_make_resource(php_git2_t **out, enum php_git2_resource_type type, void *resource, int should_free TSRMLS_DC); + +#include "helper.h" + +#endif \ No newline at end of file diff --git a/push.c b/push.c new file mode 100644 index 0000000000..2e678f026a --- /dev/null +++ b/push.c @@ -0,0 +1,239 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "push.h" + +static int php_git2_push_status_foreach_cb(const char *ref, const char *msg, void *data) +{ + php_git2_t *result; + zval *param_ref, *param_msg, *retval_ptr = NULL; + php_git2_cb_t *p = (php_git2_cb_t*)data; + int retval = 0; + GIT2_TSRMLS_SET(p->tsrm_ls) + + Z_ADDREF_P(p->payload); + MAKE_STD_ZVAL(param_ref); + MAKE_STD_ZVAL(param_msg); + ZVAL_NULL(param_ref); + ZVAL_NULL(param_msg); + + if (ref != NULL) { + ZVAL_STRING(param_ref, ref, 1); + } + if (msg != NULL) { + ZVAL_STRING(param_msg, msg, 1); + } + + if (php_git2_call_function_v(p->fci, p->fcc TSRMLS_CC, &retval_ptr, 3, ¶m_ref, ¶m_msg, &p->payload)) { + zend_list_delete(result->resource_id); + return GIT_EUSER; + } + + retval = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + return retval; +} + +/* {{{ proto resource git_push_new(resource $remote) + */ +PHP_FUNCTION(git_push_new) +{ + php_git2_t *result = NULL, *_remote = NULL; + git_push *out = NULL; + zval *remote = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &remote) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_push_new(&out, PHP_GIT2_V(_remote, remote)); + if (php_git2_check_error(error, "git_push_new" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_PUSH, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto long git_push_set_options(resource $push, $opts) + */ +PHP_FUNCTION(git_push_set_options) +{ + int result = 0; + zval *push = NULL, *opts = NULL; + php_git2_t *_push = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &push, &opts) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_push, php_git2_t*, &push, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + //result = git_push_set_options(PHP_GIT2_V(_push, push), opts); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_push_set_callbacks(resource $push, $pack_progress_cb, $pack_progress_cb_payload, $transfer_progress_cb, $transfer_progress_cb_payload) + */ +PHP_FUNCTION(git_push_set_callbacks) +{ + int result = 0; + zval *push = NULL, *pack_progress_cb_payload = NULL, *transfer_progress_cb_payload = NULL; + php_git2_t *_push = NULL; + zend_fcall_info pack_fci = empty_fcall_info; + zend_fcall_info_cache pack_fcc = empty_fcall_info_cache; + zend_fcall_info transfer_fci = empty_fcall_info; + zend_fcall_info_cache transfer_fcc = empty_fcall_info_cache; + php_git2_cb_t *pack_cb = NULL; + php_git2_cb_t *transfer_cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rfzfz", &push, &pack_fci, &pack_fcc, &pack_progress_cb_payload, &transfer_fci, &transfer_fcc, &transfer_progress_cb_payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_push, php_git2_t*, &push, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_cb_init(&pack_cb, &pack_fci, &pack_fcc, pack_progress_cb_payload TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_cb_init(&transfer_cb, &transfer_fci, &transfer_fcc, transfer_progress_cb_payload TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_push_set_callbacks(PHP_GIT2_V(_push, push), NULL, pack_cb, NULL, transfer_cb); + php_git2_cb_free(pack_cb); + php_git2_cb_free(transfer_cb); + RETURN_LONG(result); +} +/* }}} */ + + + +/* {{{ proto long git_push_add_refspec(resource $push, string $refspec) + */ +PHP_FUNCTION(git_push_add_refspec) +{ + int result = 0, refspec_len = 0; + zval *push = NULL; + php_git2_t *_push = NULL; + char *refspec = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &push, &refspec, &refspec_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_push, php_git2_t*, &push, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_push_add_refspec(PHP_GIT2_V(_push, push), refspec); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_push_update_tips(resource $push) + */ +PHP_FUNCTION(git_push_update_tips) +{ + int result = 0; + zval *push = NULL; + php_git2_t *_push = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &push) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_push, php_git2_t*, &push, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_push_update_tips(PHP_GIT2_V(_push, push)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_push_finish(resource $push) + */ +PHP_FUNCTION(git_push_finish) +{ + int result = 0; + zval *push = NULL; + php_git2_t *_push = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &push) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_push, php_git2_t*, &push, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_push_finish(PHP_GIT2_V(_push, push)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_push_unpack_ok(resource $push) + */ +PHP_FUNCTION(git_push_unpack_ok) +{ + int result = 0; + zval *push = NULL; + php_git2_t *_push = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &push) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_push, php_git2_t*, &push, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_push_unpack_ok(PHP_GIT2_V(_push, push)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_push_status_foreach(resource $push, Callable callback, mixed $payload) + */ +PHP_FUNCTION(git_push_status_foreach) +{ + int result = 0; + zval *push = NULL, *payload = NULL; + php_git2_t *_push = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rfz", &push, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_push, php_git2_t*, &push, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_push_status_foreach(PHP_GIT2_V(_push, push), php_git2_push_status_foreach_cb, cb); + php_git2_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto void git_push_free(resource $push) + */ +PHP_FUNCTION(git_push_free) +{ + zval *push = NULL; + php_git2_t *_push = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &push) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_push, php_git2_t*, &push, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_push)) { + git_push_free(PHP_GIT2_V(_push, push)); + GIT2_SHOULD_FREE(_push) = 0; + }; + zval_ptr_dtor(&push); +} +/* }}} */ + diff --git a/push.h b/push.h new file mode 100644 index 0000000000..fc4a131ace --- /dev/null +++ b/push.h @@ -0,0 +1,109 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_PUSH_H +#define PHP_GIT2_PUSH_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_push_new, 0, 0, 1) + ZEND_ARG_INFO(0, remote) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_push_set_options, 0, 0, 2) + ZEND_ARG_INFO(0, push) + ZEND_ARG_INFO(0, opts) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_push_set_callbacks, 0, 0, 5) + ZEND_ARG_INFO(0, push) + ZEND_ARG_INFO(0, pack_progress_cb) + ZEND_ARG_INFO(0, pack_progress_cb_payload) + ZEND_ARG_INFO(0, transfer_progress_cb) + ZEND_ARG_INFO(0, transfer_progress_cb_payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_push_add_refspec, 0, 0, 2) + ZEND_ARG_INFO(0, push) + ZEND_ARG_INFO(0, refspec) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_push_update_tips, 0, 0, 1) + ZEND_ARG_INFO(0, push) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_push_finish, 0, 0, 1) + ZEND_ARG_INFO(0, push) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_push_unpack_ok, 0, 0, 1) + ZEND_ARG_INFO(0, push) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_push_status_foreach, 0, 0, 3) + ZEND_ARG_INFO(0, push) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(1, data) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_push_free, 0, 0, 1) + ZEND_ARG_INFO(0, push) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_push_new(remote) +*/ +PHP_FUNCTION(git_push_new); + +/* {{{ proto long git_push_set_options(push, opts) +*/ +PHP_FUNCTION(git_push_set_options); + +/* {{{ proto long git_push_set_callbacks(push, pack_progress_cb, pack_progress_cb_payload, transfer_progress_cb, transfer_progress_cb_payload) +*/ +PHP_FUNCTION(git_push_set_callbacks); + +/* {{{ proto long git_push_add_refspec(push, refspec) +*/ +PHP_FUNCTION(git_push_add_refspec); + +/* {{{ proto long git_push_update_tips(push) +*/ +PHP_FUNCTION(git_push_update_tips); + +/* {{{ proto long git_push_finish(push) +*/ +PHP_FUNCTION(git_push_finish); + +/* {{{ proto long git_push_unpack_ok(push) +*/ +PHP_FUNCTION(git_push_unpack_ok); + +/* {{{ proto long git_push_status_foreach(push, ref, msg, data), data) +*/ +PHP_FUNCTION(git_push_status_foreach); + +/* {{{ proto void git_push_free(push) +*/ +PHP_FUNCTION(git_push_free); + +#endif diff --git a/ref.php b/ref.php new file mode 100644 index 0000000000..0235eeea8d --- /dev/null +++ b/ref.php @@ -0,0 +1,19 @@ +getFunctions() as $func) { + /** @var ReflectionFunction $func */ + + $name = $func->getName(); + $result[$name] = array(); + foreach ($func->getParameters() as $param) { + /** @var ReflectionParameter $param */ + $result[$name][] = '$' . $param->getName(); + } +} + +echo " $params) { + printf("function %s(%s){}\n", $func, join(", ", $params)); +} diff --git a/reference.c b/reference.c index d90101f515..2befa063b9 100644 --- a/reference.c +++ b/reference.c @@ -1,237 +1,874 @@ -/* - * The MIT License - * - * Copyright (c) 2010 - 2012 Shuhei Tanuma - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. +#include "php_git2.h" +#include "php_git2_priv.h" +#include "reference.h" + +static int php_git2_reference_foreach_cb(git_reference *reference, void *payload) +{ + php_git2_t *result; + zval *param_reference, *retval_ptr = NULL; + php_git2_cb_t *p = (php_git2_cb_t*)payload; + long retval = 0; + GIT2_TSRMLS_SET(p->tsrm_ls) + + Z_ADDREF_P(p->payload); + MAKE_STD_ZVAL(param_reference); + + php_git2_make_resource(&result, PHP_GIT2_TYPE_REFERENCE, reference, 0 TSRMLS_CC); + zend_list_addref(result->resource_id); + ZVAL_RESOURCE(param_reference, result->resource_id); + + if (php_git2_call_function_v(p->fci, p->fcc TSRMLS_CC, &retval_ptr, 2, ¶m_reference, &p->payload)) { + zend_list_delete(result->resource_id); + return GIT_EUSER; + } + + retval = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + zend_list_delete(result->resource_id); + return retval; +} + +static int php_git2_reference_foreach_name_cb(const char *name, void *payload) +{ + php_git2_t *result; + zval *param_name, *retval_ptr = NULL; + php_git2_cb_t *p = (php_git2_cb_t*)payload; + long retval = 0; + GIT2_TSRMLS_SET(p->tsrm_ls) + + Z_ADDREF_P(p->payload); + MAKE_STD_ZVAL(param_name); + ZVAL_STRING(param_name, name, 1); + + if (php_git2_call_function_v(p->fci, p->fcc TSRMLS_CC, &retval_ptr, 2, ¶m_name, &p->payload)) { + zval_ptr_dtor(&retval_ptr); + zend_list_delete(result->resource_id); + return GIT_EUSER; + } + retval = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + zend_list_delete(result->resource_id); + + return retval; +} + +/* {{{ proto resource git_reference_lookup(resource $repo, string $name) */ +PHP_FUNCTION(git_reference_lookup) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_reference *out = NULL; + zval *repo = NULL; + char *name = NULL; + int name_len = 0, error = 0; -#include "php_git2.h" + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repo, &name, &name_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_reference_lookup(&out, PHP_GIT2_V(_repo, repository), name); + if (php_git2_check_error(error, "git_reference_lookup" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REFERENCE, out, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ -PHPAPI zend_class_entry *git2_reference_class_entry; -static void php_git2_reference_free_storage(php_git2_reference *object TSRMLS_DC) +/* {{{ proto resource git_reference_name_to_id(repo, name) +*/ +PHP_FUNCTION(git_reference_name_to_id) { - if (object->reference != NULL) { - object->reference = NULL; + zval *repo; + php_git2_t *_repo; + char *name = {0}; + int name_len; + git_oid id; + char out[GIT2_OID_HEXSIZE] = {0}; + int error; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repo, &name, &name_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_reference_name_to_id(&id, PHP_GIT2_V(_repo, repository), name); + if (php_git2_check_error(error, "git_reference_lookup" TSRMLS_CC)) { + RETURN_FALSE } - zend_object_std_dtor(&object->zo TSRMLS_CC); - efree(object); + + git_oid_fmt(out, &id); + RETURN_STRING(out, 1); } -zend_object_value php_git2_reference_new(zend_class_entry *ce TSRMLS_DC) +/* {{{ proto resource git_reference_dwim(resource $repo, string $shorthand) + */ +PHP_FUNCTION(git_reference_dwim) { - zend_object_value retval; + php_git2_t *result = NULL, *_repo = NULL; + git_reference *out = NULL; + zval *repo = NULL; + char *shorthand = NULL; + int shorthand_len = 0, error = 0; - PHP_GIT2_STD_CREATE_OBJECT(php_git2_reference); - return retval; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repo, &shorthand, &shorthand_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_reference_dwim(&out, PHP_GIT2_V(_repo, repository), shorthand); + if (php_git2_check_error(error, "git_reference_dwim" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REFERENCE, out, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); } +/* }}} */ -ZEND_BEGIN_ARG_INFO_EX(arginfo_git2_reference_lookup, 0,0,2) - ZEND_ARG_INFO(0, repository) - ZEND_ARG_INFO(0, path) -ZEND_END_ARG_INFO() +/* {{{ proto resource git_reference_symbolic_create(resource $repo, string $name, string $target, long $force) + */ +PHP_FUNCTION(git_reference_symbolic_create) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_reference *out = NULL; + zval *repo = NULL; + char *name = NULL, *target = NULL; + int name_len = 0, target_len = 0, error = 0; + long force = 0; -ZEND_BEGIN_ARG_INFO_EX(arginfo_git2_reference_each, 0,0,2) - ZEND_ARG_INFO(0, repository) - ZEND_ARG_INFO(0, filter) -ZEND_END_ARG_INFO() + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rssl", &repo, &name, &name_len, &target, &target_len, &force) == FAILURE) { + return; + } -/* -{{{ proto: Git2\Reference::lookup(Git2\Repository $repo, string $path) + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_reference_symbolic_create(&out, PHP_GIT2_V(_repo, repository), name, target, force); + if (php_git2_check_error(error, "git_reference_symbolic_create" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REFERENCE, out, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_reference_create(resource $repo, string $name, string $id, long $force) + */ +PHP_FUNCTION(git_reference_create) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_reference *out = NULL; + zval *repo = NULL; + char *name = NULL, *id = NULL; + int name_len = 0, id_len = 0, error = 0; + git_oid __id = {0}; + long force = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rssl", &repo, &name, &name_len, &id, &id_len, &force) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__id, id, id_len)) { + RETURN_FALSE; + } + error = git_reference_create(&out, PHP_GIT2_V(_repo, repository), name, &__id, force); + if (php_git2_check_error(error, "git_reference_create" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REFERENCE, out, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto resource git_reference_target(resource $ref) + */ +PHP_FUNCTION(git_reference_target) +{ + const git_oid *result = NULL; + zval *ref = NULL; + php_git2_t *_ref = NULL; + char __result[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &ref) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_ref, php_git2_t*, &ref, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_reference_target(PHP_GIT2_V(_ref, reference)); + git_oid_fmt(__result, result); + RETURN_STRING(__result, 1); +} +/* }}} */ + +/* {{{ proto resource git_reference_target_peel(ref) */ -PHP_METHOD(git2_reference, lookup) +PHP_FUNCTION(git_reference_target_peel) { - char *path; - char oid_out[GIT_OID_HEXSZ] = {0}; - int error, path_len = 0; - git_reference *ref; - zval *repository, *object; + zval *ref; + php_git2_t *_ref; git_oid *oid; - php_git2_repository *m_repository; - php_git2_reference *m_reference; + char out[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &ref) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_ref, php_git2_t*, &ref, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + oid = git_reference_target_peel(PHP_GIT2_V(_ref, reference)); + + git_oid_fmt(out, oid); + RETURN_STRING(out, 1); +} + +/* {{{ proto string git_reference_symbolic_target(resource $ref) + */ +PHP_FUNCTION(git_reference_symbolic_target) +{ + const char *result = NULL; + zval *ref = NULL; + php_git2_t *_ref = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "Os", &repository, git2_repository_class_entry, &path, &path_len) == FAILURE) { + "r", &ref) == FAILURE) { return; } - - m_repository = PHP_GIT2_GET_OBJECT(php_git2_repository, repository); - - error = git_reference_lookup(&ref, m_repository->repository, path); - if (error == GIT_ENOTFOUND) { + + ZEND_FETCH_RESOURCE(_ref, php_git2_t*, &ref, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_reference_symbolic_target(PHP_GIT2_V(_ref, reference)); + RETURN_STRING(result, 1); +} +/* }}} */ + +/* {{{ proto resource git_reference_type(resource $ref) + */ +PHP_FUNCTION(git_reference_type) +{ + git_ref_t result; + zval *ref = NULL; + php_git2_t *_ref = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &ref) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_ref, php_git2_t*, &ref, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_reference_type(PHP_GIT2_V(_ref, reference)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto string git_reference_name(resource $ref) + */ +PHP_FUNCTION(git_reference_name) +{ + const char *result = NULL; + zval *ref = NULL; + php_git2_t *_ref = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &ref) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_ref, php_git2_t*, &ref, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_reference_name(PHP_GIT2_V(_ref, reference)); + RETURN_STRING(result, 1); +} +/* }}} */ + +/* {{{ proto resource git_reference_resolve(resource $ref) + */ +PHP_FUNCTION(git_reference_resolve) +{ + php_git2_t *result = NULL, *_ref = NULL; + git_reference *out = NULL; + zval *ref = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &ref) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_ref, php_git2_t*, &ref, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_reference_resolve(&out, PHP_GIT2_V(_ref, reference)); + if (php_git2_check_error(error, "git_reference_resolve" TSRMLS_CC)) { RETURN_FALSE; } - - MAKE_STD_ZVAL(object); - object_init_ex(object,git2_reference_class_entry); - m_reference = PHP_GIT2_GET_OBJECT(php_git2_reference, object); - m_reference->reference = ref; + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REFERENCE, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_reference_owner(resource $ref) + */ +PHP_FUNCTION(git_reference_owner) +{ + git_repository *result = NULL; + zval *ref = NULL; + php_git2_t *_ref = NULL, *__result = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &ref) == FAILURE) { + return; + } - RETURN_ZVAL(object,0,1); + ZEND_FETCH_RESOURCE(_ref, php_git2_t*, &ref, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_reference_owner(PHP_GIT2_V(_ref, reference)); + if (php_git2_make_resource(&__result, PHP_GIT2_TYPE_REFERENCE, result, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(__result)); } /* }}} */ -/* -{{{ proto: Git2\Reference::getTarget() -*/ -PHP_METHOD(git2_reference, getTarget) +/* {{{ proto resource git_reference_symbolic_set_target(resource $ref, string $target) + */ +PHP_FUNCTION(git_reference_symbolic_set_target) +{ + php_git2_t *result = NULL, *_ref = NULL; + git_reference *out = NULL; + zval *ref = NULL; + char *target = NULL; + int target_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &ref, &target, &target_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_ref, php_git2_t*, &ref, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_reference_symbolic_set_target(&out, PHP_GIT2_V(_ref, reference), target); + if (php_git2_check_error(error, "git_reference_symbolic_set_target" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REFERENCE, out, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto resource git_reference_set_target(resource $ref, string $id) + */ +PHP_FUNCTION(git_reference_set_target) { - git_reference *ref; - php_git2_reference *m_reference; - - m_reference = PHP_GIT2_GET_OBJECT(php_git2_reference, getThis()); - - if (git_reference_type(m_reference->reference) == GIT_REF_OID) { - git_oid *oid; - char oid_out[GIT_OID_HEXSZ] = {0}; - - oid = git_reference_oid(m_reference->reference); - git_oid_fmt(oid_out, oid); - RETVAL_STRINGL(oid_out,GIT_OID_HEXSZ,1); - } else { - RETVAL_STRING(git_reference_target(m_reference->reference),1); + php_git2_t *result = NULL, *_ref = NULL; + git_reference *out = NULL; + zval *ref = NULL; + char *id = NULL; + int id_len = 0, error = 0; + git_oid __id = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &ref, &id, &id_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_ref, php_git2_t*, &ref, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__id, id, id_len)) { + RETURN_FALSE; + } + error = git_reference_set_target(&out, PHP_GIT2_V(_ref, reference), &__id); + if (php_git2_check_error(error, "git_reference_set_target" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REFERENCE, out, 0 TSRMLS_CC)) { + RETURN_FALSE; } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); } /* }}} */ -/* -{{{ proto: Git2\Reference::getName() -*/ -PHP_METHOD(git2_reference, getName) +/* {{{ proto long git_reference_rename(resource $ref, string $new_name, long $force) + */ +PHP_FUNCTION(git_reference_rename) { - git_reference *ref; - php_git2_reference *m_reference; - - m_reference = PHP_GIT2_GET_OBJECT(php_git2_reference, getThis()); - - RETVAL_STRING(git_reference_name(m_reference->reference),1); + int result = 0, new_name_len = 0; + git_reference *new_ref = NULL; + zval *ref = NULL; + php_git2_t *_ref = NULL; + char *new_name = NULL; + long force = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsl", &ref, &new_name, &new_name_len, &force) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_ref, php_git2_t*, &ref, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_reference_rename(&new_ref, PHP_GIT2_V(_ref, reference), new_name, force); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_reference_delete(resource $ref) + */ +PHP_FUNCTION(git_reference_delete) +{ + int result = 0; + zval *ref = NULL; + php_git2_t *_ref = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &ref) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_ref, php_git2_t*, &ref, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_reference_delete(PHP_GIT2_V(_ref, reference)); + RETURN_LONG(result); } /* }}} */ -/* -{{{ proto: Git2\Reference::resolve() + +/* {{{ proto long git_reference_list(repo) */ -PHP_METHOD(git2_reference, resolve) +PHP_FUNCTION(git_reference_list) { - git_reference *resolved; - php_git2_reference *m_reference; - zval *object; + zval *repo; + php_git2_t *_repo; + git_strarray list; + zval *result; int error; - - m_reference = PHP_GIT2_GET_OBJECT(php_git2_reference, getThis()); - error = git_reference_resolve(&resolved, m_reference->reference); - - MAKE_STD_ZVAL(object); - object_init_ex(object, git2_reference_class_entry); - m_reference = PHP_GIT2_GET_OBJECT(php_git2_reference, object); - m_reference->reference = resolved; - - RETURN_ZVAL(object, 0, 1); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + error = git_reference_list(&list, PHP_GIT2_V(_repo, repository)); + if (php_git2_check_error(error, "git_reference_list" TSRMLS_CC)) { + RETURN_FALSE + } + + php_git2_strarray_to_array(&list, &result TSRMLS_CC); + git_strarray_free(&list); + + RETURN_ZVAL(result, 0, 1); } /* }}} */ +/* {{{ proto long git_reference_foreach(resource $repo, $callback, $payload) + */ +PHP_FUNCTION(git_reference_foreach) +{ + int result = 0; + zval *repo = NULL; + php_git2_t *_repo = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb; + zval *payload; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rfz", &repo, &fci, &fcc, &payload) == FAILURE) { + return; + } -typedef struct { - unsigned int type; - git_repository *repository; - zval *result; -} php_git2_ref_foreach_cb_t; + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_reference_foreach(PHP_GIT2_V(_repo, repository), php_git2_reference_foreach_cb, cb); + php_git2_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_reference_foreach_name(resource $repo, $callback, $payload) + */ +PHP_FUNCTION(git_reference_foreach_name) +{ + int result = 0; + zval *repo = NULL; + php_git2_t *_repo = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb; + zval *payload; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rfz", &repo, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_reference_foreach_name(PHP_GIT2_V(_repo, repository), php_git2_reference_foreach_name_cb, cb); + php_git2_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto void git_reference_free(resource $ref) + */ +PHP_FUNCTION(git_reference_free) +{ + zval *ref = NULL; + php_git2_t *_ref = NULL; -static int php_git2_ref_foreach_cb(const char *name, void *opaque) + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &ref) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_ref, php_git2_t*, &ref, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_ref)) { + git_reference_free(PHP_GIT2_V(_ref, reference)); + GIT2_SHOULD_FREE(_ref) = 0; + }; + zval_ptr_dtor(&ref); +} +/* }}} */ + +/* {{{ proto long git_reference_cmp(ref1, ref2) +*/ +PHP_FUNCTION(git_reference_cmp) +{ + zval *e1, *e2; + php_git2_t *g_e1, *g_e2; + int result; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rr", &e1, &e2) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(g_e1, php_git2_t*, &e1, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(g_e2, php_git2_t*, &e2, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + result = git_reference_cmp(PHP_GIT2_V(g_e1, reference), PHP_GIT2_V(g_e2, reference)); + RETURN_LONG(result); +} + +/* {{{ proto resource git_reference_iterator_new(resource $repo) + */ +PHP_FUNCTION(git_reference_iterator_new) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_reference_iterator *out = NULL; + zval *repo = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_reference_iterator_new(&out, PHP_GIT2_V(_repo, repository)); + if (php_git2_check_error(error, "git_reference_iterator_new" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REFERENCE_ITERATOR, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto resource git_reference_iterator_glob_new(resource $repo, string $glob) + */ +PHP_FUNCTION(git_reference_iterator_glob_new) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_reference_iterator *out = NULL; + zval *repo = NULL; + char *glob = NULL; + int glob_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repo, &glob, &glob_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_reference_iterator_glob_new(&out, PHP_GIT2_V(_repo, repository), glob); + if (php_git2_check_error(error, "git_reference_iterator_glob_new" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REFERENCE_ITERATOR, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto resource git_reference_next(resource $iter) + */ +PHP_FUNCTION(git_reference_next) +{ + php_git2_t *result = NULL, *_iter = NULL; + git_reference *out = NULL; + zval *iter = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &iter) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_iter, php_git2_t*, &iter, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_reference_next(&out, PHP_GIT2_V(_iter, reference_iterator)); + if (error == GIT_ITEROVER || php_git2_check_error(error, "git_reference_next" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REFERENCE, out, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto resource git_reference_next_name(resource $iter) + */ +PHP_FUNCTION(git_reference_next_name) +{ + php_git2_t *_iter = NULL; + const char *out = NULL; + zval *iter = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &iter) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_iter, php_git2_t*, &iter, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_reference_next_name(&out, PHP_GIT2_V(_iter, reference_iterator)); + if (php_git2_check_error(error, "git_reference_next_name" TSRMLS_CC)) { + RETURN_FALSE; + } + RETURN_STRING(out, 1); +} +/* }}} */ + + +/* {{{ proto void git_reference_iterator_free(resource $iter) + */ +PHP_FUNCTION(git_reference_iterator_free) +{ + zval *iter = NULL; + php_git2_t *_iter = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &iter) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_iter, php_git2_t*, &iter, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_iter)) { + git_reference_iterator_free(PHP_GIT2_V(_iter, reference_iterator)); + GIT2_SHOULD_FREE(_iter) = 0; + }; + zval_ptr_dtor(&iter); +} +/* }}} */ + +/* {{{ proto long git_reference_foreach_glob(resource $repo, string $glob, $callback, $payload) + */ +PHP_FUNCTION(git_reference_foreach_glob) +{ + int result = 0, glob_len = 0; + zval *repo = NULL; + php_git2_t *_repo = NULL; + char *glob = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb; + zval *payload = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsfz", &repo, &glob, &glob_len, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_reference_foreach_glob(PHP_GIT2_V(_repo, repository), glob, php_git2_reference_foreach_name_cb, cb); + php_git2_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_reference_has_log(ref) +*/ +PHP_FUNCTION(git_reference_has_log) +{ + zval *ref; + php_git2_t *_ref; + int has = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &ref) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_ref, php_git2_t*, &ref, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + has = git_reference_has_log(PHP_GIT2_V(_ref, reference)); + + RETURN_LONG(has); +} + +/* {{{ proto long git_reference_is_branch(ref) +*/ +PHP_FUNCTION(git_reference_is_branch) +{ + zval *ref; + php_git2_t *_ref; + int is_branch = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &ref) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_ref, php_git2_t*, &ref, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + is_branch = git_reference_is_branch(PHP_GIT2_V(_ref, reference)); + + RETURN_LONG(is_branch); +} + +/* {{{ proto long git_reference_is_remote(ref) +*/ +PHP_FUNCTION(git_reference_is_remote) +{ + zval *ref; + php_git2_t *_ref; + int is_remote = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &ref) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_ref, php_git2_t*, &ref, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + is_remote = git_reference_is_remote(PHP_GIT2_V(_ref, reference)); + RETURN_LONG(is_remote); +} + +/* {{{ proto long git_reference_is_tag(ref) +*/ +PHP_FUNCTION(git_reference_is_tag) { - TSRMLS_FETCH(); zval *ref; - git_reference *reference; - php_git2_ref_foreach_cb_t *payload; - php_git2_reference *m_reference; - - payload = (php_git2_ref_foreach_cb_t *)opaque; - git_reference_lookup(&reference, payload->repository,name); - - MAKE_STD_ZVAL(ref); - object_init_ex(ref, git2_reference_class_entry); - m_reference = PHP_GIT2_GET_OBJECT(php_git2_reference, ref); - m_reference->reference = reference; - - if (payload->type == 0) { - add_next_index_zval(payload->result, ref); - } else { - /* for lambda callback */ - } - - return GIT_SUCCESS; -} - -/* -{{{ proto: Git2\Reference::each(Git2\Repository $repository [,int filter[, Callable $callback]]) + php_git2_t *_ref; + int is_tag = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &ref) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_ref, php_git2_t*, &ref, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + is_tag = git_reference_is_tag(PHP_GIT2_V(_ref, reference)); + RETURN_LONG(is_tag); +} + +/* {{{ proto resource git_reference_normalize_name(name, flags) */ -PHP_METHOD(git2_reference, each) -{ - git_reference *ref; - zval *repository,*callback = NULL; - php_git2_repository *m_repository; - char *filter; - php_git2_ref_foreach_cb_t opaque; - int error, filter_len = 0; - unsigned int list_flags = GIT_REF_LISTALL; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "O|sz", &repository, git2_repository_class_entry, &filter, &filter_len, &callback) == FAILURE) { - return; - } - - m_repository = PHP_GIT2_GET_OBJECT(php_git2_repository, repository); - opaque.type = 0; - opaque.repository = m_repository->repository; - MAKE_STD_ZVAL(opaque.result); - array_init(opaque.result); - - /* @todo: closure support */ - git_reference_foreach(m_repository->repository, list_flags, &php_git2_ref_foreach_cb, (void *)&opaque); - - RETVAL_ZVAL(opaque.result,0,1); -} -/* }}} */ - - -static zend_function_entry php_git2_reference_methods[] = { - PHP_ME(git2_reference, getTarget, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_reference, getName, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_reference, resolve, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_reference, each, arginfo_git2_reference_each, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) -#ifdef lookup -#undef lookup -#endif - PHP_ME(git2_reference, lookup, arginfo_git2_reference_lookup, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) -#ifndef lookup -#define lookup php_lookup -#endif - {NULL,NULL,NULL} -}; - -void php_git2_reference_init(TSRMLS_D) -{ - zend_class_entry ce; - - INIT_NS_CLASS_ENTRY(ce, PHP_GIT2_NS, "Reference", php_git2_reference_methods); - git2_reference_class_entry = zend_register_internal_class(&ce TSRMLS_CC); - git2_reference_class_entry->create_object = php_git2_reference_new; -} \ No newline at end of file +PHP_FUNCTION(git_reference_normalize_name) +{ + char *name = {0}; + int name_len; + long flags; + char buffer[GIT2_BUFFER_SIZE] = {0}; + size_t buffer_sz = GIT2_BUFFER_SIZE; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "sl", &name, &name_len, &flags) == FAILURE) { + return; + } + error = git_reference_normalize_name(buffer, buffer_sz, name, flags); + if (php_git2_check_error(error, "git_reference_normalize_name" TSRMLS_CC)) { + RETURN_FALSE + } + RETURN_STRING(buffer, 1); +} + +/* {{{ proto resource git_reference_peel(resource $ref, $type) + */ +PHP_FUNCTION(git_reference_peel) +{ + php_git2_t *result = NULL, *_ref = NULL; + git_object *out = NULL; + zval *ref = NULL; + int error = 0; + long type = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &ref, &type) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_ref, php_git2_t*, &ref, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_reference_peel(&out, PHP_GIT2_V(_ref, reference), type); + if (php_git2_check_error(error, "git_reference_peel" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_OBJECT, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto long git_reference_is_valid_name(refname) +*/ +PHP_FUNCTION(git_reference_is_valid_name) +{ + char *refname = {0}; + int refname_len; + int acceptable = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "s", &refname, &refname_len) == FAILURE) { + return; + } + acceptable = git_reference_is_valid_name(refname); + RETURN_BOOL(acceptable); +} + +/* {{{ proto resource git_reference_shorthand(ref) +*/ +PHP_FUNCTION(git_reference_shorthand) +{ + zval *ref; + php_git2_t *_ref; + const char *name; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &ref) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_ref, php_git2_t*, &ref, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + name = git_reference_shorthand(PHP_GIT2_V(_ref, reference)); + RETURN_STRING(name, 1); +} + diff --git a/reference.h b/reference.h new file mode 100644 index 0000000000..086fc43d01 --- /dev/null +++ b/reference.h @@ -0,0 +1,335 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_REFERENCE_H +#define PHP_GIT2_REFERENCE_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_lookup, 0, 0, 2) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_name_to_id, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_dwim, 0, 0, 2) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, shorthand) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_symbolic_create, 0, 0, 4) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, target) + ZEND_ARG_INFO(0, force) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_create, 0, 0, 4) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, id) + ZEND_ARG_INFO(0, force) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_target, 0, 0, 1) + ZEND_ARG_INFO(0, ref) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_target_peel, 0, 0, 1) + ZEND_ARG_INFO(0, ref) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_symbolic_target, 0, 0, 1) + ZEND_ARG_INFO(0, ref) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_type, 0, 0, 1) + ZEND_ARG_INFO(0, ref) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_name, 0, 0, 1) + ZEND_ARG_INFO(0, ref) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_resolve, 0, 0, 1) + ZEND_ARG_INFO(0, ref) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_owner, 0, 0, 1) + ZEND_ARG_INFO(0, ref) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_symbolic_set_target, 0, 0, 2) + ZEND_ARG_INFO(0, ref) + ZEND_ARG_INFO(0, target) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_set_target, 0, 0, 2) + ZEND_ARG_INFO(0, ref) + ZEND_ARG_INFO(0, id) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_rename, 0, 0, 3) + ZEND_ARG_INFO(0, ref) + ZEND_ARG_INFO(0, new_name) + ZEND_ARG_INFO(0, force) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_delete, 0, 0, 1) + ZEND_ARG_INFO(0, ref) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_list, 0, 0, 2) + ZEND_ARG_INFO(0, array) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_foreach, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_foreach_name, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_free, 0, 0, 1) + ZEND_ARG_INFO(0, ref) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_cmp, 0, 0, 2) + ZEND_ARG_INFO(0, ref1) + ZEND_ARG_INFO(0, ref2) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_iterator_new, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_iterator_glob_new, 0, 0, 2) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, glob) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_next, 0, 0, 1) + ZEND_ARG_INFO(0, iter) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_next_name, 0, 0, 1) + ZEND_ARG_INFO(0, iter) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_iterator_free, 0, 0, 1) + ZEND_ARG_INFO(0, iter) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_foreach_glob, 0, 0, 4) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, glob) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_has_log, 0, 0, 1) + ZEND_ARG_INFO(0, ref) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_is_branch, 0, 0, 1) + ZEND_ARG_INFO(0, ref) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_is_remote, 0, 0, 1) + ZEND_ARG_INFO(0, ref) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_is_tag, 0, 0, 1) + ZEND_ARG_INFO(0, ref) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_normalize_name, 0, 0, 4) + ZEND_ARG_INFO(0, buffer_size) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, flags) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_peel, 0, 0, 2) + ZEND_ARG_INFO(0, ref) + ZEND_ARG_INFO(0, type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_is_valid_name, 0, 0, 1) + ZEND_ARG_INFO(0, refname) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reference_shorthand, 0, 0, 1) + ZEND_ARG_INFO(0, ref) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_reference_lookup(repo, name) +*/ +PHP_FUNCTION(git_reference_lookup); + +/* {{{ proto resource git_reference_name_to_id(repo, name) +*/ +PHP_FUNCTION(git_reference_name_to_id); + +/* {{{ proto resource git_reference_dwim(repo, shorthand) +*/ +PHP_FUNCTION(git_reference_dwim); + +/* {{{ proto resource git_reference_symbolic_create(repo, name, target, force) +*/ +PHP_FUNCTION(git_reference_symbolic_create); + +/* {{{ proto resource git_reference_create(repo, name, id, force) +*/ +PHP_FUNCTION(git_reference_create); + +/* {{{ proto resource git_reference_target(ref) +*/ +PHP_FUNCTION(git_reference_target); + +/* {{{ proto resource git_reference_target_peel(ref) +*/ +PHP_FUNCTION(git_reference_target_peel); + +/* {{{ proto resource git_reference_symbolic_target(ref) +*/ +PHP_FUNCTION(git_reference_symbolic_target); + +/* {{{ proto resource git_reference_type(ref) +*/ +PHP_FUNCTION(git_reference_type); + +/* {{{ proto resource git_reference_name(ref) +*/ +PHP_FUNCTION(git_reference_name); + +/* {{{ proto resource git_reference_resolve(ref) +*/ +PHP_FUNCTION(git_reference_resolve); + +/* {{{ proto resource git_reference_owner(ref) +*/ +PHP_FUNCTION(git_reference_owner); + +/* {{{ proto resource git_reference_symbolic_set_target(ref, target) +*/ +PHP_FUNCTION(git_reference_symbolic_set_target); + +/* {{{ proto resource git_reference_set_target(ref, id) +*/ +PHP_FUNCTION(git_reference_set_target); + +/* {{{ proto resource git_reference_rename(ref, new_name, force) +*/ +PHP_FUNCTION(git_reference_rename); + +/* {{{ proto long git_reference_delete(ref) +*/ +PHP_FUNCTION(git_reference_delete); + +/* {{{ proto long git_reference_list(array, repo) +*/ +PHP_FUNCTION(git_reference_list); + +/* {{{ proto long git_reference_foreach(repo, callback, payload) +*/ +PHP_FUNCTION(git_reference_foreach); + +/* {{{ proto long git_reference_foreach_name(repo, callback, payload) +*/ +PHP_FUNCTION(git_reference_foreach_name); + +/* {{{ proto void git_reference_free(ref) +*/ +PHP_FUNCTION(git_reference_free); + +/* {{{ proto long git_reference_cmp(ref1, ref2) +*/ +PHP_FUNCTION(git_reference_cmp); + +/* {{{ proto resource git_reference_iterator_new(repo) +*/ +PHP_FUNCTION(git_reference_iterator_new); + +/* {{{ proto resource git_reference_iterator_glob_new(repo, glob) +*/ +PHP_FUNCTION(git_reference_iterator_glob_new); + +/* {{{ proto resource git_reference_next(iter) +*/ +PHP_FUNCTION(git_reference_next); + +/* {{{ proto resource git_reference_next_name(iter) +*/ +PHP_FUNCTION(git_reference_next_name); + +/* {{{ proto void git_reference_iterator_free(iter) +*/ +PHP_FUNCTION(git_reference_iterator_free); + +/* {{{ proto long git_reference_foreach_glob(repo, glob, callback, payload) +*/ +PHP_FUNCTION(git_reference_foreach_glob); + +/* {{{ proto long git_reference_has_log(ref) +*/ +PHP_FUNCTION(git_reference_has_log); + +/* {{{ proto long git_reference_is_branch(ref) +*/ +PHP_FUNCTION(git_reference_is_branch); + +/* {{{ proto long git_reference_is_remote(ref) +*/ +PHP_FUNCTION(git_reference_is_remote); + +/* {{{ proto long git_reference_is_tag(ref) +*/ +PHP_FUNCTION(git_reference_is_tag); + +/* {{{ proto resource git_reference_normalize_name(buffer_size, name, flags) +*/ +PHP_FUNCTION(git_reference_normalize_name); + +/* {{{ proto resource git_reference_peel(ref, type) +*/ +PHP_FUNCTION(git_reference_peel); + +/* {{{ proto long git_reference_is_valid_name(refname) +*/ +PHP_FUNCTION(git_reference_is_valid_name); + +/* {{{ proto resource git_reference_shorthand(ref) +*/ +PHP_FUNCTION(git_reference_shorthand); + +#endif \ No newline at end of file diff --git a/reflog.c b/reflog.c new file mode 100644 index 0000000000..35d95fdec1 --- /dev/null +++ b/reflog.c @@ -0,0 +1,302 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "reflog.h" + +/* {{{ proto resource git_reflog_read(resource $repo, string $name) + */ +PHP_FUNCTION(git_reflog_read) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_reflog *out = NULL; + zval *repo = NULL; + char *name = NULL; + int name_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repo, &name, &name_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_reflog_read(&out, PHP_GIT2_V(_repo, repository), name); + if (php_git2_check_error(error, "git_reflog_read" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REFLOG, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto long git_reflog_write(resource $reflog) + */ +PHP_FUNCTION(git_reflog_write) +{ + int result = 0; + zval *reflog = NULL; + php_git2_t *_reflog = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &reflog) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_reflog, php_git2_t*, &reflog, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_reflog_write(PHP_GIT2_V(_reflog, reflog)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_reflog_append(resource $reflog, string $id, array $committer, string $msg) + */ +PHP_FUNCTION(git_reflog_append) +{ + int result = 0, id_len = 0, msg_len = 0; + zval *reflog = NULL, *committer = NULL; + php_git2_t *_reflog = NULL; + char *id = NULL, *msg = NULL; + git_oid __id = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsas", &reflog, &id, &id_len, &committer, &msg, &msg_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_reflog, php_git2_t*, &reflog, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__id, id, id_len)) { + RETURN_FALSE; + } + result = git_reflog_append(PHP_GIT2_V(_reflog, reflog), &__id, committer, msg); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_reflog_append_to(resource $repo, string $name, string $id, array $committer, string $msg) + */ +PHP_FUNCTION(git_reflog_append_to) +{ + int result = 0, name_len = 0, id_len = 0, msg_len = 0; + zval *repo = NULL, *committer = NULL; + php_git2_t *_repo = NULL; + char *name = NULL, *id = NULL, *msg = NULL; + git_oid __id = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rssas", &repo, &name, &name_len, &id, &id_len, &committer, &msg, &msg_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__id, id, id_len)) { + RETURN_FALSE; + } + result = git_reflog_append_to(PHP_GIT2_V(_repo, repository), name, &__id, committer, msg); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_reflog_rename(resource $repo, string $old_name, string $name) + */ +PHP_FUNCTION(git_reflog_rename) +{ + int result = 0, old_name_len = 0, name_len = 0; + zval *repo = NULL; + php_git2_t *_repo = NULL; + char *old_name = NULL, *name = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rss", &repo, &old_name, &old_name_len, &name, &name_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_reflog_rename(PHP_GIT2_V(_repo, repository), old_name, name); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_reflog_delete(resource $repo, string $name) + */ +PHP_FUNCTION(git_reflog_delete) +{ + int result = 0, name_len = 0; + zval *repo = NULL; + php_git2_t *_repo = NULL; + char *name = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repo, &name, &name_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_reflog_delete(PHP_GIT2_V(_repo, repository), name); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_reflog_entrycount(resource $reflog) + */ +PHP_FUNCTION(git_reflog_entrycount) +{ + size_t result = 0; + zval *reflog = NULL; + php_git2_t *_reflog = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &reflog) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_reflog, php_git2_t*, &reflog, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_reflog_entrycount(PHP_GIT2_V(_reflog, reflog)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_reflog_entry_byindex(resource $reflog, long $idx) + */ +PHP_FUNCTION(git_reflog_entry_byindex) +{ + const git_reflog_entry *result = NULL; + zval *reflog = NULL; + php_git2_t *_reflog = NULL, *_result; + long idx = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &reflog, &idx) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_reflog, php_git2_t*, &reflog, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_reflog_entry_byindex(PHP_GIT2_V(_reflog, reflog), idx); + if (php_git2_make_resource(&_result, PHP_GIT2_TYPE_REFLOG_ENTRY, result, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(_result)); +} +/* }}} */ + +/* {{{ proto long git_reflog_drop(resource $reflog, long $idx, long $rewrite_previous_entry) + */ +PHP_FUNCTION(git_reflog_drop) +{ + int result = 0; + zval *reflog = NULL; + php_git2_t *_reflog = NULL; + long idx = 0, rewrite_previous_entry = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rll", &reflog, &idx, &rewrite_previous_entry) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_reflog, php_git2_t*, &reflog, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_reflog_drop(PHP_GIT2_V(_reflog, reflog), idx, rewrite_previous_entry); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_reflog_entry_id_old(resource $entry) + */ +PHP_FUNCTION(git_reflog_entry_id_old) +{ + const git_oid *result = NULL; + zval *entry = NULL; + php_git2_t *_entry = NULL; + char __result[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &entry) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_entry, php_git2_t*, &entry, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_reflog_entry_id_old(PHP_GIT2_V(_entry, reflog_entry)); + git_oid_fmt(__result, result); + RETURN_STRING(__result, 1); +} +/* }}} */ + +/* {{{ proto string git_reflog_entry_id_new(resource $entry) + */ +PHP_FUNCTION(git_reflog_entry_id_new) +{ + const git_oid *result = NULL; + zval *entry = NULL; + php_git2_t *_entry = NULL; + char __result[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &entry) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_entry, php_git2_t*, &entry, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_reflog_entry_id_new(PHP_GIT2_V(_entry, reflog_entry)); + git_oid_fmt(__result, result); + RETURN_STRING(__result, 1); +} +/* }}} */ + +/* {{{ proto array git_reflog_entry_committer(resource $entry) + */ +PHP_FUNCTION(git_reflog_entry_committer) +{ + const git_signature *result = NULL; + zval *__result = NULL, *entry = NULL; + php_git2_t *_entry = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &entry) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_entry, php_git2_t*, &entry, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_reflog_entry_committer(PHP_GIT2_V(_entry, reflog_entry)); + php_git2_signature_to_array(result, &__result TSRMLS_CC); + RETURN_ZVAL(__result, 0, 1); +} +/* }}} */ + +/* {{{ proto string git_reflog_entry_message(resource $entry) + */ +PHP_FUNCTION(git_reflog_entry_message) +{ + const char *result = NULL; + zval *entry = NULL; + php_git2_t *_entry = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &entry) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_entry, php_git2_t*, &entry, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_reflog_entry_message(PHP_GIT2_V(_entry, reflog_entry)); + RETURN_STRING(result, 1); +} +/* }}} */ + +/* {{{ proto void git_reflog_free(resource $reflog) + */ +PHP_FUNCTION(git_reflog_free) +{ + zval *reflog = NULL; + php_git2_t *_reflog = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &reflog) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_reflog, php_git2_t*, &reflog, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_reflog)) { + git_reflog_free(PHP_GIT2_V(_reflog, reflog)); + GIT2_SHOULD_FREE(_reflog) = 0; + }; + zval_ptr_dtor(&reflog); +} +/* }}} */ + diff --git a/reflog.h b/reflog.h new file mode 100644 index 0000000000..5d1ad59618 --- /dev/null +++ b/reflog.h @@ -0,0 +1,153 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_REFLOG_H +#define PHP_GIT2_REFLOG_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reflog_read, 0, 0, 2) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reflog_write, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reflog_append, 0, 0, 4) + ZEND_ARG_INFO(0, reflog) + ZEND_ARG_INFO(0, id) + ZEND_ARG_INFO(0, committer) + ZEND_ARG_INFO(0, msg) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reflog_append_to, 0, 0, 5) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, id) + ZEND_ARG_INFO(0, committer) + ZEND_ARG_INFO(0, msg) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reflog_rename, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, old_name) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reflog_delete, 0, 0, 2) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reflog_entrycount, 0, 0, 1) + ZEND_ARG_INFO(0, reflog) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reflog_entry_byindex, 0, 0, 2) + ZEND_ARG_INFO(0, reflog) + ZEND_ARG_INFO(0, idx) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reflog_drop, 0, 0, 3) + ZEND_ARG_INFO(0, reflog) + ZEND_ARG_INFO(0, idx) + ZEND_ARG_INFO(0, rewrite_previous_entry) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reflog_entry_id_old, 0, 0, 1) + ZEND_ARG_INFO(0, entry) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reflog_entry_id_new, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reflog_entry_committer, 0, 0, 1) + ZEND_ARG_INFO(0, entry) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reflog_entry_message, 0, 0, 1) + ZEND_ARG_INFO(0, entry) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reflog_free, 0, 0, 1) + ZEND_ARG_INFO(0, reflog) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_reflog_read(repo, name) +*/ +PHP_FUNCTION(git_reflog_read); + +/* {{{ proto resource git_reflog_write() +*/ +PHP_FUNCTION(git_reflog_write); + +/* {{{ proto long git_reflog_append(reflog, id, committer, msg) +*/ +PHP_FUNCTION(git_reflog_append); + +/* {{{ proto long git_reflog_append_to(repo, name, id, committer, msg) +*/ +PHP_FUNCTION(git_reflog_append_to); + +/* {{{ proto long git_reflog_rename(repo, old_name, name) +*/ +PHP_FUNCTION(git_reflog_rename); + +/* {{{ proto long git_reflog_delete(repo, name) +*/ +PHP_FUNCTION(git_reflog_delete); + +/* {{{ proto resource git_reflog_entrycount(reflog) +*/ +PHP_FUNCTION(git_reflog_entrycount); + +/* {{{ proto resource git_reflog_entry_byindex(reflog, idx) +*/ +PHP_FUNCTION(git_reflog_entry_byindex); + +/* {{{ proto long git_reflog_drop(reflog, idx, rewrite_previous_entry) +*/ +PHP_FUNCTION(git_reflog_drop); + +/* {{{ proto resource git_reflog_entry_id_old(entry) +*/ +PHP_FUNCTION(git_reflog_entry_id_old); + +/* {{{ proto resource git_reflog_entry_id_new() +*/ +PHP_FUNCTION(git_reflog_entry_id_new); + +/* {{{ proto resource git_reflog_entry_committer(entry) +*/ +PHP_FUNCTION(git_reflog_entry_committer); + +/* {{{ proto resource git_reflog_entry_message(entry) +*/ +PHP_FUNCTION(git_reflog_entry_message); + +/* {{{ proto void git_reflog_free(reflog) +*/ +PHP_FUNCTION(git_reflog_free); + +#endif \ No newline at end of file diff --git a/refspec.c b/refspec.c new file mode 100644 index 0000000000..956d2474f2 --- /dev/null +++ b/refspec.c @@ -0,0 +1,189 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "refspec.h" + +/* {{{ proto string git_refspec_src(resource $refspec) + */ +PHP_FUNCTION(git_refspec_src) +{ + const char *result = NULL; + zval *refspec = NULL; + php_git2_t *_refspec = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &refspec) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_refspec, php_git2_t*, &refspec, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_refspec_src(PHP_GIT2_V(_refspec, refspec)); + RETURN_STRING(result, 1); +} +/* }}} */ + +/* {{{ proto string git_refspec_dst(resource $refspec) + */ +PHP_FUNCTION(git_refspec_dst) +{ + const char *result = NULL; + zval *refspec = NULL; + php_git2_t *_refspec = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &refspec) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_refspec, php_git2_t*, &refspec, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_refspec_dst(PHP_GIT2_V(_refspec, refspec)); + RETURN_STRING(result, 1); +} +/* }}} */ + +/* {{{ proto string git_refspec_string(resource $refspec) + */ +PHP_FUNCTION(git_refspec_string) +{ + const char *result = NULL; + zval *refspec = NULL; + php_git2_t *_refspec = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &refspec) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_refspec, php_git2_t*, &refspec, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_refspec_string(PHP_GIT2_V(_refspec, refspec)); + RETURN_STRING(result, 1); +} +/* }}} */ + +/* {{{ proto long git_refspec_force(resource $refspec) + */ +PHP_FUNCTION(git_refspec_force) +{ + int result = 0; + zval *refspec = NULL; + php_git2_t *_refspec = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &refspec) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_refspec, php_git2_t*, &refspec, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_refspec_force(PHP_GIT2_V(_refspec, refspec)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_refspec_direction(resource $spec) + */ +PHP_FUNCTION(git_refspec_direction) +{ + git_direction result; + zval *spec = NULL; + php_git2_t *_spec = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &spec) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_spec, php_git2_t*, &spec, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_refspec_direction(PHP_GIT2_V(_spec, refspec)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_refspec_src_matches(resource $refspec, string $refname) + */ +PHP_FUNCTION(git_refspec_src_matches) +{ + int result = 0, refname_len = 0; + zval *refspec = NULL; + php_git2_t *_refspec = NULL; + char *refname = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &refspec, &refname, &refname_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_refspec, php_git2_t*, &refspec, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_refspec_src_matches(PHP_GIT2_V(_refspec, refspec), refname); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_refspec_dst_matches(resource $refspec, string $refname) + */ +PHP_FUNCTION(git_refspec_dst_matches) +{ + int result = 0, refname_len = 0; + zval *refspec = NULL; + php_git2_t *_refspec = NULL; + char *refname = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &refspec, &refname, &refname_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_refspec, php_git2_t*, &refspec, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_refspec_dst_matches(PHP_GIT2_V(_refspec, refspec), refname); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto string git_refspec_transform(long $outlen, resource $spec, string $name) + */ +PHP_FUNCTION(git_refspec_transform) +{ + // TODO(chobie): fix this implementation + php_git2_t *_spec = NULL; + char out = NULL, *name = NULL; + long outlen = 0; + zval *spec = NULL; + int name_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "lrs", &outlen, &spec, &name, &name_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_spec, php_git2_t*, &spec, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_refspec_transform(&out, outlen, PHP_GIT2_V(_spec, refspec), name); + if (php_git2_check_error(error, "git_refspec_transform" TSRMLS_CC)) { + RETURN_FALSE; + } + RETURN_STRING(out, 1); +} +/* }}} */ + +/* {{{ proto string git_refspec_rtransform(long $outlen, resource $spec, string $name) + */ +PHP_FUNCTION(git_refspec_rtransform) +{ + // TODO(chobie): fix this implementation + php_git2_t *_spec = NULL; + char out = NULL, *name = NULL; + long outlen = 0; + zval *spec = NULL; + int name_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "lrs", &outlen, &spec, &name, &name_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_spec, php_git2_t*, &spec, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_refspec_rtransform(&out, outlen, PHP_GIT2_V(_spec, refspec), name); + if (php_git2_check_error(error, "git_refspec_rtransform" TSRMLS_CC)) { + RETURN_FALSE; + } + RETURN_STRING(out, 1); +} +/* }}} */ + diff --git a/refspec.h b/refspec.h new file mode 100644 index 0000000000..4ca4118c50 --- /dev/null +++ b/refspec.h @@ -0,0 +1,109 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_REFSPEC_H +#define PHP_GIT2_REFSPEC_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_refspec_src, 0, 0, 1) + ZEND_ARG_INFO(0, refspec) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_refspec_dst, 0, 0, 1) + ZEND_ARG_INFO(0, refspec) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_refspec_string, 0, 0, 1) + ZEND_ARG_INFO(0, refspec) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_refspec_force, 0, 0, 1) + ZEND_ARG_INFO(0, refspec) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_refspec_direction, 0, 0, 1) + ZEND_ARG_INFO(0, spec) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_refspec_src_matches, 0, 0, 2) + ZEND_ARG_INFO(0, refspec) + ZEND_ARG_INFO(0, refname) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_refspec_dst_matches, 0, 0, 2) + ZEND_ARG_INFO(0, refspec) + ZEND_ARG_INFO(0, refname) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_refspec_transform, 0, 0, 4) + ZEND_ARG_INFO(0, out) + ZEND_ARG_INFO(0, outlen) + ZEND_ARG_INFO(0, spec) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_refspec_rtransform, 0, 0, 4) + ZEND_ARG_INFO(0, out) + ZEND_ARG_INFO(0, outlen) + ZEND_ARG_INFO(0, spec) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +/* {{{ proto string git_refspec_src(resource $refspec) + */ +PHP_FUNCTION(git_refspec_src); + +/* {{{ proto string git_refspec_dst(resource $refspec) + */ +PHP_FUNCTION(git_refspec_dst); + +/* {{{ proto string git_refspec_string(resource $refspec) + */ +PHP_FUNCTION(git_refspec_string); + +/* {{{ proto long git_refspec_force(resource $refspec) + */ +PHP_FUNCTION(git_refspec_force); + +/* {{{ proto resource git_refspec_direction(resource $spec) + */ +PHP_FUNCTION(git_refspec_direction); + +/* {{{ proto long git_refspec_src_matches(resource $refspec, string $refname) + */ +PHP_FUNCTION(git_refspec_src_matches); + +/* {{{ proto long git_refspec_dst_matches(resource $refspec, string $refname) + */ +PHP_FUNCTION(git_refspec_dst_matches); + +/* {{{ proto resource git_refspec_transform(long $outlen, resource $spec, string $name) + */ +PHP_FUNCTION(git_refspec_transform); + +/* {{{ proto resource git_refspec_rtransform(long $outlen, resource $spec, string $name) + */ +PHP_FUNCTION(git_refspec_rtransform); + +#endif diff --git a/remote.c b/remote.c new file mode 100644 index 0000000000..6820d3e6e5 --- /dev/null +++ b/remote.c @@ -0,0 +1,1004 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "remote.h" + +/* {{{ proto resource git_remote_create(resource $repo, string $name, string $url) + */ +PHP_FUNCTION(git_remote_create) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_remote *out = NULL; + zval *repo = NULL; + char *name = NULL, *url = NULL; + int name_len = 0, url_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rss", &repo, &name, &name_len, &url, &url_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_remote_create(&out, PHP_GIT2_V(_repo, repository), name, url); + if (php_git2_check_error(error, "git_remote_create" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REMOTE, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto resource git_remote_create_with_fetchspec(resource $repo, string $name, string $url, string $fetch) + */ +PHP_FUNCTION(git_remote_create_with_fetchspec) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_remote *out = NULL; + zval *repo = NULL; + char *name = NULL, *url = NULL, *fetch = NULL; + int name_len = 0, url_len = 0, fetch_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsss", &repo, &name, &name_len, &url, &url_len, &fetch, &fetch_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_remote_create_with_fetchspec(&out, PHP_GIT2_V(_repo, repository), name, url, fetch); + if (php_git2_check_error(error, "git_remote_create_with_fetchspec" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REMOTE, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_remote_create_inmemory(resource $repo, string $fetch, string $url) + */ +PHP_FUNCTION(git_remote_create_inmemory) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_remote *out = NULL; + zval *repo = NULL; + char *fetch = NULL, *url = NULL; + int fetch_len = 0, url_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rss", &repo, &fetch, &fetch_len, &url, &url_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_remote_create_inmemory(&out, PHP_GIT2_V(_repo, repository), fetch, url); + if (php_git2_check_error(error, "git_remote_create_inmemory" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REMOTE, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_remote_load(resource $repo, string $name) + */ +PHP_FUNCTION(git_remote_load) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_remote *out = NULL; + zval *repo = NULL; + char *name = NULL; + int name_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repo, &name, &name_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_remote_load(&out, PHP_GIT2_V(_repo, repository), name); + if (php_git2_check_error(error, "git_remote_load" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REMOTE, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto long git_remote_save(resource $remote) + */ +PHP_FUNCTION(git_remote_save) +{ + int result = 0; + zval *remote = NULL; + php_git2_t *_remote = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &remote) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_remote_save(PHP_GIT2_V(_remote, remote)); + RETURN_BOOL(result); +} +/* }}} */ + +/* {{{ proto resource git_remote_owner(resource $remote) + */ +PHP_FUNCTION(git_remote_owner) +{ + git_repository *result = NULL; + zval *remote = NULL; + php_git2_t *_remote = NULL, *__result = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &remote) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_remote_owner(PHP_GIT2_V(_remote, remote)); + if (php_git2_make_resource(&__result, PHP_GIT2_TYPE_REMOTE, result, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(__result)); +} +/* }}} */ + +/* {{{ proto string git_remote_name(resource $remote) + */ +PHP_FUNCTION(git_remote_name) +{ + const char *result = NULL; + zval *remote = NULL; + php_git2_t *_remote = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &remote) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_remote_name(PHP_GIT2_V(_remote, remote)); + RETURN_STRING(result, 1); +} +/* }}} */ + +/* {{{ proto string git_remote_url(resource $remote) + */ +PHP_FUNCTION(git_remote_url) +{ + const char *result = NULL; + zval *remote = NULL; + php_git2_t *_remote = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &remote) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_remote_url(PHP_GIT2_V(_remote, remote)); + RETURN_STRING(result, 1); +} +/* }}} */ + +/* {{{ proto string git_remote_pushurl(resource $remote) + */ +PHP_FUNCTION(git_remote_pushurl) +{ + const char *result = NULL; + zval *remote = NULL; + php_git2_t *_remote = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &remote) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_remote_pushurl(PHP_GIT2_V(_remote, remote)); + RETURN_STRING(result, 1); +} +/* }}} */ + +/* {{{ proto long git_remote_set_url(resource $remote, string $url) + */ +PHP_FUNCTION(git_remote_set_url) +{ + int result = 0; + zval *remote = NULL; + php_git2_t *_remote = NULL; + char *url = NULL; + int url_len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &remote, &url, &url_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_remote_set_url(PHP_GIT2_V(_remote, remote), url); + RETURN_BOOL(result); +} +/* }}} */ + +/* {{{ proto long git_remote_set_pushurl(resource $remote, string $url) + */ +PHP_FUNCTION(git_remote_set_pushurl) +{ + int result = 0; + zval *remote = NULL; + php_git2_t *_remote = NULL; + char *url = NULL; + int url_len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &remote, &url, &url_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_remote_set_pushurl(PHP_GIT2_V(_remote, remote), url); + RETURN_BOOL(result); +} +/* }}} */ + + +/* {{{ proto long git_remote_add_fetch(resource $remote, string $refspec) + */ +PHP_FUNCTION(git_remote_add_fetch) +{ + int result = 0; + zval *remote = NULL; + php_git2_t *_remote = NULL; + char *refspec = NULL; + int refspec_len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &remote, &refspec, &refspec_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_remote_add_fetch(PHP_GIT2_V(_remote, remote), refspec); + RETURN_BOOL(result); +} +/* }}} */ + + +/* {{{ proto array git_remote_get_fetch_refspecs(resource $remote) + */ +PHP_FUNCTION(git_remote_get_fetch_refspecs) +{ + zval *result; + git_strarray array = {0}; + zval *remote = NULL; + php_git2_t *_remote = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &remote) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_remote_get_fetch_refspecs(&array, PHP_GIT2_V(_remote, remote)); + php_git2_strarray_to_array(&array, &result TSRMLS_CC); + git_strarray_free(&array); + + RETURN_ZVAL(result, 0, 1); + +} +/* }}} */ + + +/* {{{ proto long git_remote_set_fetch_refspecs(resource $remote, array $array) + */ +PHP_FUNCTION(git_remote_set_fetch_refspecs) +{ + int result = 0; + zval *remote = NULL, *array = NULL; + php_git2_t *_remote = NULL; + git_strarray out = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "ra", &remote, &array) == FAILURE) { + return; + } + + php_git2_array_to_strarray(&out, array TSRMLS_CC); + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_remote_set_fetch_refspecs(PHP_GIT2_V(_remote, remote), &out); + php_git2_strarray_free(&out); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto long git_remote_add_push(resource $remote, string $refspec) + */ +PHP_FUNCTION(git_remote_add_push) +{ + int result = 0; + zval *remote = NULL; + php_git2_t *_remote = NULL; + char *refspec = NULL; + int refspec_len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &remote, &refspec, &refspec_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_remote_add_push(PHP_GIT2_V(_remote, remote), refspec); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_remote_get_push_refspecs(array $array, resource $remote) + */ +PHP_FUNCTION(git_remote_get_push_refspecs) +{ + git_strarray _array = {0}; + zval *remote = NULL, *array = NULL; + php_git2_t *_remote = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "ar", &array, &remote) == FAILURE) { + return; + } + + php_git2_strarray_to_array(&_array, array TSRMLS_CC); + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_remote_get_push_refspecs(&_array, PHP_GIT2_V(_remote, remote)); + git_strarray_free(&_array); + + RETURN_LONG(error); +} +/* }}} */ + + +/* {{{ proto long git_remote_set_push_refspecs(resource $remote, array $array) + */ +PHP_FUNCTION(git_remote_set_push_refspecs) +{ + int result = 0; + zval *remote = NULL, *array = NULL; + php_git2_t *_remote = NULL; + git_strarray _array = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &remote, &array) == FAILURE) { + return; + } + + php_git2_strarray_to_array(&_array, array TSRMLS_CC); + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_remote_set_push_refspecs(PHP_GIT2_V(_remote, remote), &_array); + git_strarray_free(&_array); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto void git_remote_clear_refspecs(resource $remote) + */ +PHP_FUNCTION(git_remote_clear_refspecs) +{ + zval *remote = NULL; + php_git2_t *_remote = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &remote) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + git_remote_clear_refspecs(PHP_GIT2_V(_remote, remote)); +} +/* }}} */ + + +/* {{{ proto long git_remote_refspec_count(resource $remote) + */ +PHP_FUNCTION(git_remote_refspec_count) +{ + size_t result = 0; + zval *remote = NULL; + php_git2_t *_remote = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &remote) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_remote_refspec_count(PHP_GIT2_V(_remote, remote)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_remote_get_refspec(resource $remote, long $n) + */ +PHP_FUNCTION(git_remote_get_refspec) +{ + const git_refspec *result = NULL; + zval *remote = NULL; + php_git2_t *_remote = NULL, *out; + long n = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &remote, &n) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_remote_get_refspec(PHP_GIT2_V(_remote, remote), n); + if (php_git2_make_resource(&out, PHP_GIT2_TYPE_REFSPEC, result, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(out)); +} +/* }}} */ + +/* {{{ proto bool git_remote_connect(resource $remote, long $direction) + */ +PHP_FUNCTION(git_remote_connect) +{ + int result = 0; + zval *remote = NULL; + php_git2_t *_remote = NULL; + long direction = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &remote, &direction) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_remote_connect(PHP_GIT2_V(_remote, remote), direction); + RETURN_BOOL(result); +} +/* }}} */ + +static void php_git2_git_remote_head_to_array(git_remote_head *head, zval **out TSRMLS_DC) +{ + zval *result = NULL; + char oid[41] = {0}, loid[41] = {0}; + + + git_oid_fmt(oid, &head->oid); + git_oid_fmt(loid, &head->loid); + + MAKE_STD_ZVAL(result); + array_init(result); + add_assoc_long_ex(result, ZEND_STRS("local"), head->local); + add_assoc_string_ex(result, ZEND_STRS("oid"), oid, 1); + add_assoc_string_ex(result, ZEND_STRS("loid"), loid, 1); + add_assoc_string_ex(result, ZEND_STRS("name"), head->name, 1); + + *out = result; +} + +/* {{{ proto resource git_remote_ls(resource $remote) + */ +PHP_FUNCTION(git_remote_ls) +{ + git_remote_head **out = NULL; + size_t size = 0; + zval *remote = NULL, *retval = NULL, *container = NULL; + php_git2_t *_remote = NULL; + int error = 0, i = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &remote) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + if (git_remote_connected(PHP_GIT2_V(_remote, remote)) == 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "passed git_remote hasn't been connected"); + RETURN_FALSE; + } + error = git_remote_ls(&out, &size, PHP_GIT2_V(_remote, remote)); + if (php_git2_check_error(error, "git_remote_ls" TSRMLS_CC)) { + RETURN_FALSE; + } + + MAKE_STD_ZVAL(container); + array_init(container); + for (i = 0; i < size; i++) { + php_git2_git_remote_head_to_array(out[i], &retval TSRMLS_CC); + add_next_index_zval(container, retval); + } + RETURN_ZVAL(container, 0, 1); +} +/* }}} */ + + +/* {{{ proto long git_remote_download(resource $remote) + */ +PHP_FUNCTION(git_remote_download) +{ + int result = 0; + zval *remote = NULL; + php_git2_t *_remote = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &remote) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_remote_download(PHP_GIT2_V(_remote, remote)); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto long git_remote_connected(resource $remote) + */ +PHP_FUNCTION(git_remote_connected) +{ + int result = 0; + zval *remote = NULL; + php_git2_t *_remote = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &remote) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_remote_connected(PHP_GIT2_V(_remote, remote)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto void git_remote_stop(resource $remote) + */ +PHP_FUNCTION(git_remote_stop) +{ + zval *remote = NULL; + php_git2_t *_remote = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &remote) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + git_remote_stop(PHP_GIT2_V(_remote, remote)); +} +/* }}} */ + +/* {{{ proto void git_remote_disconnect(resource $remote) + */ +PHP_FUNCTION(git_remote_disconnect) +{ + zval *remote = NULL; + php_git2_t *_remote = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &remote) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + git_remote_disconnect(PHP_GIT2_V(_remote, remote)); +} +/* }}} */ + + +/* {{{ proto void git_remote_free(resource $remote) + */ +PHP_FUNCTION(git_remote_free) +{ + zval *remote = NULL; + php_git2_t *_remote = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &remote) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (_remote->should_free_v) { + git_remote_free(PHP_GIT2_V(_remote, remote)); + }; + zval_ptr_dtor(&remote); +} +/* }}} */ + + +/* {{{ proto long git_remote_update_tips(resource $remote) + */ +PHP_FUNCTION(git_remote_update_tips) +{ + int result = 0; + zval *remote = NULL; + php_git2_t *_remote = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &remote) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_remote_update_tips(PHP_GIT2_V(_remote, remote)); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto long git_remote_fetch(resource $remote) + */ +PHP_FUNCTION(git_remote_fetch) +{ + int result = 0; + zval *remote = NULL; + php_git2_t *_remote = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &remote) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_remote_fetch(PHP_GIT2_V(_remote, remote)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_remote_valid_url(string $url) + */ +PHP_FUNCTION(git_remote_valid_url) +{ + int result = 0; + char *url = NULL; + int url_len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "s", &url, &url_len) == FAILURE) { + return; + } + + result = git_remote_valid_url(url); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_remote_supported_url(string $url) + */ +PHP_FUNCTION(git_remote_supported_url) +{ + int result = 0; + char *url = NULL; + int url_len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "s", &url, &url_len) == FAILURE) { + return; + } + + result = git_remote_supported_url(url); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto resource git_remote_list(resource $repo) + */ +PHP_FUNCTION(git_remote_list) +{ + zval *result = NULL; + git_strarray out = {0}; + zval *repo = NULL; + php_git2_t *_repo = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_remote_list(&out, PHP_GIT2_V(_repo, repository)); + if (php_git2_check_error(error, "git_remote_list" TSRMLS_CC)) { + RETURN_FALSE; + } + + php_git2_strarray_to_array(&out, &result TSRMLS_CC); + git_strarray_free(&out); + + RETURN_ZVAL(result, 0, 1); +} +/* }}} */ + + +/* {{{ proto void git_remote_check_cert(resource $remote, long $check) + */ +PHP_FUNCTION(git_remote_check_cert) +{ + zval *remote = NULL; + php_git2_t *_remote = NULL; + long check = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &remote, &check) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + git_remote_check_cert(PHP_GIT2_V(_remote, remote), check); +} +/* }}} */ + + +/* {{{ proto long git_remote_set_transport(resource $remote, resource $transport) + */ +PHP_FUNCTION(git_remote_set_transport) +{ + int result = 0; + zval *remote = NULL; + php_git2_t *_remote = NULL; + zval *transport = NULL; + php_git2_t *_transport = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rr", &remote, &transport) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_transport, php_git2_t*, &transport, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_remote_set_transport(PHP_GIT2_V(_remote, remote), PHP_GIT2_V(_transport, transport)); + RETURN_LONG(result); +} +/* }}} */ + +typedef struct php_git2_remote_cb_t { + php_git2_fcall_t callbacks[4]; + zval *payload; + GIT2_TSRMLS_DECL +} php_git2_remote_cb_t; + +static int cred_cb(git_cred **cred, const char *url, const char *username_from_url, unsigned int allowed_types, void *data) +{ + php_git2_t *result; + zval *param_url = NULL, *param_username_from_url = NULL, *param_allowed_types = NULL, *retval_ptr; + php_git2_remote_cb_t *cb = (php_git2_remote_cb_t*)data; + GIT2_TSRMLS_SET(cb->tsrm_ls); + int retval = 1; + + if (cb != NULL) { + MAKE_STD_ZVAL(param_url); + MAKE_STD_ZVAL(param_username_from_url); + MAKE_STD_ZVAL(param_allowed_types); + ZVAL_NULL(param_url); + ZVAL_NULL(param_username_from_url); + + if (url != NULL) { + ZVAL_STRING(param_url, url, 1); + } + if (username_from_url != NULL) { + ZVAL_STRING(param_username_from_url, username_from_url, 1); + } + ZVAL_LONG(param_allowed_types, allowed_types); + Z_ADDREF_P(cb->payload); + SEPARATE_ZVAL_TO_MAKE_IS_REF(&cb->payload); + + if (php_git2_call_function_v(&cb->callbacks[0].fci, &cb->callbacks[0].fcc TSRMLS_CC, &retval_ptr, 4, + ¶m_url, ¶m_username_from_url, ¶m_allowed_types, &cb->payload)) { + fprintf(stderr, "CALL FUNCTION ERROR"); + } + } + + if (retval_ptr && Z_TYPE_P(retval_ptr) == IS_RESOURCE) { + ZEND_FETCH_RESOURCE_NO_RETURN(result, php_git2_t*, &retval_ptr, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + *cred = PHP_GIT2_V(result, cred); + zval_ptr_dtor(&retval_ptr); + } + return retval; +} + +/* {{{ proto long git_remote_set_callbacks(remote, callbacks) +*/ +PHP_FUNCTION(git_remote_set_callbacks) +{ + zval *remote; + php_git2_t *_remote; + zval *callbacks, *credentials_cb = NULL; + struct git_remote_callbacks cb = GIT_REMOTE_CALLBACKS_INIT; + php_git2_remote_cb_t *_payload = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "ra", &remote, &callbacks) == FAILURE) { + return; + } + + /* TODO(chobie): support other callbacks */ + cb.credentials = cred_cb; + credentials_cb = php_git2_read_arrval(callbacks, ZEND_STRS("credentials") TSRMLS_CC); + + /* TODO(chobie): can we free payload? */ + _payload = emalloc(sizeof(php_git2_remote_cb_t)); + MAKE_STD_ZVAL(_payload->payload); + GIT2_TSRMLS_SET2(_payload, TSRMLS_C); + + if (credentials_cb != NULL) { + char *is_callable_error; + + if(zend_fcall_info_init(credentials_cb, 0, &(_payload->callbacks[0].fci), &(_payload->callbacks[0].fci), NULL, &is_callable_error TSRMLS_CC) == SUCCESS) { + if (is_callable_error) { + efree(is_callable_error); + } + } + Z_ADDREF_P(credentials_cb); + } + cb.payload = _payload; + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + git_remote_set_callbacks(PHP_GIT2_V(_remote, remote), &cb); +} + +/* {{{ proto resource git_remote_stats(resource $remote) + */ +PHP_FUNCTION(git_remote_stats) +{ + const git_transfer_progress *result = NULL; + zval *remote = NULL, *retval = NULL; + php_git2_t *_remote = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &remote) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_remote_stats(PHP_GIT2_V(_remote, remote)); + php_git2_git_transfer_progress_to_array(result, &retval TSRMLS_CC); + RETURN_ZVAL(retval, 0, 1); +} +/* }}} */ + + +/* {{{ proto resource git_remote_autotag(resource $remote) + */ +PHP_FUNCTION(git_remote_autotag) +{ + git_remote_autotag_option_t result; + zval *remote = NULL; + php_git2_t *_remote = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &remote) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_remote_autotag(PHP_GIT2_V(_remote, remote)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto void git_remote_set_autotag(resource $remote, $value) + */ +PHP_FUNCTION(git_remote_set_autotag) +{ + zval *remote = NULL, *value = NULL; + php_git2_t *_remote = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &remote, &value) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + git_remote_set_autotag(PHP_GIT2_V(_remote, remote), Z_LVAL_P(value)); +} +/* }}} */ + + +static int php_git2_git_remote_rename_problem_cb(const char *problematic_refspec, void *payload) +{ + return 0; +} + + +/* {{{ proto long git_remote_rename(resource $remote, string $new_name, Callable $callback, $payload) + */ +PHP_FUNCTION(git_remote_rename) +{ + int result = 0, new_name_len = 0; + zval *remote = NULL, *payload = NULL; + php_git2_t *_remote = NULL; + char *new_name = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsfz", &remote, &new_name, &new_name_len, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_remote_rename(PHP_GIT2_V(_remote, remote), new_name, php_git2_git_remote_rename_problem_cb, cb); + php_git2_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto long git_remote_update_fetchhead(resource $remote) + */ +PHP_FUNCTION(git_remote_update_fetchhead) +{ + int result = 0; + zval *remote = NULL; + php_git2_t *_remote = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &remote) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_remote_update_fetchhead(PHP_GIT2_V(_remote, remote)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto void git_remote_set_update_fetchhead(resource $remote, long $value) + */ +PHP_FUNCTION(git_remote_set_update_fetchhead) +{ + zval *remote = NULL; + php_git2_t *_remote = NULL; + long value = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &remote, &value) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_remote, php_git2_t*, &remote, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + git_remote_set_update_fetchhead(PHP_GIT2_V(_remote, remote), value); +} +/* }}} */ + +/* {{{ proto long git_remote_is_valid_name(string $remote_name) + */ +PHP_FUNCTION(git_remote_is_valid_name) +{ + int result = 0; + char *remote_name = NULL; + int remote_name_len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "s", &remote_name, &remote_name_len) == FAILURE) { + return; + } + + result = git_remote_is_valid_name(remote_name); + RETURN_BOOL(result); +} +/* }}} */ + diff --git a/remote.h b/remote.h new file mode 100644 index 0000000000..c5d1f90d14 --- /dev/null +++ b/remote.h @@ -0,0 +1,391 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_REMOTE_H +#define PHP_GIT2_REMOTE_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_create, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, url) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_create_with_fetchspec, 0, 0, 4) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, url) + ZEND_ARG_INFO(0, fetch) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_create_inmemory, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, fetch) + ZEND_ARG_INFO(0, url) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_load, 0, 0, 2) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_save, 0, 0, 1) + ZEND_ARG_INFO(0, remote) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_owner, 0, 0, 1) + ZEND_ARG_INFO(0, remote) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_name, 0, 0, 1) + ZEND_ARG_INFO(0, remote) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_url, 0, 0, 1) + ZEND_ARG_INFO(0, remote) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_pushurl, 0, 0, 1) + ZEND_ARG_INFO(0, remote) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_set_url, 0, 0, 2) + ZEND_ARG_INFO(0, remote) + ZEND_ARG_INFO(0, url) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_set_pushurl, 0, 0, 2) + ZEND_ARG_INFO(0, remote) + ZEND_ARG_INFO(0, url) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_add_fetch, 0, 0, 2) + ZEND_ARG_INFO(0, remote) + ZEND_ARG_INFO(0, refspec) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_get_fetch_refspecs, 0, 0, 2) + ZEND_ARG_INFO(0, array) + ZEND_ARG_INFO(0, remote) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_set_fetch_refspecs, 0, 0, 2) + ZEND_ARG_INFO(0, remote) + ZEND_ARG_INFO(0, array) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_add_push, 0, 0, 2) + ZEND_ARG_INFO(0, remote) + ZEND_ARG_INFO(0, refspec) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_get_push_refspecs, 0, 0, 2) + ZEND_ARG_INFO(0, array) + ZEND_ARG_INFO(0, remote) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_set_push_refspecs, 0, 0, 2) + ZEND_ARG_INFO(0, remote) + ZEND_ARG_INFO(0, array) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_clear_refspecs, 0, 0, 1) + ZEND_ARG_INFO(0, remote) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_refspec_count, 0, 0, 1) + ZEND_ARG_INFO(0, remote) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_get_refspec, 0, 0, 2) + ZEND_ARG_INFO(0, remote) + ZEND_ARG_INFO(0, n) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_connect, 0, 0, 2) + ZEND_ARG_INFO(0, remote) + ZEND_ARG_INFO(0, direction) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_ls, 0, 0, 1) + ZEND_ARG_INFO(0, remote) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_download, 0, 0, 1) + ZEND_ARG_INFO(0, remote) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_connected, 0, 0, 1) + ZEND_ARG_INFO(0, remote) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_stop, 0, 0, 1) + ZEND_ARG_INFO(0, remote) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_disconnect, 0, 0, 1) + ZEND_ARG_INFO(0, remote) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_free, 0, 0, 1) + ZEND_ARG_INFO(0, remote) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_update_tips, 0, 0, 1) + ZEND_ARG_INFO(0, remote) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_fetch, 0, 0, 1) + ZEND_ARG_INFO(0, remote) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_valid_url, 0, 0, 1) + ZEND_ARG_INFO(0, url) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_supported_url, 0, 0, 1) + ZEND_ARG_INFO(0, url) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_list, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_check_cert, 0, 0, 2) + ZEND_ARG_INFO(0, remote) + ZEND_ARG_INFO(0, check) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_set_transport, 0, 0, 2) + ZEND_ARG_INFO(0, remote) + ZEND_ARG_INFO(0, transport) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_set_callbacks, 0, 0, 2) + ZEND_ARG_INFO(0, remote) + ZEND_ARG_INFO(0, callbacks) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_stats, 0, 0, 1) + ZEND_ARG_INFO(0, remote) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_autotag, 0, 0, 1) + ZEND_ARG_INFO(0, remote) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_set_autotag, 0, 0, 2) + ZEND_ARG_INFO(0, remote) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_rename, 0, 0, 4) + ZEND_ARG_INFO(0, remote) + ZEND_ARG_INFO(0, new_name) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_update_fetchhead, 0, 0, 1) + ZEND_ARG_INFO(0, remote) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_set_update_fetchhead, 0, 0, 2) + ZEND_ARG_INFO(0, remote) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_remote_is_valid_name, 0, 0, 1) + ZEND_ARG_INFO(0, remote_name) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_remote_create(repo, name, url) +*/ +PHP_FUNCTION(git_remote_create); + +/* {{{ proto resource git_remote_create_with_fetchspec(repo, name, url, fetch) +*/ +PHP_FUNCTION(git_remote_create_with_fetchspec); + +/* {{{ proto resource git_remote_create_inmemory(repo, fetch, url) +*/ +PHP_FUNCTION(git_remote_create_inmemory); + +/* {{{ proto resource git_remote_load(repo, name) +*/ +PHP_FUNCTION(git_remote_load); + +/* {{{ proto long git_remote_save(remote) +*/ +PHP_FUNCTION(git_remote_save); + +/* {{{ proto resource git_remote_owner(remote) +*/ +PHP_FUNCTION(git_remote_owner); + +/* {{{ proto resource git_remote_name(remote) +*/ +PHP_FUNCTION(git_remote_name); + +/* {{{ proto resource git_remote_url(remote) +*/ +PHP_FUNCTION(git_remote_url); + +/* {{{ proto resource git_remote_pushurl(remote) +*/ +PHP_FUNCTION(git_remote_pushurl); + +/* {{{ proto long git_remote_set_url(remote, url) +*/ +PHP_FUNCTION(git_remote_set_url); + +/* {{{ proto long git_remote_set_pushurl(remote, url) +*/ +PHP_FUNCTION(git_remote_set_pushurl); + +/* {{{ proto long git_remote_add_fetch(remote, refspec) +*/ +PHP_FUNCTION(git_remote_add_fetch); + +/* {{{ proto long git_remote_get_fetch_refspecs(array, remote) +*/ +PHP_FUNCTION(git_remote_get_fetch_refspecs); + +/* {{{ proto long git_remote_set_fetch_refspecs(remote, array) +*/ +PHP_FUNCTION(git_remote_set_fetch_refspecs); + +/* {{{ proto long git_remote_add_push(remote, refspec) +*/ +PHP_FUNCTION(git_remote_add_push); + +/* {{{ proto long git_remote_get_push_refspecs(array, remote) +*/ +PHP_FUNCTION(git_remote_get_push_refspecs); + +/* {{{ proto long git_remote_set_push_refspecs(remote, array) +*/ +PHP_FUNCTION(git_remote_set_push_refspecs); + +/* {{{ proto void git_remote_clear_refspecs(remote) +*/ +PHP_FUNCTION(git_remote_clear_refspecs); + +/* {{{ proto resource git_remote_refspec_count(remote) +*/ +PHP_FUNCTION(git_remote_refspec_count); + +/* {{{ proto resource git_remote_get_refspec(remote, n) +*/ +PHP_FUNCTION(git_remote_get_refspec); + +/* {{{ proto long git_remote_connect(remote, direction) +*/ +PHP_FUNCTION(git_remote_connect); + +/* {{{ proto resource git_remote_ls(remote) +*/ +PHP_FUNCTION(git_remote_ls); + +/* {{{ proto long git_remote_download(remote) +*/ +PHP_FUNCTION(git_remote_download); + +/* {{{ proto long git_remote_connected(remote) +*/ +PHP_FUNCTION(git_remote_connected); + +/* {{{ proto void git_remote_stop(remote) +*/ +PHP_FUNCTION(git_remote_stop); + +/* {{{ proto void git_remote_disconnect(remote) +*/ +PHP_FUNCTION(git_remote_disconnect); + +/* {{{ proto void git_remote_free(remote) +*/ +PHP_FUNCTION(git_remote_free); + +/* {{{ proto long git_remote_update_tips(remote) +*/ +PHP_FUNCTION(git_remote_update_tips); + +/* {{{ proto long git_remote_fetch(remote) +*/ +PHP_FUNCTION(git_remote_fetch); + +/* {{{ proto long git_remote_valid_url(url) +*/ +PHP_FUNCTION(git_remote_valid_url); + +/* {{{ proto long git_remote_supported_url(url) +*/ +PHP_FUNCTION(git_remote_supported_url); + +/* {{{ proto resource git_remote_list(repo) +*/ +PHP_FUNCTION(git_remote_list); + +/* {{{ proto void git_remote_check_cert(remote, check) +*/ +PHP_FUNCTION(git_remote_check_cert); + +/* {{{ proto long git_remote_set_transport(remote, transport) +*/ +PHP_FUNCTION(git_remote_set_transport); + +/* {{{ proto long git_remote_set_callbacks(remote, callbacks) +*/ +PHP_FUNCTION(git_remote_set_callbacks); + +/* {{{ proto resource git_remote_stats(remote) +*/ +PHP_FUNCTION(git_remote_stats); + +/* {{{ proto resource git_remote_autotag(remote) +*/ +PHP_FUNCTION(git_remote_autotag); + +/* {{{ proto void git_remote_set_autotag(remote, value) +*/ +PHP_FUNCTION(git_remote_set_autotag); + +/* {{{ proto long git_remote_rename(remote, new_name, callback, payload) +*/ +PHP_FUNCTION(git_remote_rename); + +/* {{{ proto long git_remote_update_fetchhead(remote) +*/ +PHP_FUNCTION(git_remote_update_fetchhead); + +/* {{{ proto void git_remote_set_update_fetchhead(remote, value) +*/ +PHP_FUNCTION(git_remote_set_update_fetchhead); + +/* {{{ proto long git_remote_is_valid_name(remote_name) +*/ +PHP_FUNCTION(git_remote_is_valid_name); + +#endif \ No newline at end of file diff --git a/repository.c b/repository.c index b4f46ddafa..49415fedb4 100644 --- a/repository.c +++ b/repository.c @@ -1,482 +1,940 @@ -/* - * The MIT License - * - * Copyright (c) 2010 - 2012 Shuhei Tanuma - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - #include "php_git2.h" +#include "php_git2_priv.h" +#include "repository.h" + +static void php_git2_array_to_git_repository_init_options(git_repository_init_options *opts, zval *array TSRMLS_DC) +{ + long lval; -PHPAPI zend_class_entry *git2_repository_class_entry; -void php_git2_repository_init(TSRMLS_D); + lval = php_git2_read_arrval_long(array, ZEND_STRS("version") TSRMLS_CC); + if (lval > 0) { + opts->version = lval; + } + opts->flags = php_git2_read_arrval_long(array, ZEND_STRS("flags") TSRMLS_CC); + opts->mode = php_git2_read_arrval_long(array, ZEND_STRS("mode") TSRMLS_CC); + + opts->workdir_path = php_git2_read_arrval_string(array, ZEND_STRS("workdir_path") TSRMLS_CC); + opts->description = php_git2_read_arrval_string(array, ZEND_STRS("description") TSRMLS_CC); + opts->template_path = php_git2_read_arrval_string(array, ZEND_STRS("template_path") TSRMLS_CC); + opts->initial_head = php_git2_read_arrval_string(array, ZEND_STRS("initial_head") TSRMLS_CC); + opts->origin_url = php_git2_read_arrval_string(array, ZEND_STRS("origin_url") TSRMLS_CC); +} -static void php_git2_repository_free_storage(php_git2_repository *object TSRMLS_DC) +static void php_git2_git_repository_init_options_to_array(git_repository_init_options *opts, zval **out TSRMLS_DC) { - if (object->repository != NULL) { - git_repository_free(object->repository); - object->repository = NULL; + zval *result; + MAKE_STD_ZVAL(result); + array_init(result); + + add_assoc_long_ex(result, ZEND_STRS("version"), opts->version); + add_assoc_long_ex(result, ZEND_STRS("flags"), opts->flags); + add_assoc_long_ex(result, ZEND_STRS("mode"), opts->mode); + + if (opts->workdir_path != NULL) { + add_assoc_string_ex(result, ZEND_STRS("workdir_path"), opts->workdir_path, 1); + } else { + add_assoc_null_ex(result, ZEND_STRS("workdir_path")); + } + + if (opts->workdir_path != NULL) { + add_assoc_string_ex(result, ZEND_STRS("description"), opts->description, 1); + } else { + add_assoc_null_ex(result, ZEND_STRS("description")); } - zend_object_std_dtor(&object->zo TSRMLS_CC); - efree(object); + + if (opts->workdir_path != NULL) { + add_assoc_string_ex(result, ZEND_STRS("template_path"), opts->template_path, 1); + } else { + add_assoc_null_ex(result, ZEND_STRS("template_path")); + } + + if (opts->workdir_path != NULL) { + add_assoc_string_ex(result, ZEND_STRS("initial_head"), opts->initial_head, 1); + } else { + add_assoc_null_ex(result, ZEND_STRS("initial_head")); + } + + if (opts->workdir_path != NULL) { + add_assoc_string_ex(result, ZEND_STRS("origin_url"), opts->origin_url, 1); + } else { + add_assoc_null_ex(result, ZEND_STRS("origin_url")); + } + *out = result; } -zend_object_value php_git2_repository_new(zend_class_entry *ce TSRMLS_DC) + +static int php_git2_repository_fetchhead_foreach_cb(const char *ref_name, + const char *remote_url, + const git_oid *oid, + unsigned int is_merge, + void *payload) { - zend_object_value retval; + zval *param_ref_name, *param_remote_url, *param_oid, *param_is_merge, *retval_ptr = NULL; + php_git2_cb_t *p = (php_git2_cb_t*)payload; + long retval = 0; + char _oid[GIT2_OID_HEXSIZE] = {0}; + GIT2_TSRMLS_SET(p->tsrm_ls) + + git_oid_fmt(_oid, oid); + + Z_ADDREF_P(p->payload); + MAKE_STD_ZVAL(param_ref_name); + MAKE_STD_ZVAL(param_remote_url); + MAKE_STD_ZVAL(param_oid); + MAKE_STD_ZVAL(param_is_merge); + ZVAL_STRING(param_ref_name, ref_name, 1); + ZVAL_STRING(param_remote_url, remote_url, 1); + ZVAL_STRING(param_oid, _oid, 1); + ZVAL_BOOL(param_is_merge, is_merge); + + if (php_git2_call_function_v(p->fci, p->fcc TSRMLS_CC, &retval_ptr, 5, + ¶m_ref_name, + ¶m_remote_url, + ¶m_oid, + ¶m_is_merge, + &p->payload)) { + return GIT_EUSER; + } - PHP_GIT2_STD_CREATE_OBJECT(php_git2_repository); + retval = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); return retval; } -ZEND_BEGIN_ARG_INFO_EX(arginfo_git2_repository___construct, 0,0,1) - ZEND_ARG_INFO(0, repository_path) -ZEND_END_ARG_INFO() +static int php_git2_repository_mergehead_foreach_cb(const git_oid *oid, + void *payload) +{ + zval *param_oid, *retval_ptr = NULL; + php_git2_cb_t *p = (php_git2_cb_t*)payload; + long retval = 0; + char _oid[GIT2_OID_HEXSIZE] = {0}; + GIT2_TSRMLS_SET(p->tsrm_ls) -ZEND_BEGIN_ARG_INFO_EX(arginfo_git2_repository_init, 0,0,1) - ZEND_ARG_INFO(0, isBare) -ZEND_END_ARG_INFO() + git_oid_fmt(_oid, oid); -ZEND_BEGIN_ARG_INFO_EX(arginfo_git2_repository_discover, 0,0,3) - ZEND_ARG_INFO(0, path) - ZEND_ARG_INFO(0, across_fs) - ZEND_ARG_INFO(0, ceiling_dirs) -ZEND_END_ARG_INFO() + Z_ADDREF_P(p->payload); + MAKE_STD_ZVAL(param_oid); + ZVAL_STRING(param_oid, _oid, 1); -ZEND_BEGIN_ARG_INFO_EX(arginfo_git2_repository_exists, 0,0,1) - ZEND_ARG_INFO(0, exists) -ZEND_END_ARG_INFO() + if (php_git2_call_function_v(p->fci, p->fcc TSRMLS_CC, &retval_ptr, 2, ¶m_oid, &p->payload)) { + return GIT_EUSER; + } -ZEND_BEGIN_ARG_INFO_EX(arginfo_git2_repository_write, 0,0,2) - ZEND_ARG_INFO(0, contents) - ZEND_ARG_INFO(0, type) -ZEND_END_ARG_INFO() + retval = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + return retval; +} -ZEND_BEGIN_ARG_INFO_EX(arginfo_git2_repository_hash, 0,0,2) - ZEND_ARG_INFO(0, contents) - ZEND_ARG_INFO(0, type) -ZEND_END_ARG_INFO() +/* {{{ proto resource git_repository_new() +*/ +PHP_FUNCTION(git_repository_new) +{ + git_repository *repository; + php_git2_t *git2; + int error; -ZEND_BEGIN_ARG_INFO_EX(arginfo_git2_repository_lookup, 0,0,1) - ZEND_ARG_INFO(0, lookup) - ZEND_ARG_INFO(0, type) -ZEND_END_ARG_INFO() + error = git_repository_new(&repository); + if (php_git2_check_error(error, "git_repository_new" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&git2, PHP_GIT2_TYPE_REPOSITORY, repository, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(git2)); +} -/* -{{{ proto: Git2\Repsotiroy::__construct(string $path) +/* {{{ proto resource git_repository_init(string $path, long is_bare = 0) */ -PHP_METHOD(git2_repository, __construct) +PHP_FUNCTION(git_repository_init) { - const char *repository_path = NULL; - int repository_path_len, ret = 0; git_repository *repository; - php_git2_repository *m_repository; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "|s", &repository_path, &repository_path_len) == FAILURE) { - return; - } - - m_repository = PHP_GIT2_GET_OBJECT(php_git2_repository, getThis()); - if (repository_path_len > 0) { - ret = git_repository_open(&repository, repository_path); - - if (ret != GIT_SUCCESS) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, git_strerror(ret)); - RETURN_FALSE; - } - - m_repository->repository = repository; - php_git2_add_protected_property_string_ex(getThis(), - "path",sizeof("path"), - git_repository_path(repository), - 1 TSRMLS_CC); - } else { - m_repository->repository = NULL; + php_git2_t *git2; + char *path; + int error, path_len, is_bare = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "s|l", &path, &path_len, &is_bare) == FAILURE) { + return; + } + error = git_repository_init(&repository, path, is_bare); + if (php_git2_check_error(error, "git_repository_init" TSRMLS_CC)) { + RETURN_FALSE + } + if (php_git2_make_resource(&git2, PHP_GIT2_TYPE_REPOSITORY, repository, 1 TSRMLS_CC)) { + RETURN_FALSE; } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(git2)); } -/* }}} */ -/* -{{{ proto: Git2\Repsotiroy::isEmpty() +/* {{{ proto resource git_repository_open(string $path) */ -PHP_METHOD(git2_repository, isEmpty) +PHP_FUNCTION(git_repository_open_bare) { + char *path; + int path_len; git_repository *repository; - php_git2_repository *m_repository; - - m_repository = PHP_GIT2_GET_OBJECT(php_git2_repository, getThis()); - if (m_repository->repository != NULL) { - if (git_repository_is_empty(m_repository->repository)) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } - } else { - /* @todo: throws an exectpion */ + int error = 0; + php_git2_t *git2; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "s", &path, &path_len) == FAILURE) { + return; + } + + error = git_repository_open_bare(&repository, path); + if (php_git2_check_error(error, "git_repository_open_bare" TSRMLS_CC)) { + RETURN_FALSE + } + if (php_git2_make_resource(&git2, PHP_GIT2_TYPE_REPOSITORY, repository, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(git2)); +} + +/* {{{ proto resource git_repository_open(string $path) + */ +PHP_FUNCTION(git_repository_open) +{ + php_git2_t *result = NULL; + git_repository *out = NULL; + char *path = NULL; + int path_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "s", &path, &path_len) == FAILURE) { + return; + } + + error = git_repository_open(&out, path); + if (php_git2_check_error(error, "git_repository_open" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REPOSITORY, out, 1 TSRMLS_CC)) { + RETURN_FALSE; } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); } /* }}} */ -/* -{{{ proto: Git2\Repsotiroy::isBare() + +/* {{{ proto string git_repository_get_namespace(resource $repository) */ -PHP_METHOD(git2_repository, isBare) +PHP_FUNCTION(git_repository_get_namespace) { - git_repository *repository; - php_git2_repository *m_repository; - - m_repository = PHP_GIT2_GET_OBJECT(php_git2_repository, getThis()); - if (m_repository->repository != NULL) { - if (git_repository_is_bare(m_repository->repository) == 1) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } + zval *repository; + php_git2_t *git2; + const char *ns; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repository) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &repository, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ns = git_repository_get_namespace(PHP_GIT2_V(git2, repository)); + if (ns != NULL) { + RETURN_STRING(ns, 1); } else { - /* @todo: throws an exectpion */ + RETURN_STRING("", 1); } } /* }}} */ -/* -{{{ proto: Git2\Repsotiroy::getPath() +/* {{{ proto string git_repository_workdir(resource $repository) */ -PHP_METHOD(git2_repository, getPath) +PHP_FUNCTION(git_repository_workdir) { - git_repository *repository; - php_git2_repository *m_repository; - const char *path = NULL; - zval *m_path = NULL; - - m_repository = PHP_GIT2_GET_OBJECT(php_git2_repository, getThis()); - if (m_repository->repository != NULL) { - path = git_repository_path(m_repository->repository); - if (path != NULL) { - MAKE_STD_ZVAL(m_path); - ZVAL_STRING(m_path, path, 1); - RETVAL_ZVAL(m_path,0,1); - } + zval *repository; + php_git2_t *git2; + const char *workdir; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repository) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &repository, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + workdir = git_repository_workdir(PHP_GIT2_V(git2, repository)); + if (workdir != NULL) { + RETURN_STRING(workdir, 1); } else { - /* @todo: throws an exectpion */ + RETURN_STRING("", 1); } } /* }}} */ -/* -{{{ proto: Git2\Repsotiroy::getWorkdir() -*/ -PHP_METHOD(git2_repository, getWorkdir) +/* {{{ proto resource git_repository_wrap_odb(resource $odb) + */ +PHP_FUNCTION(git_repository_wrap_odb) { - git_repository *repository; - php_git2_repository *m_repository; - const char *path = NULL; - zval *m_path = NULL; - - m_repository = PHP_GIT2_GET_OBJECT(php_git2_repository, getThis()); - if (m_repository->repository != NULL) { - path = git_repository_workdir(m_repository->repository); - if (path != NULL) { - MAKE_STD_ZVAL(m_path); - ZVAL_STRING(m_path, path, 1); - RETVAL_ZVAL(m_path,0,1); - } - } else { - /* @todo: throws an exectpion */ + php_git2_t *result = NULL; + git_repository *out = NULL; + zval *odb = NULL; + php_git2_t *_odb = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &odb) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_odb, php_git2_t*, &odb, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_repository_wrap_odb(&out, PHP_GIT2_V(_odb, odb)); + if (php_git2_check_error(error, "git_repository_wrap_odb" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REPOSITORY, out, 1 TSRMLS_CC)) { + RETURN_FALSE; } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); } /* }}} */ -/* -{{{ proto: Git2\Repsotiroy::init(string $path [, bool isBare]) +/* {{{ proto resource git_repository_discover(start_path, across_fs, ceiling_dirs) */ -PHP_METHOD(git2_repository, init) +PHP_FUNCTION(git_repository_discover) { - char *path; - int ret, path_len = 0; - zend_bool is_bare = 0; - git_repository *repository; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "s|b", &path, &path_len, &is_bare) == FAILURE) { - return; - } - - ret = git_repository_init(&repository, path, is_bare); - if (ret == GIT_SUCCESS) { - zval *object; - php_git2_repository *m_repository; - - MAKE_STD_ZVAL(object); - object_init_ex(object, git2_repository_class_entry); - m_repository = PHP_GIT2_GET_OBJECT(php_git2_repository, object); - m_repository->repository = repository; - - RETVAL_ZVAL(object,0,1); - } else { - /* @todo: throws an runtime exception */ + char *start_path = {0}; + int start_path_len; + long across_fs; + char *ceiling_dirs = {0}; + int ceiling_dirs_len; + int error = 0; + char buffer[GIT2_BUFFER_SIZE]; + size_t buffer_len = GIT2_BUFFER_SIZE; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "sls", &start_path, &start_path_len, &across_fs, &ceiling_dirs, &ceiling_dirs_len) == FAILURE) { + return; + } + + error = git_repository_discover(buffer, buffer_len, start_path, across_fs, ceiling_dirs); + if (php_git2_check_error(error, "git_repository_discover" TSRMLS_CC)) { + RETURN_FALSE + } + + RETURN_STRING(buffer, 1); +} + +/* {{{ proto resource git_repository_open_ext(string $path, long $flags, string $ceiling_dirs) + */ +PHP_FUNCTION(git_repository_open_ext) +{ + php_git2_t *result = NULL; + git_repository *out = NULL; + char *path = NULL; + int path_len = 0; + long flags = 0; + char *ceiling_dirs = NULL; + int ceiling_dirs_len = 0; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "sls", &path, &path_len, &flags, &ceiling_dirs, &ceiling_dirs_len) == FAILURE) { + return; + } + + error = git_repository_open_ext(&out, path, flags, ceiling_dirs); + if (php_git2_check_error(error, "git_repository_open_ext" TSRMLS_CC)) { RETURN_FALSE; } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REPOSITORY, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); } /* }}} */ -/* -{{{ proto: Git2\Repsotiroy::headDetached() - A repository's HEAD is detached when it points directly to a commit instead of a branch. -*/ -PHP_METHOD(git2_repository, headDetached) + +/* {{{ proto void git_repository_free(resource $repo) + */ +PHP_FUNCTION(git_repository_free) { - git_repository *repository; - php_git2_repository *m_repository; - - m_repository = PHP_GIT2_GET_OBJECT(php_git2_repository, getThis()); - if (m_repository->repository != NULL) { - if (git_repository_head_detached(m_repository->repository) == 1) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } - } else { - /* @todo: throws an exectpion */ + zval *repo = NULL; + php_git2_t *_repo = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; } + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_repo)) { + git_repository_free(PHP_GIT2_V(_repo, repository)); + GIT2_SHOULD_FREE(_repo) = 0; + }; + zval_ptr_dtor(&repo); } /* }}} */ -/* -{{{ proto: Git2\Repsotiroy::headOrphan() - 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. -*/ -PHP_METHOD(git2_repository, headOrphan) +/* {{{ proto resource git_repository_init_ext(string $repo_path, $opts) + */ +PHP_FUNCTION(git_repository_init_ext) { - git_repository *repository; - php_git2_repository *m_repository; - - m_repository = PHP_GIT2_GET_OBJECT(php_git2_repository, getThis()); - if (m_repository->repository != NULL) { - if (git_repository_head_orphan(m_repository->repository) == 1) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } - } else { - /* @todo: throws an exectpion */ + git_repository_init_options options = GIT_REPOSITORY_INIT_OPTIONS_INIT; + php_git2_t *result = NULL; + git_repository *out = NULL; + char *repo_path = NULL; + int repo_path_len = 0, error = 0; + zval *opts = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "sa", &repo_path, &repo_path_len, &opts) == FAILURE) { + return; + } + + php_git2_array_to_git_repository_init_options(&options, opts TSRMLS_CC); + error = git_repository_init_ext(&out, repo_path, &options); + if (php_git2_check_error(error, "git_repository_init_ext" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REPOSITORY, out, 1 TSRMLS_CC)) { + RETURN_FALSE; } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); } /* }}} */ -/* -{{{ proto: Git2\Repsotiroy::discover(string $path[, bool across_fs, string ceiling_dirs]) -*/ -PHP_METHOD(git2_repository, discover) + +/* {{{ proto resource git_repository_head(resource $repo) + */ +PHP_FUNCTION(git_repository_head) { - char path_buffer[1024] = {0}; - size_t path_size = 1024; - zend_bool across_fs = 1; - char *start_path, *ceiling_dirs = NULL; - int start_path_len, ceiling_dirs_len = 0; - + php_git2_t *result = NULL; + git_reference *out = NULL; + zval *repo = NULL; + php_git2_t *_repo = NULL; + int error = 0; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "s|bs", &start_path, &start_path_len, &across_fs, &ceiling_dirs, & ceiling_dirs_len) == FAILURE) { + "r", &repo) == FAILURE) { return; } - - if (git_repository_discover(path_buffer,path_size,(const char *)start_path,(int)across_fs, (const char *)ceiling_dirs) == GIT_SUCCESS) { - RETVAL_STRING(path_buffer, 1); - } else { + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_repository_head(&out, PHP_GIT2_V(_repo, repository)); + if (php_git2_check_error(error, "git_repository_head" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REFERENCE, out, 1 TSRMLS_CC)) { RETURN_FALSE; } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); } /* }}} */ -/* -{{{ proto: Git2\Repsotiroy::exists(string $sha1) -*/ -PHP_METHOD(git2_repository, exists) + +/* {{{ proto long git_repository_head_detached(resource $repo) + */ +PHP_FUNCTION(git_repository_head_detached) { - char *hash; - int hash_len = 0; - git_odb *odb; - git_oid id; - php_git2_repository *m_repository; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "s", &hash, &hash_len) == FAILURE) { - return; - } - - m_repository = PHP_GIT2_GET_OBJECT(php_git2_repository, getThis()); - if (git_repository_odb(&odb, m_repository->repository) == GIT_SUCCESS) { - if (git_oid_fromstr(&id, hash) != GIT_SUCCESS) { - RETURN_FALSE; - } - - if (git_odb_exists(odb, &id) == 1) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } - } else { - /* @todo: throws an exception */ + int result = 0; + zval *repo = NULL; + php_git2_t *_repo = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_repository_head_detached(PHP_GIT2_V(_repo, repository)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_repository_head_unborn(resource $repo) + */ +PHP_FUNCTION(git_repository_head_unborn) +{ + int result = 0; + zval *repo = NULL; + php_git2_t *_repo = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_repository_head_unborn(PHP_GIT2_V(_repo, repository)); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto long git_repository_is_empty(resource $repo) + */ +PHP_FUNCTION(git_repository_is_empty) +{ + int result = 0; + zval *repo = NULL; + php_git2_t *_repo = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_repository_is_empty(PHP_GIT2_V(_repo, repository)); + RETURN_BOOL(result); +} +/* }}} */ + + +/* {{{ proto string git_repository_path(resource $repo) + */ +PHP_FUNCTION(git_repository_path) +{ + const char *result = NULL; + zval *repo = NULL; + php_git2_t *_repo = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_repository_path(PHP_GIT2_V(_repo, repository)); + RETURN_STRING(result, 1); +} +/* }}} */ + + +/* {{{ proto long git_repository_set_workdir(resource $repo, string $workdir, long $update_gitlink) + */ +PHP_FUNCTION(git_repository_set_workdir) +{ + int result = 0; + zval *repo = NULL; + php_git2_t *_repo = NULL; + char *workdir = NULL; + int workdir_len = 0; + long update_gitlink = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsl", &repo, &workdir, &workdir_len, &update_gitlink) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_repository_set_workdir(PHP_GIT2_V(_repo, repository), workdir, update_gitlink); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_repository_is_bare(resource $repo) + */ +PHP_FUNCTION(git_repository_is_bare) +{ + int result = 0; + zval *repo = NULL; + php_git2_t *_repo = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_repository_is_bare(PHP_GIT2_V(_repo, repository)); + RETURN_BOOL(result); +} +/* }}} */ + +/* {{{ proto resource git_repository_config(resource $repo) + */ +PHP_FUNCTION(git_repository_config) +{ + php_git2_t *result = NULL; + git_config *out = NULL; + zval *repo = NULL; + php_git2_t *_repo = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_repository_config(&out, PHP_GIT2_V(_repo, repository)); + if (php_git2_check_error(error, "git_repository_config" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_CONFIG, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto resource git_repository_odb(resource $repo) + */ +PHP_FUNCTION(git_repository_odb) +{ + php_git2_t *result = NULL; + git_odb *out = NULL; + zval *repo = NULL; + php_git2_t *_repo = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_repository_odb(&out, PHP_GIT2_V(_repo, repository)); + if (php_git2_check_error(error, "git_repository_odb" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_ODB, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto resource git_repository_refdb(resource $repo) + */ +PHP_FUNCTION(git_repository_refdb) +{ + php_git2_t *result = NULL; + git_refdb *out = NULL; + zval *repo = NULL; + php_git2_t *_repo = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_repository_refdb(&out, PHP_GIT2_V(_repo, repository)); + if (php_git2_check_error(error, "git_repository_refdb" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REFDB, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_repository_index(resource $repo) + */ +PHP_FUNCTION(git_repository_index) +{ + php_git2_t *result = NULL; + git_index *out = NULL; + zval *repo = NULL; + php_git2_t *_repo = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_repository_index(&out, PHP_GIT2_V(_repo, repository)); + if (php_git2_check_error(error, "git_repository_index" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_INDEX, out, 1 TSRMLS_CC)) { RETURN_FALSE; } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_repository_message(long $len, resource $repo) + */ +PHP_FUNCTION(git_repository_message) +{ + zval *repo; + php_git2_t *_repo; + char buffer[GIT2_BUFFER_SIZE]; + size_t buffer_len = GIT2_BUFFER_SIZE; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_repository_message(buffer, buffer_len, PHP_GIT2_V(_repo, repository)); + if (php_git2_check_error(error, "git_repository_message" TSRMLS_CC)) { + RETURN_FALSE + } + RETURN_STRING(buffer, 1); } /* }}} */ -/* -{{{ proto: Git2\Repsotiroy::lookup(string $sha1[, int type = GIT_OBJ_ANY]) +/* {{{ proto long git_repository_message_remove(resource $repo) + */ +PHP_FUNCTION(git_repository_message_remove) +{ + int result = 0; + zval *repo = NULL; + php_git2_t *_repo = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_repository_message_remove(PHP_GIT2_V(_repo, repository)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_repository_merge_cleanup(resource $repo) + */ +PHP_FUNCTION(git_repository_merge_cleanup) +{ + int result = 0; + zval *repo = NULL; + php_git2_t *_repo = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_repository_merge_cleanup(PHP_GIT2_V(_repo, repository)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_repository_fetchhead_foreach(resource $repo, Callable $callback, $payload) + */ +PHP_FUNCTION(git_repository_fetchhead_foreach) +{ + int result = 0; + zval *repo = NULL, *payload = NULL; + php_git2_t *_repo = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rfz", &repo, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_repository_fetchhead_foreach(PHP_GIT2_V(_repo, repository), php_git2_repository_fetchhead_foreach_cb, cb); + php_git2_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_repository_mergehead_foreach(resource $repo, Callable $callback, $payload) + */ +PHP_FUNCTION(git_repository_mergehead_foreach) +{ + int result = 0; + zval *repo = NULL, *payload = NULL; + php_git2_t *_repo = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rfz", &repo, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_repository_mergehead_foreach(PHP_GIT2_V(_repo, repository), php_git2_repository_mergehead_foreach_cb, cb); + php_git2_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto string git_repository_hashfile(resource $repo, string $path, long $type, string $as_path) + */ +PHP_FUNCTION(git_repository_hashfile) +{ + php_git2_t *_repo = NULL; + git_oid out = {0}; + zval *repo = NULL; + char *path = NULL, *as_path = NULL, buf[41] = {0}; + int path_len = 0, as_path_len = 0, error = 0; + long type = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsls", &repo, &path, &path_len, &type, &as_path, &as_path_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_repository_hashfile(&out, PHP_GIT2_V(_repo, repository), path, type, as_path); + if (php_git2_check_error(error, "git_repository_hashfile" TSRMLS_CC)) { + RETURN_FALSE; + } + git_oid_fmt(buf, &out); + RETURN_STRING(buf, 1); +} +/* }}} */ + +/* {{{ proto long git_repository_set_head(repo, refname) */ -PHP_METHOD(git2_repository, lookup) +PHP_FUNCTION(git_repository_set_head) { - char *hash; - int error, hash_len = 0; - git_odb *odb; + zval *repo; + php_git2_t *_repo; + char *refname = {0}; + int refname_len; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repo, &refname, &refname_len) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_repository_set_head(PHP_GIT2_V(_repo, repository), refname); + if (php_git2_check_error(error, "git_repository_set_head" TSRMLS_CC)) { + RETURN_FALSE + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto long git_repository_set_head_detached(repo, commitish) +*/ +PHP_FUNCTION(git_repository_set_head_detached) +{ + zval *repo; + php_git2_t *_repo; + char *commitish = {0}; + int commitish_len; + int error = 0; git_oid id; - git_object *object; - long type = GIT_OBJ_ANY; - php_git2_repository *m_repository; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "s|l", &hash, &hash_len, type) == FAILURE) { - return; - } - - m_repository = PHP_GIT2_GET_OBJECT(php_git2_repository, getThis()); - if (git_repository_odb(&odb, m_repository->repository) == GIT_SUCCESS) { - zval *result = NULL; - - if (git_oid_fromstrn(&id, hash, hash_len) != GIT_SUCCESS) { - RETURN_FALSE; - } - - if (hash_len < GIT_OID_HEXSZ) { - error = git_object_lookup_prefix(&object, m_repository->repository, &id, hash_len, (git_otype)type); - } else { - error = git_object_lookup(&object, m_repository->repository, &id, (git_otype)type); - } - - result = php_git2_object_new(m_repository->repository, object TSRMLS_CC); - RETVAL_ZVAL(result,0,1); - } else { - /* @todo: throws an exception */ - RETURN_FALSE; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repo, &commitish, &commitish_len) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&id, commitish, commitish_len) != GIT_OK) { + return; + } + + error = git_repository_set_head_detached(PHP_GIT2_V(_repo, repository), &id); + if (php_git2_check_error(error, "git_repository_set_head_detached" TSRMLS_CC)) { + RETURN_FALSE } + RETURN_TRUE; } /* }}} */ -/* -{{{ proto: Git2\Repsotiroy::write(string $contents, int $type) +/* {{{ proto long git_repository_detach_head(repo) */ -PHP_METHOD(git2_repository, write) +PHP_FUNCTION(git_repository_detach_head) { - char *contents; - int contents_len = 0; - long type = 0; - git_odb_stream *stream; - git_odb *odb; - git_oid oid; - char *oid_out[GIT_OID_HEXSZ+1]; + zval *repo; + php_git2_t *_repo; int error = 0; - php_git2_repository *m_repository; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "sl", &contents, &contents_len, &type) == FAILURE) { + "r", &repo) == FAILURE) { return; } - m_repository = PHP_GIT2_GET_OBJECT(php_git2_repository, getThis()); - - error = git_repository_odb(&odb, m_repository->repository); - /* @todo: error check */ - - error = git_odb_open_wstream(&stream, odb, contents_len, (git_otype)type); - /* @todo: error check */ - - error = stream->write(stream, contents, contents_len); - /* @todo: error check */ + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_repository_detach_head(PHP_GIT2_V(_repo, repository)); + if (php_git2_check_error(error, "git_repository_detach_head" TSRMLS_CC)) { + RETURN_FALSE + } + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto long git_repository_state(repo) +*/ +PHP_FUNCTION(git_repository_state) +{ + zval *repo; + php_git2_t *_repo; + int state = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + state = git_repository_state(PHP_GIT2_V(_repo, repository)); - error = stream->finalize_write(&oid, stream); - /* @todo: error check */ - - git_oid_fmt(oid_out, &oid); - RETURN_STRINGL(oid_out,GIT_OID_HEXSZ,1); + RETURN_LONG(state); } /* }}} */ -/* -{{{ proto: Git2\Repsotiroy::hash(string $contents, int $type) +/* {{{ proto long git_repository_set_namespace(repo, nmspace) */ -PHP_METHOD(git2_repository, hash) +PHP_FUNCTION(git_repository_set_namespace) { - char *contents; - int contents_len = 0; - long type = 0; - git_odb *odb; - git_oid oid; - char *oid_out[GIT_OID_HEXSZ+1]; + zval *repo; + php_git2_t *_repo; + char *nmspace = {0}; + int nmspace_len; int error = 0; - php_git2_repository *m_repository; - + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "sl", &contents, &contents_len, &type) == FAILURE) { + "rs", &repo, &nmspace, &nmspace_len) == FAILURE) { return; } - m_repository = PHP_GIT2_GET_OBJECT(php_git2_repository, getThis()); - - error = git_repository_odb(&odb, m_repository->repository); - error = git_odb_hash(&oid, contents,contents_len, type); - - git_oid_fmt(oid_out, &oid); - RETURN_STRINGL(oid_out,GIT_OID_HEXSZ,1); + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_repository_set_namespace(PHP_GIT2_V(_repo, repository), nmspace); + if (php_git2_check_error(error, "git_repository_set_namespace" TSRMLS_CC)) { + RETURN_FALSE + } + RETURN_TRUE; } /* }}} */ +/* {{{ proto long git_repository_is_shallow(repo) +*/ +PHP_FUNCTION(git_repository_is_shallow) +{ + zval *repo; + php_git2_t *_repo; + int is_shallow; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + is_shallow = git_repository_is_shallow(PHP_GIT2_V(_repo, repository)); + RETURN_LONG(is_shallow); +} +/* }}} */ + +/* {{{ proto array git_repository_init_options_new() +*/ +PHP_FUNCTION(git_repository_init_options_new) +{ + git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT; + zval *result; -static zend_function_entry php_git2_repository_methods[] = { - PHP_ME(git2_repository, __construct, arginfo_git2_repository___construct, ZEND_ACC_PUBLIC) - PHP_ME(git2_repository, isEmpty, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_repository, isBare, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_repository, getPath, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_repository, getWorkdir, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_repository, headDetached,NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_repository, headOrphan, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_repository, init, arginfo_git2_repository_init, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_ME(git2_repository, discover, arginfo_git2_repository_discover, ZEND_ACC_PUBLIC | ZEND_ACC_STATIC) - PHP_ME(git2_repository, exists, arginfo_git2_repository_exists, ZEND_ACC_PUBLIC) - PHP_ME(git2_repository, hash, arginfo_git2_repository_hash, ZEND_ACC_PUBLIC) - PHP_ME(git2_repository, write, arginfo_git2_repository_write, ZEND_ACC_PUBLIC) -#ifdef lookup -#undef lookup -#endif - PHP_ME(git2_repository, lookup, arginfo_git2_repository_lookup, ZEND_ACC_PUBLIC) -#ifndef lookup -#define lookup php_lookup -#endif - {NULL,NULL,NULL} -}; - -void php_git2_repository_init(TSRMLS_D) -{ - zend_class_entry ce; - - INIT_NS_CLASS_ENTRY(ce, PHP_GIT2_NS, "Repository", php_git2_repository_methods); - git2_repository_class_entry = zend_register_internal_class(&ce TSRMLS_CC); - git2_repository_class_entry->create_object = php_git2_repository_new; + php_git2_git_repository_init_options_to_array(&opts, &result TSRMLS_CC); + RETURN_ZVAL(result, 0, 1); } +/* }}} */ \ No newline at end of file diff --git a/repository.h b/repository.h new file mode 100644 index 0000000000..d6ff40b191 --- /dev/null +++ b/repository.h @@ -0,0 +1,324 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_REPOSITORY_H +#define PHP_GIT2_REPOSITORY_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_new, 0, 0, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_init, 0, 0, 1) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, is_bare) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_open_bare, 0, 0, 1) + ZEND_ARG_INFO(0, bare_path) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_open, 0, 0, 1) + ZEND_ARG_INFO(0, path) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_get_namespace, 0, 0, 1) + ZEND_ARG_INFO(0, repository) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_workdir, 0, 0, 1) + ZEND_ARG_INFO(0, repository) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_wrap_odb, 0, 0, 1) + ZEND_ARG_INFO(0, odb) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_discover, 0, 0, 4) + ZEND_ARG_INFO(0, path_size) + ZEND_ARG_INFO(0, start_path) + ZEND_ARG_INFO(0, across_fs) + ZEND_ARG_INFO(0, ceiling_dirs) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_open_ext, 0, 0, 3) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, flags) + ZEND_ARG_INFO(0, ceiling_dirs) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_free, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_init_ext, 0, 0, 2) + ZEND_ARG_INFO(0, repo_path) + ZEND_ARG_INFO(0, opts) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_head, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_head_detached, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_head_unborn, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_is_empty, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_path, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_set_workdir, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, workdir) + ZEND_ARG_INFO(0, update_gitlink) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_is_bare, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_config, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_odb, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_refdb, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_index, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_message, 0, 0, 2) + ZEND_ARG_INFO(0, len) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_message_remove, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_merge_cleanup, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_fetchhead_foreach, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_mergehead_foreach, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_hashfile, 0, 0, 4) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, type) + ZEND_ARG_INFO(0, as_path) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_set_head, 0, 0, 2) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, refname) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_set_head_detached, 0, 0, 2) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, commitish) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_detach_head, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_state, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_set_namespace, 0, 0, 2) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, nmspace) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_repository_is_shallow, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_repository_new() +*/ +PHP_FUNCTION(git_repository_new); + +/* {{{ proto resource git_repository_init(string $path, long is_bare = 0) +*/ +PHP_FUNCTION(git_repository_init); + +/* {{{ proto resource git_repository_open(string $path) +*/ +PHP_FUNCTION(git_repository_open_bare); + +/* {{{ proto resource git_repository_open(string $path) +*/ +PHP_FUNCTION(git_repository_open); + +/* {{{ proto string git_repository_get_namespace(resource $repository) +*/ +PHP_FUNCTION(git_repository_get_namespace); + +/* {{{ proto string git_repository_workdir(resource $repository) +*/ +PHP_FUNCTION(git_repository_workdir); + +/* {{{ proto resource git_repository_wrap_odb(odb) +*/ +PHP_FUNCTION(git_repository_wrap_odb); + +/* {{{ proto resource git_repository_discover(path_size, start_path, across_fs, ceiling_dirs) +*/ +PHP_FUNCTION(git_repository_discover); + +/* {{{ proto resource git_repository_open_ext(path, flags, ceiling_dirs) +*/ +PHP_FUNCTION(git_repository_open_ext); + +/* {{{ proto void git_repository_free(repo) +*/ +PHP_FUNCTION(git_repository_free); + +/* {{{ proto resource git_repository_init_ext(repo_path, opts) +*/ +PHP_FUNCTION(git_repository_init_ext); + +/* {{{ proto resource git_repository_head(repo) +*/ +PHP_FUNCTION(git_repository_head); + +/* {{{ proto long git_repository_head_detached(repo) +*/ +PHP_FUNCTION(git_repository_head_detached); + +/* {{{ proto long git_repository_head_unborn(repo) +*/ +PHP_FUNCTION(git_repository_head_unborn); + +/* {{{ proto long git_repository_is_empty(repo) +*/ +PHP_FUNCTION(git_repository_is_empty); + +/* {{{ proto resource git_repository_path(repo) +*/ +PHP_FUNCTION(git_repository_path); + +/* {{{ proto long git_repository_set_workdir(repo, workdir, update_gitlink) +*/ +PHP_FUNCTION(git_repository_set_workdir); + +/* {{{ proto long git_repository_is_bare(repo) +*/ +PHP_FUNCTION(git_repository_is_bare); + +/* {{{ proto resource git_repository_config(repo) +*/ +PHP_FUNCTION(git_repository_config); + +/* {{{ proto resource git_repository_odb(repo) +*/ +PHP_FUNCTION(git_repository_odb); + +/* {{{ proto resource git_repository_refdb(repo) +*/ +PHP_FUNCTION(git_repository_refdb); + +/* {{{ proto resource git_repository_index(repo) +*/ +PHP_FUNCTION(git_repository_index); + +/* {{{ proto resource git_repository_message(len, repo) +*/ +PHP_FUNCTION(git_repository_message); + +/* {{{ proto long git_repository_message_remove(repo) +*/ +PHP_FUNCTION(git_repository_message_remove); + +/* {{{ proto long git_repository_merge_cleanup(repo) +*/ +PHP_FUNCTION(git_repository_merge_cleanup); + +/* {{{ proto long git_repository_fetchhead_foreach(repo, callback, payload) +*/ +PHP_FUNCTION(git_repository_fetchhead_foreach); + +/* {{{ proto long git_repository_mergehead_foreach(repo, callback, payload) +*/ +PHP_FUNCTION(git_repository_mergehead_foreach); + +/* {{{ proto resource git_repository_hashfile(repo, path, type, as_path) +*/ +PHP_FUNCTION(git_repository_hashfile); + +/* {{{ proto long git_repository_set_head(repo, refname) +*/ +PHP_FUNCTION(git_repository_set_head); + +/* {{{ proto long git_repository_set_head_detached(repo, commitish) +*/ +PHP_FUNCTION(git_repository_set_head_detached); + +/* {{{ proto long git_repository_detach_head(repo) +*/ +PHP_FUNCTION(git_repository_detach_head); + +/* {{{ proto long git_repository_state(repo) +*/ +PHP_FUNCTION(git_repository_state); + +/* {{{ proto long git_repository_set_namespace(repo, nmspace) +*/ +PHP_FUNCTION(git_repository_set_namespace); + +/* {{{ proto long git_repository_is_shallow(repo) +*/ +PHP_FUNCTION(git_repository_is_shallow); + +/* {{{ proto array git_repository_init_options_new() +*/ +PHP_FUNCTION(git_repository_init_options_new); + +#endif \ No newline at end of file diff --git a/reset.c b/reset.c new file mode 100644 index 0000000000..f46a616bb7 --- /dev/null +++ b/reset.c @@ -0,0 +1,52 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "reset.h" + +/* {{{ proto long git_reset(resource $repo, resource $target, $reset_type) + */ +PHP_FUNCTION(git_reset) +{ + int result = 0; + zval *repo = NULL, *target = NULL; + php_git2_t *_repo = NULL, *_target = NULL; + long reset_type = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rrl", &repo, &target, &reset_type) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_target, php_git2_t*, &target, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_reset(PHP_GIT2_V(_repo, repository), PHP_GIT2_V(_target, object), reset_type); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_reset_default(resource $repo, resource $target, array $pathspecs) + */ +PHP_FUNCTION(git_reset_default) +{ + int result = 0; + zval *repo = NULL, *target = NULL, *pathspecs = NULL, *array = NULL; + php_git2_t *_repo = NULL, *_target = NULL; + git_strarray _pathspecs = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rra", &repo, &target, &pathspecs) == FAILURE) { + return; + } + if (zend_hash_num_elements(pathspecs) > 0) { + php_git2_array_to_strarray(&_pathspecs, pathspecs TSRMLS_CC); + } + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_target, php_git2_t*, &target, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_reset_default(PHP_GIT2_V(_repo, repository), PHP_GIT2_V(_target, object), &_pathspecs); + if (zend_hash_num_elements(pathspecs) > 0) { + git_strarray_free(&array); + } + + RETURN_LONG(result); +} +/* }}} */ + diff --git a/reset.h b/reset.h new file mode 100644 index 0000000000..4c1dabfc91 --- /dev/null +++ b/reset.h @@ -0,0 +1,49 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_RESET_H +#define PHP_GIT2_RESET_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reset, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, target) + ZEND_ARG_INFO(0, reset_type) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_reset_default, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, target) + ZEND_ARG_INFO(0, pathspecs) +ZEND_END_ARG_INFO() + +/* {{{ proto long git_reset(repo, target, reset_type) +*/ +PHP_FUNCTION(git_reset); + +/* {{{ proto long git_reset_default(repo, target, pathspecs) +*/ +PHP_FUNCTION(git_reset_default); + +#endif \ No newline at end of file diff --git a/revparse.c b/revparse.c new file mode 100644 index 0000000000..07b4ab8c58 --- /dev/null +++ b/revparse.c @@ -0,0 +1,122 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "revparse.h" + +/* {{{ proto resource git_revparse_single(resource $repo, string $spec) + */ +PHP_FUNCTION(git_revparse_single) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_object *out = NULL; + zval *repo = NULL; + char *spec = NULL; + int spec_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repo, &spec, &spec_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_revparse_single(&out, PHP_GIT2_V(_repo, repository), spec); + if (php_git2_check_error(error, "git_revparse_single" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_OBJECT, out, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto array git_revparse_ext(resource $repo, string $spec) + */ +PHP_FUNCTION(git_revparse_ext) +{ + zval *array, *a, *b; + php_git2_t *result = NULL, *result2 = NULL; + git_object *object_out = NULL; + git_reference *reference_out = NULL; + zval *repo = NULL; + php_git2_t *_repo = NULL; + char *spec = NULL; + int spec_len = 0; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repo, &spec, &spec_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_revparse_ext(&object_out, &reference_out, PHP_GIT2_V(_repo, repository), spec); + if (php_git2_check_error(error, "git_revparse_ext" TSRMLS_CC)) { + RETURN_FALSE; + } + + MAKE_STD_ZVAL(array); + MAKE_STD_ZVAL(a); + MAKE_STD_ZVAL(b); + + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_OBJECT, object_out, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(a, GIT2_RVAL_P(result)); + + if (php_git2_make_resource(&result2, PHP_GIT2_TYPE_REFERENCE, reference_out, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(b, GIT2_RVAL_P(result2)); + + array_init(array); + add_next_index_zval(array, a); + add_next_index_zval(array, b); + RETURN_ZVAL(array, 0, 1); +} +/* }}} */ + +/* {{{ proto array git_revparse(resource $repo, string $spec) + */ +PHP_FUNCTION(git_revparse) +{ + git_revspec revspec; + zval *repo = NULL; + php_git2_t *_repo = NULL, *_from = NULL, *_to = NULL; + zval *result = NULL, *from, *to; + char *spec = NULL; + int spec_len = 0; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repo, &spec, &spec_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + memset(&revspec, '\0', sizeof(revspec)); + error = git_revparse(&revspec, PHP_GIT2_V(_repo, repository), spec); + if (php_git2_check_error(error, "git_revparse" TSRMLS_CC)) { + RETURN_FALSE; + } + MAKE_STD_ZVAL(result); + if (php_git2_make_resource(&_from, PHP_GIT2_TYPE_OBJECT, revspec.from, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(from, GIT2_RVAL_P(_from)); + + if (php_git2_make_resource(&_to, PHP_GIT2_TYPE_OBJECT, revspec.to, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(to, GIT2_RVAL_P(_to)); + + array_init(result); + add_assoc_zval_ex(result, ZEND_STRS("from"), from); + add_assoc_zval_ex(result, ZEND_STRS("to"), to); + add_assoc_long_ex(result, ZEND_STRS("flags"), revspec.flags); + + RETURN_ZVAL(result, 0, 1); +} +/* }}} */ + diff --git a/revparse.h b/revparse.h new file mode 100644 index 0000000000..8aa88dfa40 --- /dev/null +++ b/revparse.h @@ -0,0 +1,58 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_REVPARSE_H +#define PHP_GIT2_REVPARSE_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_revparse_single, 0, 0, 2) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, spec) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_revparse_ext, 0, 0, 3) + ZEND_ARG_INFO(0, reference_out) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, spec) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_revparse, 0, 0, 3) + ZEND_ARG_INFO(0, revspec) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, spec) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_revparse_single(repo, spec) +*/ +PHP_FUNCTION(git_revparse_single); + +/* {{{ proto resource git_revparse_ext(reference_out, repo, spec) +*/ +PHP_FUNCTION(git_revparse_ext); + +/* {{{ proto long git_revparse(revspec, repo, spec) +*/ +PHP_FUNCTION(git_revparse); + +#endif \ No newline at end of file diff --git a/revwalk.c b/revwalk.c new file mode 100644 index 0000000000..1d261356b5 --- /dev/null +++ b/revwalk.c @@ -0,0 +1,353 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "revwalk.h" + +/* {{{ proto resource git_revwalk_new(resource $repo) + */ +PHP_FUNCTION(git_revwalk_new) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_revwalk *out = NULL; + zval *repo = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_revwalk_new(&out, PHP_GIT2_V(_repo, repository)); + if (php_git2_check_error(error, "git_revwalk_new" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REVWALK, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto void git_revwalk_reset(walker) +*/ +PHP_FUNCTION(git_revwalk_reset) +{ + zval *walker; + php_git2_t *_walker; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &walker) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_walker, php_git2_t*, &walker, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + git_revwalk_reset(PHP_GIT2_V(_walker, revwalk)); +} + +/* {{{ proto long git_revwalk_push(resource $walk, string $id) + */ +PHP_FUNCTION(git_revwalk_push) +{ + int result = 0, id_len = 0; + zval *walk = NULL; + php_git2_t *_walk = NULL; + char *id = NULL; + git_oid __id = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &walk, &id, &id_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_walk, php_git2_t*, &walk, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__id, id, id_len)) { + RETURN_FALSE; + } + result = git_revwalk_push(PHP_GIT2_V(_walk, revwalk), &__id); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_revwalk_push_glob(resource $walk, string $glob) + */ +PHP_FUNCTION(git_revwalk_push_glob) +{ + int result = 0, glob_len = 0; + zval *walk = NULL; + php_git2_t *_walk = NULL; + char *glob = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &walk, &glob, &glob_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_walk, php_git2_t*, &walk, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_revwalk_push_glob(PHP_GIT2_V(_walk, revwalk), glob); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto long git_revwalk_push_head(walk) +*/ +PHP_FUNCTION(git_revwalk_push_head) +{ + zval *walk; + php_git2_t *_walk; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &walk) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_walk, php_git2_t*, &walk, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + error = git_revwalk_push_head(PHP_GIT2_V(_walk, revwalk)); + if (php_git2_check_error(error, "git_revwalk_push_head" TSRMLS_CC)) { + RETURN_FALSE; + } else { + RETURN_TRUE; + } +} + +/* {{{ proto long git_revwalk_hide(walk, commit_id) +*/ +PHP_FUNCTION(git_revwalk_hide) +{ + zval *walk; + php_git2_t *_walk; + char *commit_id = {0}; + int commit_id_len; + git_oid oid; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &walk, &commit_id, &commit_id_len) == FAILURE) { + return; + } + if (git_oid_fromstrn(&oid, commit_id, commit_id_len) != GIT_OK) { + return; + } + + ZEND_FETCH_RESOURCE(_walk, php_git2_t*, &walk, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_revwalk_hide(PHP_GIT2_V(_walk, revwalk), &oid); + + if (php_git2_check_error(error, "git_revwalk_hide" TSRMLS_CC)) { + RETURN_FALSE; + } else { + RETURN_TRUE; + } + +} + +/* {{{ proto long git_revwalk_hide_glob(resource $walk, string $glob) + */ +PHP_FUNCTION(git_revwalk_hide_glob) +{ + int result = 0, glob_len = 0; + zval *walk = NULL; + php_git2_t *_walk = NULL; + char *glob = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &walk, &glob, &glob_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_walk, php_git2_t*, &walk, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_revwalk_hide_glob(PHP_GIT2_V(_walk, revwalk), glob); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto long git_revwalk_hide_head(walk) +*/ +PHP_FUNCTION(git_revwalk_hide_head) +{ + zval *walk; + php_git2_t *_walk; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &walk) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_walk, php_git2_t*, &walk, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + error = git_revwalk_hide_head(PHP_GIT2_V(_walk, revwalk)); + if (php_git2_check_error(error, "git_revwalk_hide_head" TSRMLS_CC)) { + RETURN_FALSE; + } else { + RETURN_TRUE; + } +} + +/* {{{ proto long git_revwalk_push_ref(resource $walk, string $refname) + */ +PHP_FUNCTION(git_revwalk_push_ref) +{ + int result = 0, refname_len = 0; + zval *walk = NULL; + php_git2_t *_walk = NULL; + char *refname = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &walk, &refname, &refname_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_walk, php_git2_t*, &walk, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_revwalk_push_ref(PHP_GIT2_V(_walk, revwalk), refname); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto long git_revwalk_hide_ref(resource $walk, string $refname) + */ +PHP_FUNCTION(git_revwalk_hide_ref) +{ + int result = 0, refname_len = 0; + zval *walk = NULL; + php_git2_t *_walk = NULL; + char *refname = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &walk, &refname, &refname_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_walk, php_git2_t*, &walk, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_revwalk_hide_ref(PHP_GIT2_V(_walk, revwalk), refname); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto string git_revwalk_next(walk) +*/ +PHP_FUNCTION(git_revwalk_next) +{ + zval *walk; + php_git2_t *_walk; + git_oid id = {0}; + char out[GIT2_OID_HEXSIZE] = {0}; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &walk) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_walk, php_git2_t*, &walk, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_revwalk_next(&id, PHP_GIT2_V(_walk, revwalk)); + if (error == GIT_ITEROVER) { + RETURN_FALSE; + } + + git_oid_fmt(out, &id); + RETURN_STRING(out, 1); +} + +/* {{{ proto void git_revwalk_sorting(walk, sort_mode) +*/ +PHP_FUNCTION(git_revwalk_sorting) +{ + zval *walk; + php_git2_t *_walk; + long sort_mode = GIT_SORT_NONE; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &walk, &sort_mode) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_walk, php_git2_t*, &walk, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + git_revwalk_sorting(PHP_GIT2_V(_walk, revwalk), sort_mode); +} + +/* {{{ proto long git_revwalk_push_range(resource $walk, string $range) + */ +PHP_FUNCTION(git_revwalk_push_range) +{ + int result = 0, range_len = 0; + zval *walk = NULL; + php_git2_t *_walk = NULL; + char *range = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &walk, &range, &range_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_walk, php_git2_t*, &walk, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_revwalk_push_range(PHP_GIT2_V(_walk, revwalk), range); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto void git_revwalk_simplify_first_parent(walk) +*/ +PHP_FUNCTION(git_revwalk_simplify_first_parent) +{ + zval *walk; + php_git2_t *_walk; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &walk) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_walk, php_git2_t*, &walk, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + git_revwalk_simplify_first_parent(PHP_GIT2_V(_walk, revwalk)); +} + +/* {{{ proto void git_revwalk_free(resource $walk) + */ +PHP_FUNCTION(git_revwalk_free) +{ + zval *walk = NULL; + php_git2_t *_walk = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &walk) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_walk, php_git2_t*, &walk, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_walk)) { + git_revwalk_free(PHP_GIT2_V(_walk, revwalk)); + GIT2_SHOULD_FREE(_walk) = 0; + }; + zval_ptr_dtor(&walk); +} +/* }}} */ + + +/* {{{ proto resource git_revwalk_repository(walk) +*/ +PHP_FUNCTION(git_revwalk_repository) +{ + zval *walk; + php_git2_t *_walk, *result; + git_repository *repository; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &walk) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_walk, php_git2_t*, &walk, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + repository = git_revwalk_repository(PHP_GIT2_V(_walk, revwalk)); + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_REPOSITORY, repository, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + + ZVAL_RESOURCE(return_value, result->resource_id); +} + diff --git a/revwalk.h b/revwalk.h new file mode 100644 index 0000000000..ef9a7b6eac --- /dev/null +++ b/revwalk.h @@ -0,0 +1,166 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_REVWALK_H +#define PHP_GIT2_REVWALK_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_revwalk_new, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_revwalk_reset, 0, 0, 1) + ZEND_ARG_INFO(0, walker) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_revwalk_push, 0, 0, 2) + ZEND_ARG_INFO(0, walk) + ZEND_ARG_INFO(0, id) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_revwalk_push_glob, 0, 0, 2) + ZEND_ARG_INFO(0, walk) + ZEND_ARG_INFO(0, glob) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_revwalk_push_head, 0, 0, 1) + ZEND_ARG_INFO(0, walk) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_revwalk_hide, 0, 0, 2) + ZEND_ARG_INFO(0, walk) + ZEND_ARG_INFO(0, commit_id) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_revwalk_hide_glob, 0, 0, 2) + ZEND_ARG_INFO(0, walk) + ZEND_ARG_INFO(0, glob) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_revwalk_hide_head, 0, 0, 1) + ZEND_ARG_INFO(0, walk) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_revwalk_push_ref, 0, 0, 2) + ZEND_ARG_INFO(0, walk) + ZEND_ARG_INFO(0, refname) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_revwalk_hide_ref, 0, 0, 2) + ZEND_ARG_INFO(0, walk) + ZEND_ARG_INFO(0, refname) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_revwalk_next, 0, 0, 2) + ZEND_ARG_INFO(0, walk) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_revwalk_sorting, 0, 0, 2) + ZEND_ARG_INFO(0, walk) + ZEND_ARG_INFO(0, sort_mode) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_revwalk_push_range, 0, 0, 2) + ZEND_ARG_INFO(0, walk) + ZEND_ARG_INFO(0, range) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_revwalk_simplify_first_parent, 0, 0, 1) + ZEND_ARG_INFO(0, walk) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_revwalk_free, 0, 0, 1) + ZEND_ARG_INFO(0, walk) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_revwalk_repository, 0, 0, 1) + ZEND_ARG_INFO(0, walk) +ZEND_END_ARG_INFO() + +/* {{{ proto long git_revwalk_new(repo) +*/ +PHP_FUNCTION(git_revwalk_new); + +/* {{{ proto void git_revwalk_reset(walker) +*/ +PHP_FUNCTION(git_revwalk_reset); + +/* {{{ proto long git_revwalk_push(walk, id) +*/ +PHP_FUNCTION(git_revwalk_push); + +/* {{{ proto long git_revwalk_push_glob(walk, glob) +*/ +PHP_FUNCTION(git_revwalk_push_glob); + +/* {{{ proto long git_revwalk_push_head(walk) +*/ +PHP_FUNCTION(git_revwalk_push_head); + +/* {{{ proto long git_revwalk_hide(walk, commit_id) +*/ +PHP_FUNCTION(git_revwalk_hide); + +/* {{{ proto long git_revwalk_hide_glob(walk, glob) +*/ +PHP_FUNCTION(git_revwalk_hide_glob); + +/* {{{ proto long git_revwalk_hide_head(walk) +*/ +PHP_FUNCTION(git_revwalk_hide_head); + +/* {{{ proto long git_revwalk_push_ref(walk, refname) +*/ +PHP_FUNCTION(git_revwalk_push_ref); + +/* {{{ proto long git_revwalk_hide_ref(walk, refname) +*/ +PHP_FUNCTION(git_revwalk_hide_ref); + +/* {{{ proto long git_revwalk_next(walk) +*/ +PHP_FUNCTION(git_revwalk_next); + +/* {{{ proto void git_revwalk_sorting(walk, sort_mode) +*/ +PHP_FUNCTION(git_revwalk_sorting); + +/* {{{ proto long git_revwalk_push_range(walk, range) +*/ +PHP_FUNCTION(git_revwalk_push_range); + +/* {{{ proto void git_revwalk_simplify_first_parent(walk) +*/ +PHP_FUNCTION(git_revwalk_simplify_first_parent); + +/* {{{ proto void git_revwalk_free(walk) +*/ +PHP_FUNCTION(git_revwalk_free); + +/* {{{ proto resource git_revwalk_repository(walk) +*/ +PHP_FUNCTION(git_revwalk_repository); + + +#endif \ No newline at end of file diff --git a/script/cibuild.sh b/script/cibuild.sh new file mode 100755 index 0000000000..720213790d --- /dev/null +++ b/script/cibuild.sh @@ -0,0 +1,13 @@ +export NO_INTERACTION=1 +export TESTS="--show-diff -q" + +mkdir $TRAVIS_BUILD_DIR/libgit2/build +cd $TRAVIS_BUILD_DIR/libgit2/build +cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_SHARED_LIBS=OFF -DBUILD_CLAR=OFF -DCMAKE_C_FLAGS=-fPIC .. +cmake --build . +cd $TRAVIS_BUILD_DIR + +phpize +./configure +make +make test diff --git a/signature.c b/signature.c index a2ba49b778..e609e845f4 100644 --- a/signature.c +++ b/signature.c @@ -1,129 +1,77 @@ -/* - * The MIT License - * - * Copyright (c) 2010 - 2012 Shuhei Tanuma - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - #include "php_git2.h" -#include -#include - -PHPAPI zend_class_entry *git2_signature_class_entry; +#include "php_git2_priv.h" +#include "signature.h" -inline void php_git2_create_signature(zval *object, char *name, int name_len, char *email, int email_len, zval *date TSRMLS_DC) +/* {{{ proto resource git_signature_new(string $name, string $email, array $time, long $offset) + */ +PHP_FUNCTION(git_signature_new) { - zval *r_timestamp,*r_offset, *z_name, *z_email = NULL; - php_git2_signature *m_signature; - long timestamp, offset = 0; - int error = 0; - - MAKE_STD_ZVAL(z_name); - MAKE_STD_ZVAL(z_email); - ZVAL_STRINGL(z_name,name,name_len,1); - ZVAL_STRINGL(z_email,email,email_len,1); - - add_property_zval_ex(object, "name", sizeof("name") ,z_name TSRMLS_CC); - add_property_zval_ex(object, "email",sizeof("email"),z_email TSRMLS_CC); - add_property_zval_ex(object, "time", sizeof("time") ,date TSRMLS_CC); - - m_signature = PHP_GIT2_GET_OBJECT(php_git2_signature, object); + git_signature *out = NULL; + char *name = NULL, *email = NULL; + int name_len = 0, email_len = 0, error = 0; + long time = 0, offset = 0; + zval *signature = NULL; - error = php_git2_call_user_function_v(&r_timestamp, date, "getTimeStamp", sizeof("getTimeStamp")-1, 0); - timestamp = Z_LVAL_P(r_timestamp); - php_git2_call_user_function_v(&r_offset, date, "getOffset", sizeof("getOffset")-1, 0); - offset = Z_LVAL_P(r_offset); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "ssll", &name, &name_len, &email, &email_len, &time, &offset) == FAILURE) { + return; + } - git_signature_new(&m_signature->signature, name,email,(git_time_t)timestamp,offset / 60); - - zval_ptr_dtor(&r_timestamp); - zval_ptr_dtor(&r_offset); - zval_ptr_dtor(&z_email); - zval_ptr_dtor(&z_name); -} - - -static void php_git2_signature_free_storage(php_git2_signature *object TSRMLS_DC) -{ - if (object->signature != NULL) { - git_signature_free(object->signature); - object->signature = NULL; + error = git_signature_new(&out, name, email, time, offset); + if (php_git2_check_error(error, "git_signature_new" TSRMLS_CC)) { + RETURN_FALSE; } - zend_object_std_dtor(&object->zo TSRMLS_CC); - efree(object); -} - -zend_object_value php_git2_signature_new(zend_class_entry *ce TSRMLS_DC) -{ - zend_object_value retval; - - PHP_GIT2_STD_CREATE_OBJECT(php_git2_signature); - return retval; + php_git2_signature_to_array(out, &signature TSRMLS_CC); + git_signature_free(out); + RETURN_ZVAL(signature, 0, 1); } +/* }}} */ -ZEND_BEGIN_ARG_INFO_EX(arginfo_git2_signature___construct, 0,0,3) - ZEND_ARG_INFO(0, name) - ZEND_ARG_INFO(0, email) - ZEND_ARG_INFO(0, date) -ZEND_END_ARG_INFO() - -/* -{{{ proto: Git2\Signature::__construct(string $name, string $email, \DateTime $time) -*/ -PHP_METHOD(git2_signature, __construct) +/* {{{ proto resource git_signature_now(string $name, string $email) + */ +PHP_FUNCTION(git_signature_now) { - char *name, *email; - int error, name_len, email_len = 0; - zval *date = NULL; + git_signature *out = NULL; + char *name = NULL, *email = NULL; + int name_len = 0, email_len = 0, error = 0; + zval *signature = NULL; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "ssz", &name, &name_len, &email, &email_len, &date) == FAILURE) { + "ss", &name, &name_len, &email, &email_len) == FAILURE) { return; } - if (!instanceof_function(Z_OBJCE_P(date), php_date_get_date_ce() TSRMLS_CC)) { + error = git_signature_now(&out, name, email); + if (php_git2_check_error(error, "git_signature_now" TSRMLS_CC)) { RETURN_FALSE; } - - //@memo - //error = php_git2_call_user_function_v(×tamp, date, "getTimeStamp", sizeof("getTimeStamp")-1, 0); - //zval_ptr_dtor(×tamp); - php_git2_create_signature(getThis(), name, name_len, email, email_len, date TSRMLS_CC); + php_git2_signature_to_array(out, &signature TSRMLS_CC); + git_signature_free(out); + RETURN_ZVAL(signature, 0, 1); } /* }}} */ - - -static zend_function_entry php_git2_signature_methods[] = { - PHP_ME(git2_signature, __construct, arginfo_git2_signature___construct, ZEND_ACC_PUBLIC) - {NULL,NULL,NULL} -}; - -void php_git2_signature_init(TSRMLS_D) +/* {{{ proto resource git_signature_default(resource $repo) + */ +PHP_FUNCTION(git_signature_default) { - zend_class_entry ce; + php_git2_t *_repo = NULL; + git_signature *out = NULL; + zval *repo = NULL, *signature = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } - INIT_NS_CLASS_ENTRY(ce, PHP_GIT2_NS, "Signature", php_git2_signature_methods); - git2_signature_class_entry = zend_register_internal_class(&ce TSRMLS_CC); - git2_signature_class_entry->create_object = php_git2_signature_new; - zend_declare_property_null(git2_signature_class_entry, "name", sizeof("name")-1, ZEND_ACC_PUBLIC TSRMLS_CC); - zend_declare_property_null(git2_signature_class_entry, "email", sizeof("email")-1, ZEND_ACC_PUBLIC TSRMLS_CC); - zend_declare_property_null(git2_signature_class_entry, "time", sizeof("time")-1, ZEND_ACC_PUBLIC TSRMLS_CC); -} \ No newline at end of file + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_signature_default(&out, PHP_GIT2_V(_repo, repository)); + if (php_git2_check_error(error, "git_signature_default" TSRMLS_CC)) { + RETURN_FALSE; + } + php_git2_signature_to_array(out, &signature TSRMLS_CC); + git_signature_free(out); + RETURN_ZVAL(signature, 0, 1); +} +/* }}} */ diff --git a/signature.h b/signature.h new file mode 100644 index 0000000000..71be5b503e --- /dev/null +++ b/signature.h @@ -0,0 +1,73 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_SIGNATURE_H +#define PHP_GIT2_SIGNATURE_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_signature_new, 0, 0, 4) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, email) + ZEND_ARG_INFO(0, time) + ZEND_ARG_INFO(0, offset) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_signature_now, 0, 0, 2) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, email) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_signature_default, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_signature_dup, 0, 0, 1) + ZEND_ARG_INFO(0, sig) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_signature_free, 0, 0, 1) + ZEND_ARG_INFO(0, sig) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_signature_new(name, email, time, offset) +*/ +PHP_FUNCTION(git_signature_new); + +/* {{{ proto resource git_signature_now(name, email) +*/ +PHP_FUNCTION(git_signature_now); + +/* {{{ proto resource git_signature_default(repo) +*/ +PHP_FUNCTION(git_signature_default); + +/* {{{ proto resource git_signature_dup(sig) +*/ +PHP_FUNCTION(git_signature_dup); + +/* {{{ proto void git_signature_free(sig) +*/ +PHP_FUNCTION(git_signature_free); + +#endif \ No newline at end of file diff --git a/stash.c b/stash.c new file mode 100644 index 0000000000..1a9832a8b2 --- /dev/null +++ b/stash.c @@ -0,0 +1,107 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "stash.h" + +static int php_git2_stash_cb(size_t index, + const char* message, + const git_oid *stash_id, + void *payload) +{ + zval *param_index, *param_message,*param_stash_id, *retval_ptr = NULL; + php_git2_cb_t *p = (php_git2_cb_t*)payload; + long retval = 0; + char _oid[GIT2_OID_HEXSIZE] = {0}; + GIT2_TSRMLS_SET(p->tsrm_ls) + + git_oid_fmt(_oid, stash_id); + + Z_ADDREF_P(p->payload); + MAKE_STD_ZVAL(param_index); + MAKE_STD_ZVAL(param_message); + MAKE_STD_ZVAL(param_stash_id); + ZVAL_LONG(param_index, index); + ZVAL_STRING(param_message, message, 1); + ZVAL_STRING(param_stash_id, _oid, 1); + + if (php_git2_call_function_v(p->fci, p->fcc TSRMLS_CC, &retval_ptr, 4, ¶m_index, ¶m_message, ¶m_stash_id, &p->payload)) { + return GIT_EUSER; + } + + retval = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + return retval; +} + +/* {{{ proto resource git_stash_save(resource $repo, array $stasher, string $message, long $flags) + */ +PHP_FUNCTION(git_stash_save) +{ + php_git2_t *_repo = NULL; + git_oid out = {0}; + zval *repo = NULL, *stasher = NULL; + char *message = NULL; + int message_len = 0, error = 0; + long flags = 0; + char buf[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rasl", &repo, &stasher, &message, &message_len, &flags) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_stash_save(&out, PHP_GIT2_V(_repo, repository), stasher, message, flags); + if (php_git2_check_error(error, "git_stash_save" TSRMLS_CC)) { + RETURN_FALSE; + } + git_oid_fmt(buf, &out); + RETURN_STRING(buf, 1); +} +/* }}} */ + +/* {{{ proto long git_stash_foreach(resource $repo, Callable $callback, $payload) + */ +PHP_FUNCTION(git_stash_foreach) +{ + int result = 0; + zval *repo = NULL, *payload = NULL; + php_git2_t *_repo = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rfz", &repo, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_stash_foreach(PHP_GIT2_V(_repo, repository), php_git2_stash_cb, cb); + php_git2_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_stash_drop(resource $repo, long $index) + */ +PHP_FUNCTION(git_stash_drop) +{ + int result = 0; + zval *repo = NULL; + php_git2_t *_repo = NULL; + long index = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &repo, &index) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_stash_drop(PHP_GIT2_V(_repo, repository), index); + RETURN_LONG(result); +} +/* }}} */ + diff --git a/stash.h b/stash.h new file mode 100644 index 0000000000..5640514b0c --- /dev/null +++ b/stash.h @@ -0,0 +1,59 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_STASH_H +#define PHP_GIT2_STASH_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_stash_save, 0, 0, 4) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, stasher) + ZEND_ARG_INFO(0, message) + ZEND_ARG_INFO(0, flags) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_stash_foreach, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_stash_drop, 0, 0, 2) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_stash_save(repo, stasher, message, flags) +*/ +PHP_FUNCTION(git_stash_save); + +/* {{{ proto long git_stash_foreach(repo, callback, payload) +*/ +PHP_FUNCTION(git_stash_foreach); + +/* {{{ proto long git_stash_drop(repo, index) +*/ +PHP_FUNCTION(git_stash_drop); + +#endif \ No newline at end of file diff --git a/status.c b/status.c new file mode 100644 index 0000000000..072d713895 --- /dev/null +++ b/status.c @@ -0,0 +1,283 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "status.h" + +static void php_git2_git_status_options_to_array(git_status_options *options, zval **out TSRMLS_DC) +{ + zval *result, *pathspec; + + MAKE_STD_ZVAL(result); + array_init(result); + + add_assoc_long_ex(result, ZEND_STRS("version"), options->version); + add_assoc_long_ex(result, ZEND_STRS("show"), options->show); + add_assoc_long_ex(result, ZEND_STRS("flags"), options->flags); + php_git2_strarray_to_array(&options->pathspec, &pathspec TSRMLS_CC); + add_assoc_zval_ex(result, ZEND_STRS("pathspec"), pathspec); + + *out = result; +} + +static void php_git2_array_to_git_status_options(git_status_options *options, zval *array TSRMLS_DC) +{ + options->version = php_git2_read_arrval_long2(array, ZEND_STRS("version"), 1 TSRMLS_CC); + options->show = php_git2_read_arrval_long2(array, ZEND_STRS("version"), 0 TSRMLS_CC); + options->flags = php_git2_read_arrval_long2(array, ZEND_STRS("version"), 0 TSRMLS_CC); + + php_git2_array_to_strarray(&options->pathspec, php_git2_read_arrval(array, ZEND_STRS("pathspec") TSRMLS_CC) TSRMLS_CC); +} + +static void php_git2_git_status_entry_to_array(git_status_entry *entry, zval **out TSRMLS_DC) +{ + zval *result, *head_to_index, *index_to_workdir; + + MAKE_STD_ZVAL(result); + array_init(result); + + if (entry->head_to_index) { + php_git2_diff_delta_to_array(entry->head_to_index, &head_to_index TSRMLS_CC); + } else { + MAKE_STD_ZVAL(head_to_index); + ZVAL_NULL(head_to_index); + } + + if (entry->index_to_workdir) { + php_git2_diff_delta_to_array(entry->index_to_workdir, &index_to_workdir TSRMLS_CC); + } else { + MAKE_STD_ZVAL(index_to_workdir); + ZVAL_NULL(index_to_workdir); + } + + add_assoc_long_ex(result, ZEND_STRS("status"), entry->status); + add_assoc_zval_ex(result, ZEND_STRS("head_to_index"), head_to_index); + add_assoc_zval_ex(result, ZEND_STRS("index_to_workdir"), index_to_workdir); + + *out = result; +} + +static int php_git2_git_status_cb( + const char *path, unsigned int status_flags, void *payload) +{ + zval *param_path, *param_status_flags, *retval_ptr = NULL; + php_git2_cb_t *p = (php_git2_cb_t*)payload; + long retval = 0; + GIT2_TSRMLS_SET(p->tsrm_ls) + + Z_ADDREF_P(p->payload); + MAKE_STD_ZVAL(param_path); + MAKE_STD_ZVAL(param_status_flags); + ZVAL_STRING(param_path, path, 1); + ZVAL_LONG(param_status_flags, status_flags); + + if (php_git2_call_function_v(p->fci, p->fcc TSRMLS_CC, &retval_ptr, 3, + ¶m_path, ¶m_status_flags, &p->payload)) { + return GIT_EUSER; + } + + retval = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + return retval; +} + +/* {{{ proto long git_status_foreach(resource $repo, Callable $callback, $payload) + */ +PHP_FUNCTION(git_status_foreach) +{ + int result = 0; + zval *repo = NULL, *payload = NULL; + php_git2_t *_repo = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rfz", &repo, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_status_foreach(PHP_GIT2_V(_repo, repository), php_git2_git_status_cb, cb); + php_git2_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_status_foreach_ext(resource $repo, $opts, Callable $callback, $payload) + */ +PHP_FUNCTION(git_status_foreach_ext) +{ + int result = 0; + zval *repo = NULL, *opts = NULL, *payload = NULL; + php_git2_t *_repo = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb = NULL; + git_status_options options = GIT_STATUS_OPTIONS_INIT; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rafz", &repo, &opts, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + php_git2_array_to_git_status_options(&options, opts TSRMLS_CC); + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_status_foreach_ext(PHP_GIT2_V(_repo, repository), &options, php_git2_git_status_cb, cb); + php_git2_cb_free(cb); + if (options.pathspec.count > 0) { + php_git2_strarray_free(&options.pathspec); + } + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_status_file(long $status_flags, resource $repo, string $path) + */ +PHP_FUNCTION(git_status_file) +{ + int result = 0, path_len = 0; + long status_flags = 0; + zval *repo = NULL; + php_git2_t *_repo = NULL; + char *path = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "lrs", &status_flags, &repo, &path, &path_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_status_file(&status_flags, PHP_GIT2_V(_repo, repository), path); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_status_list_new(resource $repo, $opts) + */ +PHP_FUNCTION(git_status_list_new) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_status_list *out = NULL; + zval *repo = NULL, *opts = NULL; + git_status_options options = GIT_STATUS_OPTIONS_INIT; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "ra", &repo, &opts) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + php_git2_array_to_git_status_options(&options, opts TSRMLS_CC); + error = git_status_list_new(&out, PHP_GIT2_V(_repo, repository), &options); + if (options.pathspec.count > 0) { + php_git2_strarray_free(&options.pathspec); + } + if (php_git2_check_error(error, "git_status_list_new" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_STATUS_LIST, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto long git_status_list_entrycount(resource $statuslist) + */ +PHP_FUNCTION(git_status_list_entrycount) +{ + size_t result = 0; + zval *statuslist = NULL; + php_git2_t *_statuslist = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &statuslist) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_statuslist, php_git2_t*, &statuslist, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_status_list_entrycount(PHP_GIT2_V(_statuslist, status_list)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_status_byindex(resource $statuslist, long $idx) + */ +PHP_FUNCTION(git_status_byindex) +{ + const git_status_entry *result = NULL; + zval *statuslist = NULL, *out; + php_git2_t *_statuslist = NULL; + long idx = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &statuslist, &idx) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_statuslist, php_git2_t*, &statuslist, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_status_byindex(PHP_GIT2_V(_statuslist, status_list), idx); + if (result == NULL) { + RETURN_FALSE; + } + php_git2_git_status_entry_to_array(result, &out TSRMLS_CC); + RETURN_ZVAL(out, 0, 1); +} +/* }}} */ + +/* {{{ proto void git_status_list_free(resource $statuslist) + */ +PHP_FUNCTION(git_status_list_free) +{ + zval *statuslist = NULL; + php_git2_t *_statuslist = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &statuslist) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_statuslist, php_git2_t*, &statuslist, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (GIT2_SHOULD_FREE(_statuslist)) { + git_status_list_free(PHP_GIT2_V(_statuslist, status_list)); + GIT2_SHOULD_FREE(_statuslist) = 0; + }; + zval_ptr_dtor(&statuslist); +} +/* }}} */ + +/* {{{ proto long git_status_should_ignore(long $ignored, resource $repo, string $path) + */ +PHP_FUNCTION(git_status_should_ignore) +{ + int result = 0, path_len = 0; + long ignored = 0; + zval *repo = NULL; + php_git2_t *_repo = NULL; + char *path = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "lrs", &ignored, &repo, &path, &path_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_status_should_ignore(ignored, PHP_GIT2_V(_repo, repository), path); + RETURN_LONG(result); +} +/* }}} */ + +PHP_FUNCTION(git_status_options_new) +{ + git_status_options options = GIT_STATUS_OPTIONS_INIT; + zval *result; + + php_git2_git_status_options_to_array(&options, &result TSRMLS_CC); + RETURN_ZVAL(result, 0, 1); +} diff --git a/status.h b/status.h new file mode 100644 index 0000000000..8ff95a1e16 --- /dev/null +++ b/status.h @@ -0,0 +1,106 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_STATUS_H +#define PHP_GIT2_STATUS_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_status_foreach, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_status_foreach_ext, 0, 0, 4) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, opts) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_status_file, 0, 0, 3) + ZEND_ARG_INFO(0, status_flags) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, path) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_status_list_new, 0, 0, 2) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, opts) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_status_list_entrycount, 0, 0, 1) + ZEND_ARG_INFO(0, statuslist) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_status_byindex, 0, 0, 2) + ZEND_ARG_INFO(0, statuslist) + ZEND_ARG_INFO(0, idx) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_status_list_free, 0, 0, 1) + ZEND_ARG_INFO(0, statuslist) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_status_should_ignore, 0, 0, 3) + ZEND_ARG_INFO(0, ignored) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, path) +ZEND_END_ARG_INFO() + +/* {{{ proto long git_status_foreach(repo, callback, payload) +*/ +PHP_FUNCTION(git_status_foreach); + +/* {{{ proto long git_status_foreach_ext(repo, opts, callback, payload) +*/ +PHP_FUNCTION(git_status_foreach_ext); + +/* {{{ proto long git_status_file(status_flags, repo, path) +*/ +PHP_FUNCTION(git_status_file); + +/* {{{ proto resource git_status_list_new(repo, opts) +*/ +PHP_FUNCTION(git_status_list_new); + +/* {{{ proto resource git_status_list_entrycount(statuslist) +*/ +PHP_FUNCTION(git_status_list_entrycount); + +/* {{{ proto resource git_status_byindex(statuslist, idx) +*/ +PHP_FUNCTION(git_status_byindex); + +/* {{{ proto void git_status_list_free(statuslist) +*/ +PHP_FUNCTION(git_status_list_free); + +/* {{{ proto long git_status_should_ignore(ignored, repo, path) +*/ +PHP_FUNCTION(git_status_should_ignore); + +PHP_FUNCTION(git_status_options_new); + +#endif \ No newline at end of file diff --git a/stubs/git2.php b/stubs/git2.php new file mode 100644 index 0000000000..7b1229e428 --- /dev/null +++ b/stubs/git2.php @@ -0,0 +1,549 @@ +tsrm_ls) + + Z_ADDREF_P(p->payload); + MAKE_STD_ZVAL(param_sm); + MAKE_STD_ZVAL(param_name); + if (php_git2_make_resource(&submodule, PHP_GIT2_TYPE_SUBMODULE, sm, 0 TSRMLS_CC)) { + return GIT_EUSER; + } + ZVAL_RESOURCE(param_sm, GIT2_RVAL_P(submodule)); + + ZVAL_STRING(param_name, name, 1); + if (php_git2_call_function_v(p->fci, p->fcc TSRMLS_CC, &retval_ptr, 3, + ¶m_sm, ¶m_name, &p->payload)) { + return GIT_EUSER; + } + + retval = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + return retval; + + +} + +/* {{{ proto long git_submodule_lookup(resource $repo, string $name) + */ +PHP_FUNCTION(git_submodule_lookup) +{ + int result = 0, name_len = 0, error = 0; + git_submodule *submodule = NULL; + zval *repo = NULL; + php_git2_t *_repo = NULL, *_result = NULL; + char *name = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repo, &name, &name_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_lookup(&submodule, PHP_GIT2_V(_repo, repository), name); + if (php_git2_make_resource(&_result, PHP_GIT2_TYPE_SUBMODULE, submodule, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(_result)); +} +/* }}} */ + +/* {{{ proto long git_submodule_foreach(resource $repo, Callable $callback, $payload) + */ +PHP_FUNCTION(git_submodule_foreach) +{ + int result = 0, name_len = 0, error = 0; + zval *repo = NULL, *payload = NULL; + php_git2_t *_repo = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rfz", &repo, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_submodule_foreach(PHP_GIT2_V(_repo, repository), php_git2_git_submodule_foreach_cb, cb); + php_git2_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_submodule_add_setup(resource $repo, string $url, string $path, long $use_gitlink) + */ +PHP_FUNCTION(git_submodule_add_setup) +{ + int result = 0, url_len = 0, path_len = 0, error = 0; + git_submodule *submodule = NULL; + zval *repo = NULL; + php_git2_t *_repo = NULL; + char *url = NULL, *path = NULL; + long use_gitlink = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rssl", &repo, &url, &url_len, &path, &path_len, &use_gitlink) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_add_setup(&submodule, PHP_GIT2_V(_repo, repository), url, path, use_gitlink); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_submodule_add_finalize(resource $submodule) + */ +PHP_FUNCTION(git_submodule_add_finalize) +{ + int result = 0, error = 0; + zval *submodule = NULL; + php_git2_t *_submodule = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &submodule) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_submodule, php_git2_t*, &submodule, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_add_finalize(PHP_GIT2_V(_submodule, submodule)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_submodule_add_to_index(resource $submodule, long $write_index) + */ +PHP_FUNCTION(git_submodule_add_to_index) +{ + int result = 0, error = 0; + zval *submodule = NULL; + php_git2_t *_submodule = NULL; + long write_index = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &submodule, &write_index) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_submodule, php_git2_t*, &submodule, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_add_to_index(PHP_GIT2_V(_submodule, submodule), write_index); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_submodule_save(resource $submodule) + */ +PHP_FUNCTION(git_submodule_save) +{ + int result = 0, error = 0; + zval *submodule = NULL; + php_git2_t *_submodule = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &submodule) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_submodule, php_git2_t*, &submodule, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_save(PHP_GIT2_V(_submodule, submodule)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_submodule_owner(resource $submodule) + */ +PHP_FUNCTION(git_submodule_owner) +{ + git_repository *result = NULL; + zval *submodule = NULL; + php_git2_t *_submodule = NULL, *__result = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &submodule) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_submodule, php_git2_t*, &submodule, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_owner(PHP_GIT2_V(_submodule, submodule)); + if (php_git2_make_resource(&__result, PHP_GIT2_TYPE_REPOSITORY, result, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(__result)); +} +/* }}} */ + +/* {{{ proto string git_submodule_name(resource $submodule) + */ +PHP_FUNCTION(git_submodule_name) +{ + const char *result = NULL; + zval *submodule = NULL; + php_git2_t *_submodule = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &submodule) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_submodule, php_git2_t*, &submodule, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_name(PHP_GIT2_V(_submodule, submodule)); + RETURN_STRING(result, 1); +} +/* }}} */ + +/* {{{ proto string git_submodule_path(resource $submodule) + */ +PHP_FUNCTION(git_submodule_path) +{ + const char *result = NULL; + zval *submodule = NULL; + php_git2_t *_submodule = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &submodule) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_submodule, php_git2_t*, &submodule, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_path(PHP_GIT2_V(_submodule, submodule)); + RETURN_STRING(result, 1); +} +/* }}} */ + +/* {{{ proto string git_submodule_url(resource $submodule) + */ +PHP_FUNCTION(git_submodule_url) +{ + const char *result = NULL; + zval *submodule = NULL; + php_git2_t *_submodule = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &submodule) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_submodule, php_git2_t*, &submodule, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_url(PHP_GIT2_V(_submodule, submodule)); + RETURN_STRING(result, 1); +} +/* }}} */ + +/* {{{ proto long git_submodule_set_url(resource $submodule, string $url) + */ +PHP_FUNCTION(git_submodule_set_url) +{ + int result = 0, url_len = 0, error = 0; + zval *submodule = NULL; + php_git2_t *_submodule = NULL; + char *url = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &submodule, &url, &url_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_submodule, php_git2_t*, &submodule, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_set_url(PHP_GIT2_V(_submodule, submodule), url); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto string git_submodule_index_id(resource $submodule) + */ +PHP_FUNCTION(git_submodule_index_id) +{ + const git_oid *result = NULL; + zval *submodule = NULL; + php_git2_t *_submodule = NULL; + char __result[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &submodule) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_submodule, php_git2_t*, &submodule, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_index_id(PHP_GIT2_V(_submodule, submodule)); + git_oid_fmt(__result, result); + RETURN_STRING(__result, 1); +} +/* }}} */ + +/* {{{ proto string git_submodule_head_id(resource $submodule) + */ +PHP_FUNCTION(git_submodule_head_id) +{ + const git_oid *result = NULL; + zval *submodule = NULL; + php_git2_t *_submodule = NULL; + char __result[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &submodule) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_submodule, php_git2_t*, &submodule, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_head_id(PHP_GIT2_V(_submodule, submodule)); + git_oid_fmt(__result, result); + RETURN_STRING(__result, 1); +} +/* }}} */ + +/* {{{ proto string git_submodule_wd_id(resource $submodule) + */ +PHP_FUNCTION(git_submodule_wd_id) +{ + const git_oid *result = NULL; + zval *submodule = NULL; + php_git2_t *_submodule = NULL; + char __result[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &submodule) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_submodule, php_git2_t*, &submodule, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_wd_id(PHP_GIT2_V(_submodule, submodule)); + git_oid_fmt(__result, result); + RETURN_STRING(__result, 1); +} +/* }}} */ + +/* {{{ proto long git_submodule_ignore(resource $submodule) + */ +PHP_FUNCTION(git_submodule_ignore) +{ + git_submodule_ignore_t result; + zval *submodule = NULL; + php_git2_t *_submodule = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &submodule) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_submodule, php_git2_t*, &submodule, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_ignore(PHP_GIT2_V(_submodule, submodule)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_submodule_set_ignore(resource $submodule, $ignore) + */ +PHP_FUNCTION(git_submodule_set_ignore) +{ + git_submodule_ignore_t result; + zval *submodule = NULL; + php_git2_t *_submodule = NULL; + long ignore = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &submodule, &ignore) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_submodule, php_git2_t*, &submodule, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_set_ignore(PHP_GIT2_V(_submodule, submodule), ignore); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_submodule_update(resource $submodule) + */ +PHP_FUNCTION(git_submodule_update) +{ + git_submodule_update_t result; + zval *submodule = NULL; + php_git2_t *_submodule = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &submodule) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_submodule, php_git2_t*, &submodule, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_update(PHP_GIT2_V(_submodule, submodule)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto resource git_submodule_set_update(resource $submodule, $update) + */ +PHP_FUNCTION(git_submodule_set_update) +{ + git_submodule_update_t result; + zval *submodule = NULL; + php_git2_t *_submodule = NULL; + long update = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &submodule, &update) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_submodule, php_git2_t*, &submodule, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_set_update(PHP_GIT2_V(_submodule, submodule), update); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_submodule_fetch_recurse_submodules(resource $submodule) + */ +PHP_FUNCTION(git_submodule_fetch_recurse_submodules) +{ + int result = 0, error = 0; + zval *submodule = NULL; + php_git2_t *_submodule = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &submodule) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_submodule, php_git2_t*, &submodule, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_fetch_recurse_submodules(PHP_GIT2_V(_submodule, submodule)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_submodule_set_fetch_recurse_submodules(resource $submodule, long $fetch_recurse_submodules) + */ +PHP_FUNCTION(git_submodule_set_fetch_recurse_submodules) +{ + int result = 0, error = 0; + zval *submodule = NULL; + php_git2_t *_submodule = NULL; + long fetch_recurse_submodules = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &submodule, &fetch_recurse_submodules) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_submodule, php_git2_t*, &submodule, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_set_fetch_recurse_submodules(PHP_GIT2_V(_submodule, submodule), fetch_recurse_submodules); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_submodule_init(resource $submodule, long $overwrite) + */ +PHP_FUNCTION(git_submodule_init) +{ + int result = 0, error = 0; + zval *submodule = NULL; + php_git2_t *_submodule = NULL; + long overwrite = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &submodule, &overwrite) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_submodule, php_git2_t*, &submodule, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_init(PHP_GIT2_V(_submodule, submodule), overwrite); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_submodule_sync(resource $submodule) + */ +PHP_FUNCTION(git_submodule_sync) +{ + int result = 0, error = 0; + zval *submodule = NULL; + php_git2_t *_submodule = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &submodule) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_submodule, php_git2_t*, &submodule, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_sync(PHP_GIT2_V(_submodule, submodule)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_submodule_open(resource $submodule) + */ +PHP_FUNCTION(git_submodule_open) +{ + int result = 0, error = 0; + git_repository *repo = NULL; + zval *submodule = NULL; + php_git2_t *_submodule = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &submodule) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_submodule, php_git2_t*, &submodule, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_open(&repo, PHP_GIT2_V(_submodule, submodule)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_submodule_reload(resource $submodule) + */ +PHP_FUNCTION(git_submodule_reload) +{ + int result = 0, error = 0; + zval *submodule = NULL; + php_git2_t *_submodule = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &submodule) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_submodule, php_git2_t*, &submodule, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_reload(PHP_GIT2_V(_submodule, submodule)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_submodule_reload_all(resource $repo) + */ +PHP_FUNCTION(git_submodule_reload_all) +{ + int result = 0, error = 0; + zval *repo = NULL; + php_git2_t *_repo = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_reload_all(PHP_GIT2_V(_repo, repository)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_submodule_status(long $status, resource $submodule) + */ +PHP_FUNCTION(git_submodule_status) +{ + int result = 0, error = 0; + long status = 0; + zval *submodule = NULL; + php_git2_t *_submodule = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "lr", &status, &submodule) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_submodule, php_git2_t*, &submodule, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_status(status, PHP_GIT2_V(_submodule, submodule)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto long git_submodule_location(long $location_status, resource $submodule) + */ +PHP_FUNCTION(git_submodule_location) +{ + int result = 0, error = 0; + long location_status = 0; + zval *submodule = NULL; + php_git2_t *_submodule = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "lr", &location_status, &submodule) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_submodule, php_git2_t*, &submodule, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_submodule_location(location_status, PHP_GIT2_V(_submodule, submodule)); + RETURN_LONG(result); +} +/* }}} */ + diff --git a/submodule.h b/submodule.h new file mode 100644 index 0000000000..a7439e53ed --- /dev/null +++ b/submodule.h @@ -0,0 +1,259 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_SUBMODULE_H +#define PHP_GIT2_SUBMODULE_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_lookup, 0, 0, 2) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_foreach, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_add_setup, 0, 0, 4) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, url) + ZEND_ARG_INFO(0, path) + ZEND_ARG_INFO(0, use_gitlink) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_add_finalize, 0, 0, 1) + ZEND_ARG_INFO(0, submodule) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_add_to_index, 0, 0, 2) + ZEND_ARG_INFO(0, submodule) + ZEND_ARG_INFO(0, write_index) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_save, 0, 0, 1) + ZEND_ARG_INFO(0, submodule) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_owner, 0, 0, 1) + ZEND_ARG_INFO(0, submodule) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_name, 0, 0, 1) + ZEND_ARG_INFO(0, submodule) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_path, 0, 0, 1) + ZEND_ARG_INFO(0, submodule) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_url, 0, 0, 1) + ZEND_ARG_INFO(0, submodule) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_set_url, 0, 0, 2) + ZEND_ARG_INFO(0, submodule) + ZEND_ARG_INFO(0, url) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_index_id, 0, 0, 1) + ZEND_ARG_INFO(0, submodule) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_head_id, 0, 0, 1) + ZEND_ARG_INFO(0, submodule) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_wd_id, 0, 0, 1) + ZEND_ARG_INFO(0, submodule) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_ignore, 0, 0, 1) + ZEND_ARG_INFO(0, submodule) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_set_ignore, 0, 0, 2) + ZEND_ARG_INFO(0, submodule) + ZEND_ARG_INFO(0, ignore) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_update, 0, 0, 1) + ZEND_ARG_INFO(0, submodule) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_set_update, 0, 0, 2) + ZEND_ARG_INFO(0, submodule) + ZEND_ARG_INFO(0, update) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_fetch_recurse_submodules, 0, 0, 1) + ZEND_ARG_INFO(0, submodule) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_set_fetch_recurse_submodules, 0, 0, 2) + ZEND_ARG_INFO(0, submodule) + ZEND_ARG_INFO(0, fetch_recurse_submodules) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_init, 0, 0, 2) + ZEND_ARG_INFO(0, submodule) + ZEND_ARG_INFO(0, overwrite) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_sync, 0, 0, 1) + ZEND_ARG_INFO(0, submodule) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_open, 0, 0, 1) + ZEND_ARG_INFO(0, submodule) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_reload, 0, 0, 1) + ZEND_ARG_INFO(0, submodule) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_reload_all, 0, 0, 1) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_status, 0, 0, 2) + ZEND_ARG_INFO(0, status) + ZEND_ARG_INFO(0, submodule) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_submodule_location, 0, 0, 2) + ZEND_ARG_INFO(0, location_status) + ZEND_ARG_INFO(0, submodule) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_submodule_lookup(repo, name) +*/ +PHP_FUNCTION(git_submodule_lookup); + +/* {{{ proto long git_submodule_foreach(repo, sm, name, payload), payload) +*/ +PHP_FUNCTION(git_submodule_foreach); + +/* {{{ proto resource git_submodule_add_setup(repo, url, path, use_gitlink) +*/ +PHP_FUNCTION(git_submodule_add_setup); + +/* {{{ proto long git_submodule_add_finalize(submodule) +*/ +PHP_FUNCTION(git_submodule_add_finalize); + +/* {{{ proto long git_submodule_add_to_index(submodule, write_index) +*/ +PHP_FUNCTION(git_submodule_add_to_index); + +/* {{{ proto long git_submodule_save(submodule) +*/ +PHP_FUNCTION(git_submodule_save); + +/* {{{ proto resource git_submodule_owner(submodule) +*/ +PHP_FUNCTION(git_submodule_owner); + +/* {{{ proto resource git_submodule_name(submodule) +*/ +PHP_FUNCTION(git_submodule_name); + +/* {{{ proto resource git_submodule_path(submodule) +*/ +PHP_FUNCTION(git_submodule_path); + +/* {{{ proto resource git_submodule_url(submodule) +*/ +PHP_FUNCTION(git_submodule_url); + +/* {{{ proto long git_submodule_set_url(submodule, url) +*/ +PHP_FUNCTION(git_submodule_set_url); + +/* {{{ proto resource git_submodule_index_id(submodule) +*/ +PHP_FUNCTION(git_submodule_index_id); + +/* {{{ proto resource git_submodule_head_id(submodule) +*/ +PHP_FUNCTION(git_submodule_head_id); + +/* {{{ proto resource git_submodule_wd_id(submodule) +*/ +PHP_FUNCTION(git_submodule_wd_id); + +/* {{{ proto resource git_submodule_ignore(submodule) +*/ +PHP_FUNCTION(git_submodule_ignore); + +/* {{{ proto resource git_submodule_set_ignore(submodule, ignore) +*/ +PHP_FUNCTION(git_submodule_set_ignore); + +/* {{{ proto resource git_submodule_update(submodule) +*/ +PHP_FUNCTION(git_submodule_update); + +/* {{{ proto resource git_submodule_set_update(submodule, update) +*/ +PHP_FUNCTION(git_submodule_set_update); + +/* {{{ proto long git_submodule_fetch_recurse_submodules(submodule) +*/ +PHP_FUNCTION(git_submodule_fetch_recurse_submodules); + +/* {{{ proto long git_submodule_set_fetch_recurse_submodules(submodule, fetch_recurse_submodules) +*/ +PHP_FUNCTION(git_submodule_set_fetch_recurse_submodules); + +/* {{{ proto long git_submodule_init(submodule, overwrite) +*/ +PHP_FUNCTION(git_submodule_init); + +/* {{{ proto long git_submodule_sync(submodule) +*/ +PHP_FUNCTION(git_submodule_sync); + +/* {{{ proto resource git_submodule_open(submodule) +*/ +PHP_FUNCTION(git_submodule_open); + +/* {{{ proto long git_submodule_reload(submodule) +*/ +PHP_FUNCTION(git_submodule_reload); + +/* {{{ proto long git_submodule_reload_all(repo) +*/ +PHP_FUNCTION(git_submodule_reload_all); + +/* {{{ proto long git_submodule_status(status, submodule) +*/ +PHP_FUNCTION(git_submodule_status); + +/* {{{ proto long git_submodule_location(location_status, submodule) +*/ +PHP_FUNCTION(git_submodule_location); + +#endif \ No newline at end of file diff --git a/tag.c b/tag.c new file mode 100644 index 0000000000..a7c54e8c4b --- /dev/null +++ b/tag.c @@ -0,0 +1,553 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "tag.h" + +static int php_git2_tag_foreach_cb(const char *name, git_oid *oid, void *payload) +{ + php_git2_t *result; + zval *param_name, *param_oid, *retval_ptr = NULL; + php_git2_cb_t *p = (php_git2_cb_t*)payload; + long retval = 0; + char buffer[GIT2_OID_HEXSIZE] = {0}; + GIT2_TSRMLS_SET(p->tsrm_ls) + + git_oid_fmt(buffer, oid); + + Z_ADDREF_P(p->payload); + MAKE_STD_ZVAL(param_name); + MAKE_STD_ZVAL(param_oid); + ZVAL_STRING(param_name, name, 1); + ZVAL_STRING(param_oid, buffer, 1); + + if (php_git2_call_function_v(p->fci, p->fcc TSRMLS_CC, &retval_ptr, 3, ¶m_name, ¶m_oid, &p->payload)) { + zval_ptr_dtor(&retval_ptr); + zend_list_delete(result->resource_id); + return GIT_EUSER; + } + + retval = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + zend_list_delete(result->resource_id); + + return retval; +} + +/* {{{ proto resource git_tag_lookup(resource $repo, string $id) + */ +PHP_FUNCTION(git_tag_lookup) +{ + php_git2_t *result = NULL, *_repo = NULL; + git_tag *out = NULL; + zval *repo = NULL; + char *id = NULL; + int id_len = 0, error = 0; + git_oid __id = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repo, &id, &id_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__id, id, id_len)) { + RETURN_FALSE; + } + error = git_tag_lookup(&out, PHP_GIT2_V(_repo, repository), &__id); + if (php_git2_check_error(error, "git_tag_lookup" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_TAG, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_tag_lookup_prefix(resource $repo, string $id) + */ +PHP_FUNCTION(git_tag_lookup_prefix) +{ + php_git2_t *result = NULL; + git_tag *out = NULL; + zval *repo = NULL; + php_git2_t *_repo = NULL; + char *id = NULL; + int id_len = 0; + git_oid __id; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsl", &repo, &id, &id_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__id, id, id_len)) { + RETURN_FALSE; + } + error = git_tag_lookup_prefix(&out, PHP_GIT2_V(_repo, repository), &__id, id_len); + if (php_git2_check_error(error, "git_tag_lookup_prefix" TSRMLS_CC)) { + RETURN_FALSE; + } + PHP_GIT2_MAKE_RESOURCE(result); + PHP_GIT2_V(result, tag) = out; + result->type = PHP_GIT2_TYPE_TAG; + result->resource_id = PHP_GIT2_LIST_INSERT(result, git2_resource_handle); + result->should_free_v = 0; + ZVAL_RESOURCE(return_value, result->resource_id); +} +/* }}} */ + +/* {{{ proto void git_tag_free(resource $tag) + */ +PHP_FUNCTION(git_tag_free) +{ + zval *tag = NULL; + php_git2_t *_tag = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &tag) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_tag, php_git2_t*, &tag, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (_tag->should_free_v) { + git_tag_free(PHP_GIT2_V(_tag, tag)); + }; + zval_ptr_dtor(&tag); +} +/* }}} */ + +/* {{{ proto resource git_tag_id(resource $tag) + */ +PHP_FUNCTION(git_tag_id) +{ + const git_oid *result = NULL; + zval *tag = NULL; + php_git2_t *_tag = NULL; + char __result[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &tag) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_tag, php_git2_t*, &tag, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_tag_id(PHP_GIT2_V(_tag, tag)); + git_oid_fmt(__result, result); + RETURN_STRING(__result, 1); +} +/* }}} */ + +/* {{{ proto resource git_tag_owner(resource $tag) + */ +PHP_FUNCTION(git_tag_owner) +{ + git_repository *result = NULL; + zval *tag = NULL; + php_git2_t *_tag = NULL, *__result = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &tag) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_tag, php_git2_t*, &tag, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_tag_owner(PHP_GIT2_V(_tag, tag)); + if (php_git2_make_resource(&__result, PHP_GIT2_TYPE_TAG, result, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(__result)); +} +/* }}} */ + +/* {{{ proto resource git_tag_target(resource $tag) + */ +PHP_FUNCTION(git_tag_target) +{ + php_git2_t *result = NULL; + git_object *target_out = NULL; + zval *tag = NULL; + php_git2_t *_tag = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &tag) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_tag, php_git2_t*, &tag, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_tag_target(&target_out, PHP_GIT2_V(_tag, tag)); + if (php_git2_check_error(error, "git_tag_target" TSRMLS_CC)) { + RETURN_FALSE; + } + PHP_GIT2_MAKE_RESOURCE(result); + PHP_GIT2_V(result, object) = target_out; + result->type = PHP_GIT2_TYPE_OBJECT; + result->resource_id = PHP_GIT2_LIST_INSERT(result, git2_resource_handle); + result->should_free_v = 0; + ZVAL_RESOURCE(return_value, result->resource_id); +} +/* }}} */ + +/* {{{ proto resource git_tag_target_id(resource $tag) + */ +PHP_FUNCTION(git_tag_target_id) +{ + const git_oid *result = NULL; + zval *tag = NULL; + php_git2_t *_tag = NULL; + char __result[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &tag) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_tag, php_git2_t*, &tag, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_tag_target_id(PHP_GIT2_V(_tag, tag)); + git_oid_fmt(__result, result); + RETURN_STRING(__result, 1); +} +/* }}} */ + +/* {{{ proto resource git_tag_target_type(resource $tag) + */ +PHP_FUNCTION(git_tag_target_type) +{ + git_otype result; + zval *tag = NULL; + php_git2_t *_tag = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &tag) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_tag, php_git2_t*, &tag, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_tag_target_type(PHP_GIT2_V(_tag, tag)); + RETURN_LONG(result); +} +/* }}} */ + +/* {{{ proto string git_tag_name(resource $tag) + */ +PHP_FUNCTION(git_tag_name) +{ + const char *result = NULL; + zval *tag = NULL; + php_git2_t *_tag = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &tag) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_tag, php_git2_t*, &tag, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_tag_name(PHP_GIT2_V(_tag, tag)); + RETURN_STRING(result, 1); +} +/* }}} */ + +/* {{{ proto array git_tag_tagger(resource $tag) + */ +PHP_FUNCTION(git_tag_tagger) +{ + const git_signature *result = NULL; + zval *__result = NULL; + zval *tag = NULL; + php_git2_t *_tag = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &tag) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_tag, php_git2_t*, &tag, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_tag_tagger(PHP_GIT2_V(_tag, tag)); + php_git2_signature_to_array(result, &__result TSRMLS_CC); + RETURN_ZVAL(__result, 0, 1); +} +/* }}} */ + +/* {{{ proto string git_tag_message(resource $tag) + */ +PHP_FUNCTION(git_tag_message) +{ + const char *result = NULL; + zval *tag = NULL; + php_git2_t *_tag = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &tag) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_tag, php_git2_t*, &tag, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_tag_message(PHP_GIT2_V(_tag, tag)); + RETURN_STRING(result, 1); +} +/* }}} */ + +/* {{{ proto string git_tag_create(resource $repo, string $tag_name, resource $target, array $tagger, string $message, long $force) + */ +PHP_FUNCTION(git_tag_create) +{ + int result = 0; + git_oid __oid; + zval *repo = NULL; + php_git2_t *_repo = NULL; + char *tag_name = NULL; + int tag_name_len = 0; + zval *target = NULL; + php_git2_t *_target = NULL; + zval *tagger = NULL; + char *message = NULL; + int message_len = 0; + long force = 0; + char buffer[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsrasl", &repo, &tag_name, &tag_name_len, &target, &tagger, &message, &message_len, &force) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_target, php_git2_t*, &target, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_tag_create(&__oid, PHP_GIT2_V(_repo, repository), tag_name, PHP_GIT2_V(_target, object), tagger, message, force); + if (php_git2_check_error(result, "git_tag_create" TSRMLS_CC)) { + RETURN_FALSE + } + git_oid_fmt(buffer, &__oid); + RETURN_STRING(buffer, 1); + +} +/* }}} */ + + +/* {{{ proto string git_tag_annotation_create(resource $repo, string $tag_name, resource $target, array $tagger, string $message) + */ +PHP_FUNCTION(git_tag_annotation_create) +{ + int result = 0; + git_oid __oid; + zval *repo = NULL; + php_git2_t *_repo = NULL; + char *tag_name = NULL; + int tag_name_len = 0; + zval *target = NULL; + php_git2_t *_target = NULL; + zval *tagger = NULL; + char *message = NULL; + int message_len = 0; + char buffer[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsras", &repo, &tag_name, &tag_name_len, &target, &tagger, &message, &message_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_target, php_git2_t*, &target, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_tag_annotation_create(&__oid, PHP_GIT2_V(_repo, repository), tag_name, PHP_GIT2_V(_target, object), tagger, message); + if (php_git2_check_error(result, "git_tag_annotation_create" TSRMLS_CC)) { + RETURN_FALSE + } + git_oid_fmt(buffer, &__oid); + RETURN_STRING(buffer, 1); + +} +/* }}} */ + +/* {{{ proto string git_tag_create_frombuffer(resource $repo, string $buffer, long $force) + */ +PHP_FUNCTION(git_tag_create_frombuffer) +{ + int result = 0; + git_oid __oid; + zval *repo = NULL; + php_git2_t *_repo = NULL; + char *buffer = NULL; + int buffer_len = 0; + long force = 0; + char oid[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsl", &repo, &buffer, &buffer_len, &force) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_tag_create_frombuffer(&__oid, PHP_GIT2_V(_repo, repository), buffer, force); + if (php_git2_check_error(result, "git_tag_create_frombuffer" TSRMLS_CC)) { + RETURN_FALSE + } + git_oid_fmt(oid, &__oid); + RETURN_STRING(oid, 1); +} +/* }}} */ + + +/* {{{ proto string git_tag_create_lightweight(resource $repo, string $tag_name, resource $target, long $force) + */ +PHP_FUNCTION(git_tag_create_lightweight) +{ + int result = 0; + git_oid __oid; + zval *repo = NULL; + php_git2_t *_repo = NULL; + char *tag_name = NULL; + int tag_name_len = 0; + zval *target = NULL; + php_git2_t *_target = NULL; + long force = 0; + char oid[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rsrl", &repo, &tag_name, &tag_name_len, &target, &force) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_target, php_git2_t*, &target, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_tag_create_lightweight(&__oid, PHP_GIT2_V(_repo, repository), tag_name, PHP_GIT2_V(_target, object), force); + if (php_git2_check_error(result, "git_tag_create_lightweight" TSRMLS_CC)) { + RETURN_FALSE + } + git_oid_fmt(oid, &__oid); + RETURN_STRING(oid, 1); +} +/* }}} */ + +/* {{{ proto long git_tag_delete(resource $repo, string $tag_name) + */ +PHP_FUNCTION(git_tag_delete) +{ + int result = 0; + zval *repo = NULL; + php_git2_t *_repo = NULL; + char *tag_name = NULL; + int tag_name_len = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repo, &tag_name, &tag_name_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_tag_delete(PHP_GIT2_V(_repo, repository), tag_name); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto long git_tag_list(resource $repo) + */ +PHP_FUNCTION(git_tag_list) +{ + int error = 0; + git_strarray tag_names = {0}; + zval *repo = NULL; + php_git2_t *_repo = NULL; + zval *result; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &repo) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_tag_list(&tag_names, PHP_GIT2_V(_repo, repository)); + if (php_git2_check_error(error, "git_tag_list" TSRMLS_CC)) { + RETURN_FALSE + } + php_git2_strarray_to_array(&tag_names, &result TSRMLS_CC); + git_strarray_free(&tag_names); + RETURN_ZVAL(result, 0, 1); +} +/* }}} */ + + +/* {{{ proto long git_tag_list_match(string $pattern, resource $repo) + */ +PHP_FUNCTION(git_tag_list_match) +{ + zval *result; + git_strarray tag_names = {0}; + char *pattern = NULL; + int pattern_len = 0; + zval *repo = NULL; + php_git2_t *_repo = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "sr", &pattern, &pattern_len, &repo) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_tag_list_match(&tag_names, pattern, PHP_GIT2_V(_repo, repository)); + if (php_git2_check_error(error, "git_tag_list_match" TSRMLS_CC)) { + RETURN_FALSE + } + php_git2_strarray_to_array(&tag_names, &result TSRMLS_CC); + git_strarray_free(&tag_names); + RETURN_ZVAL(result, 0, 1); + +} +/* }}} */ + + +/* {{{ proto long git_tag_foreach(resource $repo, $callback, $payload) + */ +PHP_FUNCTION(git_tag_foreach) +{ + int result = 0; + zval *repo = NULL; + php_git2_t *_repo = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb; + zval *payload = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rfz", &repo, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_tag_foreach(PHP_GIT2_V(_repo, repository), php_git2_tag_foreach_cb, cb); + php_git2_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto resource git_tag_peel(resource $tag) + */ +PHP_FUNCTION(git_tag_peel) +{ + php_git2_t *result = NULL, *_tag = NULL; + git_object *tag_target_out = NULL; + zval *tag = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &tag) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_tag, php_git2_t*, &tag, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_tag_peel(&tag_target_out, PHP_GIT2_V(_tag, tag)); + if (php_git2_check_error(error, "git_tag_peel" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_OBJECT, tag_target_out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ diff --git a/tag.h b/tag.h new file mode 100644 index 0000000000..015502fcce --- /dev/null +++ b/tag.h @@ -0,0 +1,212 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_TAG_H +#define PHP_GIT2_TAG_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tag_lookup, 0, 0, 2) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, id) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tag_lookup_prefix, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, id) + ZEND_ARG_INFO(0, len) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tag_free, 0, 0, 1) + ZEND_ARG_INFO(0, tag) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tag_id, 0, 0, 1) + ZEND_ARG_INFO(0, tag) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tag_owner, 0, 0, 1) + ZEND_ARG_INFO(0, tag) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tag_target, 0, 0, 1) + ZEND_ARG_INFO(0, tag) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tag_target_id, 0, 0, 1) + ZEND_ARG_INFO(0, tag) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tag_target_type, 0, 0, 1) + ZEND_ARG_INFO(0, tag) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tag_name, 0, 0, 1) + ZEND_ARG_INFO(0, tag) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tag_tagger, 0, 0, 1) + ZEND_ARG_INFO(0, tag) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tag_message, 0, 0, 1) + ZEND_ARG_INFO(0, tag) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tag_create, 0, 0, 6) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, tag_name) + ZEND_ARG_INFO(0, target) + ZEND_ARG_INFO(0, tagger) + ZEND_ARG_INFO(0, message) + ZEND_ARG_INFO(0, force) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tag_annotation_create, 0, 0, 5) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, tag_name) + ZEND_ARG_INFO(0, target) + ZEND_ARG_INFO(0, tagger) + ZEND_ARG_INFO(0, message) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tag_create_frombuffer, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, buffer) + ZEND_ARG_INFO(0, force) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tag_create_lightweight, 0, 0, 4) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, tag_name) + ZEND_ARG_INFO(0, target) + ZEND_ARG_INFO(0, force) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tag_delete, 0, 0, 2) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, tag_name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tag_list, 0, 0, 2) + ZEND_ARG_INFO(0, tag_names) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tag_list_match, 0, 0, 3) + ZEND_ARG_INFO(0, tag_names) + ZEND_ARG_INFO(0, pattern) + ZEND_ARG_INFO(0, repo) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tag_foreach, 0, 0, 3) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tag_peel, 0, 0, 1) + ZEND_ARG_INFO(0, tag) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_tag_lookup(repo, id) +*/ +PHP_FUNCTION(git_tag_lookup); + +/* {{{ proto resource git_tag_lookup_prefix(repo, id, len) +*/ +PHP_FUNCTION(git_tag_lookup_prefix); + +/* {{{ proto void git_tag_free(tag) +*/ +PHP_FUNCTION(git_tag_free); + +/* {{{ proto resource git_tag_id(tag) +*/ +PHP_FUNCTION(git_tag_id); + +/* {{{ proto resource git_tag_owner(tag) +*/ +PHP_FUNCTION(git_tag_owner); + +/* {{{ proto resource git_tag_target(tag) +*/ +PHP_FUNCTION(git_tag_target); + +/* {{{ proto resource git_tag_target_id(tag) +*/ +PHP_FUNCTION(git_tag_target_id); + +/* {{{ proto resource git_tag_target_type(tag) +*/ +PHP_FUNCTION(git_tag_target_type); + +/* {{{ proto resource git_tag_name(tag) +*/ +PHP_FUNCTION(git_tag_name); + +/* {{{ proto resource git_tag_tagger(tag) +*/ +PHP_FUNCTION(git_tag_tagger); + +/* {{{ proto resource git_tag_message(tag) +*/ +PHP_FUNCTION(git_tag_message); + +/* {{{ proto resource git_tag_create(repo, tag_name, target, tagger, message, force) +*/ +PHP_FUNCTION(git_tag_create); + +/* {{{ proto resource git_tag_annotation_create(repo, tag_name, target, tagger, message) +*/ +PHP_FUNCTION(git_tag_annotation_create); + +/* {{{ proto resource git_tag_create_frombuffer(repo, buffer, force) +*/ +PHP_FUNCTION(git_tag_create_frombuffer); + +/* {{{ proto resource git_tag_create_lightweight(repo, tag_name, target, force) +*/ +PHP_FUNCTION(git_tag_create_lightweight); + +/* {{{ proto long git_tag_delete(repo, tag_name) +*/ +PHP_FUNCTION(git_tag_delete); + +/* {{{ proto long git_tag_list(tag_names, repo) +*/ +PHP_FUNCTION(git_tag_list); + +/* {{{ proto long git_tag_list_match(tag_names, pattern, repo) +*/ +PHP_FUNCTION(git_tag_list_match); + +/* {{{ proto long git_tag_foreach(repo, callback, payload) +*/ +PHP_FUNCTION(git_tag_foreach); + +/* {{{ proto resource git_tag_peel(tag) +*/ +PHP_FUNCTION(git_tag_peel); + +#endif \ No newline at end of file diff --git a/tests/000-load_extension.phpt b/tests/000-load_extension.phpt deleted file mode 100644 index f77d3d7dd6..0000000000 --- a/tests/000-load_extension.phpt +++ /dev/null @@ -1,9 +0,0 @@ ---TEST-- -Check for Git2 Presence ---SKIPIF-- - ---FILE-- - ---FILE-- - ---FILE-- -isEmpty()) { - echo "FAIL" . PHP_EOL; -} else { - echo "OK" . PHP_EOL; -} ---EXPECT-- -OK diff --git a/tests/001-03-repository_is_bare.phpt b/tests/001-03-repository_is_bare.phpt deleted file mode 100644 index 6716334cd0..0000000000 --- a/tests/001-03-repository_is_bare.phpt +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -Check for Git2\Repository::isBare ---SKIPIF-- - ---FILE-- -isBare()) { - echo "OK" . PHP_EOL; -} else { - echo "FAIL" . PHP_EOL; -} ---EXPECT-- -OK diff --git a/tests/001-04-repository-get_path.phpt b/tests/001-04-repository-get_path.phpt deleted file mode 100644 index 9c3501d2c7..0000000000 --- a/tests/001-04-repository-get_path.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---TEST-- -Check for Git2\Repository::getPath ---SKIPIF-- - ---FILE-- -getPath() == __DIR__ . "/mock/001-01/") { - /* getPath should add DIRECTORY_SEPARATOR at last */ - echo "OK" . PHP_EOL; -} else { - echo "FAIL" . PHP_EOL; -} ---EXPECT-- -OK diff --git a/tests/001-05-repository_get_workdir.phpt b/tests/001-05-repository_get_workdir.phpt deleted file mode 100644 index 03544f9402..0000000000 --- a/tests/001-05-repository_get_workdir.phpt +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -Check for Git2\Repository::getWorkdir ---SKIPIF-- - ---FILE-- -getWorkdir() == "") { - echo "OK" . PHP_EOL; -} else { - echo "FAIL" . PHP_EOL; -} ---EXPECT-- -OK diff --git a/tests/001-06-repository_init.phpt b/tests/001-06-repository_init.phpt deleted file mode 100644 index eddec17cb3..0000000000 --- a/tests/001-06-repository_init.phpt +++ /dev/null @@ -1,89 +0,0 @@ ---TEST-- -Check for Git2\Repository::init ---SKIPIF-- - ---FILE-- - ---FILE-- -headDetached()) { - echo "OK" . PHP_EOL; -} else { - echo "FAIL" . PHP_EOL; -} ---EXPECT-- -OK diff --git a/tests/001-08-repository_head_orphen.phpt b/tests/001-08-repository_head_orphen.phpt deleted file mode 100644 index 723526fe7a..0000000000 --- a/tests/001-08-repository_head_orphen.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---TEST-- -Check for Git2\Repository::headOrphan ---SKIPIF-- - ---FILE-- -headOrphan()) { - echo "OK" . PHP_EOL; -} else { - echo "FAIL" . PHP_EOL; -} ---EXPECT-- -OK diff --git a/tests/001-09-repository_discover.phpt b/tests/001-09-repository_discover.phpt deleted file mode 100644 index a98adb4ef3..0000000000 --- a/tests/001-09-repository_discover.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---TEST-- -Check for Git2\Repository::discover ---SKIPIF-- - ---FILE-- - ---FILE-- -exists("ab68c54212af15d3545c41057e3a8f2f9ff6fd0d")) { - echo "OK" . PHP_EOL; -} else { - echo "FAIL" . PHP_EOL; -} - -if ($repo->exists("unabailablehashid00000000000000000000000")) { - echo "FAIL" . PHP_EOL; -} else { - echo "OK" . PHP_EOL; -} - ---EXPECT-- -OK -OK diff --git a/tests/001-0b-repository_write.phpt b/tests/001-0b-repository_write.phpt deleted file mode 100644 index 8d9345803d..0000000000 --- a/tests/001-0b-repository_write.phpt +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -Check for Git2\TreeBuilder::construct ---SKIPIF-- - ---FILE-- -write("Hello World", 3); -echo $oid . PHP_EOL; -echo `GIT_DIR={$path} git cat-file blob 5e1c309dae7f45e0f39b1bf3ac3cd9db12e7d689` . PHP_EOL; -$blob = $repo->lookup("5e1c309dae7f45e0f39b1bf3ac3cd9db12e7d689"); -echo $blob . PHP_EOL; -`rm -rf {$path}`; ---EXPECT-- -5e1c309dae7f45e0f39b1bf3ac3cd9db12e7d689 -Hello World -Hello World \ No newline at end of file diff --git a/tests/001-0c-repository_hash.phpt b/tests/001-0c-repository_hash.phpt deleted file mode 100644 index a1cb6dfed8..0000000000 --- a/tests/001-0c-repository_hash.phpt +++ /dev/null @@ -1,23 +0,0 @@ ---TEST-- -Check for Git2\TreeBuilder::construct ---SKIPIF-- - ---FILE-- -hash("Hello World", 3); -echo $oid . PHP_EOL; -if (!file_exists($path . "/objects/5e/5e1c309dae7f45e0f39b1bf3ac3cd9db12e7d689")) { - echo "OK" . PHP_EOL; -} else { - echo "FAIL" . PHP_EOL; -} -`rm -rf {$path}`; ---EXPECT-- -5e1c309dae7f45e0f39b1bf3ac3cd9db12e7d689 -OK \ No newline at end of file diff --git a/tests/002-01-commit_construct.phpt b/tests/002-01-commit_construct.phpt deleted file mode 100644 index 56ba20a9c7..0000000000 --- a/tests/002-01-commit_construct.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -Check for Git2\Commit::construct ---SKIPIF-- - ---FILE-- -lookup("ab68c54212af15d3545c41057e3a8f2f9ff6fd0d"); - -if ($commit instanceof Git2\Commit) { - echo "OK" . PHP_EOL; -} else { - echo "FAIL" . PHP_EOL; -} ---EXPECT-- -OK diff --git a/tests/002-02-commit_parent_count.phpt b/tests/002-02-commit_parent_count.phpt deleted file mode 100644 index 3bb448e5a6..0000000000 --- a/tests/002-02-commit_parent_count.phpt +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -Check for Git2\Commit::construct ---SKIPIF-- - ---FILE-- -lookup("ab68c54212af15d3545c41057e3a8f2f9ff6fd0d"); - -echo $commit->parentCount(); ---EXPECT-- -0 diff --git a/tests/002-03-commit_get_message.phpt b/tests/002-03-commit_get_message.phpt deleted file mode 100644 index be7b8c109a..0000000000 --- a/tests/002-03-commit_get_message.phpt +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -Check for Git2\Commit::construct ---SKIPIF-- - ---FILE-- -lookup("ab68c54212af15d3545c41057e3a8f2f9ff6fd0d"); - -echo $commit->getMessage(); ---EXPECT-- -initial commit diff --git a/tests/002-04-commit_get_message_encoding.phpt b/tests/002-04-commit_get_message_encoding.phpt deleted file mode 100644 index ea811da038..0000000000 --- a/tests/002-04-commit_get_message_encoding.phpt +++ /dev/null @@ -1,12 +0,0 @@ ---TEST-- -Check for Git2\Commit::construct ---SKIPIF-- - ---FILE-- -lookup("ab68c54212af15d3545c41057e3a8f2f9ff6fd0d"); - -echo $commit->getMessageEncoding(); ---EXPECT-- -UTF-8 diff --git a/tests/002-05-commit_get_author.phpt b/tests/002-05-commit_get_author.phpt deleted file mode 100644 index 5ae5246090..0000000000 --- a/tests/002-05-commit_get_author.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -Check for Git2\Commit::getAuthor ---SKIPIF-- - ---FILE-- -lookup("ab68c54212af15d3545c41057e3a8f2f9ff6fd0d"); - -$signature = $commit->getAuthor(); -printf("name: %s\n", $signature->name); -printf("email: %s\n", $signature->email); -printf("time: %s\n", $signature->time->format("Y-m-d H:i:s")); ---EXPECT-- -name: Shuhei Tanuma -email: shuhei.tanuma@gmail.com -time: 2012-01-17 21:50:45 \ No newline at end of file diff --git a/tests/002-06-commit_get_committer.phpt b/tests/002-06-commit_get_committer.phpt deleted file mode 100644 index 91f5e7288a..0000000000 --- a/tests/002-06-commit_get_committer.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -Check for Git2\Commit::getCommitter ---SKIPIF-- - ---FILE-- -lookup("ab68c54212af15d3545c41057e3a8f2f9ff6fd0d"); - -$signature = $commit->getCommitter(); -printf("name: %s\n", $signature->name); -printf("email: %s\n", $signature->email); -printf("time: %s\n", $signature->time->format("Y-m-d H:i:s")); ---EXPECT-- -name: Shuhei Tanuma -email: shuhei.tanuma@gmail.com -time: 2012-01-17 21:50:45 \ No newline at end of file diff --git a/tests/002-07-commit_create.phpt b/tests/002-07-commit_create.phpt deleted file mode 100644 index 48e0cc0448..0000000000 --- a/tests/002-07-commit_create.phpt +++ /dev/null @@ -1,50 +0,0 @@ ---TEST-- -Check for Git2\Commit::getCommitter ---SKIPIF-- - ---FILE-- -write("Hello World", 3); - -$author = new Git2\Signature("Shuhei Tanuma","chobieee@gmail.com",new DateTime("@1327164747")); -$committer = new Git2\Signature("Shuhei Tanuma San","chobieee@gmail.com",new DateTime("@1327164747")); -$bld = new Git2\TreeBuilder(); -$bld->insert(new Git2\TreeEntry(array( - "name" => "README.txt", - "oid" => $oid, - "attributes" => octdec('100644'), -))); -$tree = $bld->write($repo); - -$parent = ""; -$parents = array(); -$parent = Git2\Commit::create($repo, array( - "author" => $author, - "committer" => $committer, - "message" => "Hello World", - "tree" => $tree, - "parents" => $parents, -)); - -$commit = $repo->lookup($parent); - -printf("commit_id: %s\n",$parent); -printf("author: %s\n", $commit->getAuthor()->name); -printf("email: %s\n", $commit->getAuthor()->email); -printf("time: %s\n", $commit->getAuthor()->time->getTimestamp()); -echo PHP_EOL; -printf("%s\n", $commit->getMessage()); -`rm -rf {$path}`; ---EXPECT-- -commit_id: 239442d8e6cdbd904e150e25778cc45024b60d51 -author: Shuhei Tanuma -email: chobieee@gmail.com -time: 1327164747 - -Hello World \ No newline at end of file diff --git a/tests/003-01-tree_construct.phpt b/tests/003-01-tree_construct.phpt deleted file mode 100644 index 66330f290a..0000000000 --- a/tests/003-01-tree_construct.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -Check for Git2\Tree::construct ---SKIPIF-- - ---FILE-- -lookup("67dc4302383b2715f4e0b8c41840eb05b1873697"); - -if ($tree instanceof Git2\Tree) { - echo "OK" . PHP_EOL; -} else { - echo "FAIL" . PHP_EOL; -} ---EXPECT-- -OK diff --git a/tests/003-02-tree_iterate.phpt b/tests/003-02-tree_iterate.phpt deleted file mode 100644 index 08ff05e966..0000000000 --- a/tests/003-02-tree_iterate.phpt +++ /dev/null @@ -1,18 +0,0 @@ ---TEST-- -Check for Git2\Tree::construct ---SKIPIF-- - ---FILE-- -lookup("67dc4302383b2715f4e0b8c41840eb05b1873697"); - -foreach ($tree as $entry) { - echo $entry->name . PHP_EOL; - echo $entry->oid . PHP_EOL; - echo $entry->attributes . PHP_EOL; -} ---EXPECT-- -README -557db03de997c86a4a028e1ebd3a1ceb225be23 -33188 \ No newline at end of file diff --git a/tests/004-01-blob_construct.phpt b/tests/004-01-blob_construct.phpt deleted file mode 100644 index 9db9188144..0000000000 --- a/tests/004-01-blob_construct.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -Check for Git2\Blob::construct ---SKIPIF-- - ---FILE-- -lookup("557db03de997c86a4a028e1ebd3a1ceb225be238"); - -if ($blob instanceof Git2\Blob) { - echo "OK" . PHP_EOL; -} else { - echo "FAIL" . PHP_EOL; -} ---EXPECT-- -OK diff --git a/tests/004-02-blob___to_string.phpt b/tests/004-02-blob___to_string.phpt deleted file mode 100644 index d38e738e40..0000000000 --- a/tests/004-02-blob___to_string.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -Check for Git2\Blob::__toString ---SKIPIF-- - ---FILE-- -lookup("557db03de997c86a4a028e1ebd3a1ceb225be238"); - -if ($blob instanceof Git2\Blob) { - echo $blob->__toString(); -} else { - echo "FAIL" . PHP_EOL; -} ---EXPECT-- -Hello World diff --git a/tests/005-01-signature___construct.phpt b/tests/005-01-signature___construct.phpt deleted file mode 100644 index 3ed85507a8..0000000000 --- a/tests/005-01-signature___construct.phpt +++ /dev/null @@ -1,19 +0,0 @@ ---TEST-- -Check for Git2\Signature::construct ---SKIPIF-- - ---FILE-- -name . PHP_EOL; -echo $sig->email . PHP_EOL; -echo $sig->time->format("Y-m-d H:i:s") . PHP_EOL; - ---EXPECT-- -Shuhei Tanuma -chobieee@gmail.com -2012-01-19 00:32:32 diff --git a/tests/006-01-tree_entry___construct.phpt b/tests/006-01-tree_entry___construct.phpt deleted file mode 100644 index e65779bf50..0000000000 --- a/tests/006-01-tree_entry___construct.phpt +++ /dev/null @@ -1,19 +0,0 @@ ---TEST-- -Check for Git2\TreeEntry::construct ---SKIPIF-- - ---FILE-- - "README.txt", - "oid" => "63542fbea05732b78711479a31557bd1b0aa2116", - "attributes" => 33188, -)); - -echo $entry->name . PHP_EOL; -echo $entry->oid . PHP_EOL; -echo $entry->attributes . PHP_EOL; ---EXPECT-- -README.txt -63542fbea05732b78711479a31557bd1b0aa2116 -33188 diff --git a/tests/007-01-tree_builder___construct.phpt b/tests/007-01-tree_builder___construct.phpt deleted file mode 100644 index 6d5036fa43..0000000000 --- a/tests/007-01-tree_builder___construct.phpt +++ /dev/null @@ -1,13 +0,0 @@ ---TEST-- -Check for Git2\TreeBuilder::construct ---SKIPIF-- - ---FILE-- - ---FILE-- -insert(new Git2\TreeEntry(array( - "name" => "README.txt", - "oid" => "63542fbea05732b78711479a31557bd1b0aa2116", - "attributes" => 33188, -))); -$oid = $bld->write($repo); -echo $oid . PHP_EOL; -if (is_file($path . "/objects/75/b9737032278849da7e57829164a1265911afda")) { - echo "PASS" . PHP_EOL; -} else { - echo "FAIL" . PHP_EOL; -} -echo `GIT_DIR={$path} git ls-tree 75b9737032278849da7e57829164a1265911afda`; -`rm -rf {$path}`; ---EXPECT-- -75b9737032278849da7e57829164a1265911afda -PASS -100644 blob 63542fbea05732b78711479a31557bd1b0aa2116 README.txt \ No newline at end of file diff --git a/tests/008-01-walker___construct.phpt b/tests/008-01-walker___construct.phpt deleted file mode 100644 index 37b6dbef08..0000000000 --- a/tests/008-01-walker___construct.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -Check for Git2\Walker::construct ---SKIPIF-- - ---FILE-- - ---FILE-- -push("6e20138dc38f9f626107f1cd3ef0f9838c43defe"); - -foreach ($walker as $oid => $commit) { - printf("oid: %s\n", $oid); - printf("message: %s\n", $commit->getMessage()); -} ---EXPECT-- -oid: 6e20138dc38f9f626107f1cd3ef0f9838c43defe -message: added section 1 contents - -oid: 9bb8c853c9ea27609a6bdc48b78cd26a320daf7d -message: added section 1 - -oid: 7fce1026cb624448e5a8cf8752bd5e19d8f2cb1f -message: modified README - -oid: ffc6c773865c1342db9cd5df5777fc91ddeb8a4d -message: initial commit \ No newline at end of file diff --git a/tests/009-01-reference_lookup.phpt b/tests/009-01-reference_lookup.phpt deleted file mode 100644 index e9d09d7c82..0000000000 --- a/tests/009-01-reference_lookup.phpt +++ /dev/null @@ -1,14 +0,0 @@ ---TEST-- -Check for Git2\Reference::lookup ---SKIPIF-- - ---FILE-- -getName() . PHP_EOL; -echo $ref->getTarget() . PHP_EOL; ---EXPECT-- -refs/heads/master -ab68c54212af15d3545c41057e3a8f2f9ff6fd0d \ No newline at end of file diff --git a/tests/009-02-reference_resolve.phpt b/tests/009-02-reference_resolve.phpt deleted file mode 100644 index 3ab162b0e9..0000000000 --- a/tests/009-02-reference_resolve.phpt +++ /dev/null @@ -1,19 +0,0 @@ ---TEST-- -Check for Git2\Reference::lookup ---SKIPIF-- - ---FILE-- -getName() . PHP_EOL; -echo $ref->getTarget() . PHP_EOL; -$resolved = $ref->resolve(); -echo $resolved->getName() . PHP_EOL; -echo $resolved->getTarget() . PHP_EOL; ---EXPECT-- -HEAD -refs/heads/master -refs/heads/master -ab68c54212af15d3545c41057e3a8f2f9ff6fd0d \ No newline at end of file diff --git a/tests/blob/git_blob_create_frombuffer.phpt b/tests/blob/git_blob_create_frombuffer.phpt new file mode 100644 index 0000000000..ff0d61ef52 --- /dev/null +++ b/tests/blob/git_blob_create_frombuffer.phpt @@ -0,0 +1,17 @@ +--TEST-- +Check for git_blob_create_frombuffer presence +--SKIPIF-- + +--FILE-- +\).*$/Signed-off-by: \1/p') -# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" - -# This example catches duplicate Signed-off-by lines. - -test "" = "$(grep '^Signed-off-by: ' "$1" | - sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { - echo >&2 Duplicate Signed-off-by lines. - exit 1 -} diff --git a/tests/mock/001-01/hooks/post-commit.sample b/tests/mock/001-01/hooks/post-commit.sample deleted file mode 100755 index 22668216a3..0000000000 --- a/tests/mock/001-01/hooks/post-commit.sample +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# -# An example hook script that is called after a successful -# commit is made. -# -# To enable this hook, rename this file to "post-commit". - -: Nothing diff --git a/tests/mock/001-01/hooks/post-receive.sample b/tests/mock/001-01/hooks/post-receive.sample deleted file mode 100755 index 7a83e17ab5..0000000000 --- a/tests/mock/001-01/hooks/post-receive.sample +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -# -# An example hook script for the "post-receive" event. -# -# The "post-receive" script is run after receive-pack has accepted a pack -# and the repository has been updated. It is passed arguments in through -# stdin in the form -# -# For example: -# aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master -# -# see contrib/hooks/ for a sample, or uncomment the next line and -# rename the file to "post-receive". - -#. /usr/share/doc/git-core/contrib/hooks/post-receive-email diff --git a/tests/mock/001-01/hooks/post-update.sample b/tests/mock/001-01/hooks/post-update.sample deleted file mode 100755 index ec17ec1939..0000000000 --- a/tests/mock/001-01/hooks/post-update.sample +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# -# An example hook script to prepare a packed repository for use over -# dumb transports. -# -# To enable this hook, rename this file to "post-update". - -exec git update-server-info diff --git a/tests/mock/001-01/hooks/pre-applypatch.sample b/tests/mock/001-01/hooks/pre-applypatch.sample deleted file mode 100755 index b1f187c2e9..0000000000 --- a/tests/mock/001-01/hooks/pre-applypatch.sample +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# -# An example hook script to verify what is about to be committed -# by applypatch from an e-mail message. -# -# The hook should exit with non-zero status after issuing an -# appropriate message if it wants to stop the commit. -# -# To enable this hook, rename this file to "pre-applypatch". - -. git-sh-setup -test -x "$GIT_DIR/hooks/pre-commit" && - exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} -: diff --git a/tests/mock/001-01/hooks/pre-commit.sample b/tests/mock/001-01/hooks/pre-commit.sample deleted file mode 100755 index b187c4bb1f..0000000000 --- a/tests/mock/001-01/hooks/pre-commit.sample +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh -# -# An example hook script to verify what is about to be committed. -# Called by "git commit" with no arguments. The hook should -# exit with non-zero status after issuing an appropriate message if -# it wants to stop the commit. -# -# To enable this hook, rename this file to "pre-commit". - -if git rev-parse --verify HEAD >/dev/null 2>&1 -then - against=HEAD -else - # Initial commit: diff against an empty tree object - against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 -fi - -# If you want to allow non-ascii filenames set this variable to true. -allownonascii=$(git config hooks.allownonascii) - -# Cross platform projects tend to avoid non-ascii filenames; prevent -# them from being added to the repository. We exploit the fact that the -# printable range starts at the space character and ends with tilde. -if [ "$allownonascii" != "true" ] && - # Note that the use of brackets around a tr range is ok here, (it's - # even required, for portability to Solaris 10's /usr/bin/tr), since - # the square bracket bytes happen to fall in the designated range. - test "$(git diff --cached --name-only --diff-filter=A -z $against | - LC_ALL=C tr -d '[ -~]\0')" -then - echo "Error: Attempt to add a non-ascii file name." - echo - echo "This can cause problems if you want to work" - echo "with people on other platforms." - echo - echo "To be portable it is advisable to rename the file ..." - echo - echo "If you know what you are doing you can disable this" - echo "check using:" - echo - echo " git config hooks.allownonascii true" - echo - exit 1 -fi - -exec git diff-index --check --cached $against -- diff --git a/tests/mock/001-01/hooks/pre-rebase.sample b/tests/mock/001-01/hooks/pre-rebase.sample deleted file mode 100755 index 9773ed4cb2..0000000000 --- a/tests/mock/001-01/hooks/pre-rebase.sample +++ /dev/null @@ -1,169 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2006, 2008 Junio C Hamano -# -# The "pre-rebase" hook is run just before "git rebase" starts doing -# its job, and can prevent the command from running by exiting with -# non-zero status. -# -# The hook is called with the following parameters: -# -# $1 -- the upstream the series was forked from. -# $2 -- the branch being rebased (or empty when rebasing the current branch). -# -# This sample shows how to prevent topic branches that are already -# merged to 'next' branch from getting rebased, because allowing it -# would result in rebasing already published history. - -publish=next -basebranch="$1" -if test "$#" = 2 -then - topic="refs/heads/$2" -else - topic=`git symbolic-ref HEAD` || - exit 0 ;# we do not interrupt rebasing detached HEAD -fi - -case "$topic" in -refs/heads/??/*) - ;; -*) - exit 0 ;# we do not interrupt others. - ;; -esac - -# Now we are dealing with a topic branch being rebased -# on top of master. Is it OK to rebase it? - -# Does the topic really exist? -git show-ref -q "$topic" || { - echo >&2 "No such branch $topic" - exit 1 -} - -# Is topic fully merged to master? -not_in_master=`git rev-list --pretty=oneline ^master "$topic"` -if test -z "$not_in_master" -then - echo >&2 "$topic is fully merged to master; better remove it." - exit 1 ;# we could allow it, but there is no point. -fi - -# Is topic ever merged to next? If so you should not be rebasing it. -only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` -only_next_2=`git rev-list ^master ${publish} | sort` -if test "$only_next_1" = "$only_next_2" -then - not_in_topic=`git rev-list "^$topic" master` - if test -z "$not_in_topic" - then - echo >&2 "$topic is already up-to-date with master" - exit 1 ;# we could allow it, but there is no point. - else - exit 0 - fi -else - not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` - /usr/bin/perl -e ' - my $topic = $ARGV[0]; - my $msg = "* $topic has commits already merged to public branch:\n"; - my (%not_in_next) = map { - /^([0-9a-f]+) /; - ($1 => 1); - } split(/\n/, $ARGV[1]); - for my $elem (map { - /^([0-9a-f]+) (.*)$/; - [$1 => $2]; - } split(/\n/, $ARGV[2])) { - if (!exists $not_in_next{$elem->[0]}) { - if ($msg) { - print STDERR $msg; - undef $msg; - } - print STDERR " $elem->[1]\n"; - } - } - ' "$topic" "$not_in_next" "$not_in_master" - exit 1 -fi - -exit 0 - -################################################################ - -This sample hook safeguards topic branches that have been -published from being rewound. - -The workflow assumed here is: - - * Once a topic branch forks from "master", "master" is never - merged into it again (either directly or indirectly). - - * Once a topic branch is fully cooked and merged into "master", - it is deleted. If you need to build on top of it to correct - earlier mistakes, a new topic branch is created by forking at - the tip of the "master". This is not strictly necessary, but - it makes it easier to keep your history simple. - - * Whenever you need to test or publish your changes to topic - branches, merge them into "next" branch. - -The script, being an example, hardcodes the publish branch name -to be "next", but it is trivial to make it configurable via -$GIT_DIR/config mechanism. - -With this workflow, you would want to know: - -(1) ... if a topic branch has ever been merged to "next". Young - topic branches can have stupid mistakes you would rather - clean up before publishing, and things that have not been - merged into other branches can be easily rebased without - affecting other people. But once it is published, you would - not want to rewind it. - -(2) ... if a topic branch has been fully merged to "master". - Then you can delete it. More importantly, you should not - build on top of it -- other people may already want to - change things related to the topic as patches against your - "master", so if you need further changes, it is better to - fork the topic (perhaps with the same name) afresh from the - tip of "master". - -Let's look at this example: - - o---o---o---o---o---o---o---o---o---o "next" - / / / / - / a---a---b A / / - / / / / - / / c---c---c---c B / - / / / \ / - / / / b---b C \ / - / / / / \ / - ---o---o---o---o---o---o---o---o---o---o---o "master" - - -A, B and C are topic branches. - - * A has one fix since it was merged up to "next". - - * B has finished. It has been fully merged up to "master" and "next", - and is ready to be deleted. - - * C has not merged to "next" at all. - -We would want to allow C to be rebased, refuse A, and encourage -B to be deleted. - -To compute (1): - - git rev-list ^master ^topic next - git rev-list ^master next - - if these match, topic has not merged in next at all. - -To compute (2): - - git rev-list master..topic - - if this is empty, it is fully merged to "master". diff --git a/tests/mock/001-01/hooks/prepare-commit-msg.sample b/tests/mock/001-01/hooks/prepare-commit-msg.sample deleted file mode 100755 index f093a02ec4..0000000000 --- a/tests/mock/001-01/hooks/prepare-commit-msg.sample +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh -# -# An example hook script to prepare the commit log message. -# Called by "git commit" with the name of the file that has the -# commit message, followed by the description of the commit -# message's source. The hook's purpose is to edit the commit -# message file. If the hook fails with a non-zero status, -# the commit is aborted. -# -# To enable this hook, rename this file to "prepare-commit-msg". - -# This hook includes three examples. The first comments out the -# "Conflicts:" part of a merge commit. -# -# The second includes the output of "git diff --name-status -r" -# into the message, just before the "git status" output. It is -# commented because it doesn't cope with --amend or with squashed -# commits. -# -# The third example adds a Signed-off-by line to the message, that can -# still be edited. This is rarely a good idea. - -case "$2,$3" in - merge,) - /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; - -# ,|template,) -# /usr/bin/perl -i.bak -pe ' -# print "\n" . `git diff --cached --name-status -r` -# if /^#/ && $first++ == 0' "$1" ;; - - *) ;; -esac - -# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') -# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" diff --git a/tests/mock/001-01/hooks/update.sample b/tests/mock/001-01/hooks/update.sample deleted file mode 100755 index 71ab04edc0..0000000000 --- a/tests/mock/001-01/hooks/update.sample +++ /dev/null @@ -1,128 +0,0 @@ -#!/bin/sh -# -# An example hook script to blocks unannotated tags from entering. -# Called by "git receive-pack" with arguments: refname sha1-old sha1-new -# -# To enable this hook, rename this file to "update". -# -# Config -# ------ -# hooks.allowunannotated -# This boolean sets whether unannotated tags will be allowed into the -# repository. By default they won't be. -# hooks.allowdeletetag -# This boolean sets whether deleting tags will be allowed in the -# repository. By default they won't be. -# hooks.allowmodifytag -# This boolean sets whether a tag may be modified after creation. By default -# it won't be. -# hooks.allowdeletebranch -# This boolean sets whether deleting branches will be allowed in the -# repository. By default they won't be. -# hooks.denycreatebranch -# This boolean sets whether remotely creating branches will be denied -# in the repository. By default this is allowed. -# - -# --- Command line -refname="$1" -oldrev="$2" -newrev="$3" - -# --- Safety check -if [ -z "$GIT_DIR" ]; then - echo "Don't run this script from the command line." >&2 - echo " (if you want, you could supply GIT_DIR then run" >&2 - echo " $0 )" >&2 - exit 1 -fi - -if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then - echo "Usage: $0 " >&2 - exit 1 -fi - -# --- Config -allowunannotated=$(git config --bool hooks.allowunannotated) -allowdeletebranch=$(git config --bool hooks.allowdeletebranch) -denycreatebranch=$(git config --bool hooks.denycreatebranch) -allowdeletetag=$(git config --bool hooks.allowdeletetag) -allowmodifytag=$(git config --bool hooks.allowmodifytag) - -# check for no description -projectdesc=$(sed -e '1q' "$GIT_DIR/description") -case "$projectdesc" in -"Unnamed repository"* | "") - echo "*** Project description file hasn't been set" >&2 - exit 1 - ;; -esac - -# --- Check types -# if $newrev is 0000...0000, it's a commit to delete a ref. -zero="0000000000000000000000000000000000000000" -if [ "$newrev" = "$zero" ]; then - newrev_type=delete -else - newrev_type=$(git cat-file -t $newrev) -fi - -case "$refname","$newrev_type" in - refs/tags/*,commit) - # un-annotated tag - short_refname=${refname##refs/tags/} - if [ "$allowunannotated" != "true" ]; then - echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 - echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 - exit 1 - fi - ;; - refs/tags/*,delete) - # delete tag - if [ "$allowdeletetag" != "true" ]; then - echo "*** Deleting a tag is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/tags/*,tag) - # annotated tag - if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 - then - echo "*** Tag '$refname' already exists." >&2 - echo "*** Modifying a tag is not allowed in this repository." >&2 - exit 1 - fi - ;; - refs/heads/*,commit) - # branch - if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then - echo "*** Creating a branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/heads/*,delete) - # delete branch - if [ "$allowdeletebranch" != "true" ]; then - echo "*** Deleting a branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/remotes/*,commit) - # tracking branch - ;; - refs/remotes/*,delete) - # delete tracking branch - if [ "$allowdeletebranch" != "true" ]; then - echo "*** Deleting a tracking branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - *) - # Anything else (is there anything else?) - echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 - exit 1 - ;; -esac - -# --- Finished -exit 0 diff --git a/tests/mock/001-01/info/exclude b/tests/mock/001-01/info/exclude deleted file mode 100644 index a5196d1be8..0000000000 --- a/tests/mock/001-01/info/exclude +++ /dev/null @@ -1,6 +0,0 @@ -# git ls-files --others --exclude-from=.git/info/exclude -# Lines that start with '#' are comments. -# For a project mostly in C, the following would be a good set of -# exclude patterns (uncomment them if you want to use them): -# *.[oa] -# *~ diff --git a/tests/mock/001-01/objects/55/7db03de997c86a4a028e1ebd3a1ceb225be238 b/tests/mock/001-01/objects/55/7db03de997c86a4a028e1ebd3a1ceb225be238 deleted file mode 100644 index 2cbc51b51f..0000000000 Binary files a/tests/mock/001-01/objects/55/7db03de997c86a4a028e1ebd3a1ceb225be238 and /dev/null differ diff --git a/tests/mock/001-01/objects/67/dc4302383b2715f4e0b8c41840eb05b1873697 b/tests/mock/001-01/objects/67/dc4302383b2715f4e0b8c41840eb05b1873697 deleted file mode 100644 index 527a79413f..0000000000 Binary files a/tests/mock/001-01/objects/67/dc4302383b2715f4e0b8c41840eb05b1873697 and /dev/null differ diff --git a/tests/mock/001-01/objects/ab/68c54212af15d3545c41057e3a8f2f9ff6fd0d b/tests/mock/001-01/objects/ab/68c54212af15d3545c41057e3a8f2f9ff6fd0d deleted file mode 100644 index 73d6d1640c..0000000000 Binary files a/tests/mock/001-01/objects/ab/68c54212af15d3545c41057e3a8f2f9ff6fd0d and /dev/null differ diff --git a/tests/mock/001-01/packed-refs b/tests/mock/001-01/packed-refs deleted file mode 100644 index 1fc364da10..0000000000 --- a/tests/mock/001-01/packed-refs +++ /dev/null @@ -1,2 +0,0 @@ -# pack-refs with: peeled -ab68c54212af15d3545c41057e3a8f2f9ff6fd0d refs/heads/master diff --git a/tests/mock/001-01/refs/heads/.gitkeep b/tests/mock/001-01/refs/heads/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/mock/001-02/HEAD b/tests/mock/001-02/HEAD deleted file mode 100644 index cb089cd89a..0000000000 --- a/tests/mock/001-02/HEAD +++ /dev/null @@ -1 +0,0 @@ -ref: refs/heads/master diff --git a/tests/mock/001-02/config b/tests/mock/001-02/config deleted file mode 100644 index cb3402cf5d..0000000000 --- a/tests/mock/001-02/config +++ /dev/null @@ -1,7 +0,0 @@ -[core] - repositoryformatversion = 0 - filemode = true - bare = true - ignorecase = true -[remote "origin"] - url = /Users/chobie/src/php-git2/tests/mock/tmp diff --git a/tests/mock/001-02/description b/tests/mock/001-02/description deleted file mode 100644 index 498b267a8c..0000000000 --- a/tests/mock/001-02/description +++ /dev/null @@ -1 +0,0 @@ -Unnamed repository; edit this file 'description' to name the repository. diff --git a/tests/mock/001-02/hooks/applypatch-msg.sample b/tests/mock/001-02/hooks/applypatch-msg.sample deleted file mode 100755 index 8b2a2fe84f..0000000000 --- a/tests/mock/001-02/hooks/applypatch-msg.sample +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -# -# An example hook script to check the commit log message taken by -# applypatch from an e-mail message. -# -# The hook should exit with non-zero status after issuing an -# appropriate message if it wants to stop the commit. The hook is -# allowed to edit the commit message file. -# -# To enable this hook, rename this file to "applypatch-msg". - -. git-sh-setup -test -x "$GIT_DIR/hooks/commit-msg" && - exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} -: diff --git a/tests/mock/001-02/hooks/commit-msg.sample b/tests/mock/001-02/hooks/commit-msg.sample deleted file mode 100755 index b58d1184a9..0000000000 --- a/tests/mock/001-02/hooks/commit-msg.sample +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -# -# An example hook script to check the commit log message. -# Called by "git commit" with one argument, the name of the file -# that has the commit message. The hook should exit with non-zero -# status after issuing an appropriate message if it wants to stop the -# commit. The hook is allowed to edit the commit message file. -# -# To enable this hook, rename this file to "commit-msg". - -# Uncomment the below to add a Signed-off-by line to the message. -# Doing this in a hook is a bad idea in general, but the prepare-commit-msg -# hook is more suited to it. -# -# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') -# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" - -# This example catches duplicate Signed-off-by lines. - -test "" = "$(grep '^Signed-off-by: ' "$1" | - sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { - echo >&2 Duplicate Signed-off-by lines. - exit 1 -} diff --git a/tests/mock/001-02/hooks/post-commit.sample b/tests/mock/001-02/hooks/post-commit.sample deleted file mode 100755 index 22668216a3..0000000000 --- a/tests/mock/001-02/hooks/post-commit.sample +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# -# An example hook script that is called after a successful -# commit is made. -# -# To enable this hook, rename this file to "post-commit". - -: Nothing diff --git a/tests/mock/001-02/hooks/post-receive.sample b/tests/mock/001-02/hooks/post-receive.sample deleted file mode 100755 index 7a83e17ab5..0000000000 --- a/tests/mock/001-02/hooks/post-receive.sample +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -# -# An example hook script for the "post-receive" event. -# -# The "post-receive" script is run after receive-pack has accepted a pack -# and the repository has been updated. It is passed arguments in through -# stdin in the form -# -# For example: -# aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master -# -# see contrib/hooks/ for a sample, or uncomment the next line and -# rename the file to "post-receive". - -#. /usr/share/doc/git-core/contrib/hooks/post-receive-email diff --git a/tests/mock/001-02/hooks/post-update.sample b/tests/mock/001-02/hooks/post-update.sample deleted file mode 100755 index ec17ec1939..0000000000 --- a/tests/mock/001-02/hooks/post-update.sample +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# -# An example hook script to prepare a packed repository for use over -# dumb transports. -# -# To enable this hook, rename this file to "post-update". - -exec git update-server-info diff --git a/tests/mock/001-02/hooks/pre-applypatch.sample b/tests/mock/001-02/hooks/pre-applypatch.sample deleted file mode 100755 index b1f187c2e9..0000000000 --- a/tests/mock/001-02/hooks/pre-applypatch.sample +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# -# An example hook script to verify what is about to be committed -# by applypatch from an e-mail message. -# -# The hook should exit with non-zero status after issuing an -# appropriate message if it wants to stop the commit. -# -# To enable this hook, rename this file to "pre-applypatch". - -. git-sh-setup -test -x "$GIT_DIR/hooks/pre-commit" && - exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} -: diff --git a/tests/mock/001-02/hooks/pre-commit.sample b/tests/mock/001-02/hooks/pre-commit.sample deleted file mode 100755 index b187c4bb1f..0000000000 --- a/tests/mock/001-02/hooks/pre-commit.sample +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh -# -# An example hook script to verify what is about to be committed. -# Called by "git commit" with no arguments. The hook should -# exit with non-zero status after issuing an appropriate message if -# it wants to stop the commit. -# -# To enable this hook, rename this file to "pre-commit". - -if git rev-parse --verify HEAD >/dev/null 2>&1 -then - against=HEAD -else - # Initial commit: diff against an empty tree object - against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 -fi - -# If you want to allow non-ascii filenames set this variable to true. -allownonascii=$(git config hooks.allownonascii) - -# Cross platform projects tend to avoid non-ascii filenames; prevent -# them from being added to the repository. We exploit the fact that the -# printable range starts at the space character and ends with tilde. -if [ "$allownonascii" != "true" ] && - # Note that the use of brackets around a tr range is ok here, (it's - # even required, for portability to Solaris 10's /usr/bin/tr), since - # the square bracket bytes happen to fall in the designated range. - test "$(git diff --cached --name-only --diff-filter=A -z $against | - LC_ALL=C tr -d '[ -~]\0')" -then - echo "Error: Attempt to add a non-ascii file name." - echo - echo "This can cause problems if you want to work" - echo "with people on other platforms." - echo - echo "To be portable it is advisable to rename the file ..." - echo - echo "If you know what you are doing you can disable this" - echo "check using:" - echo - echo " git config hooks.allownonascii true" - echo - exit 1 -fi - -exec git diff-index --check --cached $against -- diff --git a/tests/mock/001-02/hooks/pre-rebase.sample b/tests/mock/001-02/hooks/pre-rebase.sample deleted file mode 100755 index 9773ed4cb2..0000000000 --- a/tests/mock/001-02/hooks/pre-rebase.sample +++ /dev/null @@ -1,169 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2006, 2008 Junio C Hamano -# -# The "pre-rebase" hook is run just before "git rebase" starts doing -# its job, and can prevent the command from running by exiting with -# non-zero status. -# -# The hook is called with the following parameters: -# -# $1 -- the upstream the series was forked from. -# $2 -- the branch being rebased (or empty when rebasing the current branch). -# -# This sample shows how to prevent topic branches that are already -# merged to 'next' branch from getting rebased, because allowing it -# would result in rebasing already published history. - -publish=next -basebranch="$1" -if test "$#" = 2 -then - topic="refs/heads/$2" -else - topic=`git symbolic-ref HEAD` || - exit 0 ;# we do not interrupt rebasing detached HEAD -fi - -case "$topic" in -refs/heads/??/*) - ;; -*) - exit 0 ;# we do not interrupt others. - ;; -esac - -# Now we are dealing with a topic branch being rebased -# on top of master. Is it OK to rebase it? - -# Does the topic really exist? -git show-ref -q "$topic" || { - echo >&2 "No such branch $topic" - exit 1 -} - -# Is topic fully merged to master? -not_in_master=`git rev-list --pretty=oneline ^master "$topic"` -if test -z "$not_in_master" -then - echo >&2 "$topic is fully merged to master; better remove it." - exit 1 ;# we could allow it, but there is no point. -fi - -# Is topic ever merged to next? If so you should not be rebasing it. -only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` -only_next_2=`git rev-list ^master ${publish} | sort` -if test "$only_next_1" = "$only_next_2" -then - not_in_topic=`git rev-list "^$topic" master` - if test -z "$not_in_topic" - then - echo >&2 "$topic is already up-to-date with master" - exit 1 ;# we could allow it, but there is no point. - else - exit 0 - fi -else - not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` - /usr/bin/perl -e ' - my $topic = $ARGV[0]; - my $msg = "* $topic has commits already merged to public branch:\n"; - my (%not_in_next) = map { - /^([0-9a-f]+) /; - ($1 => 1); - } split(/\n/, $ARGV[1]); - for my $elem (map { - /^([0-9a-f]+) (.*)$/; - [$1 => $2]; - } split(/\n/, $ARGV[2])) { - if (!exists $not_in_next{$elem->[0]}) { - if ($msg) { - print STDERR $msg; - undef $msg; - } - print STDERR " $elem->[1]\n"; - } - } - ' "$topic" "$not_in_next" "$not_in_master" - exit 1 -fi - -exit 0 - -################################################################ - -This sample hook safeguards topic branches that have been -published from being rewound. - -The workflow assumed here is: - - * Once a topic branch forks from "master", "master" is never - merged into it again (either directly or indirectly). - - * Once a topic branch is fully cooked and merged into "master", - it is deleted. If you need to build on top of it to correct - earlier mistakes, a new topic branch is created by forking at - the tip of the "master". This is not strictly necessary, but - it makes it easier to keep your history simple. - - * Whenever you need to test or publish your changes to topic - branches, merge them into "next" branch. - -The script, being an example, hardcodes the publish branch name -to be "next", but it is trivial to make it configurable via -$GIT_DIR/config mechanism. - -With this workflow, you would want to know: - -(1) ... if a topic branch has ever been merged to "next". Young - topic branches can have stupid mistakes you would rather - clean up before publishing, and things that have not been - merged into other branches can be easily rebased without - affecting other people. But once it is published, you would - not want to rewind it. - -(2) ... if a topic branch has been fully merged to "master". - Then you can delete it. More importantly, you should not - build on top of it -- other people may already want to - change things related to the topic as patches against your - "master", so if you need further changes, it is better to - fork the topic (perhaps with the same name) afresh from the - tip of "master". - -Let's look at this example: - - o---o---o---o---o---o---o---o---o---o "next" - / / / / - / a---a---b A / / - / / / / - / / c---c---c---c B / - / / / \ / - / / / b---b C \ / - / / / / \ / - ---o---o---o---o---o---o---o---o---o---o---o "master" - - -A, B and C are topic branches. - - * A has one fix since it was merged up to "next". - - * B has finished. It has been fully merged up to "master" and "next", - and is ready to be deleted. - - * C has not merged to "next" at all. - -We would want to allow C to be rebased, refuse A, and encourage -B to be deleted. - -To compute (1): - - git rev-list ^master ^topic next - git rev-list ^master next - - if these match, topic has not merged in next at all. - -To compute (2): - - git rev-list master..topic - - if this is empty, it is fully merged to "master". diff --git a/tests/mock/001-02/hooks/prepare-commit-msg.sample b/tests/mock/001-02/hooks/prepare-commit-msg.sample deleted file mode 100755 index f093a02ec4..0000000000 --- a/tests/mock/001-02/hooks/prepare-commit-msg.sample +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh -# -# An example hook script to prepare the commit log message. -# Called by "git commit" with the name of the file that has the -# commit message, followed by the description of the commit -# message's source. The hook's purpose is to edit the commit -# message file. If the hook fails with a non-zero status, -# the commit is aborted. -# -# To enable this hook, rename this file to "prepare-commit-msg". - -# This hook includes three examples. The first comments out the -# "Conflicts:" part of a merge commit. -# -# The second includes the output of "git diff --name-status -r" -# into the message, just before the "git status" output. It is -# commented because it doesn't cope with --amend or with squashed -# commits. -# -# The third example adds a Signed-off-by line to the message, that can -# still be edited. This is rarely a good idea. - -case "$2,$3" in - merge,) - /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; - -# ,|template,) -# /usr/bin/perl -i.bak -pe ' -# print "\n" . `git diff --cached --name-status -r` -# if /^#/ && $first++ == 0' "$1" ;; - - *) ;; -esac - -# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') -# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" diff --git a/tests/mock/001-02/hooks/update.sample b/tests/mock/001-02/hooks/update.sample deleted file mode 100755 index 71ab04edc0..0000000000 --- a/tests/mock/001-02/hooks/update.sample +++ /dev/null @@ -1,128 +0,0 @@ -#!/bin/sh -# -# An example hook script to blocks unannotated tags from entering. -# Called by "git receive-pack" with arguments: refname sha1-old sha1-new -# -# To enable this hook, rename this file to "update". -# -# Config -# ------ -# hooks.allowunannotated -# This boolean sets whether unannotated tags will be allowed into the -# repository. By default they won't be. -# hooks.allowdeletetag -# This boolean sets whether deleting tags will be allowed in the -# repository. By default they won't be. -# hooks.allowmodifytag -# This boolean sets whether a tag may be modified after creation. By default -# it won't be. -# hooks.allowdeletebranch -# This boolean sets whether deleting branches will be allowed in the -# repository. By default they won't be. -# hooks.denycreatebranch -# This boolean sets whether remotely creating branches will be denied -# in the repository. By default this is allowed. -# - -# --- Command line -refname="$1" -oldrev="$2" -newrev="$3" - -# --- Safety check -if [ -z "$GIT_DIR" ]; then - echo "Don't run this script from the command line." >&2 - echo " (if you want, you could supply GIT_DIR then run" >&2 - echo " $0 )" >&2 - exit 1 -fi - -if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then - echo "Usage: $0 " >&2 - exit 1 -fi - -# --- Config -allowunannotated=$(git config --bool hooks.allowunannotated) -allowdeletebranch=$(git config --bool hooks.allowdeletebranch) -denycreatebranch=$(git config --bool hooks.denycreatebranch) -allowdeletetag=$(git config --bool hooks.allowdeletetag) -allowmodifytag=$(git config --bool hooks.allowmodifytag) - -# check for no description -projectdesc=$(sed -e '1q' "$GIT_DIR/description") -case "$projectdesc" in -"Unnamed repository"* | "") - echo "*** Project description file hasn't been set" >&2 - exit 1 - ;; -esac - -# --- Check types -# if $newrev is 0000...0000, it's a commit to delete a ref. -zero="0000000000000000000000000000000000000000" -if [ "$newrev" = "$zero" ]; then - newrev_type=delete -else - newrev_type=$(git cat-file -t $newrev) -fi - -case "$refname","$newrev_type" in - refs/tags/*,commit) - # un-annotated tag - short_refname=${refname##refs/tags/} - if [ "$allowunannotated" != "true" ]; then - echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 - echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 - exit 1 - fi - ;; - refs/tags/*,delete) - # delete tag - if [ "$allowdeletetag" != "true" ]; then - echo "*** Deleting a tag is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/tags/*,tag) - # annotated tag - if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 - then - echo "*** Tag '$refname' already exists." >&2 - echo "*** Modifying a tag is not allowed in this repository." >&2 - exit 1 - fi - ;; - refs/heads/*,commit) - # branch - if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then - echo "*** Creating a branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/heads/*,delete) - # delete branch - if [ "$allowdeletebranch" != "true" ]; then - echo "*** Deleting a branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/remotes/*,commit) - # tracking branch - ;; - refs/remotes/*,delete) - # delete tracking branch - if [ "$allowdeletebranch" != "true" ]; then - echo "*** Deleting a tracking branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - *) - # Anything else (is there anything else?) - echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 - exit 1 - ;; -esac - -# --- Finished -exit 0 diff --git a/tests/mock/001-02/info/exclude b/tests/mock/001-02/info/exclude deleted file mode 100644 index a5196d1be8..0000000000 --- a/tests/mock/001-02/info/exclude +++ /dev/null @@ -1,6 +0,0 @@ -# git ls-files --others --exclude-from=.git/info/exclude -# Lines that start with '#' are comments. -# For a project mostly in C, the following would be a good set of -# exclude patterns (uncomment them if you want to use them): -# *.[oa] -# *~ diff --git a/tests/mock/001-02/packed-refs b/tests/mock/001-02/packed-refs deleted file mode 100644 index 1fc364da10..0000000000 --- a/tests/mock/001-02/packed-refs +++ /dev/null @@ -1,2 +0,0 @@ -# pack-refs with: peeled -ab68c54212af15d3545c41057e3a8f2f9ff6fd0d refs/heads/master diff --git a/tests/mock/001-02/refs/heads/.gitkeep b/tests/mock/001-02/refs/heads/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/mock/001-07/detached/HEAD b/tests/mock/001-07/detached/HEAD deleted file mode 100644 index 7a87492286..0000000000 --- a/tests/mock/001-07/detached/HEAD +++ /dev/null @@ -1 +0,0 @@ -66d2a2155270b1021c0fdc764c34e13801bd4ae4 diff --git a/tests/mock/001-07/detached/config b/tests/mock/001-07/detached/config deleted file mode 100644 index 07cb01e2c2..0000000000 --- a/tests/mock/001-07/detached/config +++ /dev/null @@ -1,7 +0,0 @@ -[core] - repositoryformatversion = 0 - filemode = true - bare = true - ignorecase = true -[remote "origin"] - url = /Users/chobie/src/php-git2/tests/mock/001-07/a diff --git a/tests/mock/001-07/detached/description b/tests/mock/001-07/detached/description deleted file mode 100644 index 498b267a8c..0000000000 --- a/tests/mock/001-07/detached/description +++ /dev/null @@ -1 +0,0 @@ -Unnamed repository; edit this file 'description' to name the repository. diff --git a/tests/mock/001-07/detached/hooks/applypatch-msg.sample b/tests/mock/001-07/detached/hooks/applypatch-msg.sample deleted file mode 100755 index 8b2a2fe84f..0000000000 --- a/tests/mock/001-07/detached/hooks/applypatch-msg.sample +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -# -# An example hook script to check the commit log message taken by -# applypatch from an e-mail message. -# -# The hook should exit with non-zero status after issuing an -# appropriate message if it wants to stop the commit. The hook is -# allowed to edit the commit message file. -# -# To enable this hook, rename this file to "applypatch-msg". - -. git-sh-setup -test -x "$GIT_DIR/hooks/commit-msg" && - exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} -: diff --git a/tests/mock/001-07/detached/hooks/commit-msg.sample b/tests/mock/001-07/detached/hooks/commit-msg.sample deleted file mode 100755 index b58d1184a9..0000000000 --- a/tests/mock/001-07/detached/hooks/commit-msg.sample +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -# -# An example hook script to check the commit log message. -# Called by "git commit" with one argument, the name of the file -# that has the commit message. The hook should exit with non-zero -# status after issuing an appropriate message if it wants to stop the -# commit. The hook is allowed to edit the commit message file. -# -# To enable this hook, rename this file to "commit-msg". - -# Uncomment the below to add a Signed-off-by line to the message. -# Doing this in a hook is a bad idea in general, but the prepare-commit-msg -# hook is more suited to it. -# -# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') -# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" - -# This example catches duplicate Signed-off-by lines. - -test "" = "$(grep '^Signed-off-by: ' "$1" | - sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { - echo >&2 Duplicate Signed-off-by lines. - exit 1 -} diff --git a/tests/mock/001-07/detached/hooks/post-commit.sample b/tests/mock/001-07/detached/hooks/post-commit.sample deleted file mode 100755 index 22668216a3..0000000000 --- a/tests/mock/001-07/detached/hooks/post-commit.sample +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# -# An example hook script that is called after a successful -# commit is made. -# -# To enable this hook, rename this file to "post-commit". - -: Nothing diff --git a/tests/mock/001-07/detached/hooks/post-receive.sample b/tests/mock/001-07/detached/hooks/post-receive.sample deleted file mode 100755 index 7a83e17ab5..0000000000 --- a/tests/mock/001-07/detached/hooks/post-receive.sample +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -# -# An example hook script for the "post-receive" event. -# -# The "post-receive" script is run after receive-pack has accepted a pack -# and the repository has been updated. It is passed arguments in through -# stdin in the form -# -# For example: -# aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master -# -# see contrib/hooks/ for a sample, or uncomment the next line and -# rename the file to "post-receive". - -#. /usr/share/doc/git-core/contrib/hooks/post-receive-email diff --git a/tests/mock/001-07/detached/hooks/post-update.sample b/tests/mock/001-07/detached/hooks/post-update.sample deleted file mode 100755 index ec17ec1939..0000000000 --- a/tests/mock/001-07/detached/hooks/post-update.sample +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# -# An example hook script to prepare a packed repository for use over -# dumb transports. -# -# To enable this hook, rename this file to "post-update". - -exec git update-server-info diff --git a/tests/mock/001-07/detached/hooks/pre-applypatch.sample b/tests/mock/001-07/detached/hooks/pre-applypatch.sample deleted file mode 100755 index b1f187c2e9..0000000000 --- a/tests/mock/001-07/detached/hooks/pre-applypatch.sample +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# -# An example hook script to verify what is about to be committed -# by applypatch from an e-mail message. -# -# The hook should exit with non-zero status after issuing an -# appropriate message if it wants to stop the commit. -# -# To enable this hook, rename this file to "pre-applypatch". - -. git-sh-setup -test -x "$GIT_DIR/hooks/pre-commit" && - exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} -: diff --git a/tests/mock/001-07/detached/hooks/pre-commit.sample b/tests/mock/001-07/detached/hooks/pre-commit.sample deleted file mode 100755 index b187c4bb1f..0000000000 --- a/tests/mock/001-07/detached/hooks/pre-commit.sample +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh -# -# An example hook script to verify what is about to be committed. -# Called by "git commit" with no arguments. The hook should -# exit with non-zero status after issuing an appropriate message if -# it wants to stop the commit. -# -# To enable this hook, rename this file to "pre-commit". - -if git rev-parse --verify HEAD >/dev/null 2>&1 -then - against=HEAD -else - # Initial commit: diff against an empty tree object - against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 -fi - -# If you want to allow non-ascii filenames set this variable to true. -allownonascii=$(git config hooks.allownonascii) - -# Cross platform projects tend to avoid non-ascii filenames; prevent -# them from being added to the repository. We exploit the fact that the -# printable range starts at the space character and ends with tilde. -if [ "$allownonascii" != "true" ] && - # Note that the use of brackets around a tr range is ok here, (it's - # even required, for portability to Solaris 10's /usr/bin/tr), since - # the square bracket bytes happen to fall in the designated range. - test "$(git diff --cached --name-only --diff-filter=A -z $against | - LC_ALL=C tr -d '[ -~]\0')" -then - echo "Error: Attempt to add a non-ascii file name." - echo - echo "This can cause problems if you want to work" - echo "with people on other platforms." - echo - echo "To be portable it is advisable to rename the file ..." - echo - echo "If you know what you are doing you can disable this" - echo "check using:" - echo - echo " git config hooks.allownonascii true" - echo - exit 1 -fi - -exec git diff-index --check --cached $against -- diff --git a/tests/mock/001-07/detached/hooks/pre-rebase.sample b/tests/mock/001-07/detached/hooks/pre-rebase.sample deleted file mode 100755 index 9773ed4cb2..0000000000 --- a/tests/mock/001-07/detached/hooks/pre-rebase.sample +++ /dev/null @@ -1,169 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2006, 2008 Junio C Hamano -# -# The "pre-rebase" hook is run just before "git rebase" starts doing -# its job, and can prevent the command from running by exiting with -# non-zero status. -# -# The hook is called with the following parameters: -# -# $1 -- the upstream the series was forked from. -# $2 -- the branch being rebased (or empty when rebasing the current branch). -# -# This sample shows how to prevent topic branches that are already -# merged to 'next' branch from getting rebased, because allowing it -# would result in rebasing already published history. - -publish=next -basebranch="$1" -if test "$#" = 2 -then - topic="refs/heads/$2" -else - topic=`git symbolic-ref HEAD` || - exit 0 ;# we do not interrupt rebasing detached HEAD -fi - -case "$topic" in -refs/heads/??/*) - ;; -*) - exit 0 ;# we do not interrupt others. - ;; -esac - -# Now we are dealing with a topic branch being rebased -# on top of master. Is it OK to rebase it? - -# Does the topic really exist? -git show-ref -q "$topic" || { - echo >&2 "No such branch $topic" - exit 1 -} - -# Is topic fully merged to master? -not_in_master=`git rev-list --pretty=oneline ^master "$topic"` -if test -z "$not_in_master" -then - echo >&2 "$topic is fully merged to master; better remove it." - exit 1 ;# we could allow it, but there is no point. -fi - -# Is topic ever merged to next? If so you should not be rebasing it. -only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` -only_next_2=`git rev-list ^master ${publish} | sort` -if test "$only_next_1" = "$only_next_2" -then - not_in_topic=`git rev-list "^$topic" master` - if test -z "$not_in_topic" - then - echo >&2 "$topic is already up-to-date with master" - exit 1 ;# we could allow it, but there is no point. - else - exit 0 - fi -else - not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` - /usr/bin/perl -e ' - my $topic = $ARGV[0]; - my $msg = "* $topic has commits already merged to public branch:\n"; - my (%not_in_next) = map { - /^([0-9a-f]+) /; - ($1 => 1); - } split(/\n/, $ARGV[1]); - for my $elem (map { - /^([0-9a-f]+) (.*)$/; - [$1 => $2]; - } split(/\n/, $ARGV[2])) { - if (!exists $not_in_next{$elem->[0]}) { - if ($msg) { - print STDERR $msg; - undef $msg; - } - print STDERR " $elem->[1]\n"; - } - } - ' "$topic" "$not_in_next" "$not_in_master" - exit 1 -fi - -exit 0 - -################################################################ - -This sample hook safeguards topic branches that have been -published from being rewound. - -The workflow assumed here is: - - * Once a topic branch forks from "master", "master" is never - merged into it again (either directly or indirectly). - - * Once a topic branch is fully cooked and merged into "master", - it is deleted. If you need to build on top of it to correct - earlier mistakes, a new topic branch is created by forking at - the tip of the "master". This is not strictly necessary, but - it makes it easier to keep your history simple. - - * Whenever you need to test or publish your changes to topic - branches, merge them into "next" branch. - -The script, being an example, hardcodes the publish branch name -to be "next", but it is trivial to make it configurable via -$GIT_DIR/config mechanism. - -With this workflow, you would want to know: - -(1) ... if a topic branch has ever been merged to "next". Young - topic branches can have stupid mistakes you would rather - clean up before publishing, and things that have not been - merged into other branches can be easily rebased without - affecting other people. But once it is published, you would - not want to rewind it. - -(2) ... if a topic branch has been fully merged to "master". - Then you can delete it. More importantly, you should not - build on top of it -- other people may already want to - change things related to the topic as patches against your - "master", so if you need further changes, it is better to - fork the topic (perhaps with the same name) afresh from the - tip of "master". - -Let's look at this example: - - o---o---o---o---o---o---o---o---o---o "next" - / / / / - / a---a---b A / / - / / / / - / / c---c---c---c B / - / / / \ / - / / / b---b C \ / - / / / / \ / - ---o---o---o---o---o---o---o---o---o---o---o "master" - - -A, B and C are topic branches. - - * A has one fix since it was merged up to "next". - - * B has finished. It has been fully merged up to "master" and "next", - and is ready to be deleted. - - * C has not merged to "next" at all. - -We would want to allow C to be rebased, refuse A, and encourage -B to be deleted. - -To compute (1): - - git rev-list ^master ^topic next - git rev-list ^master next - - if these match, topic has not merged in next at all. - -To compute (2): - - git rev-list master..topic - - if this is empty, it is fully merged to "master". diff --git a/tests/mock/001-07/detached/hooks/prepare-commit-msg.sample b/tests/mock/001-07/detached/hooks/prepare-commit-msg.sample deleted file mode 100755 index f093a02ec4..0000000000 --- a/tests/mock/001-07/detached/hooks/prepare-commit-msg.sample +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh -# -# An example hook script to prepare the commit log message. -# Called by "git commit" with the name of the file that has the -# commit message, followed by the description of the commit -# message's source. The hook's purpose is to edit the commit -# message file. If the hook fails with a non-zero status, -# the commit is aborted. -# -# To enable this hook, rename this file to "prepare-commit-msg". - -# This hook includes three examples. The first comments out the -# "Conflicts:" part of a merge commit. -# -# The second includes the output of "git diff --name-status -r" -# into the message, just before the "git status" output. It is -# commented because it doesn't cope with --amend or with squashed -# commits. -# -# The third example adds a Signed-off-by line to the message, that can -# still be edited. This is rarely a good idea. - -case "$2,$3" in - merge,) - /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; - -# ,|template,) -# /usr/bin/perl -i.bak -pe ' -# print "\n" . `git diff --cached --name-status -r` -# if /^#/ && $first++ == 0' "$1" ;; - - *) ;; -esac - -# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') -# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" diff --git a/tests/mock/001-07/detached/hooks/update.sample b/tests/mock/001-07/detached/hooks/update.sample deleted file mode 100755 index 71ab04edc0..0000000000 --- a/tests/mock/001-07/detached/hooks/update.sample +++ /dev/null @@ -1,128 +0,0 @@ -#!/bin/sh -# -# An example hook script to blocks unannotated tags from entering. -# Called by "git receive-pack" with arguments: refname sha1-old sha1-new -# -# To enable this hook, rename this file to "update". -# -# Config -# ------ -# hooks.allowunannotated -# This boolean sets whether unannotated tags will be allowed into the -# repository. By default they won't be. -# hooks.allowdeletetag -# This boolean sets whether deleting tags will be allowed in the -# repository. By default they won't be. -# hooks.allowmodifytag -# This boolean sets whether a tag may be modified after creation. By default -# it won't be. -# hooks.allowdeletebranch -# This boolean sets whether deleting branches will be allowed in the -# repository. By default they won't be. -# hooks.denycreatebranch -# This boolean sets whether remotely creating branches will be denied -# in the repository. By default this is allowed. -# - -# --- Command line -refname="$1" -oldrev="$2" -newrev="$3" - -# --- Safety check -if [ -z "$GIT_DIR" ]; then - echo "Don't run this script from the command line." >&2 - echo " (if you want, you could supply GIT_DIR then run" >&2 - echo " $0 )" >&2 - exit 1 -fi - -if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then - echo "Usage: $0 " >&2 - exit 1 -fi - -# --- Config -allowunannotated=$(git config --bool hooks.allowunannotated) -allowdeletebranch=$(git config --bool hooks.allowdeletebranch) -denycreatebranch=$(git config --bool hooks.denycreatebranch) -allowdeletetag=$(git config --bool hooks.allowdeletetag) -allowmodifytag=$(git config --bool hooks.allowmodifytag) - -# check for no description -projectdesc=$(sed -e '1q' "$GIT_DIR/description") -case "$projectdesc" in -"Unnamed repository"* | "") - echo "*** Project description file hasn't been set" >&2 - exit 1 - ;; -esac - -# --- Check types -# if $newrev is 0000...0000, it's a commit to delete a ref. -zero="0000000000000000000000000000000000000000" -if [ "$newrev" = "$zero" ]; then - newrev_type=delete -else - newrev_type=$(git cat-file -t $newrev) -fi - -case "$refname","$newrev_type" in - refs/tags/*,commit) - # un-annotated tag - short_refname=${refname##refs/tags/} - if [ "$allowunannotated" != "true" ]; then - echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 - echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 - exit 1 - fi - ;; - refs/tags/*,delete) - # delete tag - if [ "$allowdeletetag" != "true" ]; then - echo "*** Deleting a tag is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/tags/*,tag) - # annotated tag - if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 - then - echo "*** Tag '$refname' already exists." >&2 - echo "*** Modifying a tag is not allowed in this repository." >&2 - exit 1 - fi - ;; - refs/heads/*,commit) - # branch - if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then - echo "*** Creating a branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/heads/*,delete) - # delete branch - if [ "$allowdeletebranch" != "true" ]; then - echo "*** Deleting a branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/remotes/*,commit) - # tracking branch - ;; - refs/remotes/*,delete) - # delete tracking branch - if [ "$allowdeletebranch" != "true" ]; then - echo "*** Deleting a tracking branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - *) - # Anything else (is there anything else?) - echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 - exit 1 - ;; -esac - -# --- Finished -exit 0 diff --git a/tests/mock/001-07/detached/info/exclude b/tests/mock/001-07/detached/info/exclude deleted file mode 100644 index a5196d1be8..0000000000 --- a/tests/mock/001-07/detached/info/exclude +++ /dev/null @@ -1,6 +0,0 @@ -# git ls-files --others --exclude-from=.git/info/exclude -# Lines that start with '#' are comments. -# For a project mostly in C, the following would be a good set of -# exclude patterns (uncomment them if you want to use them): -# *.[oa] -# *~ diff --git a/tests/mock/001-07/detached/objects/66/d2a2155270b1021c0fdc764c34e13801bd4ae4 b/tests/mock/001-07/detached/objects/66/d2a2155270b1021c0fdc764c34e13801bd4ae4 deleted file mode 100644 index d5a5500472..0000000000 Binary files a/tests/mock/001-07/detached/objects/66/d2a2155270b1021c0fdc764c34e13801bd4ae4 and /dev/null differ diff --git a/tests/mock/001-07/detached/objects/73/cfa43b65a81d3094e9e09cd05b3710368fc304 b/tests/mock/001-07/detached/objects/73/cfa43b65a81d3094e9e09cd05b3710368fc304 deleted file mode 100644 index 1755500b6f..0000000000 Binary files a/tests/mock/001-07/detached/objects/73/cfa43b65a81d3094e9e09cd05b3710368fc304 and /dev/null differ diff --git a/tests/mock/001-07/detached/objects/c0/328dd7e4af62d858ad174db4e95871fa9f7b8f b/tests/mock/001-07/detached/objects/c0/328dd7e4af62d858ad174db4e95871fa9f7b8f deleted file mode 100644 index 949cf5363e..0000000000 Binary files a/tests/mock/001-07/detached/objects/c0/328dd7e4af62d858ad174db4e95871fa9f7b8f and /dev/null differ diff --git a/tests/mock/001-07/detached/packed-refs b/tests/mock/001-07/detached/packed-refs deleted file mode 100644 index cc94885ddd..0000000000 --- a/tests/mock/001-07/detached/packed-refs +++ /dev/null @@ -1 +0,0 @@ -# pack-refs with: peeled diff --git a/tests/mock/001-08/orphaned/HEAD b/tests/mock/001-08/orphaned/HEAD deleted file mode 100644 index df8f25d97f..0000000000 --- a/tests/mock/001-08/orphaned/HEAD +++ /dev/null @@ -1 +0,0 @@ -ref: refs/heads/nothing diff --git a/tests/mock/001-08/orphaned/config b/tests/mock/001-08/orphaned/config deleted file mode 100644 index 07cb01e2c2..0000000000 --- a/tests/mock/001-08/orphaned/config +++ /dev/null @@ -1,7 +0,0 @@ -[core] - repositoryformatversion = 0 - filemode = true - bare = true - ignorecase = true -[remote "origin"] - url = /Users/chobie/src/php-git2/tests/mock/001-07/a diff --git a/tests/mock/001-08/orphaned/description b/tests/mock/001-08/orphaned/description deleted file mode 100644 index 498b267a8c..0000000000 --- a/tests/mock/001-08/orphaned/description +++ /dev/null @@ -1 +0,0 @@ -Unnamed repository; edit this file 'description' to name the repository. diff --git a/tests/mock/001-08/orphaned/hooks/applypatch-msg.sample b/tests/mock/001-08/orphaned/hooks/applypatch-msg.sample deleted file mode 100755 index 8b2a2fe84f..0000000000 --- a/tests/mock/001-08/orphaned/hooks/applypatch-msg.sample +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -# -# An example hook script to check the commit log message taken by -# applypatch from an e-mail message. -# -# The hook should exit with non-zero status after issuing an -# appropriate message if it wants to stop the commit. The hook is -# allowed to edit the commit message file. -# -# To enable this hook, rename this file to "applypatch-msg". - -. git-sh-setup -test -x "$GIT_DIR/hooks/commit-msg" && - exec "$GIT_DIR/hooks/commit-msg" ${1+"$@"} -: diff --git a/tests/mock/001-08/orphaned/hooks/commit-msg.sample b/tests/mock/001-08/orphaned/hooks/commit-msg.sample deleted file mode 100755 index b58d1184a9..0000000000 --- a/tests/mock/001-08/orphaned/hooks/commit-msg.sample +++ /dev/null @@ -1,24 +0,0 @@ -#!/bin/sh -# -# An example hook script to check the commit log message. -# Called by "git commit" with one argument, the name of the file -# that has the commit message. The hook should exit with non-zero -# status after issuing an appropriate message if it wants to stop the -# commit. The hook is allowed to edit the commit message file. -# -# To enable this hook, rename this file to "commit-msg". - -# Uncomment the below to add a Signed-off-by line to the message. -# Doing this in a hook is a bad idea in general, but the prepare-commit-msg -# hook is more suited to it. -# -# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') -# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" - -# This example catches duplicate Signed-off-by lines. - -test "" = "$(grep '^Signed-off-by: ' "$1" | - sort | uniq -c | sed -e '/^[ ]*1[ ]/d')" || { - echo >&2 Duplicate Signed-off-by lines. - exit 1 -} diff --git a/tests/mock/001-08/orphaned/hooks/post-commit.sample b/tests/mock/001-08/orphaned/hooks/post-commit.sample deleted file mode 100755 index 22668216a3..0000000000 --- a/tests/mock/001-08/orphaned/hooks/post-commit.sample +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# -# An example hook script that is called after a successful -# commit is made. -# -# To enable this hook, rename this file to "post-commit". - -: Nothing diff --git a/tests/mock/001-08/orphaned/hooks/post-receive.sample b/tests/mock/001-08/orphaned/hooks/post-receive.sample deleted file mode 100755 index 7a83e17ab5..0000000000 --- a/tests/mock/001-08/orphaned/hooks/post-receive.sample +++ /dev/null @@ -1,15 +0,0 @@ -#!/bin/sh -# -# An example hook script for the "post-receive" event. -# -# The "post-receive" script is run after receive-pack has accepted a pack -# and the repository has been updated. It is passed arguments in through -# stdin in the form -# -# For example: -# aa453216d1b3e49e7f6f98441fa56946ddcd6a20 68f7abf4e6f922807889f52bc043ecd31b79f814 refs/heads/master -# -# see contrib/hooks/ for a sample, or uncomment the next line and -# rename the file to "post-receive". - -#. /usr/share/doc/git-core/contrib/hooks/post-receive-email diff --git a/tests/mock/001-08/orphaned/hooks/post-update.sample b/tests/mock/001-08/orphaned/hooks/post-update.sample deleted file mode 100755 index ec17ec1939..0000000000 --- a/tests/mock/001-08/orphaned/hooks/post-update.sample +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -# -# An example hook script to prepare a packed repository for use over -# dumb transports. -# -# To enable this hook, rename this file to "post-update". - -exec git update-server-info diff --git a/tests/mock/001-08/orphaned/hooks/pre-applypatch.sample b/tests/mock/001-08/orphaned/hooks/pre-applypatch.sample deleted file mode 100755 index b1f187c2e9..0000000000 --- a/tests/mock/001-08/orphaned/hooks/pre-applypatch.sample +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh -# -# An example hook script to verify what is about to be committed -# by applypatch from an e-mail message. -# -# The hook should exit with non-zero status after issuing an -# appropriate message if it wants to stop the commit. -# -# To enable this hook, rename this file to "pre-applypatch". - -. git-sh-setup -test -x "$GIT_DIR/hooks/pre-commit" && - exec "$GIT_DIR/hooks/pre-commit" ${1+"$@"} -: diff --git a/tests/mock/001-08/orphaned/hooks/pre-commit.sample b/tests/mock/001-08/orphaned/hooks/pre-commit.sample deleted file mode 100755 index b187c4bb1f..0000000000 --- a/tests/mock/001-08/orphaned/hooks/pre-commit.sample +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/sh -# -# An example hook script to verify what is about to be committed. -# Called by "git commit" with no arguments. The hook should -# exit with non-zero status after issuing an appropriate message if -# it wants to stop the commit. -# -# To enable this hook, rename this file to "pre-commit". - -if git rev-parse --verify HEAD >/dev/null 2>&1 -then - against=HEAD -else - # Initial commit: diff against an empty tree object - against=4b825dc642cb6eb9a060e54bf8d69288fbee4904 -fi - -# If you want to allow non-ascii filenames set this variable to true. -allownonascii=$(git config hooks.allownonascii) - -# Cross platform projects tend to avoid non-ascii filenames; prevent -# them from being added to the repository. We exploit the fact that the -# printable range starts at the space character and ends with tilde. -if [ "$allownonascii" != "true" ] && - # Note that the use of brackets around a tr range is ok here, (it's - # even required, for portability to Solaris 10's /usr/bin/tr), since - # the square bracket bytes happen to fall in the designated range. - test "$(git diff --cached --name-only --diff-filter=A -z $against | - LC_ALL=C tr -d '[ -~]\0')" -then - echo "Error: Attempt to add a non-ascii file name." - echo - echo "This can cause problems if you want to work" - echo "with people on other platforms." - echo - echo "To be portable it is advisable to rename the file ..." - echo - echo "If you know what you are doing you can disable this" - echo "check using:" - echo - echo " git config hooks.allownonascii true" - echo - exit 1 -fi - -exec git diff-index --check --cached $against -- diff --git a/tests/mock/001-08/orphaned/hooks/pre-rebase.sample b/tests/mock/001-08/orphaned/hooks/pre-rebase.sample deleted file mode 100755 index 9773ed4cb2..0000000000 --- a/tests/mock/001-08/orphaned/hooks/pre-rebase.sample +++ /dev/null @@ -1,169 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2006, 2008 Junio C Hamano -# -# The "pre-rebase" hook is run just before "git rebase" starts doing -# its job, and can prevent the command from running by exiting with -# non-zero status. -# -# The hook is called with the following parameters: -# -# $1 -- the upstream the series was forked from. -# $2 -- the branch being rebased (or empty when rebasing the current branch). -# -# This sample shows how to prevent topic branches that are already -# merged to 'next' branch from getting rebased, because allowing it -# would result in rebasing already published history. - -publish=next -basebranch="$1" -if test "$#" = 2 -then - topic="refs/heads/$2" -else - topic=`git symbolic-ref HEAD` || - exit 0 ;# we do not interrupt rebasing detached HEAD -fi - -case "$topic" in -refs/heads/??/*) - ;; -*) - exit 0 ;# we do not interrupt others. - ;; -esac - -# Now we are dealing with a topic branch being rebased -# on top of master. Is it OK to rebase it? - -# Does the topic really exist? -git show-ref -q "$topic" || { - echo >&2 "No such branch $topic" - exit 1 -} - -# Is topic fully merged to master? -not_in_master=`git rev-list --pretty=oneline ^master "$topic"` -if test -z "$not_in_master" -then - echo >&2 "$topic is fully merged to master; better remove it." - exit 1 ;# we could allow it, but there is no point. -fi - -# Is topic ever merged to next? If so you should not be rebasing it. -only_next_1=`git rev-list ^master "^$topic" ${publish} | sort` -only_next_2=`git rev-list ^master ${publish} | sort` -if test "$only_next_1" = "$only_next_2" -then - not_in_topic=`git rev-list "^$topic" master` - if test -z "$not_in_topic" - then - echo >&2 "$topic is already up-to-date with master" - exit 1 ;# we could allow it, but there is no point. - else - exit 0 - fi -else - not_in_next=`git rev-list --pretty=oneline ^${publish} "$topic"` - /usr/bin/perl -e ' - my $topic = $ARGV[0]; - my $msg = "* $topic has commits already merged to public branch:\n"; - my (%not_in_next) = map { - /^([0-9a-f]+) /; - ($1 => 1); - } split(/\n/, $ARGV[1]); - for my $elem (map { - /^([0-9a-f]+) (.*)$/; - [$1 => $2]; - } split(/\n/, $ARGV[2])) { - if (!exists $not_in_next{$elem->[0]}) { - if ($msg) { - print STDERR $msg; - undef $msg; - } - print STDERR " $elem->[1]\n"; - } - } - ' "$topic" "$not_in_next" "$not_in_master" - exit 1 -fi - -exit 0 - -################################################################ - -This sample hook safeguards topic branches that have been -published from being rewound. - -The workflow assumed here is: - - * Once a topic branch forks from "master", "master" is never - merged into it again (either directly or indirectly). - - * Once a topic branch is fully cooked and merged into "master", - it is deleted. If you need to build on top of it to correct - earlier mistakes, a new topic branch is created by forking at - the tip of the "master". This is not strictly necessary, but - it makes it easier to keep your history simple. - - * Whenever you need to test or publish your changes to topic - branches, merge them into "next" branch. - -The script, being an example, hardcodes the publish branch name -to be "next", but it is trivial to make it configurable via -$GIT_DIR/config mechanism. - -With this workflow, you would want to know: - -(1) ... if a topic branch has ever been merged to "next". Young - topic branches can have stupid mistakes you would rather - clean up before publishing, and things that have not been - merged into other branches can be easily rebased without - affecting other people. But once it is published, you would - not want to rewind it. - -(2) ... if a topic branch has been fully merged to "master". - Then you can delete it. More importantly, you should not - build on top of it -- other people may already want to - change things related to the topic as patches against your - "master", so if you need further changes, it is better to - fork the topic (perhaps with the same name) afresh from the - tip of "master". - -Let's look at this example: - - o---o---o---o---o---o---o---o---o---o "next" - / / / / - / a---a---b A / / - / / / / - / / c---c---c---c B / - / / / \ / - / / / b---b C \ / - / / / / \ / - ---o---o---o---o---o---o---o---o---o---o---o "master" - - -A, B and C are topic branches. - - * A has one fix since it was merged up to "next". - - * B has finished. It has been fully merged up to "master" and "next", - and is ready to be deleted. - - * C has not merged to "next" at all. - -We would want to allow C to be rebased, refuse A, and encourage -B to be deleted. - -To compute (1): - - git rev-list ^master ^topic next - git rev-list ^master next - - if these match, topic has not merged in next at all. - -To compute (2): - - git rev-list master..topic - - if this is empty, it is fully merged to "master". diff --git a/tests/mock/001-08/orphaned/hooks/prepare-commit-msg.sample b/tests/mock/001-08/orphaned/hooks/prepare-commit-msg.sample deleted file mode 100755 index f093a02ec4..0000000000 --- a/tests/mock/001-08/orphaned/hooks/prepare-commit-msg.sample +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/sh -# -# An example hook script to prepare the commit log message. -# Called by "git commit" with the name of the file that has the -# commit message, followed by the description of the commit -# message's source. The hook's purpose is to edit the commit -# message file. If the hook fails with a non-zero status, -# the commit is aborted. -# -# To enable this hook, rename this file to "prepare-commit-msg". - -# This hook includes three examples. The first comments out the -# "Conflicts:" part of a merge commit. -# -# The second includes the output of "git diff --name-status -r" -# into the message, just before the "git status" output. It is -# commented because it doesn't cope with --amend or with squashed -# commits. -# -# The third example adds a Signed-off-by line to the message, that can -# still be edited. This is rarely a good idea. - -case "$2,$3" in - merge,) - /usr/bin/perl -i.bak -ne 's/^/# /, s/^# #/#/ if /^Conflicts/ .. /#/; print' "$1" ;; - -# ,|template,) -# /usr/bin/perl -i.bak -pe ' -# print "\n" . `git diff --cached --name-status -r` -# if /^#/ && $first++ == 0' "$1" ;; - - *) ;; -esac - -# SOB=$(git var GIT_AUTHOR_IDENT | sed -n 's/^\(.*>\).*$/Signed-off-by: \1/p') -# grep -qs "^$SOB" "$1" || echo "$SOB" >> "$1" diff --git a/tests/mock/001-08/orphaned/hooks/update.sample b/tests/mock/001-08/orphaned/hooks/update.sample deleted file mode 100755 index 71ab04edc0..0000000000 --- a/tests/mock/001-08/orphaned/hooks/update.sample +++ /dev/null @@ -1,128 +0,0 @@ -#!/bin/sh -# -# An example hook script to blocks unannotated tags from entering. -# Called by "git receive-pack" with arguments: refname sha1-old sha1-new -# -# To enable this hook, rename this file to "update". -# -# Config -# ------ -# hooks.allowunannotated -# This boolean sets whether unannotated tags will be allowed into the -# repository. By default they won't be. -# hooks.allowdeletetag -# This boolean sets whether deleting tags will be allowed in the -# repository. By default they won't be. -# hooks.allowmodifytag -# This boolean sets whether a tag may be modified after creation. By default -# it won't be. -# hooks.allowdeletebranch -# This boolean sets whether deleting branches will be allowed in the -# repository. By default they won't be. -# hooks.denycreatebranch -# This boolean sets whether remotely creating branches will be denied -# in the repository. By default this is allowed. -# - -# --- Command line -refname="$1" -oldrev="$2" -newrev="$3" - -# --- Safety check -if [ -z "$GIT_DIR" ]; then - echo "Don't run this script from the command line." >&2 - echo " (if you want, you could supply GIT_DIR then run" >&2 - echo " $0 )" >&2 - exit 1 -fi - -if [ -z "$refname" -o -z "$oldrev" -o -z "$newrev" ]; then - echo "Usage: $0 " >&2 - exit 1 -fi - -# --- Config -allowunannotated=$(git config --bool hooks.allowunannotated) -allowdeletebranch=$(git config --bool hooks.allowdeletebranch) -denycreatebranch=$(git config --bool hooks.denycreatebranch) -allowdeletetag=$(git config --bool hooks.allowdeletetag) -allowmodifytag=$(git config --bool hooks.allowmodifytag) - -# check for no description -projectdesc=$(sed -e '1q' "$GIT_DIR/description") -case "$projectdesc" in -"Unnamed repository"* | "") - echo "*** Project description file hasn't been set" >&2 - exit 1 - ;; -esac - -# --- Check types -# if $newrev is 0000...0000, it's a commit to delete a ref. -zero="0000000000000000000000000000000000000000" -if [ "$newrev" = "$zero" ]; then - newrev_type=delete -else - newrev_type=$(git cat-file -t $newrev) -fi - -case "$refname","$newrev_type" in - refs/tags/*,commit) - # un-annotated tag - short_refname=${refname##refs/tags/} - if [ "$allowunannotated" != "true" ]; then - echo "*** The un-annotated tag, $short_refname, is not allowed in this repository" >&2 - echo "*** Use 'git tag [ -a | -s ]' for tags you want to propagate." >&2 - exit 1 - fi - ;; - refs/tags/*,delete) - # delete tag - if [ "$allowdeletetag" != "true" ]; then - echo "*** Deleting a tag is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/tags/*,tag) - # annotated tag - if [ "$allowmodifytag" != "true" ] && git rev-parse $refname > /dev/null 2>&1 - then - echo "*** Tag '$refname' already exists." >&2 - echo "*** Modifying a tag is not allowed in this repository." >&2 - exit 1 - fi - ;; - refs/heads/*,commit) - # branch - if [ "$oldrev" = "$zero" -a "$denycreatebranch" = "true" ]; then - echo "*** Creating a branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/heads/*,delete) - # delete branch - if [ "$allowdeletebranch" != "true" ]; then - echo "*** Deleting a branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - refs/remotes/*,commit) - # tracking branch - ;; - refs/remotes/*,delete) - # delete tracking branch - if [ "$allowdeletebranch" != "true" ]; then - echo "*** Deleting a tracking branch is not allowed in this repository" >&2 - exit 1 - fi - ;; - *) - # Anything else (is there anything else?) - echo "*** Update hook: unknown type of update to ref $refname of type $newrev_type" >&2 - exit 1 - ;; -esac - -# --- Finished -exit 0 diff --git a/tests/mock/001-08/orphaned/info/exclude b/tests/mock/001-08/orphaned/info/exclude deleted file mode 100644 index a5196d1be8..0000000000 --- a/tests/mock/001-08/orphaned/info/exclude +++ /dev/null @@ -1,6 +0,0 @@ -# git ls-files --others --exclude-from=.git/info/exclude -# Lines that start with '#' are comments. -# For a project mostly in C, the following would be a good set of -# exclude patterns (uncomment them if you want to use them): -# *.[oa] -# *~ diff --git a/tests/mock/001-08/orphaned/objects/66/d2a2155270b1021c0fdc764c34e13801bd4ae4 b/tests/mock/001-08/orphaned/objects/66/d2a2155270b1021c0fdc764c34e13801bd4ae4 deleted file mode 100644 index d5a5500472..0000000000 Binary files a/tests/mock/001-08/orphaned/objects/66/d2a2155270b1021c0fdc764c34e13801bd4ae4 and /dev/null differ diff --git a/tests/mock/001-08/orphaned/objects/73/cfa43b65a81d3094e9e09cd05b3710368fc304 b/tests/mock/001-08/orphaned/objects/73/cfa43b65a81d3094e9e09cd05b3710368fc304 deleted file mode 100644 index 1755500b6f..0000000000 Binary files a/tests/mock/001-08/orphaned/objects/73/cfa43b65a81d3094e9e09cd05b3710368fc304 and /dev/null differ diff --git a/tests/mock/001-08/orphaned/objects/c0/328dd7e4af62d858ad174db4e95871fa9f7b8f b/tests/mock/001-08/orphaned/objects/c0/328dd7e4af62d858ad174db4e95871fa9f7b8f deleted file mode 100644 index 949cf5363e..0000000000 Binary files a/tests/mock/001-08/orphaned/objects/c0/328dd7e4af62d858ad174db4e95871fa9f7b8f and /dev/null differ diff --git a/tests/mock/001-08/orphaned/packed-refs b/tests/mock/001-08/orphaned/packed-refs deleted file mode 100644 index cc94885ddd..0000000000 --- a/tests/mock/001-08/orphaned/packed-refs +++ /dev/null @@ -1 +0,0 @@ -# pack-refs with: peeled diff --git a/tests/mock/001-08/orphaned/refs/heads/.gitkeep b/tests/mock/001-08/orphaned/refs/heads/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tests/mock/008-02/COMMIT_EDITMSG b/tests/mock/008-02/COMMIT_EDITMSG deleted file mode 100644 index 6f99fc72a2..0000000000 --- a/tests/mock/008-02/COMMIT_EDITMSG +++ /dev/null @@ -1 +0,0 @@ -added section 1 contents diff --git a/tests/mock/008-02/HEAD b/tests/mock/008-02/HEAD deleted file mode 100644 index cb089cd89a..0000000000 --- a/tests/mock/008-02/HEAD +++ /dev/null @@ -1 +0,0 @@ -ref: refs/heads/master diff --git a/tests/mock/008-02/config b/tests/mock/008-02/config deleted file mode 100644 index e7df272033..0000000000 --- a/tests/mock/008-02/config +++ /dev/null @@ -1,7 +0,0 @@ -[core] - repositoryformatversion = 0 - filemode = true - bare = false - logallrefupdates = true - ignorecase = true - base = true diff --git a/tests/mock/008-02/description b/tests/mock/008-02/description deleted file mode 100644 index 498b267a8c..0000000000 --- a/tests/mock/008-02/description +++ /dev/null @@ -1 +0,0 @@ -Unnamed repository; edit this file 'description' to name the repository. diff --git a/tests/mock/008-02/index b/tests/mock/008-02/index deleted file mode 100644 index 7bb64bdcfb..0000000000 Binary files a/tests/mock/008-02/index and /dev/null differ diff --git a/tests/mock/008-02/info/exclude b/tests/mock/008-02/info/exclude deleted file mode 100644 index a5196d1be8..0000000000 --- a/tests/mock/008-02/info/exclude +++ /dev/null @@ -1,6 +0,0 @@ -# git ls-files --others --exclude-from=.git/info/exclude -# Lines that start with '#' are comments. -# For a project mostly in C, the following would be a good set of -# exclude patterns (uncomment them if you want to use them): -# *.[oa] -# *~ diff --git a/tests/mock/008-02/logs/HEAD b/tests/mock/008-02/logs/HEAD deleted file mode 100644 index 1ca1072b1c..0000000000 --- a/tests/mock/008-02/logs/HEAD +++ /dev/null @@ -1,4 +0,0 @@ -0000000000000000000000000000000000000000 ffc6c773865c1342db9cd5df5777fc91ddeb8a4d Shuhei Tanuma 1327128850 +0900 commit (initial): initial commit -ffc6c773865c1342db9cd5df5777fc91ddeb8a4d 7fce1026cb624448e5a8cf8752bd5e19d8f2cb1f Shuhei Tanuma 1327128901 +0900 commit: modified README -7fce1026cb624448e5a8cf8752bd5e19d8f2cb1f 9bb8c853c9ea27609a6bdc48b78cd26a320daf7d Shuhei Tanuma 1327128919 +0900 commit: added section 1 -9bb8c853c9ea27609a6bdc48b78cd26a320daf7d 6e20138dc38f9f626107f1cd3ef0f9838c43defe Shuhei Tanuma 1327128937 +0900 commit: added section 1 contents diff --git a/tests/mock/008-02/logs/refs/heads/master b/tests/mock/008-02/logs/refs/heads/master deleted file mode 100644 index 1ca1072b1c..0000000000 --- a/tests/mock/008-02/logs/refs/heads/master +++ /dev/null @@ -1,4 +0,0 @@ -0000000000000000000000000000000000000000 ffc6c773865c1342db9cd5df5777fc91ddeb8a4d Shuhei Tanuma 1327128850 +0900 commit (initial): initial commit -ffc6c773865c1342db9cd5df5777fc91ddeb8a4d 7fce1026cb624448e5a8cf8752bd5e19d8f2cb1f Shuhei Tanuma 1327128901 +0900 commit: modified README -7fce1026cb624448e5a8cf8752bd5e19d8f2cb1f 9bb8c853c9ea27609a6bdc48b78cd26a320daf7d Shuhei Tanuma 1327128919 +0900 commit: added section 1 -9bb8c853c9ea27609a6bdc48b78cd26a320daf7d 6e20138dc38f9f626107f1cd3ef0f9838c43defe Shuhei Tanuma 1327128937 +0900 commit: added section 1 contents diff --git a/tests/mock/008-02/objects/23/ea9dd670731cabbf02dc9c9380a1f055521137 b/tests/mock/008-02/objects/23/ea9dd670731cabbf02dc9c9380a1f055521137 deleted file mode 100644 index 4a13a8a0bb..0000000000 Binary files a/tests/mock/008-02/objects/23/ea9dd670731cabbf02dc9c9380a1f055521137 and /dev/null differ diff --git a/tests/mock/008-02/objects/44/e3736675973ddffc3d66dc939adc958df45561 b/tests/mock/008-02/objects/44/e3736675973ddffc3d66dc939adc958df45561 deleted file mode 100644 index e2f5305476..0000000000 Binary files a/tests/mock/008-02/objects/44/e3736675973ddffc3d66dc939adc958df45561 and /dev/null differ diff --git a/tests/mock/008-02/objects/55/7db03de997c86a4a028e1ebd3a1ceb225be238 b/tests/mock/008-02/objects/55/7db03de997c86a4a028e1ebd3a1ceb225be238 deleted file mode 100644 index 2cbc51b51f..0000000000 Binary files a/tests/mock/008-02/objects/55/7db03de997c86a4a028e1ebd3a1ceb225be238 and /dev/null differ diff --git a/tests/mock/008-02/objects/6e/20138dc38f9f626107f1cd3ef0f9838c43defe b/tests/mock/008-02/objects/6e/20138dc38f9f626107f1cd3ef0f9838c43defe deleted file mode 100644 index 07d587d840..0000000000 --- a/tests/mock/008-02/objects/6e/20138dc38f9f626107f1cd3ef0f9838c43defe +++ /dev/null @@ -1 +0,0 @@ -x¥ANÅ0 YçÞ#}%q'BÜ.àØ.­DÔ¦÷§úW`9o1z#½µm@œÃË8Ì@ÌHÓR#aÖ0•)‘,5Ì6³/H9t¿|Ø> Ôš%Ï(Å8Rò…SU™r¥,côÊ ©ãk¬ý€ÏõZmƒ/Þ¯Æðv>ñ1žøñÝxûyHoï0Rˆ¹ Á«/Þ»{½û‡Â±ª)œ&cë;¾;âtÁ%Pé \ No newline at end of file diff --git a/tests/mock/008-02/objects/7f/ce1026cb624448e5a8cf8752bd5e19d8f2cb1f b/tests/mock/008-02/objects/7f/ce1026cb624448e5a8cf8752bd5e19d8f2cb1f deleted file mode 100644 index 882451f2fb..0000000000 --- a/tests/mock/008-02/objects/7f/ce1026cb624448e5a8cf8752bd5e19d8f2cb1f +++ /dev/null @@ -1,2 +0,0 @@ -x¥ŽM -Â0F]ç³$ÿ“‚ˆ‚.ݨHg0­Ôôþ¯àò=>Mµ–ÚêM›S–Ò£}°ž$Zfê=*”ÄÉYvl +--FILE-- +tsrm_ls) + + Z_ADDREF_P(p->payload); + MAKE_STD_ZVAL(param_owner); + if (php_git2_make_resource(&_param_owner, PHP_GIT2_TYPE_REMOTE, owner, 0 TSRMLS_CC)) { + return 0; + } + ZVAL_RESOURCE(param_owner, GIT2_RVAL_P(_param_owner)); + + if (php_git2_call_function_v(p->fci, p->fcc TSRMLS_CC, &retval_ptr, 2, ¶m_owner, &p->payload)) { + return GIT_EUSER; + } + + /* TODO(chobie): implement this */ + + retval = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + return retval; +} + + +/* {{{ proto resource git_transport_new(resource $owner, string $url) + */ +PHP_FUNCTION(git_transport_new) +{ + php_git2_t *result = NULL, *_owner = NULL; + git_transport *out = NULL; + zval *owner = NULL; + char *url = NULL; + int url_len = 0, error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &owner, &url, &url_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_owner, php_git2_t*, &owner, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_transport_new(&out, PHP_GIT2_V(_owner, remote), url); + if (php_git2_check_error(error, "git_transport_new" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_TRANSPORT, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto long git_transport_register(string $prefix, $priority, Callable $cb, $param) + */ +PHP_FUNCTION(git_transport_register) +{ + int result = 0, prefix_len = 0; + char *prefix = NULL; + long priority = NULL; + zval *param = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "slfz", &prefix, &prefix_len, &priority, &fci, &fcc, ¶m) == FAILURE) { + return; + } + + if (php_git2_cb_init(&cb, &fci, &fcc, param TSRMLS_CC)) { + RETURN_FALSE; + } + result = git_transport_register(prefix, priority, php_git2_transport_cb, cb); + php_git2_cb_free(cb); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto long git_transport_unregister(string $prefix, $priority) + */ +PHP_FUNCTION(git_transport_unregister) +{ + int result = 0, prefix_len = 0; + char *prefix = NULL; + long priority = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "sl", &prefix, &prefix_len, &priority) == FAILURE) { + return; + } + + result = git_transport_unregister(prefix, priority); + RETURN_LONG(result); +} +/* }}} */ + + +/* {{{ proto resource git_transport_dummy(resource $owner) + */ +PHP_FUNCTION(git_transport_dummy) +{ + php_git2_t *result = NULL, *_owner = NULL; + git_transport *out = NULL; + zval *owner = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &owner) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_owner, php_git2_t*, &owner, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_transport_dummy(&out, PHP_GIT2_V(_owner, remote), NULL); + if (php_git2_check_error(error, "git_transport_dummy" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_TRANSPORT, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto resource git_transport_local(resource $owner) + */ +PHP_FUNCTION(git_transport_local) +{ + php_git2_t *result = NULL, *_owner = NULL; + git_transport *out = NULL; + zval *owner = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &owner) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_owner, php_git2_t*, &owner, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_transport_local(&out, PHP_GIT2_V(_owner, remote), NULL); + if (php_git2_check_error(error, "git_transport_local" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_TRANSPORT, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto resource git_transport_smart(resource $owner, $payload) + */ +PHP_FUNCTION(git_transport_smart) +{ + php_git2_t *result = NULL, *_owner = NULL; + git_transport *out = NULL; + zval *owner = NULL, *payload = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &owner, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_owner, php_git2_t*, &owner, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_transport_smart(&out, PHP_GIT2_V(_owner, remote), payload); + if (php_git2_check_error(error, "git_transport_smart" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_TRANSPORT, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto resource git_smart_subtransport_http(resource $owner) + */ +PHP_FUNCTION(git_smart_subtransport_http) +{ + php_git2_t *result = NULL, *_owner = NULL; + git_smart_subtransport *out = NULL; + zval *owner = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &owner) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_owner, php_git2_t*, &owner, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_smart_subtransport_http(&out, PHP_GIT2_V(_owner, transport)); + if (php_git2_check_error(error, "git_smart_subtransport_http" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_SMART_SUBTRANSPORT, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto resource git_smart_subtransport_git(resource $owner) + */ +PHP_FUNCTION(git_smart_subtransport_git) +{ + php_git2_t *result = NULL, *_owner = NULL; + git_smart_subtransport *out = NULL; + zval *owner = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &owner) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_owner, php_git2_t*, &owner, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_smart_subtransport_git(&out, PHP_GIT2_V(_owner, transport)); + if (php_git2_check_error(error, "git_smart_subtransport_git" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_SMART_SUBTRANSPORT, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + +/* {{{ proto resource git_smart_subtransport_ssh(resource $owner) + */ +PHP_FUNCTION(git_smart_subtransport_ssh) +{ + php_git2_t *result = NULL, *_owner = NULL; + git_smart_subtransport *out = NULL; + zval *owner = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &owner) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_owner, php_git2_t*, &owner, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_smart_subtransport_ssh(&out, PHP_GIT2_V(_owner, transport)); + if (php_git2_check_error(error, "git_smart_subtransport_ssh" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_SMART_SUBTRANSPORT, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ diff --git a/transport.h b/transport.h new file mode 100644 index 0000000000..075210dbcc --- /dev/null +++ b/transport.h @@ -0,0 +1,109 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_TRANSPORT_H +#define PHP_GIT2_TRANSPORT_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_transport_new, 0, 0, 2) + ZEND_ARG_INFO(0, owner) + ZEND_ARG_INFO(0, url) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_transport_register, 0, 0, 4) + ZEND_ARG_INFO(0, prefix) + ZEND_ARG_INFO(0, priority) + ZEND_ARG_INFO(0, cb) + ZEND_ARG_INFO(0, param) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_transport_unregister, 0, 0, 2) + ZEND_ARG_INFO(0, prefix) + ZEND_ARG_INFO(0, priority) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_transport_dummy, 0, 0, 2) + ZEND_ARG_INFO(0, owner) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_transport_local, 0, 0, 2) + ZEND_ARG_INFO(0, owner) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_transport_smart, 0, 0, 2) + ZEND_ARG_INFO(0, owner) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_smart_subtransport_http, 0, 0, 1) + ZEND_ARG_INFO(0, owner) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_smart_subtransport_git, 0, 0, 1) + ZEND_ARG_INFO(0, owner) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_smart_subtransport_ssh, 0, 0, 1) + ZEND_ARG_INFO(0, owner) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_transport_new(owner, url) +*/ +PHP_FUNCTION(git_transport_new); + +/* {{{ proto long git_transport_register(prefix, priority, cb, param) +*/ +PHP_FUNCTION(git_transport_register); + +/* {{{ proto long git_transport_unregister(prefix, priority) +*/ +PHP_FUNCTION(git_transport_unregister); + +/* {{{ proto resource git_transport_dummy(owner, payload) +*/ +PHP_FUNCTION(git_transport_dummy); + +/* {{{ proto resource git_transport_local(owner, payload) +*/ +PHP_FUNCTION(git_transport_local); + +/* {{{ proto resource git_transport_smart(owner, payload) +*/ +PHP_FUNCTION(git_transport_smart); + +/* {{{ proto resource git_smart_subtransport_http(owner) +*/ +PHP_FUNCTION(git_smart_subtransport_http); + +/* {{{ proto resource git_smart_subtransport_git(owner) +*/ +PHP_FUNCTION(git_smart_subtransport_git); + +/* {{{ proto resource git_smart_subtransport_ssh(owner) +*/ +PHP_FUNCTION(git_smart_subtransport_ssh); + +#endif \ No newline at end of file diff --git a/tree.c b/tree.c index 74f4dc0b55..3d92ba75d9 100644 --- a/tree.c +++ b/tree.c @@ -1,143 +1,488 @@ -/* - * The MIT License - * - * Copyright (c) 2010 - 2012 Shuhei Tanuma - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - #include "php_git2.h" -#include -#include +#include "php_git2_priv.h" +#include "tree.h" -PHPAPI zend_class_entry *git2_tree_class_entry; +typedef struct tree_walk_cb_t { + zval *payload; + zend_fcall_info *fci; + zend_fcall_info_cache *fcc; + GIT2_TSRMLS_DECL +}; -static void php_git2_tree_free_storage(php_git2_tree *object TSRMLS_DC) +static int tree_walk_cb(const char *root, const git_tree_entry *entry, void *payload) { - if (object->tree != NULL) { - git_tree_free(object->tree); - object->tree = NULL; + php_git2_t *result; + zval *param_root, *param_rsrc, *retval_ptr = NULL; + struct tree_walk_cb_t *p = (struct tree_walk_cb_t*)payload; + GIT2_TSRMLS_SET(p->tsrm_ls) + + Z_ADDREF_P(p->payload); + MAKE_STD_ZVAL(param_root); + MAKE_STD_ZVAL(param_rsrc); + + ZVAL_STRING(param_root, root, 1); + php_git2_make_resource(&result, PHP_GIT2_TYPE_TREE_ENTRY, entry, 0 TSRMLS_CC); + zend_list_addref(result->resource_id); + ZVAL_RESOURCE(param_rsrc, result->resource_id); + + if (php_git2_call_function_v(p->fci, p->fcc TSRMLS_CC, &retval_ptr, 3, ¶m_root, ¶m_rsrc, &p->payload)) { + zend_list_delete(result->resource_id); + return 0; } - zend_object_std_dtor(&object->zo TSRMLS_CC); - efree(object); + zval_ptr_dtor(&retval_ptr); + zend_list_delete(result->resource_id); + + return 1; } -zend_object_value php_git2_tree_new(zend_class_entry *ce TSRMLS_DC) +static int php_git2_tree_walk_cb_init(struct tree_walk_cb **out, zend_fcall_info *fci, zend_fcall_info_cache *fcc, void *payload TSRMLS_DC) { - zend_object_value retval; + struct tree_walk_cb_t *cb; + + cb = (struct tree_walk_cb_t*)emalloc(sizeof(struct tree_walk_cb_t)); + if (cb == NULL) { + return 1; + } + + cb->payload = payload; + cb->fci = fci; + cb->fcc = fcc; + GIT2_TSRMLS_SET2(cb, TSRMLS_C); - PHP_GIT2_STD_CREATE_OBJECT(php_git2_tree); - object->offset = 0; - return retval; + *out = cb; + return 0; } +static void php_git2_tree_walk_cb_free(struct tree_walk_cb *target) +{ + efree(target); +} + +/* {{{ proto resource git_tree_entry_byindex(resource $tree, string $name) +*/ +PHP_FUNCTION(git_tree_entry_byindex) +{ + zval *tree; + php_git2_t *git2, *result; + long index; + const git_tree_entry *entry; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rl", &tree, &index) == FAILURE) { + return; + } + + PHP_GIT2_MAKE_RESOURCE(result); + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + entry = git_tree_entry_byindex(PHP_GIT2_V(git2, tree), index); -/* Iterator Implementation */ + PHP_GIT2_V(result, tree_entry) = entry; + result->type = PHP_GIT2_TYPE_TREE_ENTRY; + result->resource_id = PHP_GIT2_LIST_INSERT(result, git2_resource_handle); + result->should_free_v = 0; -/* -{{{ proto: Git2\Tree::current() + ZVAL_RESOURCE(return_value, result->resource_id); +} + +/* {{{ proto resource git_tree_entry_byoid(resource $tree, string $oid) */ -PHP_METHOD(git2_tree, current) +PHP_FUNCTION(git_tree_entry_byoid) { - php_git2_tree *m_tree; + zval *tree; + php_git2_t *git2, *result; + char *hash; + int hash_len; + git_oid id; const git_tree_entry *entry; - zval *z_entry; - m_tree = PHP_GIT2_GET_OBJECT(php_git2_tree, getThis()); - entry = git_tree_entry_byindex(m_tree->tree, m_tree->offset); - if (entry == NULL) { - zend_throw_exception_ex(spl_ce_InvalidArgumentException, 0 TSRMLS_CC, - "specified offset does not exist. %d"); - RETURN_FALSE; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &tree, &hash, &hash_len) == FAILURE) { + return; + } + + if (git_oid_fromstrn(&id, hash, hash_len) != GIT_OK) { + return; } - create_tree_entry_from_entry(&z_entry, entry ,m_tree->repository); - RETURN_ZVAL(z_entry, 0, 1); + + PHP_GIT2_MAKE_RESOURCE(result); + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + entry = git_tree_entry_byoid(PHP_GIT2_V(git2, tree), &id); + + PHP_GIT2_V(result, tree_entry) = entry; + result->type = PHP_GIT2_TYPE_TREE_ENTRY; + result->resource_id = PHP_GIT2_LIST_INSERT(result, git2_resource_handle); + result->should_free_v = 0; + + ZVAL_RESOURCE(return_value, result->resource_id); } -/* -{{{ proto: Git2\Tree::key() + +/* {{{ proto resource git_tree_entry_byname(resource $tree, string $name) */ -PHP_METHOD(git2_tree, key) +PHP_FUNCTION(git_tree_entry_byname) { - php_git2_tree *m_tree; + zval *tree; + php_git2_t *git2, *result; + char *name; + int name_len; + const git_tree_entry *entry; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &tree, &name, &name_len) == FAILURE) { + return; + } + + PHP_GIT2_MAKE_RESOURCE(result); + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + entry = git_tree_entry_byname(PHP_GIT2_V(git2, tree), name); - m_tree = PHP_GIT2_GET_OBJECT(php_git2_tree, getThis()); - RETURN_LONG(m_tree->offset); + + PHP_GIT2_V(result, tree_entry) = entry; + result->type = PHP_GIT2_TYPE_TREE_ENTRY; + result->resource_id = PHP_GIT2_LIST_INSERT(result, git2_resource_handle); + result->should_free_v = 0; + + ZVAL_RESOURCE(return_value, result->resource_id); } -/* -{{{ proto: Git2\Tree::valid() +/* {{{ proto array git_tree_entry_bypath(resource $tree, string $path) */ -PHP_METHOD(git2_tree, next) +PHP_FUNCTION(git_tree_entry_bypath) { - php_git2_tree *m_tree; + zval *tree; + php_git2_t *git2, *result; + char *path; + int path_len; + const git_tree_entry *entry; + int error; - m_tree = PHP_GIT2_GET_OBJECT(php_git2_tree, getThis()); - m_tree->offset++; + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &tree, &path, &path_len) == FAILURE) { + return; + } + + PHP_GIT2_MAKE_RESOURCE(result); + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + error = git_tree_entry_bypath(&entry, PHP_GIT2_V(git2, tree), path); + + PHP_GIT2_V(result, tree_entry) = entry; + result->type = PHP_GIT2_TYPE_TREE_ENTRY; + result->resource_id = PHP_GIT2_LIST_INSERT(result, git2_resource_handle); + result->should_free_v = 0; + + ZVAL_RESOURCE(return_value, result->resource_id); } -/* -{{{ proto: Git2\Tree::rewind() +/* {{{ proto string git_tree_entry_id(resource $tree_entry) */ -PHP_METHOD(git2_tree, rewind) +PHP_FUNCTION(git_tree_entry_id) { - php_git2_tree *m_tree; + zval *tree_entry; + php_git2_t *git2; + char out[GIT2_OID_HEXSIZE] = {0}; + const git_oid *id; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &tree_entry) == FAILURE) { + return; + } - m_tree = PHP_GIT2_GET_OBJECT(php_git2_tree, getThis()); - m_tree->offset = 0; + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree_entry, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + id = git_tree_entry_id(PHP_GIT2_V(git2, tree_entry)); + git_oid_fmt(out, id); + RETURN_STRING(out, 1); } -/* -{{{ proto: Git2\Tree::valid() + +/* {{{ proto long git_tree_entry_type(resource $tree_entry) */ -PHP_METHOD(git2_tree, valid) +PHP_FUNCTION(git_tree_entry_type) { - php_git2_tree *m_tree; - int entry_count = 0; - - m_tree = PHP_GIT2_GET_OBJECT(php_git2_tree, getThis()); - entry_count = git_tree_entrycount(m_tree->tree); - if (m_tree->offset < entry_count && m_tree->offset >= 0) { - RETURN_TRUE; - } else { - RETURN_FALSE; + zval *tree; + php_git2_t *git2; + git_otype type; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &tree) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + type = git_tree_entry_type(PHP_GIT2_V(git2, tree)); + RETURN_LONG(type); +} + +/* {{{ proto string git_tree_entry_name(resource $tree_entry) +*/ +PHP_FUNCTION(git_tree_entry_name) +{ + zval *tree_entry; + php_git2_t *git2; + const char *name; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &tree_entry) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree_entry, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + name = git_tree_entry_name(PHP_GIT2_V(git2, tree_entry)); + RETURN_STRING(name, 1); +} + +/* {{{ proto long git_tree_entry_count(resource $tree) +*/ +PHP_FUNCTION(git_tree_entrycount) +{ + zval *tree; + php_git2_t *git2; + size_t count; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &tree) == FAILURE) { + return; } + + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + count = git_tree_entrycount(PHP_GIT2_V(git2, tree)); + RETURN_LONG(count); +} + +/* {{{ proto long git_tree_entry_filemode(resource $tree_entry) +*/ +PHP_FUNCTION(git_tree_entry_filemode) +{ + zval *tree_entry; + php_git2_t *git2; + git_filemode_t filemode; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &tree_entry) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree_entry, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + filemode = git_tree_entry_filemode(PHP_GIT2_V(git2, tree_entry)); + RETURN_LONG(filemode); +} + +/* {{{ proto long git_tree_entry_filemode_raw(resource $tree_entry) +*/ +PHP_FUNCTION(git_tree_entry_filemode_raw) +{ + zval *tree_entry; + php_git2_t *git2; + git_filemode_t filemode; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &tree_entry) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree_entry, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + filemode = git_tree_entry_filemode_raw(PHP_GIT2_V(git2, tree_entry)); + RETURN_LONG(filemode); +} + +/* {{{ proto bool git_tree_entry_cmp(resource $e1, resource $e2) +*/ +PHP_FUNCTION(git_tree_entry_cmp) +{ + zval *e1, *e2; + php_git2_t *g_e1, *g_e2; + int result; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rr", &e1, &e2) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(g_e1, php_git2_t*, &e1, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(g_e2, php_git2_t*, &e2, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_tree_entry_cmp(PHP_GIT2_V(g_e1, tree_entry), PHP_GIT2_V(g_e2, tree_entry)); + RETURN_LONG(result); +} + + +/* {{{ proto void git_tree_free(resource $tree_entry) +*/ +PHP_FUNCTION(git_tree_free) +{ + zval *tree; + php_git2_t *git2; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &tree) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git2->should_free_v) { + git_tree_free(PHP_GIT2_V(git2, tree)); + git2->should_free_v = 0; + } + + zval_ptr_dtor(&tree); +} + +/* {{{ proto void git_tree_entry_free(resource $tree_entry) +*/ +PHP_FUNCTION(git_tree_entry_free) +{ + zval *tree_entry; + php_git2_t *git2; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &tree_entry) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree_entry, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git2->should_free_v) { + git_tree_entry_free(PHP_GIT2_V(git2, tree_entry)); + git2->should_free_v = 0; + } + + zval_ptr_dtor(&tree_entry); +} + +/* {{{ proto resource git_tree_entry_dup(resource $tree_entry) +*/ +PHP_FUNCTION(git_tree_entry_dup) +{ + zval *tree_entry; + php_git2_t *git2, *result; + git_tree_entry *entry; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &tree_entry) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree_entry, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + entry = git_tree_entry_dup(PHP_GIT2_V(git2, tree_entry)); + + PHP_GIT2_MAKE_RESOURCE(result); + PHP_GIT2_V(result, tree_entry) = entry; + result->type = PHP_GIT2_TYPE_TREE_ENTRY; + result->resource_id = PHP_GIT2_LIST_INSERT(result, git2_resource_handle); + result->should_free_v = 1; + + ZVAL_RESOURCE(return_value, result->resource_id); +} + +/* {{{ proto string git_tree_id(resource $tree_entry) +*/ +PHP_FUNCTION(git_tree_id) +{ + zval *tree; + php_git2_t *git2; + char out[GIT2_OID_HEXSIZE] = {0}; + const git_oid *id; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &tree) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + id = git_tree_id(PHP_GIT2_V(git2, tree)); + git_oid_fmt(out, id); + RETURN_STRING(out, 1); +} + + +/* {{{ proto resource git_tree_lookup(resource $repository, mixed $oid) +*/ +PHP_FUNCTION(git_tree_lookup) +{ + zval *repository; + php_git2_t *git2, *result; + git_tree *tree; + char *hash; + int hash_len; + int error; + git_oid id; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &repository, &hash, &hash_len) == FAILURE) { + return; + } + + if (git_oid_fromstrn(&id, hash, hash_len) != GIT_OK) { + return; + } + + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &repository, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + error = git_tree_lookup(&tree, PHP_GIT2_V(git2, repository), &id); + if (php_git2_check_error(error, "git_commit_lookup" TSRMLS_CC)) { + RETURN_FALSE + } + + PHP_GIT2_MAKE_RESOURCE(result); + PHP_GIT2_V(result, tree) = tree; + result->type = PHP_GIT2_TYPE_TREE; + result->resource_id = PHP_GIT2_LIST_INSERT(result, git2_resource_handle); + result->should_free_v = 0; + + ZVAL_RESOURCE(return_value, result->resource_id); } /* }}} */ +/* {{{ proto resource git_tree_owner(resource $tree) + */ +PHP_FUNCTION(git_tree_owner) +{ + git_repository *result = NULL; + zval *tree = NULL; + php_git2_t *_tree = NULL, *__result = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &tree) == FAILURE) { + return; + } -static zend_function_entry php_git2_tree_methods[] = { - /* Iterator Implementation */ - PHP_ME(git2_tree, current, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_tree, key, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_tree, next, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_tree, rewind, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_tree, valid, NULL, ZEND_ACC_PUBLIC) - {NULL,NULL,NULL} -}; + ZEND_FETCH_RESOURCE(_tree, php_git2_t*, &tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + result = git_tree_owner(PHP_GIT2_V(_tree, tree)); + if (php_git2_make_resource(&__result, PHP_GIT2_TYPE_TREE, result, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(__result)); +} +/* }}} */ -void php_git2_tree_init(TSRMLS_D) + +/* {{{ proto void git_tree_walk(resource $tree, long $mode, Callable $callback, mixed &$payload) +*/ +PHP_FUNCTION(git_tree_walk) { - zend_class_entry ce; - - INIT_NS_CLASS_ENTRY(ce, PHP_GIT2_NS, "Tree", php_git2_tree_methods); - git2_tree_class_entry = zend_register_internal_class(&ce TSRMLS_CC); - git2_tree_class_entry->create_object = php_git2_tree_new; - zend_class_implements(git2_tree_class_entry TSRMLS_CC, 1, spl_ce_Iterator); -} \ No newline at end of file + zval *tree, *payload; + php_git2_t *git2; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + long mode = GIT_TREEWALK_PRE; + struct tree_walk_cb_t *cb; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rlf|z", &tree, &mode, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_tree_walk_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + error = git_tree_walk(PHP_GIT2_V(git2, tree), mode, tree_walk_cb, cb); + php_git2_tree_walk_cb_free(cb); + if (php_git2_check_error(error, "git_tree_walk" TSRMLS_CC)) { + RETURN_FALSE + } + +} +/* }}} */ diff --git a/tree.h b/tree.h new file mode 100644 index 0000000000..30b9d3f412 --- /dev/null +++ b/tree.h @@ -0,0 +1,183 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_TREE_H +#define PHP_GIT2_TREE_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tree_entry_byoid, 0, 0, 2) + ZEND_ARG_INFO(0, tree) + ZEND_ARG_INFO(0, oid) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tree_entry_byindex, 0, 0, 2) + ZEND_ARG_INFO(0, tree) + ZEND_ARG_INFO(0, index) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tree_entry_byname, 0, 0, 2) + ZEND_ARG_INFO(0, tree) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tree_entry_bypath, 0, 0, 2) + ZEND_ARG_INFO(0, tree) + ZEND_ARG_INFO(0, path) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tree_entry_id, 0, 0, 1) + ZEND_ARG_INFO(0, tree_entry) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tree_entry_name, 0, 0, 1) + ZEND_ARG_INFO(0, tree_entry) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tree_entrycount, 0, 0, 1) + ZEND_ARG_INFO(0, tree_entry) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tree_entry_type, 0, 0, 1) + ZEND_ARG_INFO(0, tree_entry) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tree_entry_filemode, 0, 0, 1) + ZEND_ARG_INFO(0, tree_entry) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tree_entry_filemode_raw, 0, 0, 1) + ZEND_ARG_INFO(0, tree_entry) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tree_entry_cmp, 0, 0, 2) + ZEND_ARG_INFO(0, e1) + ZEND_ARG_INFO(0, e2) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tree_entry_free, 0, 0, 1) + ZEND_ARG_INFO(0, tree_entry) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tree_free, 0, 0, 1) + ZEND_ARG_INFO(0, tree) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tree_entry_dup, 0, 0, 1) + ZEND_ARG_INFO(0, tree_entry) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tree_id, 0, 0, 1) + ZEND_ARG_INFO(0, tree) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tree_lookup, 0, 0, 2) + ZEND_ARG_INFO(0, repository) + ZEND_ARG_INFO(0, id) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tree_owner, 0, 0, 1) + ZEND_ARG_INFO(0, tree) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_tree_walk, 0, 0, 4) + ZEND_ARG_INFO(0, tree) + ZEND_ARG_INFO(0, mode) + ZEND_ARG_INFO(0, callback) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + + +/* {{{ proto array git_tree_entry_byoid(resource $tree, string $oid) +*/ +PHP_FUNCTION(git_tree_entry_byoid); + +/* {{{ proto array git_tree_entry_byindex(resource $tree, long $index) +*/ +PHP_FUNCTION(git_tree_entry_byindex); + +/* {{{ proto array git_tree_entry_byname(resource $tree, string $name) +*/ +PHP_FUNCTION(git_tree_entry_byname); + +/* {{{ proto array git_tree_entry_bypath(resource $tree, string $path) +*/ +PHP_FUNCTION(git_tree_entry_bypath); + +/* {{{ proto string git_tree_entry_id(resource $tree_entry) +*/ +PHP_FUNCTION(git_tree_entry_id); + +/* {{{ proto string git_tree_entry_name(resource $tree_entry) +*/ +PHP_FUNCTION(git_tree_entry_name); + +/* {{{ proto long git_tree_entrycount(resource $tree_entry) +*/ +PHP_FUNCTION(git_tree_entrycount); + +/* {{{ proto long git_tree_entry_type(resource $tree_entry) +*/ +PHP_FUNCTION(git_tree_entry_type); + +/* {{{ proto long git_tree_entry_filemode(resource $tree_entry) +*/ +PHP_FUNCTION(git_tree_entry_filemode); + +/* {{{ proto long git_tree_entry_filemode_raw(resource $tree_entry) +*/ +PHP_FUNCTION(git_tree_entry_filemode_raw); + +/* {{{ proto long git_tree_entry_cmp(resource $e1, resource $e2) +*/ +PHP_FUNCTION(git_tree_entry_cmp); + +/* {{{ proto void git_tree_entry_free(resource $tree_entry) +*/ +PHP_FUNCTION(git_tree_entry_free); + +/* {{{ proto void git_tree_free(resource $tree_entry) +*/ +PHP_FUNCTION(git_tree_free); + +/* {{{ proto resource git_tree_entry_dup(resource $tree_entry) +*/ +PHP_FUNCTION(git_tree_entry_dup); + +/* {{{ proto string git_tree_id(resource $tree) +*/ +PHP_FUNCTION(git_tree_id); + +/* {{{ proto resource git_tree_lookup(resource $repository, string id) +*/ +PHP_FUNCTION(git_tree_lookup); + +/* {{{ proto resource git_tree_owner(resource $tree) +*/ +PHP_FUNCTION(git_tree_owner); + +/* {{{ proto resource git_tree_walk(resource $tree, long $mode, Callable $callback, mixed $payload) +*/ +PHP_FUNCTION(git_tree_walk); + +#endif \ No newline at end of file diff --git a/tree_builder.c b/tree_builder.c deleted file mode 100644 index 893e7d2d39..0000000000 --- a/tree_builder.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2010 - 2012 Shuhei Tanuma - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "php_git2.h" - -PHPAPI zend_class_entry *git2_tree_builder_class_entry; - -static void php_git2_tree_builder_free_storage(php_git2_tree_builder *object TSRMLS_DC) -{ - if (object->builder!= NULL) { - git_treebuilder_free(object->builder); - object->builder = NULL; - } - zend_object_std_dtor(&object->zo TSRMLS_CC); - efree(object); -} - -zend_object_value php_git2_tree_builder_new(zend_class_entry *ce TSRMLS_DC) -{ - zend_object_value retval; - - PHP_GIT2_STD_CREATE_OBJECT(php_git2_tree_builder); - return retval; -} - -ZEND_BEGIN_ARG_INFO_EX(arginfo_git2_tree_builder___construct, 0,0,1) - ZEND_ARG_INFO(0, tree) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_git2_tree_builder_insert, 0,0,1) - ZEND_ARG_INFO(0, entry) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_git2_tree_builder_remove, 0,0,1) - ZEND_ARG_INFO(0, name) -ZEND_END_ARG_INFO() - -/* -{{{ proto: Git2\TreeBuilder::__construct([Git2\Tree $tree]) -*/ -PHP_METHOD(git2_tree_builder, __construct) -{ - git_treebuilder *builder; - zval *z_tree = NULL; - git_tree *tree = NULL; - php_git2_tree *m_tree; - php_git2_tree_builder *m_builder; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "|O", &z_tree, git2_tree_class_entry) == FAILURE) { - return; - } - if (z_tree != NULL) { - m_tree = PHP_GIT2_GET_OBJECT(php_git2_tree, z_tree); - tree = m_tree->tree; - } - - git_treebuilder_create(&builder, tree); - m_builder = PHP_GIT2_GET_OBJECT(php_git2_tree_builder, getThis()); - m_builder->builder = builder; -} -/* }}} */ - -/* -{{{ proto: Git2\TreeBuilder::insert(Git2\TreeEntry $entry) -*/ -PHP_METHOD(git2_tree_builder, insert) -{ - zval *z_name, *z_oid, *z_attributes, *m_entry = NULL; - php_git2_tree_builder *m_builder; - git_oid oid; - int error = 0; - unsigned int attributes = 0; - char *name; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "O", &m_entry, git2_tree_entry_class_entry) == FAILURE) { - return; - } - - z_name = zend_read_property(git2_tree_entry_class_entry, m_entry,"name",sizeof("name")-1, 0 TSRMLS_CC); - z_oid = zend_read_property(git2_tree_entry_class_entry, m_entry,"oid",sizeof("oid")-1, 0 TSRMLS_CC); - z_attributes = zend_read_property(git2_tree_entry_class_entry, m_entry,"attributes",sizeof("attributes")-1, 0 TSRMLS_CC); - m_builder = PHP_GIT2_GET_OBJECT(php_git2_tree_builder, getThis()); - - name = Z_STRVAL_P(z_name); - attributes = (unsigned int)Z_LVAL_P(z_attributes); - - git_oid_fromstrn(&oid, Z_STRVAL_P(z_oid), Z_STRLEN_P(z_oid)); - error = git_treebuilder_insert(NULL, m_builder->builder, name, &oid, attributes); -} -/* }}} */ - -/* -{{{ proto: Git2\TreeBuilder::remove(string $name) -*/ -PHP_METHOD(git2_tree_builder, remove) -{ - char *name; - int name_len = 0; - php_git2_tree_builder *m_builder; - int error = 0; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "s", &name, &name_len) == FAILURE) { - return; - } - m_builder = PHP_GIT2_GET_OBJECT(php_git2_tree_builder, getThis()); - - RETURN_LONG(git_treebuilder_remove(m_builder->builder, name)); -} -/* }}} */ - -/* -{{{ proto: Git2\TreeBuilder::write() -*/ -PHP_METHOD(git2_tree_builder, write) -{ - git_oid oid; - php_git2_repository *m_repository; - php_git2_tree_builder *m_builder; - char oid_out[GIT_OID_HEXSZ+1] = {0}; - zval *repository; - int error = 0; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "O", &repository, git2_repository_class_entry) == FAILURE) { - return; - } - - m_builder = PHP_GIT2_GET_OBJECT(php_git2_tree_builder, getThis()); - m_repository = PHP_GIT2_GET_OBJECT(php_git2_repository, repository); - - error = git_treebuilder_write(&oid, m_repository->repository, m_builder->builder); - if (error != GIT_SUCCESS) { - RETURN_FALSE; - } - - git_oid_fmt(oid_out, &oid); - RETURN_STRINGL(oid_out,GIT_OID_HEXSZ,1); -} -/* }}} */ - -/* -{{{ proto: Git2\TreeBuilder::clear() -*/ -PHP_METHOD(git2_tree_builder, clear) -{ - php_git2_tree_builder *m_builder; - m_builder = PHP_GIT2_GET_OBJECT(php_git2_tree_builder, getThis()); - - git_treebuilder_clear(m_builder->builder); -} -/* }}} */ - -static zend_function_entry php_git2_tree_builder_methods[] = { - PHP_ME(git2_tree_builder, __construct, arginfo_git2_tree_builder___construct, ZEND_ACC_PUBLIC) - PHP_ME(git2_tree_builder, insert, arginfo_git2_tree_builder_insert, ZEND_ACC_PUBLIC) - PHP_ME(git2_tree_builder, remove, arginfo_git2_tree_builder_remove, ZEND_ACC_PUBLIC) - PHP_ME(git2_tree_builder, clear, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_tree_builder, write, NULL, ZEND_ACC_PUBLIC) - /* @todo: filter */ - {NULL,NULL,NULL} -}; - -void php_git2_tree_builder_init(TSRMLS_D) -{ - zend_class_entry ce; - - INIT_NS_CLASS_ENTRY(ce, PHP_GIT2_NS, "TreeBuilder", php_git2_tree_builder_methods); - git2_tree_builder_class_entry = zend_register_internal_class(&ce TSRMLS_CC); - git2_tree_builder_class_entry->create_object = php_git2_tree_builder_new; -} \ No newline at end of file diff --git a/tree_entry.c b/tree_entry.c deleted file mode 100644 index fb03c579c1..0000000000 --- a/tree_entry.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2010 - 2012 Shuhei Tanuma - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "php_git2.h" - -PHPAPI zend_class_entry *git2_tree_entry_class_entry; - -static void php_git2_tree_entry_free_storage(php_git2_tree_entry *object TSRMLS_DC) -{ - if (object->entry != NULL) { - object->entry = NULL; - } - zend_object_std_dtor(&object->zo TSRMLS_CC); - efree(object); -} - -zend_object_value php_git2_tree_entry_new(zend_class_entry *ce TSRMLS_DC) -{ - zend_object_value retval; - - PHP_GIT2_STD_CREATE_OBJECT(php_git2_tree_entry); - return retval; -} - -ZEND_BEGIN_ARG_INFO_EX(arginfo_git2_tree_entry___construct, 0,0,1) - ZEND_ARG_INFO(0, entry) -ZEND_END_ARG_INFO() - -/* -{{{ proto: Git2\TreeEntry::__construct([array $entry]) -*/ -PHP_METHOD(git2_tree_entry, __construct) -{ - zval *z_entry= NULL; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "|z", &z_entry) == FAILURE) { - return; - } - - if (z_entry != NULL) { - zval **zvalue = NULL; - zval *zvaluep = NULL; - - if (zend_hash_find(Z_ARRVAL_P(z_entry),"name",sizeof("name"),(void **)&zvalue) != FAILURE) { - zvaluep = *zvalue; - add_property_string_ex(getThis(), "name",sizeof("name"),Z_STRVAL_P(zvaluep) ,1 TSRMLS_CC); - zvalue = NULL; - zvaluep = NULL; - } - if (zend_hash_find(Z_ARRVAL_P(z_entry),"attributes",sizeof("attributes"),(void **)&zvalue) != FAILURE) { - zvaluep = *zvalue; - add_property_long_ex(getThis(), "attributes",sizeof("attributes"),Z_LVAL_P(zvaluep) TSRMLS_CC); - zvalue = NULL; - zvaluep = NULL; - } - if (zend_hash_find(Z_ARRVAL_P(z_entry),"oid",sizeof("oid"),(void **)&zvalue) != FAILURE) { - zvaluep = *zvalue; - add_property_string_ex(getThis(), "oid",sizeof("oid"),Z_STRVAL_P(zvaluep),1 TSRMLS_CC); - zvalue = NULL; - zvaluep = NULL; - } - } -} -/* }}} */ - - - -static zend_function_entry php_git2_tree_entry_methods[] = { - PHP_ME(git2_tree_entry, __construct, arginfo_git2_tree_entry___construct, ZEND_ACC_PUBLIC) - {NULL,NULL,NULL} -}; - -void php_git2_tree_entry_init(TSRMLS_D) -{ - zend_class_entry ce; - - INIT_NS_CLASS_ENTRY(ce, PHP_GIT2_NS, "TreeEntry", php_git2_tree_entry_methods); - git2_tree_entry_class_entry = zend_register_internal_class(&ce TSRMLS_CC); - git2_tree_entry_class_entry->create_object = php_git2_tree_entry_new; - - zend_declare_property_null(git2_tree_entry_class_entry, "name", sizeof("name")-1, ZEND_ACC_PUBLIC TSRMLS_CC); - zend_declare_property_null(git2_tree_entry_class_entry, "oid", sizeof("oid")-1, ZEND_ACC_PUBLIC TSRMLS_CC); - zend_declare_property_null(git2_tree_entry_class_entry, "attributes", sizeof("attributes")-1, ZEND_ACC_PUBLIC TSRMLS_CC); -} \ No newline at end of file diff --git a/treebuilder.c b/treebuilder.c new file mode 100644 index 0000000000..09cabd2162 --- /dev/null +++ b/treebuilder.c @@ -0,0 +1,256 @@ +#include "php_git2.h" +#include "php_git2_priv.h" +#include "revwalk.h" + +static int php_git2_treebuilder_filter_cb(const git_tree_entry *entry, void *payload) +{ + php_git2_t *result; + zval *param_tree_entry, *retval_ptr = NULL; + php_git2_cb_t *p = (php_git2_cb_t*)payload; + long retval = 0; + GIT2_TSRMLS_SET(p->tsrm_ls) + + MAKE_STD_ZVAL(param_tree_entry); + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_TREE_ENTRY, entry, 0 TSRMLS_CC)) { + return 0; + } + ZVAL_RESOURCE(param_tree_entry, GIT2_RVAL_P(result)); + zend_list_addref(GIT2_RVAL_P(result)); + Z_ADDREF_P(p->payload); + + if (php_git2_call_function_v(p->fci, p->fcc TSRMLS_CC, &retval_ptr, 2, ¶m_tree_entry, &p->payload)) { + zval_ptr_dtor(¶m_tree_entry); + zval_ptr_dtor(&p->payload); + zend_list_delete(result->resource_id); + retval = 0; + return 0; + } + + retval = Z_LVAL_P(retval_ptr); + zval_ptr_dtor(&retval_ptr); + zend_list_delete(result->resource_id); + + return retval; +} + + +/* {{{ proto resource git_treebuilder_create([resource $source]) + */ +PHP_FUNCTION(git_treebuilder_create) +{ + php_git2_t *result = NULL, *_source = NULL; + git_treebuilder *out = NULL; + zval *source = NULL; + git_tree *tree = NULL; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "|r", &source) == FAILURE) { + return; + } + if (source != NULL) { + tree = PHP_GIT2_V(_source, tree); + } + + ZEND_FETCH_RESOURCE(_source, php_git2_t*, &source, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + error = git_treebuilder_create(&out, tree); + if (php_git2_check_error(error, "git_treebuilder_create" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_TREEBUILDER, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto void git_treebuilder_clear(bld) +*/ +PHP_FUNCTION(git_treebuilder_clear) +{ + zval *bld; + php_git2_t *_bld; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &bld) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_bld, php_git2_t*, &bld, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + git_treebuilder_clear(PHP_GIT2_V(_bld, treebuilder)); +} + +/* {{{ proto resource git_treebuilder_entrycount(bld) +*/ +PHP_FUNCTION(git_treebuilder_entrycount) +{ + zval *bld; + php_git2_t *_bld; + int count; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &bld) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_bld, php_git2_t*, &bld, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + count = git_treebuilder_entrycount(PHP_GIT2_V(_bld, treebuilder)); + RETURN_LONG(count); +} + +/* {{{ proto void git_treebuilder_free(bld) +*/ +PHP_FUNCTION(git_treebuilder_free) +{ + zval *bld; + php_git2_t *_bld; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "r", &bld) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_bld, php_git2_t*, &bld, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + git_treebuilder_free(PHP_GIT2_V(_bld, treebuilder)); +} + +/* {{{ proto resource git_treebuilder_get(bld, filename) +*/ +PHP_FUNCTION(git_treebuilder_get) +{ + zval *bld; + php_git2_t *_bld, *result; + char *filename = {0}; + int filename_len; + const git_tree_entry *entry = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &bld, &filename, &filename_len) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_bld, php_git2_t*, &bld, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + entry = git_treebuilder_get(PHP_GIT2_V(_bld, treebuilder), filename); + if (entry != NULL) { + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_TREE_ENTRY, entry, 0 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, result->resource_id); + } else { + RETURN_FALSE; + } +} + +/* {{{ proto resource git_treebuilder_insert(resource $bld, string $filename, string $id, $filemode) + */ +PHP_FUNCTION(git_treebuilder_insert) +{ + php_git2_t *result = NULL, *_bld = NULL; + git_tree_entry *out = NULL; + zval *bld = NULL; + char *filename = NULL, *id = NULL; + int filename_len = 0, id_len = 0, error = 0; + git_oid __id = {0}; + long filemode = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rssl", &bld, &filename, &filename_len, &id, &id_len, &filemode) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_bld, php_git2_t*, &bld, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (git_oid_fromstrn(&__id, id, id_len)) { + RETURN_FALSE; + } + error = git_treebuilder_insert(&out, PHP_GIT2_V(_bld, treebuilder), filename, &__id, filemode); + if (php_git2_check_error(error, "git_treebuilder_insert" TSRMLS_CC)) { + RETURN_FALSE; + } + if (php_git2_make_resource(&result, PHP_GIT2_TYPE_TREE_ENTRY, out, 1 TSRMLS_CC)) { + RETURN_FALSE; + } + ZVAL_RESOURCE(return_value, GIT2_RVAL_P(result)); +} +/* }}} */ + + +/* {{{ proto long git_treebuilder_remove(bld, filename) +*/ +PHP_FUNCTION(git_treebuilder_remove) +{ + zval *bld; + php_git2_t *_bld; + char *filename = {0}; + int filename_len; + int error = 0; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rs", &bld, &filename, &filename_len) == FAILURE) { + return; + } + ZEND_FETCH_RESOURCE(_bld, php_git2_t*, &bld, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + error = git_treebuilder_remove(PHP_GIT2_V(_bld, treebuilder), filename); + + if (php_git2_check_error(error, "git_treebuilder_remove" TSRMLS_CC)) { + RETURN_FALSE; + } + + RETURN_TRUE; +} + +/* {{{ proto void git_treebuilder_filter(resource $bld, $filter, $payload) + */ +PHP_FUNCTION(git_treebuilder_filter) +{ + zval *bld = NULL; + php_git2_t *_bld = NULL; + zend_fcall_info fci = empty_fcall_info; + zend_fcall_info_cache fcc = empty_fcall_info_cache; + php_git2_cb_t *cb; + zval *payload = NULL; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rfz", &bld, &fci, &fcc, &payload) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_bld, php_git2_t*, &bld, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + if (php_git2_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) { + RETURN_FALSE; + } + git_treebuilder_filter(PHP_GIT2_V(_bld, treebuilder), php_git2_treebuilder_filter_cb, cb); + php_git2_cb_free(cb); +} +/* }}} */ + + +/* {{{ proto resource git_treebuilder_write(repo, bld) +*/ +PHP_FUNCTION(git_treebuilder_write) +{ + zval *repo; + php_git2_t *_repo; + zval *bld; + php_git2_t *_bld; + git_oid id; + int error = 0; + char out[GIT2_OID_HEXSIZE] = {0}; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, + "rr", &repo, &bld) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(_repo, php_git2_t*, &repo, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + ZEND_FETCH_RESOURCE(_bld, php_git2_t*, &bld, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle); + + error = git_treebuilder_write(&id, PHP_GIT2_V(_repo, repository), PHP_GIT2_V(_bld, treebuilder)); + if (php_git2_check_error(error, "git_treebuilder_write" TSRMLS_CC)) { + RETURN_FALSE; + } + + git_oid_fmt(out, &id); + RETURN_STRING(out, 1); + +} + diff --git a/treebuilder.h b/treebuilder.h new file mode 100644 index 0000000000..46be8dcfe1 --- /dev/null +++ b/treebuilder.h @@ -0,0 +1,109 @@ +/* + * PHP Libgit2 Extension + * + * https://github.com/libgit2/php-git + * + * Copyright 2014 Shuhei Tanuma. 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 PHP_GIT2_TREEBUILDER_H +#define PHP_GIT2_TREEBUILDER_H + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_treebuilder_create, 0, 0, 1) + ZEND_ARG_INFO(0, source) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_treebuilder_clear, 0, 0, 1) + ZEND_ARG_INFO(0, bld) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_treebuilder_entrycount, 0, 0, 1) + ZEND_ARG_INFO(0, bld) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_treebuilder_free, 0, 0, 1) + ZEND_ARG_INFO(0, bld) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_treebuilder_get, 0, 0, 2) + ZEND_ARG_INFO(0, bld) + ZEND_ARG_INFO(0, filename) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_treebuilder_insert, 0, 0, 4) + ZEND_ARG_INFO(0, bld) + ZEND_ARG_INFO(0, filename) + ZEND_ARG_INFO(0, id) + ZEND_ARG_INFO(0, filemode) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_treebuilder_remove, 0, 0, 2) + ZEND_ARG_INFO(0, bld) + ZEND_ARG_INFO(0, filename) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_treebuilder_filter, 0, 0, 3) + ZEND_ARG_INFO(0, bld) + ZEND_ARG_INFO(0, filter) + ZEND_ARG_INFO(1, payload) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_git_treebuilder_write, 0, 0, 2) + ZEND_ARG_INFO(0, repo) + ZEND_ARG_INFO(0, bld) +ZEND_END_ARG_INFO() + +/* {{{ proto resource git_treebuilder_create(source) +*/ +PHP_FUNCTION(git_treebuilder_create); + +/* {{{ proto void git_treebuilder_clear(bld) +*/ +PHP_FUNCTION(git_treebuilder_clear); + +/* {{{ proto resource git_treebuilder_entrycount(bld) +*/ +PHP_FUNCTION(git_treebuilder_entrycount); + +/* {{{ proto void git_treebuilder_free(bld) +*/ +PHP_FUNCTION(git_treebuilder_free); + +/* {{{ proto resource git_treebuilder_get(bld, filename) +*/ +PHP_FUNCTION(git_treebuilder_get); + +/* {{{ proto resource git_treebuilder_insert(bld, filename, id, filemode) +*/ +PHP_FUNCTION(git_treebuilder_insert); + +/* {{{ proto long git_treebuilder_remove(bld, filename) +*/ +PHP_FUNCTION(git_treebuilder_remove); + +/* {{{ proto void git_treebuilder_filter(bld, filter, payload) +*/ +PHP_FUNCTION(git_treebuilder_filter); + +/* {{{ proto long git_treebuilder_write(repo, bld) +*/ +PHP_FUNCTION(git_treebuilder_write); + +#endif \ No newline at end of file diff --git a/walker.c b/walker.c deleted file mode 100644 index 8acc3b83f0..0000000000 --- a/walker.c +++ /dev/null @@ -1,288 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2010 - 2012 Shuhei Tanuma - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#include "php_git2.h" -#include -#include - -PHPAPI zend_class_entry *git2_walker_class_entry; - -static void php_git2_walker_free_storage(php_git2_walker *object TSRMLS_DC) -{ - if (object->walker != NULL) { - git_revwalk_free(object->walker); - object->walker = NULL; - } - if (object->current != NULL) { - efree(object->current); - object->current = NULL; - } - - /* the repository will be free'd by Git2\Repository */ - object->repository = NULL; - - zend_object_std_dtor(&object->zo TSRMLS_CC); - efree(object); -} - -zend_object_value php_git2_walker_new(zend_class_entry *ce TSRMLS_DC) -{ - zend_object_value retval; - - PHP_GIT2_STD_CREATE_OBJECT(php_git2_walker); - - object->current = emalloc(sizeof(git_oid)); - return retval; -} - -ZEND_BEGIN_ARG_INFO_EX(arginfo_git2_walker___construct, 0,0,1) - ZEND_ARG_INFO(0, repository) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_git2_walker_sorting, 0,0,1) - ZEND_ARG_INFO(0, mode) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_git2_walker_push, 0,0,1) - ZEND_ARG_INFO(0, sha) -ZEND_END_ARG_INFO() - -ZEND_BEGIN_ARG_INFO_EX(arginfo_git2_walker_hide, 0,0,1) - ZEND_ARG_INFO(0, sha) -ZEND_END_ARG_INFO() - -/* -{{{ proto: Git2\Walker::__construct(Git2\Repository $repo) -*/ -PHP_METHOD(git2_walker, __construct) -{ - php_git2_repository *m_repository; - php_git2_walker *m_walker; - zval *repository; - int error = 0; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "O", &repository, git2_repository_class_entry) == FAILURE) { - return; - } - - m_walker = PHP_GIT2_GET_OBJECT(php_git2_walker, getThis()); - m_repository = PHP_GIT2_GET_OBJECT(php_git2_repository, repository); - - error = git_revwalk_new(&m_walker->walker, m_repository->repository); - - if (error != GIT_SUCCESS) { - /* @todo error handling */ - } - m_walker->repository = m_repository->repository; -} -/* }}} */ - -/* -{{{ proto: Git2\Walker::sorting(long $mode) -*/ -PHP_METHOD(git2_walker, sorting) -{ - php_git2_walker *m_walker; - long mode = GIT_SORT_NONE; - int error = 0; - - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "l", &mode) == FAILURE) { - return; - } - - m_walker = PHP_GIT2_GET_OBJECT(php_git2_walker, getThis()); - git_revwalk_sorting(m_walker->walker, (unsigned int)mode); -} -/* }}} */ - -/* -{{{ proto: Git2\Walker::push(string $hex_sha_intersting) -*/ -PHP_METHOD(git2_walker, push) -{ - php_git2_walker *m_walker; - char *sha; - int sha_len = 0; - int error = 0; - git_oid oid; - - /* @todo: also supports Git2\Commit object */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "s", &sha, &sha_len) == FAILURE) { - return; - } - - m_walker = PHP_GIT2_GET_OBJECT(php_git2_walker, getThis()); - - git_oid_fromstrn(&oid, sha, sha_len); - git_revwalk_reset(m_walker->walker); - git_revwalk_push(m_walker->walker, &oid); - memcpy(m_walker->current, &oid, sizeof(git_oid)); -} -/* }}} */ - -/* -{{{ proto: Git2\Walker::hide(string $hex_sha_unintersting) -*/ -PHP_METHOD(git2_walker, hide) -{ - php_git2_walker *m_walker; - char *sha; - int sha_len = 0; - int error = 0; - git_oid oid; - - /* @todo: also supports Git2\Commit object */ - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, - "s", &sha, &sha_len) == FAILURE) { - return; - } - - m_walker = PHP_GIT2_GET_OBJECT(php_git2_walker, getThis()); - git_oid_fromstrn(&oid, sha, sha_len); - git_revwalk_hide(m_walker->walker, &oid); -} -/* }}} */ - - -/* -{{{ proto: Git2\Walker::reset() -*/ -PHP_METHOD(git2_walker, reset) -{ - php_git2_walker *m_walker; - - m_walker = PHP_GIT2_GET_OBJECT(php_git2_walker, getThis()); - git_revwalk_reset(m_walker->walker); -} -/* }}} */ - - -/* Iterator Implementation */ - -/* -{{{ proto: Git2\Walker::current() -*/ -PHP_METHOD(git2_walker, current) -{ - php_git2_walker *m_walker; - zval *result; - git_object *object; - int error = 0; - - m_walker = PHP_GIT2_GET_OBJECT(php_git2_walker, getThis()); - error = git_object_lookup(&object, m_walker->repository, m_walker->current, GIT_OBJ_COMMIT); - result = php_git2_object_new(m_walker->repository, object TSRMLS_CC); - RETVAL_ZVAL(result,0,1); -} - -/* -{{{ proto: Git2\Walker::key() -*/ -PHP_METHOD(git2_walker, key) -{ - char out[GIT_OID_HEXSZ] = {0}; - php_git2_walker *m_walker; - - m_walker = PHP_GIT2_GET_OBJECT(php_git2_walker, getThis()); - git_oid_fmt(out, m_walker->current); - RETURN_STRINGL(out,GIT_OID_HEXSZ,1); -} - -/* -{{{ proto: Git2\Walker::valid() -*/ -PHP_METHOD(git2_walker, next) -{ - php_git2_walker *m_walker; - int error = 0; - - m_walker = PHP_GIT2_GET_OBJECT(php_git2_walker, getThis()); - error = git_revwalk_next(m_walker->current, m_walker->walker); - if (error != GIT_SUCCESS) { - efree(m_walker->current); - m_walker->current = NULL; - } -} - -/* -{{{ proto: Git2\Walker::rewind() -*/ -PHP_METHOD(git2_walker, rewind) -{ - php_git2_walker *m_walker; - - m_walker = PHP_GIT2_GET_OBJECT(php_git2_walker, getThis()); - git_revwalk_reset(m_walker->walker); - if (m_walker->current == NULL) { - zend_throw_exception_ex(spl_ce_RuntimeException, 0 TSRMLS_CC, - "does not specify interested hash before calling Git2\\Walker::rewind."); - RETURN_FALSE; - } - git_revwalk_push(m_walker->walker, m_walker->current); - git_revwalk_next(m_walker->current, m_walker->walker); -} - -/* -{{{ proto: Git2\Walker::valid() -*/ -PHP_METHOD(git2_walker, valid) -{ - php_git2_walker *m_walker; - - m_walker = PHP_GIT2_GET_OBJECT(php_git2_walker, getThis()); - if (m_walker->current != NULL) { - RETURN_TRUE; - } else { - RETURN_FALSE; - } -} -/* }}} */ - -static zend_function_entry php_git2_walker_methods[] = { - PHP_ME(git2_walker, __construct, arginfo_git2_walker___construct, ZEND_ACC_PUBLIC) - PHP_ME(git2_walker, sorting, arginfo_git2_walker_sorting, ZEND_ACC_PUBLIC) - PHP_ME(git2_walker, push, arginfo_git2_walker_push, ZEND_ACC_PUBLIC) - PHP_ME(git2_walker, hide, arginfo_git2_walker_hide, ZEND_ACC_PUBLIC) - PHP_ME(git2_walker, reset, NULL, ZEND_ACC_PUBLIC) - /* Iterator Implementation */ - PHP_ME(git2_walker, current, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_walker, key, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_walker, next, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_walker, rewind, NULL, ZEND_ACC_PUBLIC) - PHP_ME(git2_walker, valid, NULL, ZEND_ACC_PUBLIC) - {NULL,NULL,NULL} -}; - -void php_git2_walker_init(TSRMLS_D) -{ - zend_class_entry ce; - - INIT_NS_CLASS_ENTRY(ce, PHP_GIT2_NS, "Walker", php_git2_walker_methods); - git2_walker_class_entry = zend_register_internal_class(&ce TSRMLS_CC); - git2_walker_class_entry->create_object = php_git2_walker_new; - zend_class_implements(git2_walker_class_entry TSRMLS_CC, 1, spl_ce_Iterator); -} \ No newline at end of file