2 c35a7943 2018-07-12 stsp * Copyright (c) 2018 Stefan Sperling <stsp@openbsd.org>
4 c35a7943 2018-07-12 stsp * Permission to use, copy, modify, and distribute this software for any
5 c35a7943 2018-07-12 stsp * purpose with or without fee is hereby granted, provided that the above
6 c35a7943 2018-07-12 stsp * copyright notice and this permission notice appear in all copies.
8 c35a7943 2018-07-12 stsp * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 c35a7943 2018-07-12 stsp * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 c35a7943 2018-07-12 stsp * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 c35a7943 2018-07-12 stsp * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 c35a7943 2018-07-12 stsp * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 c35a7943 2018-07-12 stsp * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 c35a7943 2018-07-12 stsp * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 c35a7943 2018-07-12 stsp #include <sys/queue.h>
18 c35a7943 2018-07-12 stsp #include <sys/stat.h>
20 c35a7943 2018-07-12 stsp #include <stdio.h>
21 c35a7943 2018-07-12 stsp #include <stdlib.h>
22 c35a7943 2018-07-12 stsp #include <sha1.h>
23 c35a7943 2018-07-12 stsp #include <zlib.h>
25 c35a7943 2018-07-12 stsp #include "got_object.h"
27 c35a7943 2018-07-12 stsp #include "got_error.h"
28 c35a7943 2018-07-12 stsp #include "got_lib_delta.h"
29 c35a7943 2018-07-12 stsp #include "got_lib_inflate.h"
30 c35a7943 2018-07-12 stsp #include "got_lib_object.h"
31 c35a7943 2018-07-12 stsp #include "got_lib_diffoffset.h"
34 c35a7943 2018-07-12 stsp * A line offset between an old file and a new file, derived from diff chunk
35 c35a7943 2018-07-12 stsp * header info @@ -old_lineno,old_length +new_lineno,new_length @@ in a diff
36 c35a7943 2018-07-12 stsp * with zero context lines (as in diff -U0 old-file new-file).
38 c35a7943 2018-07-12 stsp struct got_diffoffset_chunk {
39 c35a7943 2018-07-12 stsp int lineno; /* first line which has shifted */
40 c35a7943 2018-07-12 stsp int offset; /* applies to subsequent lines until next chunk */
41 c35a7943 2018-07-12 stsp SIMPLEQ_ENTRY(got_diffoffset_chunk) entry;
44 c35a7943 2018-07-12 stsp static struct got_diffoffset_chunk *
45 c35a7943 2018-07-12 stsp alloc_chunk(int lineno, int offset)
47 c35a7943 2018-07-12 stsp struct got_diffoffset_chunk *chunk;
49 c35a7943 2018-07-12 stsp chunk = calloc(1, sizeof(*chunk));
50 c35a7943 2018-07-12 stsp if (chunk == NULL)
51 c35a7943 2018-07-12 stsp return NULL;
53 c35a7943 2018-07-12 stsp chunk->lineno = lineno;
54 c35a7943 2018-07-12 stsp chunk->offset = offset;
56 c35a7943 2018-07-12 stsp return chunk;
59 c35a7943 2018-07-12 stsp const struct got_error *
60 c35a7943 2018-07-12 stsp got_diffoffset_alloc(struct got_diffoffset_chunks **chunks)
62 c35a7943 2018-07-12 stsp const struct got_error *err = NULL;
63 c35a7943 2018-07-12 stsp struct got_diffoffset_chunk *first;
65 c35a7943 2018-07-12 stsp first = alloc_chunk(0, 0);
66 c35a7943 2018-07-12 stsp if (first == NULL)
67 638f9024 2019-05-13 stsp return got_error_from_errno("alloc_chunk");
69 c35a7943 2018-07-12 stsp *chunks = calloc(1, sizeof(**chunks));
70 c35a7943 2018-07-12 stsp if (*chunks == NULL) {
71 638f9024 2019-05-13 stsp err = got_error_from_errno("calloc");
72 c35a7943 2018-07-12 stsp free(first);
76 c35a7943 2018-07-12 stsp SIMPLEQ_INIT(*chunks);
77 c35a7943 2018-07-12 stsp SIMPLEQ_INSERT_HEAD(*chunks, first, entry);
79 c35a7943 2018-07-12 stsp return NULL;
83 c35a7943 2018-07-12 stsp got_diffoffset_free(struct got_diffoffset_chunks *chunks)
85 c35a7943 2018-07-12 stsp struct got_diffoffset_chunk *chunk;
87 c35a7943 2018-07-12 stsp while (!SIMPLEQ_EMPTY(chunks)) {
88 c35a7943 2018-07-12 stsp chunk = SIMPLEQ_FIRST(chunks);
89 c35a7943 2018-07-12 stsp SIMPLEQ_REMOVE_HEAD(chunks, entry);
90 c35a7943 2018-07-12 stsp free(chunk);
92 c35a7943 2018-07-12 stsp free(chunks);
95 c35a7943 2018-07-12 stsp const struct got_error *
96 c35a7943 2018-07-12 stsp got_diffoffset_add(struct got_diffoffset_chunks *chunks,
97 c35a7943 2018-07-12 stsp int old_lineno, int old_length, int new_lineno, int new_length)
99 c35a7943 2018-07-12 stsp struct got_diffoffset_chunk *chunk1, *chunk2;
101 c35a7943 2018-07-12 stsp chunk1 = alloc_chunk(old_lineno, new_lineno - old_lineno);
102 c35a7943 2018-07-12 stsp if (chunk1 == NULL)
103 638f9024 2019-05-13 stsp return got_error_from_errno("alloc_chunk");
105 c35a7943 2018-07-12 stsp chunk2 = alloc_chunk(old_lineno + old_length,
106 c35a7943 2018-07-12 stsp new_lineno - old_lineno + new_length - old_length);
107 c35a7943 2018-07-12 stsp if (chunk2 == NULL) {
108 230a42bd 2019-05-11 jcs const struct got_error *err =
109 638f9024 2019-05-13 stsp got_error_from_errno("alloc_chunk");
110 c35a7943 2018-07-12 stsp free(chunk1);
111 c35a7943 2018-07-12 stsp return err;
114 c35a7943 2018-07-12 stsp SIMPLEQ_INSERT_TAIL(chunks, chunk1, entry);
115 c35a7943 2018-07-12 stsp SIMPLEQ_INSERT_TAIL(chunks, chunk2, entry);
116 c35a7943 2018-07-12 stsp return NULL;
120 c35a7943 2018-07-12 stsp got_diffoffset_get(struct got_diffoffset_chunks *chunks, int lineno)
122 c35a7943 2018-07-12 stsp struct got_diffoffset_chunk *chunk, *prev;
124 c35a7943 2018-07-12 stsp prev = SIMPLEQ_FIRST(chunks);
125 c35a7943 2018-07-12 stsp SIMPLEQ_FOREACH(chunk, chunks, entry) {
126 c35a7943 2018-07-12 stsp if (chunk->lineno > lineno)
128 c35a7943 2018-07-12 stsp prev = chunk;
131 c35a7943 2018-07-12 stsp return lineno + prev->offset;