c8242103b5f571990161a8e69861c3d4c6b19d3a
   1/* By carefully stacking #includes here (even if WE don't really need them)
   2 * we strive to make the thing actually compile. Git header files aren't very
   3 * nice. Perl headers are one of the signs of the coming apocalypse. */
   4#include <ctype.h>
   5/* Ok, it hasn't been so bad so far. */
   6
   7/* libgit interface */
   8#include "../cache.h"
   9#include "../exec_cmd.h"
  10
  11#define die perlyshadow_die__
  12
  13/* XS and Perl interface */
  14#include "EXTERN.h"
  15#include "perl.h"
  16#include "XSUB.h"
  17
  18#undef die
  19
  20
  21static char *
  22report_xs(const char *prefix, const char *err, va_list params)
  23{
  24        static char buf[4096];
  25        strcpy(buf, prefix);
  26        vsnprintf(buf + strlen(prefix), 4096 - strlen(prefix), err, params);
  27        return buf;
  28}
  29
  30static void NORETURN
  31die_xs(const char *err, va_list params)
  32{
  33        char *str;
  34        str = report_xs("fatal: ", err, params);
  35        croak(str);
  36}
  37
  38static void
  39error_xs(const char *err, va_list params)
  40{
  41        char *str;
  42        str = report_xs("error: ", err, params);
  43        warn(str);
  44}
  45
  46
  47MODULE = Git            PACKAGE = Git
  48
  49PROTOTYPES: DISABLE
  50
  51
  52BOOT:
  53{
  54        set_error_routine(error_xs);
  55        set_die_routine(die_xs);
  56}
  57
  58
  59# /* TODO: xs_call_gate(). See Git.pm. */
  60
  61
  62char *
  63xs_version()
  64CODE:
  65{
  66        RETVAL = GIT_VERSION;
  67}
  68OUTPUT:
  69        RETVAL
  70
  71
  72char *
  73xs_exec_path()
  74CODE:
  75{
  76        RETVAL = (char *)git_exec_path();
  77}
  78OUTPUT:
  79        RETVAL
  80
  81
  82void
  83xs__execv_git_cmd(...)
  84CODE:
  85{
  86        const char **argv;
  87        int i;
  88
  89        argv = malloc(sizeof(const char *) * (items + 1));
  90        if (!argv)
  91                croak("malloc failed");
  92        for (i = 0; i < items; i++)
  93                argv[i] = strdup(SvPV_nolen(ST(i)));
  94        argv[i] = NULL;
  95
  96        execv_git_cmd(argv);
  97
  98        for (i = 0; i < items; i++)
  99                if (argv[i])
 100                        free((char *) argv[i]);
 101        free((char **) argv);
 102}
 103
 104char *
 105xs_hash_object_pipe(type, fd)
 106        char *type;
 107        int fd;
 108CODE:
 109{
 110        unsigned char sha1[20];
 111
 112        if (index_pipe(sha1, fd, type, 0))
 113                croak("Unable to hash given filehandle");
 114        RETVAL = sha1_to_hex(sha1);
 115}
 116OUTPUT:
 117        RETVAL
 118
 119char *
 120xs_hash_object_file(type, path)
 121        char *type;
 122        char *path;
 123CODE:
 124{
 125        unsigned char sha1[20];
 126        int fd = open(path, O_RDONLY);
 127        struct stat st;
 128
 129        if (fd < 0 ||
 130            fstat(fd, &st) < 0 ||
 131            index_fd(sha1, fd, &st, 0, type))
 132                croak("Unable to hash %s", path);
 133        close(fd);
 134
 135        RETVAL = sha1_to_hex(sha1);
 136}
 137OUTPUT:
 138        RETVAL