5169cd762f65fc3f8b416d6f993838e901e2382e
[rsync-patches.git] / last-match.diff
1 This adds the ability to put rules into a filter/include/exclude file
2 in last-match-wins order.  All you need to do is to start the file with
3 this line:
4
5 [last-match]
6
7 --- orig/exclude.c      2005-02-27 07:34:27
8 +++ exclude.c   2005-02-26 03:22:20
9 @@ -73,6 +73,7 @@ static BOOL parent_dirscan = False;
10  static struct filter_struct **mergelist_parents;
11  static int mergelist_cnt = 0;
12  static int mergelist_size = 0;
13 +static int reversing_rules = 0;
14  
15  /* Each filter_list_struct describes a singly-linked list by keeping track
16   * of both the head and tail pointers.  The list is slightly unusual in that
17 @@ -231,6 +232,9 @@ static void add_rule(struct filter_list_
18         if (!listp->tail) {
19                 ret->next = listp->head;
20                 listp->head = listp->tail = ret;
21 +       } else if (reversing_rules) {
22 +               ret->next = listp->head;
23 +               listp->head = ret;
24         } else {
25                 ret->next = listp->tail->next;
26                 listp->tail->next = ret;
27 @@ -959,6 +963,7 @@ void parse_filter_file(struct filter_lis
28         char line[MAXPATHLEN+MAX_RULE_PREFIX+1]; /* +1 for trailing slash. */
29         char *eob = line + sizeof line - 1;
30         int word_split = mflags & MATCHFLG_WORD_SPLIT;
31 +       int save_reversing_rules = reversing_rules;
32  
33         if (!fname || !*fname)
34                 return;
35 @@ -994,6 +999,7 @@ void parse_filter_file(struct filter_lis
36         }
37         dirbuf[dirbuf_len] = '\0';
38  
39 +       reversing_rules = 0;
40         while (1) {
41                 char *s = line;
42                 int ch, overflow = 0;
43 @@ -1017,6 +1023,10 @@ void parse_filter_file(struct filter_lis
44                         s = line;
45                 }
46                 *s = '\0';
47 +               if (*line == '[' && strcmp(line+1, "last-match]") == 0) {
48 +                       reversing_rules = 1;
49 +                       continue;
50 +               }
51                 /* Skip an empty token and (when line parsing) comments. */
52                 if (*line && (word_split || (*line != ';' && *line != '#')))
53                         parse_rule(listp, line, mflags, xflags);
54 @@ -1024,6 +1034,7 @@ void parse_filter_file(struct filter_lis
55                         break;
56         }
57         fclose(fp);
58 +       reversing_rules = save_reversing_rules;
59  }
60  
61  /* If the "for_xfer" flag is set, the prefix is made compatible with the