Blame


1 c35a7943 2018-07-12 stsp /*
2 c35a7943 2018-07-12 stsp * Copyright (c) 2018 Stefan Sperling <stsp@openbsd.org>
3 c35a7943 2018-07-12 stsp *
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.
7 c35a7943 2018-07-12 stsp *
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.
15 c35a7943 2018-07-12 stsp */
16 c35a7943 2018-07-12 stsp
17 c35a7943 2018-07-12 stsp #include <sys/queue.h>
18 c35a7943 2018-07-12 stsp #include <sys/stat.h>
19 c35a7943 2018-07-12 stsp
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>
24 c35a7943 2018-07-12 stsp
25 c35a7943 2018-07-12 stsp #include "got_object.h"
26 c35a7943 2018-07-12 stsp
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"
32 c35a7943 2018-07-12 stsp
33 c35a7943 2018-07-12 stsp /*
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).
37 c35a7943 2018-07-12 stsp */
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;
42 c35a7943 2018-07-12 stsp };
43 c35a7943 2018-07-12 stsp
44 c35a7943 2018-07-12 stsp static struct got_diffoffset_chunk *
45 c35a7943 2018-07-12 stsp alloc_chunk(int lineno, int offset)
46 c35a7943 2018-07-12 stsp {
47 c35a7943 2018-07-12 stsp struct got_diffoffset_chunk *chunk;
48 c35a7943 2018-07-12 stsp
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;
52 c35a7943 2018-07-12 stsp
53 c35a7943 2018-07-12 stsp chunk->lineno = lineno;
54 c35a7943 2018-07-12 stsp chunk->offset = offset;
55 c35a7943 2018-07-12 stsp
56 c35a7943 2018-07-12 stsp return chunk;
57 c35a7943 2018-07-12 stsp }
58 c35a7943 2018-07-12 stsp
59 c35a7943 2018-07-12 stsp const struct got_error *
60 c35a7943 2018-07-12 stsp got_diffoffset_alloc(struct got_diffoffset_chunks **chunks)
61 c35a7943 2018-07-12 stsp {
62 c35a7943 2018-07-12 stsp const struct got_error *err = NULL;
63 c35a7943 2018-07-12 stsp struct got_diffoffset_chunk *first;
64 c35a7943 2018-07-12 stsp
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");
68 c35a7943 2018-07-12 stsp
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);
73 c35a7943 2018-07-12 stsp return err;
74 c35a7943 2018-07-12 stsp }
75 c35a7943 2018-07-12 stsp
76 c35a7943 2018-07-12 stsp SIMPLEQ_INIT(*chunks);
77 c35a7943 2018-07-12 stsp SIMPLEQ_INSERT_HEAD(*chunks, first, entry);
78 c35a7943 2018-07-12 stsp
79 c35a7943 2018-07-12 stsp return NULL;
80 c35a7943 2018-07-12 stsp }
81 c35a7943 2018-07-12 stsp
82 c35a7943 2018-07-12 stsp void
83 c35a7943 2018-07-12 stsp got_diffoffset_free(struct got_diffoffset_chunks *chunks)
84 c35a7943 2018-07-12 stsp {
85 c35a7943 2018-07-12 stsp struct got_diffoffset_chunk *chunk;
86 c35a7943 2018-07-12 stsp
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);
91 c35a7943 2018-07-12 stsp }
92 c35a7943 2018-07-12 stsp free(chunks);
93 c35a7943 2018-07-12 stsp }
94 c35a7943 2018-07-12 stsp
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)
98 c35a7943 2018-07-12 stsp {
99 c35a7943 2018-07-12 stsp struct got_diffoffset_chunk *chunk1, *chunk2;
100 c35a7943 2018-07-12 stsp
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");
104 c35a7943 2018-07-12 stsp
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;
112 c35a7943 2018-07-12 stsp }
113 c35a7943 2018-07-12 stsp
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;
117 c35a7943 2018-07-12 stsp }
118 c35a7943 2018-07-12 stsp
119 c35a7943 2018-07-12 stsp int
120 c35a7943 2018-07-12 stsp got_diffoffset_get(struct got_diffoffset_chunks *chunks, int lineno)
121 c35a7943 2018-07-12 stsp {
122 c35a7943 2018-07-12 stsp struct got_diffoffset_chunk *chunk, *prev;
123 c35a7943 2018-07-12 stsp
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)
127 c35a7943 2018-07-12 stsp break;
128 c35a7943 2018-07-12 stsp prev = chunk;
129 c35a7943 2018-07-12 stsp }
130 c35a7943 2018-07-12 stsp
131 c35a7943 2018-07-12 stsp return lineno + prev->offset;
132 c35a7943 2018-07-12 stsp }