xdiff / xutils.con commit Documentation: revise top of git man page (23091e9)
   1/*
   2 *  LibXDiff by Davide Libenzi ( File Differential Library )
   3 *  Copyright (C) 2003  Davide Libenzi
   4 *
   5 *  This library is free software; you can redistribute it and/or
   6 *  modify it under the terms of the GNU Lesser General Public
   7 *  License as published by the Free Software Foundation; either
   8 *  version 2.1 of the License, or (at your option) any later version.
   9 *
  10 *  This library is distributed in the hope that it will be useful,
  11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13 *  Lesser General Public License for more details.
  14 *
  15 *  You should have received a copy of the GNU Lesser General Public
  16 *  License along with this library; if not, write to the Free Software
  17 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18 *
  19 *  Davide Libenzi <davidel@xmailserver.org>
  20 *
  21 */
  22
  23#include "xinclude.h"
  24
  25
  26
  27#define XDL_GUESS_NLINES 256
  28
  29
  30
  31
  32int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize,
  33                     xdemitcb_t *ecb) {
  34        mmbuffer_t mb[3];
  35        int i;
  36
  37        mb[0].ptr = (char *) pre;
  38        mb[0].size = psize;
  39        mb[1].ptr = (char *) rec;
  40        mb[1].size = size;
  41        i = 2;
  42
  43        if (!size || rec[size-1] != '\n') {
  44                mb[2].ptr = "\n\\ No newline at end of file\n";
  45                mb[2].size = strlen(mb[2].ptr);
  46                i = 3;
  47        }
  48
  49        if (ecb->outf(ecb->priv, mb, i) < 0) {
  50
  51                return -1;
  52        }
  53
  54        return 0;
  55}
  56
  57void *xdl_mmfile_first(mmfile_t *mmf, long *size)
  58{
  59        *size = mmf->size;
  60        return mmf->ptr;
  61}
  62
  63
  64void *xdl_mmfile_next(mmfile_t *mmf, long *size)
  65{
  66        return NULL;
  67}
  68
  69
  70long xdl_mmfile_size(mmfile_t *mmf)
  71{
  72        return mmf->size;
  73}
  74
  75
  76int xdl_cha_init(chastore_t *cha, long isize, long icount) {
  77
  78        cha->head = cha->tail = NULL;
  79        cha->isize = isize;
  80        cha->nsize = icount * isize;
  81        cha->ancur = cha->sncur = NULL;
  82        cha->scurr = 0;
  83
  84        return 0;
  85}
  86
  87
  88void xdl_cha_free(chastore_t *cha) {
  89        chanode_t *cur, *tmp;
  90
  91        for (cur = cha->head; (tmp = cur) != NULL;) {
  92                cur = cur->next;
  93                xdl_free(tmp);
  94        }
  95}
  96
  97
  98void *xdl_cha_alloc(chastore_t *cha) {
  99        chanode_t *ancur;
 100        void *data;
 101
 102        if (!(ancur = cha->ancur) || ancur->icurr == cha->nsize) {
 103                if (!(ancur = (chanode_t *) xdl_malloc(sizeof(chanode_t) + cha->nsize))) {
 104
 105                        return NULL;
 106                }
 107                ancur->icurr = 0;
 108                ancur->next = NULL;
 109                if (cha->tail)
 110                        cha->tail->next = ancur;
 111                if (!cha->head)
 112                        cha->head = ancur;
 113                cha->tail = ancur;
 114                cha->ancur = ancur;
 115        }
 116
 117        data = (char *) ancur + sizeof(chanode_t) + ancur->icurr;
 118        ancur->icurr += cha->isize;
 119
 120        return data;
 121}
 122
 123
 124void *xdl_cha_first(chastore_t *cha) {
 125        chanode_t *sncur;
 126
 127        if (!(cha->sncur = sncur = cha->head))
 128                return NULL;
 129
 130        cha->scurr = 0;
 131
 132        return (char *) sncur + sizeof(chanode_t) + cha->scurr;
 133}
 134
 135
 136void *xdl_cha_next(chastore_t *cha) {
 137        chanode_t *sncur;
 138
 139        if (!(sncur = cha->sncur))
 140                return NULL;
 141        cha->scurr += cha->isize;
 142        if (cha->scurr == sncur->icurr) {
 143                if (!(sncur = cha->sncur = sncur->next))
 144                        return NULL;
 145                cha->scurr = 0;
 146        }
 147
 148        return (char *) sncur + sizeof(chanode_t) + cha->scurr;
 149}
 150
 151
 152long xdl_guess_lines(mmfile_t *mf) {
 153        long nl = 0, size, tsize = 0;
 154        char const *data, *cur, *top;
 155
 156        if ((cur = data = xdl_mmfile_first(mf, &size)) != NULL) {
 157                for (top = data + size; nl < XDL_GUESS_NLINES;) {
 158                        if (cur >= top) {
 159                                tsize += (long) (cur - data);
 160                                if (!(cur = data = xdl_mmfile_next(mf, &size)))
 161                                        break;
 162                                top = data + size;
 163                        }
 164                        nl++;
 165                        if (!(cur = memchr(cur, '\n', top - cur)))
 166                                cur = top;
 167                        else
 168                                cur++;
 169                }
 170                tsize += (long) (cur - data);
 171        }
 172
 173        if (nl && tsize)
 174                nl = xdl_mmfile_size(mf) / (tsize / nl);
 175
 176        return nl + 1;
 177}
 178
 179
 180unsigned long xdl_hash_record(char const **data, char const *top) {
 181        unsigned long ha = 5381;
 182        char const *ptr = *data;
 183
 184        for (; ptr < top && *ptr != '\n'; ptr++) {
 185                ha += (ha << 5);
 186                ha ^= (unsigned long) *ptr;
 187        }
 188        *data = ptr < top ? ptr + 1: ptr;
 189
 190        return ha;
 191}
 192
 193
 194unsigned int xdl_hashbits(unsigned int size) {
 195        unsigned int val = 1, bits = 0;
 196
 197        for (; val < size && bits < CHAR_BIT * sizeof(unsigned int); val <<= 1, bits++);
 198        return bits ? bits: 1;
 199}
 200
 201
 202int xdl_num_out(char *out, long val) {
 203        char *ptr, *str = out;
 204        char buf[32];
 205
 206        ptr = buf + sizeof(buf) - 1;
 207        *ptr = '\0';
 208        if (val < 0) {
 209                *--ptr = '-';
 210                val = -val;
 211        }
 212        for (; val && ptr > buf; val /= 10)
 213                *--ptr = "0123456789"[val % 10];
 214        if (*ptr)
 215                for (; *ptr; ptr++, str++)
 216                        *str = *ptr;
 217        else
 218                *str++ = '0';
 219        *str = '\0';
 220
 221        return str - out;
 222}
 223
 224
 225long xdl_atol(char const *str, char const **next) {
 226        long val, base;
 227        char const *top;
 228
 229        for (top = str; XDL_ISDIGIT(*top); top++);
 230        if (next)
 231                *next = top;
 232        for (val = 0, base = 1, top--; top >= str; top--, base *= 10)
 233                val += base * (long)(*top - '0');
 234        return val;
 235}
 236
 237
 238int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2,
 239                      const char *func, long funclen, xdemitcb_t *ecb) {
 240        int nb = 0;
 241        mmbuffer_t mb;
 242        char buf[128];
 243
 244        memcpy(buf, "@@ -", 4);
 245        nb += 4;
 246
 247        nb += xdl_num_out(buf + nb, c1 ? s1: 0);
 248
 249        if (c1 != 1) {
 250                memcpy(buf + nb, ",", 1);
 251                nb += 1;
 252
 253                nb += xdl_num_out(buf + nb, c1);
 254        }
 255
 256        memcpy(buf + nb, " +", 2);
 257        nb += 2;
 258
 259        nb += xdl_num_out(buf + nb, c2 ? s2: 0);
 260
 261        if (c2 != 1) {
 262                memcpy(buf + nb, ",", 1);
 263                nb += 1;
 264
 265                nb += xdl_num_out(buf + nb, c2);
 266        }
 267
 268        memcpy(buf + nb, " @@", 3);
 269        nb += 3;
 270        if (func && funclen) {
 271                buf[nb++] = ' ';
 272                if (funclen > sizeof(buf) - nb - 1)
 273                        funclen = sizeof(buf) - nb - 1;
 274                memcpy(buf + nb, func, funclen);
 275                nb += funclen;
 276        }
 277        buf[nb++] = '\n';
 278
 279        mb.ptr = buf;
 280        mb.size = nb;
 281        if (ecb->outf(ecb->priv, &mb, 1) < 0)
 282                return -1;
 283
 284        return 0;
 285}
 286