2 #include "xdiff-interface.h"
4 static int parse_num(char **cp_p
, int *num_p
)
10 while ('0' <= *cp
&& *cp
<= '9')
11 num
= num
* 10 + *cp
++ - '0';
12 if (!(read_some
= cp
- *cp_p
))
19 int parse_hunk_header(char *line
, int len
,
25 if (parse_num(&cp
, ob
)) {
27 return error("malformed diff output: %s", line
);
31 if (parse_num(&cp
, on
))
36 if (*cp
++ != ' ' || *cp
++ != '+')
38 if (parse_num(&cp
, nb
))
42 if (parse_num(&cp
, nn
))
47 return -!!memcmp(cp
, " @@", 3);
50 static void consume_one(void *priv_
, char *s
, unsigned long size
)
52 struct xdiff_emit_state
*priv
= priv_
;
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
);
64 int xdiff_outf(void *priv_
, mmbuffer_t
*mb
, int nbuf
)
66 struct xdiff_emit_state
*priv
= priv_
;
69 for (i
= 0; i
< nbuf
; i
++) {
70 if (mb
[i
].ptr
[mb
[i
].size
-1] != '\n') {
72 priv
->remainder
= xrealloc(priv
->remainder
,
73 priv
->remainder_size
+
75 memcpy(priv
->remainder
+ priv
->remainder_size
,
76 mb
[i
].ptr
, mb
[i
].size
);
77 priv
->remainder_size
+= mb
[i
].size
;
81 /* we have a complete line */
82 if (!priv
->remainder
) {
83 consume_one(priv
, mb
[i
].ptr
, mb
[i
].size
);
86 priv
->remainder
= xrealloc(priv
->remainder
,
87 priv
->remainder_size
+
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;
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;
106 int xdi_diff(mmfile_t
*mf1
, mmfile_t
*mf2
, xpparam_t
const *xpp
, xdemitconf_t
const *xecfg
, xdemitcb_t
*xecb
)
108 return xdl_diff(mf1
, mf2
, xpp
, xecfg
, xecb
);
111 int read_mmfile(mmfile_t
*ptr
, const char *filename
)
117 if (stat(filename
, &st
))
118 return error("Could not stat %s", filename
);
119 if ((f
= fopen(filename
, "rb")) == NULL
)
120 return error("Could not open %s", filename
);
121 sz
= xsize_t(st
.st_size
);
122 ptr
->ptr
= xmalloc(sz
);
123 if (fread(ptr
->ptr
, sz
, 1, f
) != 1)
124 return error("Could not read %s", filename
);
130 #define FIRST_FEW_BYTES 8000
131 int buffer_is_binary(const char *ptr
, unsigned long size
)
133 if (FIRST_FEW_BYTES
< size
)
134 size
= FIRST_FEW_BYTES
;
135 return !!memchr(ptr
, 0, size
);
146 static long ff_regexp(const char *line
, long len
,
147 char *buffer
, long buffer_size
, void *priv
)
149 char *line_buffer
= xstrndup(line
, len
); /* make NUL terminated */
150 struct ff_regs
*regs
= priv
;
151 regmatch_t pmatch
[2];
154 for (i
= 0; i
< regs
->nr
; i
++) {
155 struct ff_reg
*reg
= regs
->array
+ i
;
156 if (reg
->negate
^ !!regexec(®
->re
,
157 line_buffer
, 2, pmatch
, 0)) {
162 i
= pmatch
[1].rm_so
>= 0 ? 1 : 0;
163 line
+= pmatch
[i
].rm_so
;
164 result
= pmatch
[i
].rm_eo
- pmatch
[i
].rm_so
;
165 if (result
> buffer_size
)
166 result
= buffer_size
;
168 while (result
> 0 && (isspace(line
[result
- 1]) ||
169 line
[result
- 1] == '\n'))
171 memcpy(buffer
, line
, result
);
176 void xdiff_set_find_func(xdemitconf_t
*xecfg
, const char *value
)
179 struct ff_regs
*regs
;
181 xecfg
->find_func
= ff_regexp
;
182 regs
= xecfg
->find_func_priv
= xmalloc(sizeof(struct ff_regs
));
183 for (i
= 0, regs
->nr
= 1; value
[i
]; i
++)
184 if (value
[i
] == '\n')
186 regs
->array
= xmalloc(regs
->nr
* sizeof(struct ff_reg
));
187 for (i
= 0; i
< regs
->nr
; i
++) {
188 struct ff_reg
*reg
= regs
->array
+ i
;
189 const char *ep
= strchr(value
, '\n'), *expression
;
192 reg
->negate
= (*value
== '!');
193 if (reg
->negate
&& i
== regs
->nr
- 1)
194 die("Last expression must not be negated: %s", value
);
198 expression
= buffer
= xstrndup(value
, ep
- value
);
201 if (regcomp(®
->re
, expression
, 0))
202 die("Invalid regexp to look for hunk header: %s", expression
);