]>
Commit | Line | Data |
---|---|---|
d9ea73e0 JH |
1 | #include "cache.h" |
2 | #include "xdiff-interface.h" | |
3 | ||
a0fd3146 | 4 | static int parse_num(char **cp_p, int *num_p) |
c1e335a4 JH |
5 | { |
6 | char *cp = *cp_p; | |
a0fd3146 | 7 | int num = 0; |
c1e335a4 JH |
8 | int read_some; |
9 | ||
10 | while ('0' <= *cp && *cp <= '9') | |
11 | num = num * 10 + *cp++ - '0'; | |
12 | if (!(read_some = cp - *cp_p)) | |
13 | return -1; | |
14 | *cp_p = cp; | |
15 | *num_p = num; | |
16 | return 0; | |
17 | } | |
18 | ||
19 | int parse_hunk_header(char *line, int len, | |
a0fd3146 JH |
20 | int *ob, int *on, |
21 | int *nb, int *nn) | |
c1e335a4 JH |
22 | { |
23 | char *cp; | |
24 | cp = line + 4; | |
25 | if (parse_num(&cp, ob)) { | |
26 | bad_line: | |
27 | return error("malformed diff output: %s", line); | |
28 | } | |
29 | if (*cp == ',') { | |
30 | cp++; | |
31 | if (parse_num(&cp, on)) | |
32 | goto bad_line; | |
33 | } | |
34 | else | |
35 | *on = 1; | |
36 | if (*cp++ != ' ' || *cp++ != '+') | |
37 | goto bad_line; | |
38 | if (parse_num(&cp, nb)) | |
39 | goto bad_line; | |
40 | if (*cp == ',') { | |
41 | cp++; | |
42 | if (parse_num(&cp, nn)) | |
43 | goto bad_line; | |
44 | } | |
45 | else | |
46 | *nn = 1; | |
47 | return -!!memcmp(cp, " @@", 3); | |
48 | } | |
49 | ||
d9ea73e0 JH |
50 | static void consume_one(void *priv_, char *s, unsigned long size) |
51 | { | |
52 | struct xdiff_emit_state *priv = priv_; | |
53 | char *ep; | |
54 | while (size) { | |
55 | unsigned long this_size; | |
56 | ep = memchr(s, '\n', size); | |
57 | this_size = (ep == NULL) ? size : (ep - s + 1); | |
58 | priv->consume(priv, s, this_size); | |
59 | size -= this_size; | |
60 | s += this_size; | |
61 | } | |
62 | } | |
63 | ||
64 | int xdiff_outf(void *priv_, mmbuffer_t *mb, int nbuf) | |
65 | { | |
66 | struct xdiff_emit_state *priv = priv_; | |
67 | int i; | |
68 | ||
69 | for (i = 0; i < nbuf; i++) { | |
70 | if (mb[i].ptr[mb[i].size-1] != '\n') { | |
71 | /* Incomplete line */ | |
83572c1a JF |
72 | priv->remainder = xrealloc(priv->remainder, |
73 | priv->remainder_size + | |
74 | mb[i].size); | |
d9ea73e0 JH |
75 | memcpy(priv->remainder + priv->remainder_size, |
76 | mb[i].ptr, mb[i].size); | |
77 | priv->remainder_size += mb[i].size; | |
78 | continue; | |
79 | } | |
80 | ||
81 | /* we have a complete line */ | |
82 | if (!priv->remainder) { | |
83 | consume_one(priv, mb[i].ptr, mb[i].size); | |
84 | continue; | |
85 | } | |
83572c1a JF |
86 | priv->remainder = xrealloc(priv->remainder, |
87 | priv->remainder_size + | |
88 | mb[i].size); | |
d9ea73e0 JH |
89 | memcpy(priv->remainder + priv->remainder_size, |
90 | mb[i].ptr, mb[i].size); | |
91 | consume_one(priv, priv->remainder, | |
92 | priv->remainder_size + mb[i].size); | |
93 | free(priv->remainder); | |
94 | priv->remainder = NULL; | |
95 | priv->remainder_size = 0; | |
96 | } | |
97 | if (priv->remainder) { | |
98 | consume_one(priv, priv->remainder, priv->remainder_size); | |
99 | free(priv->remainder); | |
100 | priv->remainder = NULL; | |
101 | priv->remainder_size = 0; | |
102 | } | |
103 | return 0; | |
104 | } | |
7cab5883 JS |
105 | |
106 | int read_mmfile(mmfile_t *ptr, const char *filename) | |
107 | { | |
108 | struct stat st; | |
109 | FILE *f; | |
110 | ||
111 | if (stat(filename, &st)) | |
112 | return error("Could not stat %s", filename); | |
113 | if ((f = fopen(filename, "rb")) == NULL) | |
114 | return error("Could not open %s", filename); | |
115 | ptr->ptr = xmalloc(st.st_size); | |
116 | if (fread(ptr->ptr, st.st_size, 1, f) != 1) | |
117 | return error("Could not read %s", filename); | |
118 | fclose(f); | |
119 | ptr->size = st.st_size; | |
120 | return 0; | |
121 | } | |
122 | ||
123 |