Fix cvsimport warning when called without --no-cvs-direct
[git.git] / apply.c
1 /*
2  * apply.c
3  *
4  * Copyright (C) Linus Torvalds, 2005
5  *
6  * This applies patches on top of some (arbitrary) version of the SCM.
7  *
8  * NOTE! It does all its work in the index file, and only cares about
9  * the files in the working directory if you tell it to "merge" the
10  * patch apply.
11  *
12  * Even when merging it always takes the source from the index, and
13  * uses the working tree as a "branch" for a 3-way merge.
14  */
15 #include <ctype.h>
16 #include <fnmatch.h>
17 #include "cache.h"
18 #include "quote.h"
19
20 // We default to the merge behaviour, since that's what most people would
21 // expect.
22 //
23 //  --check turns on checking that the working tree matches the
24 //    files that are being modified, but doesn't apply the patch
25 //  --stat does just a diffstat, and doesn't actually apply
26 //  --show-files shows the directory changes
27 //
28 static int merge_patch = 1;
29 static int check_index = 0;
30 static int write_index = 0;
31 static int diffstat = 0;
32 static int summary = 0;
33 static int check = 0;
34 static int apply = 1;
35 static int show_files = 0;
36 static const char apply_usage[] =
37 "git-apply [--no-merge] [--stat] [--summary] [--check] [--index] [--apply] [--show-files] <patch>...";
38
39 /*
40  * For "diff-stat" like behaviour, we keep track of the biggest change
41  * we've seen, and the longest filename. That allows us to do simple
42  * scaling.
43  */
44 static int max_change, max_len;
45
46 /*
47  * Various "current state", notably line numbers and what
48  * file (and how) we're patching right now.. The "is_xxxx"
49  * things are flags, where -1 means "don't know yet".
50  */
51 static int linenr = 1;
52
53 struct fragment {
54         unsigned long oldpos, oldlines;
55         unsigned long newpos, newlines;
56         const char *patch;
57         int size;
58         struct fragment *next;
59 };
60
61 struct patch {
62         char *new_name, *old_name, *def_name;
63         unsigned int old_mode, new_mode;
64         int is_rename, is_copy, is_new, is_delete;
65         int lines_added, lines_deleted;
66         int score;
67         struct fragment *fragments;
68         char *result;
69         unsigned long resultsize;
70         struct patch *next;
71 };
72
73 #define CHUNKSIZE (8192)
74 #define SLOP (16)
75
76 static void *read_patch_file(int fd, unsigned long *sizep)
77 {
78         unsigned long size = 0, alloc = CHUNKSIZE;
79         void *buffer = xmalloc(alloc);
80
81         for (;;) {
82                 int nr = alloc - size;
83                 if (nr < 1024) {
84                         alloc += CHUNKSIZE;
85                         buffer = xrealloc(buffer, alloc);
86                         nr = alloc - size;
87                 }
88                 nr = read(fd, buffer + size, nr);
89                 if (!nr)
90                         break;
91                 if (nr < 0) {
92                         if (errno == EAGAIN)
93                                 continue;
94                         die("git-apply: read returned %s", strerror(errno));
95                 }
96                 size += nr;
97         }
98         *sizep = size;
99
100         /*
101          * Make sure that we have some slop in the buffer
102          * so that we can do speculative "memcmp" etc, and
103          * see to it that it is NUL-filled.
104          */
105         if (alloc < size + SLOP)
106                 buffer = xrealloc(buffer, size + SLOP);
107         memset(buffer + size, 0, SLOP);
108         return buffer;
109 }
110
111 static unsigned long linelen(const char *buffer, unsigned long size)
112 {
113         unsigned long len = 0;
114         while (size--) {
115                 len++;
116                 if (*buffer++ == '\n')
117                         break;
118         }
119         return len;
120 }
121
122 static int is_dev_null(const char *str)
123 {
124         return !memcmp("/dev/null", str, 9) && isspace(str[9]);
125 }
126
127 #define TERM_SPACE      1
128 #define TERM_TAB        2
129
130 static int name_terminate(const char *name, int namelen, int c, int terminate)
131 {
132         if (c == ' ' && !(terminate & TERM_SPACE))
133                 return 0;
134         if (c == '\t' && !(terminate & TERM_TAB))
135                 return 0;
136
137         return 1;
138 }
139
140 static char * find_name(const char *line, char *def, int p_value, int terminate)
141 {
142         int len;
143         const char *start = line;
144         char *name;
145
146         if (*line == '"') {
147                 /* Proposed "new-style" GNU patch/diff format; see
148                  * http://marc.theaimsgroup.com/?l=git&m=112927316408690&w=2
149                  */
150                 name = unquote_c_style(line, NULL);
151                 if (name) {
152                         char *cp = name;
153                         while (p_value) {
154                                 cp = strchr(name, '/');
155                                 if (!cp)
156                                         break;
157                                 cp++;
158                                 p_value--;
159                         }
160                         if (cp) {
161                                 /* name can later be freed, so we need
162                                  * to memmove, not just return cp
163                                  */
164                                 memmove(name, cp, strlen(cp) + 1);
165                                 free(def);
166                                 return name;
167                         }
168                         else {
169                                 free(name);
170                                 name = NULL;
171                         }
172                 }
173         }
174
175         for (;;) {
176                 char c = *line;
177
178                 if (isspace(c)) {
179                         if (c == '\n')
180                                 break;
181                         if (name_terminate(start, line-start, c, terminate))
182                                 break;
183                 }
184                 line++;
185                 if (c == '/' && !--p_value)
186                         start = line;
187         }
188         if (!start)
189                 return def;
190         len = line - start;
191         if (!len)
192                 return def;
193
194         /*
195          * Generally we prefer the shorter name, especially
196          * if the other one is just a variation of that with
197          * something else tacked on to the end (ie "file.orig"
198          * or "file~").
199          */
200         if (def) {
201                 int deflen = strlen(def);
202                 if (deflen < len && !strncmp(start, def, deflen))
203                         return def;
204         }
205
206         name = xmalloc(len + 1);
207         memcpy(name, start, len);
208         name[len] = 0;
209         free(def);
210         return name;
211 }
212
213 /*
214  * Get the name etc info from the --/+++ lines of a traditional patch header
215  *
216  * NOTE! This hardcodes "-p1" behaviour in filename detection.
217  *
218  * FIXME! The end-of-filename heuristics are kind of screwy. For existing
219  * files, we can happily check the index for a match, but for creating a
220  * new file we should try to match whatever "patch" does. I have no idea.
221  */
222 static void parse_traditional_patch(const char *first, const char *second, struct patch *patch)
223 {
224         int p_value = 1;
225         char *name;
226
227         first += 4;     // skip "--- "
228         second += 4;    // skip "+++ "
229         if (is_dev_null(first)) {
230                 patch->is_new = 1;
231                 patch->is_delete = 0;
232                 name = find_name(second, NULL, p_value, TERM_SPACE | TERM_TAB);
233                 patch->new_name = name;
234         } else if (is_dev_null(second)) {
235                 patch->is_new = 0;
236                 patch->is_delete = 1;
237                 name = find_name(first, NULL, p_value, TERM_SPACE | TERM_TAB);
238                 patch->old_name = name;
239         } else {
240                 name = find_name(first, NULL, p_value, TERM_SPACE | TERM_TAB);
241                 name = find_name(second, name, p_value, TERM_SPACE | TERM_TAB);
242                 patch->old_name = patch->new_name = name;
243         }
244         if (!name)
245                 die("unable to find filename in patch at line %d", linenr);
246 }
247
248 static int gitdiff_hdrend(const char *line, struct patch *patch)
249 {
250         return -1;
251 }
252
253 /*
254  * We're anal about diff header consistency, to make
255  * sure that we don't end up having strange ambiguous
256  * patches floating around.
257  *
258  * As a result, gitdiff_{old|new}name() will check
259  * their names against any previous information, just
260  * to make sure..
261  */
262 static char *gitdiff_verify_name(const char *line, int isnull, char *orig_name, const char *oldnew)
263 {
264         if (!orig_name && !isnull)
265                 return find_name(line, NULL, 1, 0);
266
267         if (orig_name) {
268                 int len;
269                 const char *name;
270                 char *another;
271                 name = orig_name;
272                 len = strlen(name);
273                 if (isnull)
274                         die("git-apply: bad git-diff - expected /dev/null, got %s on line %d", name, linenr);
275                 another = find_name(line, NULL, 1, 0);
276                 if (!another || memcmp(another, name, len))
277                         die("git-apply: bad git-diff - inconsistent %s filename on line %d", oldnew, linenr);
278                 free(another);
279                 return orig_name;
280         }
281         else {
282                 /* expect "/dev/null" */
283                 if (memcmp("/dev/null", line, 9) || line[9] != '\n')
284                         die("git-apply: bad git-diff - expected /dev/null on line %d", linenr);
285                 return NULL;
286         }
287 }
288
289 static int gitdiff_oldname(const char *line, struct patch *patch)
290 {
291         patch->old_name = gitdiff_verify_name(line, patch->is_new, patch->old_name, "old");
292         return 0;
293 }
294
295 static int gitdiff_newname(const char *line, struct patch *patch)
296 {
297         patch->new_name = gitdiff_verify_name(line, patch->is_delete, patch->new_name, "new");
298         return 0;
299 }
300
301 static int gitdiff_oldmode(const char *line, struct patch *patch)
302 {
303         patch->old_mode = strtoul(line, NULL, 8);
304         return 0;
305 }
306
307 static int gitdiff_newmode(const char *line, struct patch *patch)
308 {
309         patch->new_mode = strtoul(line, NULL, 8);
310         return 0;
311 }
312
313 static int gitdiff_delete(const char *line, struct patch *patch)
314 {
315         patch->is_delete = 1;
316         patch->old_name = patch->def_name;
317         return gitdiff_oldmode(line, patch);
318 }
319
320 static int gitdiff_newfile(const char *line, struct patch *patch)
321 {
322         patch->is_new = 1;
323         patch->new_name = patch->def_name;
324         return gitdiff_newmode(line, patch);
325 }
326
327 static int gitdiff_copysrc(const char *line, struct patch *patch)
328 {
329         patch->is_copy = 1;
330         patch->old_name = find_name(line, NULL, 0, 0);
331         return 0;
332 }
333
334 static int gitdiff_copydst(const char *line, struct patch *patch)
335 {
336         patch->is_copy = 1;
337         patch->new_name = find_name(line, NULL, 0, 0);
338         return 0;
339 }
340
341 static int gitdiff_renamesrc(const char *line, struct patch *patch)
342 {
343         patch->is_rename = 1;
344         patch->old_name = find_name(line, NULL, 0, 0);
345         return 0;
346 }
347
348 static int gitdiff_renamedst(const char *line, struct patch *patch)
349 {
350         patch->is_rename = 1;
351         patch->new_name = find_name(line, NULL, 0, 0);
352         return 0;
353 }
354
355 static int gitdiff_similarity(const char *line, struct patch *patch)
356 {
357         if ((patch->score = strtoul(line, NULL, 10)) == ULONG_MAX)
358                 patch->score = 0;
359         return 0;
360 }
361
362 static int gitdiff_dissimilarity(const char *line, struct patch *patch)
363 {
364         if ((patch->score = strtoul(line, NULL, 10)) == ULONG_MAX)
365                 patch->score = 0;
366         return 0;
367 }
368
369 /*
370  * This is normal for a diff that doesn't change anything: we'll fall through
371  * into the next diff. Tell the parser to break out.
372  */
373 static int gitdiff_unrecognized(const char *line, struct patch *patch)
374 {
375         return -1;
376 }
377
378 static const char *stop_at_slash(const char *line, int llen)
379 {
380         int i;
381
382         for (i = 0; i < llen; i++) {
383                 int ch = line[i];
384                 if (ch == '/')
385                         return line + i;
386         }
387         return NULL;
388 }
389
390 /* This is to extract the same name that appears on "diff --git"
391  * line.  We do not find and return anything if it is a rename
392  * patch, and it is OK because we will find the name elsewhere.
393  * We need to reliably find name only when it is mode-change only,
394  * creation or deletion of an empty file.  In any of these cases,
395  * both sides are the same name under a/ and b/ respectively.
396  */
397 static char *git_header_name(char *line, int llen)
398 {
399         int len;
400         const char *name;
401         const char *second = NULL;
402
403         line += strlen("diff --git ");
404         llen -= strlen("diff --git ");
405
406         if (*line == '"') {
407                 const char *cp;
408                 char *first = unquote_c_style(line, &second);
409                 if (!first)
410                         return NULL;
411
412                 /* advance to the first slash */
413                 cp = stop_at_slash(first, strlen(first));
414                 if (!cp || cp == first) {
415                         /* we do not accept absolute paths */
416                 free_first_and_fail:
417                         free(first);
418                         return NULL;
419                 }
420                 len = strlen(cp+1);
421                 memmove(first, cp+1, len+1); /* including NUL */
422
423                 /* second points at one past closing dq of name.
424                  * find the second name.
425                  */
426                 while ((second < line + llen) && isspace(*second))
427                         second++;
428
429                 if (line + llen <= second)
430                         goto free_first_and_fail;
431                 if (*second == '"') {
432                         char *sp = unquote_c_style(second, NULL);
433                         if (!sp)
434                                 goto free_first_and_fail;
435                         cp = stop_at_slash(sp, strlen(sp));
436                         if (!cp || cp == sp) {
437                         free_both_and_fail:
438                                 free(sp);
439                                 goto free_first_and_fail;
440                         }
441                         /* They must match, otherwise ignore */
442                         if (strcmp(cp+1, first))
443                                 goto free_both_and_fail;
444                         free(sp);
445                         return first;
446                 }
447
448                 /* unquoted second */
449                 cp = stop_at_slash(second, line + llen - second);
450                 if (!cp || cp == second)
451                         goto free_first_and_fail;
452                 cp++;
453                 if (line + llen - cp != len + 1 ||
454                     memcmp(first, cp, len))
455                         goto free_first_and_fail;
456                 return first;
457         }
458
459         /* unquoted first name */
460         name = stop_at_slash(line, llen);
461         if (!name || name == line)
462                 return NULL;
463
464         name++;
465
466         /* since the first name is unquoted, a dq if exists must be
467          * the beginning of the second name.
468          */
469         for (second = name; second < line + llen; second++) {
470                 if (*second == '"') {
471                         const char *cp = second;
472                         const char *np;
473                         char *sp = unquote_c_style(second, NULL);
474
475                         if (!sp)
476                                 return NULL;
477                         np = stop_at_slash(sp, strlen(sp));
478                         if (!np || np == sp) {
479                         free_second_and_fail:
480                                 free(sp);
481                                 return NULL;
482                         }
483                         np++;
484                         len = strlen(np);
485                         if (len < cp - name &&
486                             !strncmp(np, name, len) &&
487                             isspace(name[len])) {
488                                 /* Good */
489                                 memmove(sp, np, len + 1);
490                                 return sp;
491                         }
492                         goto free_second_and_fail;
493                 }
494         }
495
496         /*
497          * Accept a name only if it shows up twice, exactly the same
498          * form.
499          */
500         for (len = 0 ; ; len++) {
501                 char c = name[len];
502
503                 switch (c) {
504                 default:
505                         continue;
506                 case '\n':
507                         return NULL;
508                 case '\t': case ' ':
509                         second = name+len;
510                         for (;;) {
511                                 char c = *second++;
512                                 if (c == '\n')
513                                         return NULL;
514                                 if (c == '/')
515                                         break;
516                         }
517                         if (second[len] == '\n' && !memcmp(name, second, len)) {
518                                 char *ret = xmalloc(len + 1);
519                                 memcpy(ret, name, len);
520                                 ret[len] = 0;
521                                 return ret;
522                         }
523                 }
524         }
525         return NULL;
526 }
527
528 /* Verify that we recognize the lines following a git header */
529 static int parse_git_header(char *line, int len, unsigned int size, struct patch *patch)
530 {
531         unsigned long offset;
532
533         /* A git diff has explicit new/delete information, so we don't guess */
534         patch->is_new = 0;
535         patch->is_delete = 0;
536
537         /*
538          * Some things may not have the old name in the
539          * rest of the headers anywhere (pure mode changes,
540          * or removing or adding empty files), so we get
541          * the default name from the header.
542          */
543         patch->def_name = git_header_name(line, len);
544
545         line += len;
546         size -= len;
547         linenr++;
548         for (offset = len ; size > 0 ; offset += len, size -= len, line += len, linenr++) {
549                 static const struct opentry {
550                         const char *str;
551                         int (*fn)(const char *, struct patch *);
552                 } optable[] = {
553                         { "@@ -", gitdiff_hdrend },
554                         { "--- ", gitdiff_oldname },
555                         { "+++ ", gitdiff_newname },
556                         { "old mode ", gitdiff_oldmode },
557                         { "new mode ", gitdiff_newmode },
558                         { "deleted file mode ", gitdiff_delete },
559                         { "new file mode ", gitdiff_newfile },
560                         { "copy from ", gitdiff_copysrc },
561                         { "copy to ", gitdiff_copydst },
562                         { "rename old ", gitdiff_renamesrc },
563                         { "rename new ", gitdiff_renamedst },
564                         { "rename from ", gitdiff_renamesrc },
565                         { "rename to ", gitdiff_renamedst },
566                         { "similarity index ", gitdiff_similarity },
567                         { "dissimilarity index ", gitdiff_dissimilarity },
568                         { "", gitdiff_unrecognized },
569                 };
570                 int i;
571
572                 len = linelen(line, size);
573                 if (!len || line[len-1] != '\n')
574                         break;
575                 for (i = 0; i < sizeof(optable) / sizeof(optable[0]); i++) {
576                         const struct opentry *p = optable + i;
577                         int oplen = strlen(p->str);
578                         if (len < oplen || memcmp(p->str, line, oplen))
579                                 continue;
580                         if (p->fn(line + oplen, patch) < 0)
581                                 return offset;
582                         break;
583                 }
584         }
585
586         return offset;
587 }
588
589 static int parse_num(const char *line, unsigned long *p)
590 {
591         char *ptr;
592
593         if (!isdigit(*line))
594                 return 0;
595         *p = strtoul(line, &ptr, 10);
596         return ptr - line;
597 }
598
599 static int parse_range(const char *line, int len, int offset, const char *expect,
600                         unsigned long *p1, unsigned long *p2)
601 {
602         int digits, ex;
603
604         if (offset < 0 || offset >= len)
605                 return -1;
606         line += offset;
607         len -= offset;
608
609         digits = parse_num(line, p1);
610         if (!digits)
611                 return -1;
612
613         offset += digits;
614         line += digits;
615         len -= digits;
616
617         *p2 = *p1;
618         if (*line == ',') {
619                 digits = parse_num(line+1, p2);
620                 if (!digits)
621                         return -1;
622
623                 offset += digits+1;
624                 line += digits+1;
625                 len -= digits+1;
626         }
627
628         ex = strlen(expect);
629         if (ex > len)
630                 return -1;
631         if (memcmp(line, expect, ex))
632                 return -1;
633
634         return offset + ex;
635 }
636
637 /*
638  * Parse a unified diff fragment header of the
639  * form "@@ -a,b +c,d @@"
640  */
641 static int parse_fragment_header(char *line, int len, struct fragment *fragment)
642 {
643         int offset;
644
645         if (!len || line[len-1] != '\n')
646                 return -1;
647
648         /* Figure out the number of lines in a fragment */
649         offset = parse_range(line, len, 4, " +", &fragment->oldpos, &fragment->oldlines);
650         offset = parse_range(line, len, offset, " @@", &fragment->newpos, &fragment->newlines);
651
652         return offset;
653 }
654
655 static int find_header(char *line, unsigned long size, int *hdrsize, struct patch *patch)
656 {
657         unsigned long offset, len;
658
659         patch->is_rename = patch->is_copy = 0;
660         patch->is_new = patch->is_delete = -1;
661         patch->old_mode = patch->new_mode = 0;
662         patch->old_name = patch->new_name = NULL;
663         for (offset = 0; size > 0; offset += len, size -= len, line += len, linenr++) {
664                 unsigned long nextlen;
665
666                 len = linelen(line, size);
667                 if (!len)
668                         break;
669
670                 /* Testing this early allows us to take a few shortcuts.. */
671                 if (len < 6)
672                         continue;
673
674                 /*
675                  * Make sure we don't find any unconnected patch fragmants.
676                  * That's a sign that we didn't find a header, and that a
677                  * patch has become corrupted/broken up.
678                  */
679                 if (!memcmp("@@ -", line, 4)) {
680                         struct fragment dummy;
681                         if (parse_fragment_header(line, len, &dummy) < 0)
682                                 continue;
683                         error("patch fragment without header at line %d: %.*s", linenr, (int)len-1, line);
684                 }
685
686                 if (size < len + 6)
687                         break;
688
689                 /*
690                  * Git patch? It might not have a real patch, just a rename
691                  * or mode change, so we handle that specially
692                  */
693                 if (!memcmp("diff --git ", line, 11)) {
694                         int git_hdr_len = parse_git_header(line, len, size, patch);
695                         if (git_hdr_len <= len)
696                                 continue;
697                         if (!patch->old_name && !patch->new_name) {
698                                 if (!patch->def_name)
699                                         die("git diff header lacks filename information (line %d)", linenr);
700                                 patch->old_name = patch->new_name = patch->def_name;
701                         }
702                         *hdrsize = git_hdr_len;
703                         return offset;
704                 }
705
706                 /** --- followed by +++ ? */
707                 if (memcmp("--- ", line,  4) || memcmp("+++ ", line + len, 4))
708                         continue;
709
710                 /*
711                  * We only accept unified patches, so we want it to
712                  * at least have "@@ -a,b +c,d @@\n", which is 14 chars
713                  * minimum
714                  */
715                 nextlen = linelen(line + len, size - len);
716                 if (size < nextlen + 14 || memcmp("@@ -", line + len + nextlen, 4))
717                         continue;
718
719                 /* Ok, we'll consider it a patch */
720                 parse_traditional_patch(line, line+len, patch);
721                 *hdrsize = len + nextlen;
722                 linenr += 2;
723                 return offset;
724         }
725         return -1;
726 }
727
728 /*
729  * Parse a unified diff. Note that this really needs
730  * to parse each fragment separately, since the only
731  * way to know the difference between a "---" that is
732  * part of a patch, and a "---" that starts the next
733  * patch is to look at the line counts..
734  */
735 static int parse_fragment(char *line, unsigned long size, struct patch *patch, struct fragment *fragment)
736 {
737         int added, deleted;
738         int len = linelen(line, size), offset;
739         unsigned long oldlines, newlines;
740
741         offset = parse_fragment_header(line, len, fragment);
742         if (offset < 0)
743                 return -1;
744         oldlines = fragment->oldlines;
745         newlines = fragment->newlines;
746
747         if (patch->is_new < 0) {
748                 patch->is_new =  !oldlines;
749                 if (!oldlines)
750                         patch->old_name = NULL;
751         }
752         if (patch->is_delete < 0) {
753                 patch->is_delete = !newlines;
754                 if (!newlines)
755                         patch->new_name = NULL;
756         }
757
758         if (patch->is_new != !oldlines)
759                 return error("new file depends on old contents");
760         if (patch->is_delete != !newlines) {
761                 if (newlines)
762                         return error("deleted file still has contents");
763                 fprintf(stderr, "** warning: file %s becomes empty but is not deleted\n", patch->new_name);
764         }
765
766         /* Parse the thing.. */
767         line += len;
768         size -= len;
769         linenr++;
770         added = deleted = 0;
771         for (offset = len; size > 0; offset += len, size -= len, line += len, linenr++) {
772                 if (!oldlines && !newlines)
773                         break;
774                 len = linelen(line, size);
775                 if (!len || line[len-1] != '\n')
776                         return -1;
777                 switch (*line) {
778                 default:
779                         return -1;
780                 case ' ':
781                         oldlines--;
782                         newlines--;
783                         break;
784                 case '-':
785                         deleted++;
786                         oldlines--;
787                         break;
788                 case '+':
789                         added++;
790                         newlines--;
791                         break;
792
793                 /* We allow "\ No newline at end of file". Depending
794                  * on locale settings when the patch was produced we
795                  * don't know what this line looks like. The only
796                  * thing we do know is that it begins with "\ ". */
797                 case '\\':
798                         if (len < 12 || memcmp(line, "\\ ", 2))
799                                 return -1;
800                         break;
801                 }
802         }
803         /* If a fragment ends with an incomplete line, we failed to include
804          * it in the above loop because we hit oldlines == newlines == 0
805          * before seeing it.
806          */
807         if (12 < size && !memcmp(line, "\\ ", 2))
808                 offset += linelen(line, size);
809
810         patch->lines_added += added;
811         patch->lines_deleted += deleted;
812         return offset;
813 }
814
815 static int parse_single_patch(char *line, unsigned long size, struct patch *patch)
816 {
817         unsigned long offset = 0;
818         struct fragment **fragp = &patch->fragments;
819
820         while (size > 4 && !memcmp(line, "@@ -", 4)) {
821                 struct fragment *fragment;
822                 int len;
823
824                 fragment = xmalloc(sizeof(*fragment));
825                 memset(fragment, 0, sizeof(*fragment));
826                 len = parse_fragment(line, size, patch, fragment);
827                 if (len <= 0)
828                         die("corrupt patch at line %d", linenr);
829
830                 fragment->patch = line;
831                 fragment->size = len;
832
833                 *fragp = fragment;
834                 fragp = &fragment->next;
835
836                 offset += len;
837                 line += len;
838                 size -= len;
839         }
840         return offset;
841 }
842
843 static inline int metadata_changes(struct patch *patch)
844 {
845         return  patch->is_rename > 0 ||
846                 patch->is_copy > 0 ||
847                 patch->is_new > 0 ||
848                 patch->is_delete ||
849                 (patch->old_mode && patch->new_mode &&
850                  patch->old_mode != patch->new_mode);
851 }
852
853 static int parse_chunk(char *buffer, unsigned long size, struct patch *patch)
854 {
855         int hdrsize, patchsize;
856         int offset = find_header(buffer, size, &hdrsize, patch);
857
858         if (offset < 0)
859                 return offset;
860
861         patchsize = parse_single_patch(buffer + offset + hdrsize, size - offset - hdrsize, patch);
862
863         if (!patchsize && !metadata_changes(patch))
864                 die("patch with only garbage at line %d", linenr);
865
866         return offset + hdrsize + patchsize;
867 }
868
869 static const char pluses[] = "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
870 static const char minuses[]= "----------------------------------------------------------------------";
871
872 static void show_stats(struct patch *patch)
873 {
874         const char *prefix = "";
875         char *name = patch->new_name;
876         char *qname = NULL;
877         int len, max, add, del, total;
878
879         if (!name)
880                 name = patch->old_name;
881
882         if (0 < (len = quote_c_style(name, NULL, NULL, 0))) {
883                 qname = xmalloc(len + 1);
884                 quote_c_style(name, qname, NULL, 0);
885                 name = qname;
886         }
887
888         /*
889          * "scale" the filename
890          */
891         len = strlen(name);
892         max = max_len;
893         if (max > 50)
894                 max = 50;
895         if (len > max) {
896                 char *slash;
897                 prefix = "...";
898                 max -= 3;
899                 name += len - max;
900                 slash = strchr(name, '/');
901                 if (slash)
902                         name = slash;
903         }
904         len = max;
905
906         /*
907          * scale the add/delete
908          */
909         max = max_change;
910         if (max + len > 70)
911                 max = 70 - len;
912
913         add = patch->lines_added;
914         del = patch->lines_deleted;
915         total = add + del;
916
917         if (max_change > 0) {
918                 total = (total * max + max_change / 2) / max_change;
919                 add = (add * max + max_change / 2) / max_change;
920                 del = total - add;
921         }
922         printf(" %s%-*s |%5d %.*s%.*s\n", prefix,
923                 len, name, patch->lines_added + patch->lines_deleted,
924                 add, pluses, del, minuses);
925         if (qname)
926                 free(qname);
927 }
928
929 static int read_old_data(struct stat *st, const char *path, void *buf, unsigned long size)
930 {
931         int fd;
932         unsigned long got;
933
934         switch (st->st_mode & S_IFMT) {
935         case S_IFLNK:
936                 return readlink(path, buf, size);
937         case S_IFREG:
938                 fd = open(path, O_RDONLY);
939                 if (fd < 0)
940                         return error("unable to open %s", path);
941                 got = 0;
942                 for (;;) {
943                         int ret = read(fd, buf + got, size - got);
944                         if (ret < 0) {
945                                 if (errno == EAGAIN)
946                                         continue;
947                                 break;
948                         }
949                         if (!ret)
950                                 break;
951                         got += ret;
952                 }
953                 close(fd);
954                 return got;
955
956         default:
957                 return -1;
958         }
959 }
960
961 static int find_offset(const char *buf, unsigned long size, const char *fragment, unsigned long fragsize, int line)
962 {
963         int i;
964         unsigned long start, backwards, forwards;
965
966         if (fragsize > size)
967                 return -1;
968
969         start = 0;
970         if (line > 1) {
971                 unsigned long offset = 0;
972                 i = line-1;
973                 while (offset + fragsize <= size) {
974                         if (buf[offset++] == '\n') {
975                                 start = offset;
976                                 if (!--i)
977                                         break;
978                         }
979                 }
980         }
981
982         /* Exact line number? */
983         if (!memcmp(buf + start, fragment, fragsize))
984                 return start;
985
986         /*
987          * There's probably some smart way to do this, but I'll leave
988          * that to the smart and beautiful people. I'm simple and stupid.
989          */
990         backwards = start;
991         forwards = start;
992         for (i = 0; ; i++) {
993                 unsigned long try;
994                 int n;
995
996                 /* "backward" */
997                 if (i & 1) {
998                         if (!backwards) {
999                                 if (forwards + fragsize > size)
1000                                         break;
1001                                 continue;
1002                         }
1003                         do {
1004                                 --backwards;
1005                         } while (backwards && buf[backwards-1] != '\n');
1006                         try = backwards;
1007                 } else {
1008                         while (forwards + fragsize <= size) {
1009                                 if (buf[forwards++] == '\n')
1010                                         break;
1011                         }
1012                         try = forwards;
1013                 }
1014
1015                 if (try + fragsize > size)
1016                         continue;
1017                 if (memcmp(buf + try, fragment, fragsize))
1018                         continue;
1019                 n = (i >> 1)+1;
1020                 if (i & 1)
1021                         n = -n;
1022                 return try;
1023         }
1024
1025         /*
1026          * We should start searching forward and backward.
1027          */
1028         return -1;
1029 }
1030
1031 struct buffer_desc {
1032         char *buffer;
1033         unsigned long size;
1034         unsigned long alloc;
1035 };
1036
1037 static int apply_one_fragment(struct buffer_desc *desc, struct fragment *frag)
1038 {
1039         char *buf = desc->buffer;
1040         const char *patch = frag->patch;
1041         int offset, size = frag->size;
1042         char *old = xmalloc(size);
1043         char *new = xmalloc(size);
1044         int oldsize = 0, newsize = 0;
1045
1046         while (size > 0) {
1047                 int len = linelen(patch, size);
1048                 int plen;
1049
1050                 if (!len)
1051                         break;
1052
1053                 /*
1054                  * "plen" is how much of the line we should use for
1055                  * the actual patch data. Normally we just remove the
1056                  * first character on the line, but if the line is
1057                  * followed by "\ No newline", then we also remove the
1058                  * last one (which is the newline, of course).
1059                  */
1060                 plen = len-1;
1061                 if (len < size && patch[len] == '\\')
1062                         plen--;
1063                 switch (*patch) {
1064                 case ' ':
1065                 case '-':
1066                         memcpy(old + oldsize, patch + 1, plen);
1067                         oldsize += plen;
1068                         if (*patch == '-')
1069                                 break;
1070                 /* Fall-through for ' ' */
1071                 case '+':
1072                         memcpy(new + newsize, patch + 1, plen);
1073                         newsize += plen;
1074                         break;
1075                 case '@': case '\\':
1076                         /* Ignore it, we already handled it */
1077                         break;
1078                 default:
1079                         return -1;
1080                 }
1081                 patch += len;
1082                 size -= len;
1083         }
1084
1085         offset = find_offset(buf, desc->size, old, oldsize, frag->newpos);
1086         if (offset >= 0) {
1087                 int diff = newsize - oldsize;
1088                 unsigned long size = desc->size + diff;
1089                 unsigned long alloc = desc->alloc;
1090
1091                 if (size > alloc) {
1092                         alloc = size + 8192;
1093                         desc->alloc = alloc;
1094                         buf = xrealloc(buf, alloc);
1095                         desc->buffer = buf;
1096                 }
1097                 desc->size = size;
1098                 memmove(buf + offset + newsize, buf + offset + oldsize, size - offset - newsize);
1099                 memcpy(buf + offset, new, newsize);
1100                 offset = 0;
1101         }
1102
1103         free(old);
1104         free(new);
1105         return offset;
1106 }
1107
1108 static int apply_fragments(struct buffer_desc *desc, struct patch *patch)
1109 {
1110         struct fragment *frag = patch->fragments;
1111
1112         while (frag) {
1113                 if (apply_one_fragment(desc, frag) < 0)
1114                         return error("patch failed: %s:%ld", patch->old_name, frag->oldpos);
1115                 frag = frag->next;
1116         }
1117         return 0;
1118 }
1119
1120 static int apply_data(struct patch *patch, struct stat *st)
1121 {
1122         char *buf;
1123         unsigned long size, alloc;
1124         struct buffer_desc desc;
1125
1126         size = 0;
1127         alloc = 0;
1128         buf = NULL;
1129         if (patch->old_name) {
1130                 size = st->st_size;
1131                 alloc = size + 8192;
1132                 buf = xmalloc(alloc);
1133                 if (read_old_data(st, patch->old_name, buf, alloc) != size)
1134                         return error("read of %s failed", patch->old_name);
1135         }
1136
1137         desc.size = size;
1138         desc.alloc = alloc;
1139         desc.buffer = buf;
1140         if (apply_fragments(&desc, patch) < 0)
1141                 return -1;
1142         patch->result = desc.buffer;
1143         patch->resultsize = desc.size;
1144
1145         if (patch->is_delete && patch->resultsize)
1146                 return error("removal patch leaves file contents");
1147
1148         return 0;
1149 }
1150
1151 static int check_patch(struct patch *patch)
1152 {
1153         struct stat st;
1154         const char *old_name = patch->old_name;
1155         const char *new_name = patch->new_name;
1156
1157         if (old_name) {
1158                 int changed;
1159
1160                 if (lstat(old_name, &st) < 0)
1161                         return error("%s: %s", old_name, strerror(errno));
1162                 if (check_index) {
1163                         int pos = cache_name_pos(old_name, strlen(old_name));
1164                         if (pos < 0)
1165                                 return error("%s: does not exist in index", old_name);
1166                         changed = ce_match_stat(active_cache[pos], &st);
1167                         if (changed)
1168                                 return error("%s: does not match index", old_name);
1169                 }
1170                 if (patch->is_new < 0)
1171                         patch->is_new = 0;
1172                 st.st_mode = ntohl(create_ce_mode(st.st_mode));
1173                 if (!patch->old_mode)
1174                         patch->old_mode = st.st_mode;
1175                 if ((st.st_mode ^ patch->old_mode) & S_IFMT)
1176                         return error("%s: wrong type", old_name);
1177                 if (st.st_mode != patch->old_mode)
1178                         fprintf(stderr, "warning: %s has type %o, expected %o\n",
1179                                 old_name, st.st_mode, patch->old_mode);
1180         }
1181
1182         if (new_name && (patch->is_new | patch->is_rename | patch->is_copy)) {
1183                 if (check_index && cache_name_pos(new_name, strlen(new_name)) >= 0)
1184                         return error("%s: already exists in index", new_name);
1185                 if (!lstat(new_name, &st))
1186                         return error("%s: already exists in working directory", new_name);
1187                 if (errno != ENOENT)
1188                         return error("%s: %s", new_name, strerror(errno));
1189                 if (!patch->new_mode) {
1190                         if (patch->is_new)
1191                                 patch->new_mode = S_IFREG | 0644;
1192                         else
1193                                 patch->new_mode = patch->old_mode;
1194                 }
1195         }
1196
1197         if (new_name && old_name) {
1198                 int same = !strcmp(old_name, new_name);
1199                 if (!patch->new_mode)
1200                         patch->new_mode = patch->old_mode;
1201                 if ((patch->old_mode ^ patch->new_mode) & S_IFMT)
1202                         return error("new mode (%o) of %s does not match old mode (%o)%s%s",
1203                                 patch->new_mode, new_name, patch->old_mode,
1204                                 same ? "" : " of ", same ? "" : old_name);
1205         }       
1206
1207         if (apply_data(patch, &st) < 0)
1208                 return error("%s: patch does not apply", old_name);
1209         return 0;
1210 }
1211
1212 static int check_patch_list(struct patch *patch)
1213 {
1214         int error = 0;
1215
1216         for (;patch ; patch = patch->next)
1217                 error |= check_patch(patch);
1218         return error;
1219 }
1220
1221 static void show_file(int c, unsigned int mode, const char *name)
1222 {
1223         printf("%c %o %s\n", c, mode, name);
1224 }
1225
1226 static void show_file_list(struct patch *patch)
1227 {
1228         for (;patch ; patch = patch->next) {
1229                 if (patch->is_rename) {
1230                         show_file('-', patch->old_mode, patch->old_name);
1231                         show_file('+', patch->new_mode, patch->new_name);
1232                         continue;
1233                 }
1234                 if (patch->is_copy || patch->is_new) {
1235                         show_file('+', patch->new_mode, patch->new_name);
1236                         continue;
1237                 }
1238                 if (patch->is_delete) {
1239                         show_file('-', patch->old_mode, patch->old_name);
1240                         continue;
1241                 }
1242                 if (patch->old_mode && patch->new_mode && patch->old_mode != patch->new_mode) {
1243                         printf("M %o:%o %s\n", patch->old_mode, patch->new_mode, patch->old_name);
1244                         continue;
1245                 }
1246                 printf("M %o %s\n", patch->old_mode, patch->old_name);
1247         }
1248 }
1249
1250 static void stat_patch_list(struct patch *patch)
1251 {
1252         int files, adds, dels;
1253
1254         for (files = adds = dels = 0 ; patch ; patch = patch->next) {
1255                 files++;
1256                 adds += patch->lines_added;
1257                 dels += patch->lines_deleted;
1258                 show_stats(patch);
1259         }
1260
1261         printf(" %d files changed, %d insertions(+), %d deletions(-)\n", files, adds, dels);
1262 }
1263
1264 static void show_file_mode_name(const char *newdelete, unsigned int mode, const char *name)
1265 {
1266         if (mode)
1267                 printf(" %s mode %06o %s\n", newdelete, mode, name);
1268         else
1269                 printf(" %s %s\n", newdelete, name);
1270 }
1271
1272 static void show_mode_change(struct patch *p, int show_name)
1273 {
1274         if (p->old_mode && p->new_mode && p->old_mode != p->new_mode) {
1275                 if (show_name)
1276                         printf(" mode change %06o => %06o %s\n",
1277                                p->old_mode, p->new_mode, p->new_name);
1278                 else
1279                         printf(" mode change %06o => %06o\n",
1280                                p->old_mode, p->new_mode);
1281         }
1282 }
1283
1284 static void show_rename_copy(struct patch *p)
1285 {
1286         const char *renamecopy = p->is_rename ? "rename" : "copy";
1287         const char *old, *new;
1288
1289         /* Find common prefix */
1290         old = p->old_name;
1291         new = p->new_name;
1292         while (1) {
1293                 const char *slash_old, *slash_new;
1294                 slash_old = strchr(old, '/');
1295                 slash_new = strchr(new, '/');
1296                 if (!slash_old ||
1297                     !slash_new ||
1298                     slash_old - old != slash_new - new ||
1299                     memcmp(old, new, slash_new - new))
1300                         break;
1301                 old = slash_old + 1;
1302                 new = slash_new + 1;
1303         }
1304         /* p->old_name thru old is the common prefix, and old and new
1305          * through the end of names are renames
1306          */
1307         if (old != p->old_name)
1308                 printf(" %s %.*s{%s => %s} (%d%%)\n", renamecopy,
1309                        (int)(old - p->old_name), p->old_name,
1310                        old, new, p->score);
1311         else
1312                 printf(" %s %s => %s (%d%%)\n", renamecopy,
1313                        p->old_name, p->new_name, p->score);
1314         show_mode_change(p, 0);
1315 }
1316
1317 static void summary_patch_list(struct patch *patch)
1318 {
1319         struct patch *p;
1320
1321         for (p = patch; p; p = p->next) {
1322                 if (p->is_new)
1323                         show_file_mode_name("create", p->new_mode, p->new_name);
1324                 else if (p->is_delete)
1325                         show_file_mode_name("delete", p->old_mode, p->old_name);
1326                 else {
1327                         if (p->is_rename || p->is_copy)
1328                                 show_rename_copy(p);
1329                         else {
1330                                 if (p->score) {
1331                                         printf(" rewrite %s (%d%%)\n",
1332                                                p->new_name, p->score);
1333                                         show_mode_change(p, 0);
1334                                 }
1335                                 else
1336                                         show_mode_change(p, 1);
1337                         }
1338                 }
1339         }
1340 }
1341
1342 static void patch_stats(struct patch *patch)
1343 {
1344         int lines = patch->lines_added + patch->lines_deleted;
1345
1346         if (lines > max_change)
1347                 max_change = lines;
1348         if (patch->old_name) {
1349                 int len = quote_c_style(patch->old_name, NULL, NULL, 0);
1350                 if (!len)
1351                         len = strlen(patch->old_name);
1352                 if (len > max_len)
1353                         max_len = len;
1354         }
1355         if (patch->new_name) {
1356                 int len = quote_c_style(patch->new_name, NULL, NULL, 0);
1357                 if (!len)
1358                         len = strlen(patch->new_name);
1359                 if (len > max_len)
1360                         max_len = len;
1361         }
1362 }
1363
1364 static void remove_file(struct patch *patch)
1365 {
1366         if (write_index) {
1367                 if (remove_file_from_cache(patch->old_name) < 0)
1368                         die("unable to remove %s from index", patch->old_name);
1369         }
1370         unlink(patch->old_name);
1371 }
1372
1373 static void add_index_file(const char *path, unsigned mode, void *buf, unsigned long size)
1374 {
1375         struct stat st;
1376         struct cache_entry *ce;
1377         int namelen = strlen(path);
1378         unsigned ce_size = cache_entry_size(namelen);
1379
1380         if (!write_index)
1381                 return;
1382
1383         ce = xmalloc(ce_size);
1384         memset(ce, 0, ce_size);
1385         memcpy(ce->name, path, namelen);
1386         ce->ce_mode = create_ce_mode(mode);
1387         ce->ce_flags = htons(namelen);
1388         if (lstat(path, &st) < 0)
1389                 die("unable to stat newly created file %s", path);
1390         fill_stat_cache_info(ce, &st);
1391         if (write_sha1_file(buf, size, "blob", ce->sha1) < 0)
1392                 die("unable to create backing store for newly created file %s", path);
1393         if (add_cache_entry(ce, ADD_CACHE_OK_TO_ADD) < 0)
1394                 die("unable to add cache entry for %s", path);
1395 }
1396
1397 static void create_subdirectories(const char *path)
1398 {
1399         int len = strlen(path);
1400         char *buf = xmalloc(len + 1);
1401         const char *slash = path;
1402
1403         while ((slash = strchr(slash+1, '/')) != NULL) {
1404                 len = slash - path;
1405                 memcpy(buf, path, len);
1406                 buf[len] = 0;
1407                 if (mkdir(buf, 0777) < 0) {
1408                         if (errno != EEXIST)
1409                                 break;
1410                 }
1411         }
1412         free(buf);
1413 }
1414
1415 static int try_create_file(const char *path, unsigned int mode, const char *buf, unsigned long size)
1416 {
1417         int fd;
1418
1419         if (S_ISLNK(mode))
1420                 return symlink(buf, path);
1421         fd = open(path, O_CREAT | O_EXCL | O_WRONLY | O_TRUNC, (mode & 0100) ? 0777 : 0666);
1422         if (fd < 0)
1423                 return -1;
1424         while (size) {
1425                 int written = write(fd, buf, size);
1426                 if (written < 0) {
1427                         if (errno == EINTR || errno == EAGAIN)
1428                                 continue;
1429                         die("writing file %s: %s", path, strerror(errno));
1430                 }
1431                 if (!written)
1432                         die("out of space writing file %s", path);
1433                 buf += written;
1434                 size -= written;
1435         }
1436         if (close(fd) < 0)
1437                 die("closing file %s: %s", path, strerror(errno));
1438         return 0;
1439 }
1440
1441 /*
1442  * We optimistically assume that the directories exist,
1443  * which is true 99% of the time anyway. If they don't,
1444  * we create them and try again.
1445  */
1446 static void create_one_file(const char *path, unsigned mode, const char *buf, unsigned long size)
1447 {
1448         if (!try_create_file(path, mode, buf, size))
1449                 return;
1450
1451         if (errno == ENOENT) {
1452                 create_subdirectories(path);
1453                 if (!try_create_file(path, mode, buf, size))
1454                         return;
1455         }
1456
1457         if (errno == EEXIST) {
1458                 unsigned int nr = getpid();
1459
1460                 for (;;) {
1461                         const char *newpath;
1462                         newpath = mkpath("%s~%u", path, nr);
1463                         if (!try_create_file(newpath, mode, buf, size)) {
1464                                 if (!rename(newpath, path))
1465                                         return;
1466                                 unlink(newpath);
1467                                 break;
1468                         }
1469                         if (errno != EEXIST)
1470                                 break;
1471                 }                       
1472         }
1473         die("unable to write file %s mode %o", path, mode);
1474 }
1475
1476 static void create_file(struct patch *patch)
1477 {
1478         const char *path = patch->new_name;
1479         unsigned mode = patch->new_mode;
1480         unsigned long size = patch->resultsize;
1481         char *buf = patch->result;
1482
1483         if (!mode)
1484                 mode = S_IFREG | 0644;
1485         create_one_file(path, mode, buf, size); 
1486         add_index_file(path, mode, buf, size);
1487 }
1488
1489 static void write_out_one_result(struct patch *patch)
1490 {
1491         if (patch->is_delete > 0) {
1492                 remove_file(patch);
1493                 return;
1494         }
1495         if (patch->is_new > 0 || patch->is_copy) {
1496                 create_file(patch);
1497                 return;
1498         }
1499         /*
1500          * Rename or modification boils down to the same
1501          * thing: remove the old, write the new
1502          */
1503         remove_file(patch);
1504         create_file(patch);
1505 }
1506
1507 static void write_out_results(struct patch *list, int skipped_patch)
1508 {
1509         if (!list && !skipped_patch)
1510                 die("No changes");
1511
1512         while (list) {
1513                 write_out_one_result(list);
1514                 list = list->next;
1515         }
1516 }
1517
1518 static struct cache_file cache_file;
1519
1520 static struct excludes {
1521         struct excludes *next;
1522         const char *path;
1523 } *excludes;
1524
1525 static int use_patch(struct patch *p)
1526 {
1527         const char *pathname = p->new_name ? p->new_name : p->old_name;
1528         struct excludes *x = excludes;
1529         while (x) {
1530                 if (fnmatch(x->path, pathname, 0) == 0)
1531                         return 0;
1532                 x = x->next;
1533         }
1534         return 1;
1535 }
1536
1537 static int apply_patch(int fd)
1538 {
1539         int newfd;
1540         unsigned long offset, size;
1541         char *buffer = read_patch_file(fd, &size);
1542         struct patch *list = NULL, **listp = &list;
1543         int skipped_patch = 0;
1544
1545         if (!buffer)
1546                 return -1;
1547         offset = 0;
1548         while (size > 0) {
1549                 struct patch *patch;
1550                 int nr;
1551
1552                 patch = xmalloc(sizeof(*patch));
1553                 memset(patch, 0, sizeof(*patch));
1554                 nr = parse_chunk(buffer + offset, size, patch);
1555                 if (nr < 0)
1556                         break;
1557                 if (use_patch(patch)) {
1558                         patch_stats(patch);
1559                         *listp = patch;
1560                         listp = &patch->next;
1561                 } else {
1562                         /* perhaps free it a bit better? */
1563                         free(patch);
1564                         skipped_patch++;
1565                 }
1566                 offset += nr;
1567                 size -= nr;
1568         }
1569
1570         newfd = -1;
1571         write_index = check_index && apply;
1572         if (write_index)
1573                 newfd = hold_index_file_for_update(&cache_file, get_index_file());
1574         if (check_index) {
1575                 if (read_cache() < 0)
1576                         die("unable to read index file");
1577         }
1578
1579         if ((check || apply) && check_patch_list(list) < 0)
1580                 exit(1);
1581
1582         if (apply)
1583                 write_out_results(list, skipped_patch);
1584
1585         if (write_index) {
1586                 if (write_cache(newfd, active_cache, active_nr) ||
1587                     commit_index_file(&cache_file))
1588                         die("Unable to write new cachefile");
1589         }
1590
1591         if (show_files)
1592                 show_file_list(list);
1593
1594         if (diffstat)
1595                 stat_patch_list(list);
1596
1597         if (summary)
1598                 summary_patch_list(list);
1599
1600         free(buffer);
1601         return 0;
1602 }
1603
1604 int main(int argc, char **argv)
1605 {
1606         int i;
1607         int read_stdin = 1;
1608
1609         for (i = 1; i < argc; i++) {
1610                 const char *arg = argv[i];
1611                 int fd;
1612
1613                 if (!strcmp(arg, "-")) {
1614                         apply_patch(0);
1615                         read_stdin = 0;
1616                         continue;
1617                 }
1618                 if (!strncmp(arg, "--exclude=", 10)) {
1619                         struct excludes *x = xmalloc(sizeof(*x));
1620                         x->path = arg + 10;
1621                         x->next = excludes;
1622                         excludes = x;
1623                         continue;
1624                 }
1625                 /* NEEDSWORK: this does not do anything at this moment. */
1626                 if (!strcmp(arg, "--no-merge")) {
1627                         merge_patch = 0;
1628                         continue;
1629                 }
1630                 if (!strcmp(arg, "--stat")) {
1631                         apply = 0;
1632                         diffstat = 1;
1633                         continue;
1634                 }
1635                 if (!strcmp(arg, "--summary")) {
1636                         apply = 0;
1637                         summary = 1;
1638                         continue;
1639                 }
1640                 if (!strcmp(arg, "--check")) {
1641                         apply = 0;
1642                         check = 1;
1643                         continue;
1644                 }
1645                 if (!strcmp(arg, "--index")) {
1646                         check_index = 1;
1647                         continue;
1648                 }
1649                 if (!strcmp(arg, "--apply")) {
1650                         apply = 1;
1651                         continue;
1652                 }
1653                 if (!strcmp(arg, "--show-files")) {
1654                         show_files = 1;
1655                         continue;
1656                 }
1657                 fd = open(arg, O_RDONLY);
1658                 if (fd < 0)
1659                         usage(apply_usage);
1660                 read_stdin = 0;
1661                 apply_patch(fd);
1662                 close(fd);
1663         }
1664         if (read_stdin)
1665                 apply_patch(0);
1666         return 0;
1667 }