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;
64 c35a7943 2018-07-12 stsp *chunks = calloc(1, sizeof(**chunks));
65 c35a7943 2018-07-12 stsp if (*chunks == NULL) {
66 638f9024 2019-05-13 stsp err = got_error_from_errno("calloc");
70 c35a7943 2018-07-12 stsp SIMPLEQ_INIT(*chunks);
71 c35a7943 2018-07-12 stsp return NULL;
75 c35a7943 2018-07-12 stsp got_diffoffset_free(struct got_diffoffset_chunks *chunks)
77 c35a7943 2018-07-12 stsp struct got_diffoffset_chunk *chunk;
79 c35a7943 2018-07-12 stsp while (!SIMPLEQ_EMPTY(chunks)) {
80 c35a7943 2018-07-12 stsp chunk = SIMPLEQ_FIRST(chunks);
81 c35a7943 2018-07-12 stsp SIMPLEQ_REMOVE_HEAD(chunks, entry);
82 c35a7943 2018-07-12 stsp free(chunk);
84 c35a7943 2018-07-12 stsp free(chunks);
87 c35a7943 2018-07-12 stsp const struct got_error *
88 1e45b069 2019-08-19 stsp add_chunk(struct got_diffoffset_chunks *chunks, int lineno, int offset)
90 1e45b069 2019-08-19 stsp struct got_diffoffset_chunk *chunk;
92 1e45b069 2019-08-19 stsp chunk = alloc_chunk(lineno, offset);
93 1e45b069 2019-08-19 stsp if (chunk == NULL)
94 638f9024 2019-05-13 stsp return got_error_from_errno("alloc_chunk");
96 1e45b069 2019-08-19 stsp SIMPLEQ_INSERT_TAIL(chunks, chunk, entry);
97 1e45b069 2019-08-19 stsp return NULL;
101 1e45b069 2019-08-19 stsp const struct got_error *
102 1e45b069 2019-08-19 stsp got_diffoffset_add(struct got_diffoffset_chunks *chunks,
103 1e45b069 2019-08-19 stsp int old_lineno, int old_length, int new_lineno, int new_length)
105 1e45b069 2019-08-19 stsp const struct got_error *err = NULL;
106 1e45b069 2019-08-19 stsp int offset;
108 1e45b069 2019-08-19 stsp offset = new_lineno - old_lineno;
109 1e45b069 2019-08-19 stsp if (offset != 0) {
110 1e45b069 2019-08-19 stsp err = add_chunk(chunks, old_lineno, offset);
112 1e45b069 2019-08-19 stsp return err;
115 1e45b069 2019-08-19 stsp offset = new_lineno - old_lineno + new_length - old_length;
116 1e45b069 2019-08-19 stsp if (offset != 0)
117 1e45b069 2019-08-19 stsp err = add_chunk(chunks, old_lineno + old_length, offset);
119 1e45b069 2019-08-19 stsp return err;
123 c35a7943 2018-07-12 stsp got_diffoffset_get(struct got_diffoffset_chunks *chunks, int lineno)
125 c35a7943 2018-07-12 stsp struct got_diffoffset_chunk *chunk, *prev;
127 c35a7943 2018-07-12 stsp prev = SIMPLEQ_FIRST(chunks);
128 c35a7943 2018-07-12 stsp SIMPLEQ_FOREACH(chunk, chunks, entry) {
129 c35a7943 2018-07-12 stsp if (chunk->lineno > lineno)
131 c35a7943 2018-07-12 stsp prev = chunk;
134 c35a7943 2018-07-12 stsp return lineno + prev->offset;