]> git.neil.brown.name Git - wiggle.git/commitdiff
Move parse_patch and related to new parse.c
authorNeil Brown <neilb@suse.de>
Sun, 13 May 2012 23:17:32 +0000 (09:17 +1000)
committerNeil Brown <neilb@suse.de>
Sun, 13 May 2012 23:17:32 +0000 (09:17 +1000)
... so we can use it from wiggle.c

Signed-off-by: NeilBrown <neilb@suse.de>
Makefile
merge2.c
parse.c [new file with mode: 0644]
vpatch.c
wiggle.h

index 02f65c724f9fbef73d702ea13f9514d36053c66b..46ab76940b4cdb358aa9b87ce8a35acc44d9ae57 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -16,9 +16,9 @@ LDLIBS = -lncurses
 
 all: wiggle wiggle.man test
 
-wiggle : wiggle.o load.o split.o extract.o diff.o bestmatch.o ReadMe.o \
+wiggle : wiggle.o load.o parse.o split.o extract.o diff.o bestmatch.o ReadMe.o \
               merge2.o vpatch.o ccan/hash/hash.o
-wiggle.o load.o split.o extract.o diff.o bestmatch.o ReadMe.o \
+wiggle.o load.o parse.o split.o extract.o diff.o bestmatch.o ReadMe.o \
                merge2.o vpatch.o :: wiggle.h
 split.o :: ccan/hash/hash.h config.h
 
index 34080767022620da798f5696cb72fae78b51f94c..96768fb401273580771262cd6ce1db994da4960d 100644 (file)
--- a/merge2.c
+++ b/merge2.c
@@ -24,7 +24,6 @@
  */
 
 #include "wiggle.h"
-#include <stdlib.h>
 
 /*
  * Second attempt at merging....
@@ -49,11 +48,6 @@ static inline int min(int a, int b)
 {
        return a < b ? a : b;
 }
-static inline void assert(int a)
-{
-       if (!a)
-               abort();
-}
 
 static int check_alreadyapplied(struct file af, struct file cf,
                                struct merge *m)
diff --git a/parse.c b/parse.c
new file mode 100644 (file)
index 0000000..15b06ae
--- /dev/null
+++ b/parse.c
@@ -0,0 +1,324 @@
+/*
+ * wiggle - apply rejected patches
+ *
+ * Copyright (C) 2003-2012 Neil Brown <neilb@suse.de>
+ *
+ *
+ *    This program is free software; you can redistribute it and/or modify
+ *    it under the terms of the GNU General Public License as published by
+ *    the Free Software Foundation; either version 2 of the License, or
+ *    (at your option) any later version.
+ *
+ *    This program is distributed in the hope that it will be useful,
+ *    but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *    GNU General Public License for more details.
+ *
+ *    You should have received a copy of the GNU General Public License
+ *    along with this program; if not, write to the Free Software Foundation, Inc.,
+ *    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ *    Author: Neil Brown
+ *    Email: <neilb@suse.de>
+ */
+
+/*
+ * Parse a patch file to find the names of the different
+ * files to patch and record which parts of the patch
+ * file applies to which target file.
+ */
+
+#include       "wiggle.h"
+#include       <unistd.h>
+#include       <fcntl.h>
+
+/* determine how much we need to stripe of the front of
+ * paths to find them from current directory.  This is
+ * used to guess correct '-p' value.
+ */
+static int get_strip(char *file)
+{
+       int fd;
+       int strip = 0;
+
+       while (file && *file) {
+               fd  = open(file, O_RDONLY);
+               if (fd >= 0) {
+                       close(fd);
+                       return strip;
+               }
+               strip++;
+               file = strchr(file, '/');
+               if (file)
+                       while (*file == '/')
+                               file++;
+       }
+       return -1;
+
+}
+
+int set_prefix(struct plist *pl, int n, int strip)
+{
+       int i;
+       for (i = 0; i < 4 && i < n  && strip < 0; i++)
+               strip = get_strip(pl[i].file);
+
+       if (strip < 0) {
+               fprintf(stderr, "%s: Cannot find files to patch: please specify --strip\n",
+                       Cmd);
+               return 0;
+       }
+       for (i = 0; i < n; i++) {
+               char *p = pl[i].file;
+               int j;
+               for (j = 0; j < strip; j++) {
+                       if (p)
+                               p = strchr(p, '/');
+                       while (p && *p == '/')
+                               p++;
+               }
+               if (p == NULL) {
+                       fprintf(stderr, "%s: cannot strip %d segments from %s\n",
+                               Cmd, strip, pl[i].file);
+                       return 0;
+               }
+               pl[i].file = p;
+       }
+       return 1;
+}
+
+static int pl_cmp(const void *av, const void *bv)
+{
+       const struct plist *a = av;
+       const struct plist *b = bv;
+       return strcmp(a->file, b->file);
+}
+
+static int common_depth(char *a, char *b)
+{
+       /* find number of path segments that these two have
+        * in common
+        */
+       int depth = 0;
+       while (1) {
+               char *c;
+               int al, bl;
+               c = strchr(a, '/');
+               if (c)
+                       al = c-a;
+               else
+                       al = strlen(a);
+               c = strchr(b, '/');
+               if (c)
+                       bl = c-b;
+               else
+                       bl = strlen(b);
+               if (al == 0 || al != bl || strncmp(a, b, al) != 0)
+                       return depth;
+               a += al;
+               while (*a == '/')
+                       a++;
+               b += bl;
+               while (*b == '/')
+                       b++;
+
+               depth++;
+       }
+}
+
+static struct plist *patch_add_file(struct plist *pl, int *np, char *file,
+                                   unsigned int start, unsigned int end)
+{
+       /* size of pl is 0, 16, n^2 */
+       int n = *np;
+       int asize;
+
+       while (*file == '/')
+               /* leading '/' are bad... */
+               file++;
+
+       if (n == 0)
+               asize = 0;
+       else if (n <= 16)
+               asize = 16;
+       else if ((n&(n-1)) == 0)
+               asize = n;
+       else
+               asize = n+1; /* not accurate, but not too large */
+       if (asize <= n) {
+               /* need to extend array */
+               struct plist *npl;
+               if (asize < 16)
+                       asize = 16;
+               else
+                       asize += asize;
+               npl = realloc(pl, asize * sizeof(struct plist));
+               if (!npl) {
+                       fprintf(stderr, "realloc failed - skipping %s\n", file);
+                       return pl;
+               }
+               pl = npl;
+       }
+       pl[n].file = file;
+       pl[n].start = start;
+       pl[n].end = end;
+       pl[n].last = pl[n].next = pl[n].prev = pl[n].parent = -1;
+       pl[n].chunks = pl[n].wiggles = 0; pl[n].conflicts = 100;
+       pl[n].open = 1;
+       pl[n].calced = 0;
+       pl[n].is_merge = 0;
+       *np = n+1;
+       return pl;
+}
+
+static struct plist *add_dir(struct plist *pl, int *np, char *file, char *curr)
+{
+       /* any parent of file that is not a parent of curr
+        * needs to be added to pl
+        */
+       int d = common_depth(file, curr);
+       char *buf = curr;
+       while (d) {
+               char *c = strchr(file, '/');
+               int l;
+               if (c)
+                       l = c-file;
+               else
+                       l = strlen(file);
+               file += l;
+               curr += l;
+               while (*file == '/')
+                       file++;
+               while (*curr == '/')
+                       curr++;
+               d--;
+       }
+       while (*file) {
+               if (curr > buf && curr[-1] != '/')
+                       *curr++ = '/';
+               while (*file && *file != '/')
+                       *curr++ = *file++;
+               while (*file == '/')
+                       file++;
+               *curr = '\0';
+               if (*file)
+                       pl = patch_add_file(pl, np, strdup(buf),
+                                           0, 0);
+       }
+       return pl;
+}
+
+struct plist *sort_patches(struct plist *pl, int *np)
+{
+       /* sort the patches, add directory names, and re-sort */
+       char curr[1024];
+       char *prev;
+       int parents[100];
+       int prevnode[100];
+       int i, n;
+       qsort(pl, *np, sizeof(struct plist), pl_cmp);
+       curr[0] = 0;
+       n = *np;
+       for (i = 0; i < n; i++)
+               pl = add_dir(pl, np, pl[i].file, curr);
+
+       qsort(pl, *np, sizeof(struct plist), pl_cmp);
+
+       /* array is now stable, so set up parent pointers */
+       n = *np;
+       curr[0] = 0;
+       prevnode[0] = -1;
+       prev = "";
+       for (i = 0; i < n; i++) {
+               int d = common_depth(prev, pl[i].file);
+               if (d == 0)
+                       pl[i].parent = -1;
+               else {
+                       pl[i].parent = parents[d-1];
+                       pl[pl[i].parent].last = i;
+               }
+               pl[i].prev = prevnode[d];
+               if (pl[i].prev > -1)
+                       pl[pl[i].prev].next = i;
+               prev = pl[i].file;
+               parents[d] = i;
+               prevnode[d] = i;
+               prevnode[d+1] = -1;
+       }
+       return pl;
+}
+
+struct plist *parse_patch(FILE *f, FILE *of, int *np)
+{
+       /* read a multi-file patch from 'f' and record relevant
+        * details in a plist.
+        * if 'of' >= 0, fd might not be seekable so we write
+        * to 'of' and use lseek on 'of' to determine position
+        */
+       struct plist *plist = NULL;
+
+       *np = 0;
+       while (!feof(f)) {
+               /* first, find the start of a patch: "\n+++ "
+                * grab the file name and scan to the end of a line
+                */
+               char *target = "\n+++ ";
+               char *target2 = "\n--- ";
+               char *pos = target;
+               int c;
+               char name[1024];
+               unsigned start, end;
+
+               while (*pos && (c = fgetc(f)) != EOF) {
+                       if (of)
+                               fputc(c, of);
+                       if (c == *pos)
+                               pos++;
+                       else
+                               pos = target;
+               }
+               if (c == EOF)
+                       break;
+               assert(c == ' ');
+               /* now read a file name */
+               pos = name;
+               while ((c = fgetc(f)) != EOF
+                      && c != '\t' && c != '\n' && c != ' ' &&
+                      pos - name < 1023) {
+                       *pos++ = c;
+                       if (of)
+                               fputc(c, of);
+               }
+               *pos = 0;
+               if (c == EOF)
+                       break;
+               if (of)
+                       fputc(c, of);
+               while (c != '\n' && (c = fgetc(f)) != EOF)
+                       if (of)
+                               fputc(c, of);
+
+               start = ftell(of ?: f);
+
+               if (c == EOF)
+                       break;
+
+               /* now skip to end - "\n--- " */
+               pos = target2+1;
+
+               while (*pos && (c = fgetc(f)) != EOF) {
+                       if (of)
+                               fputc(c, of);
+                       if (c == *pos)
+                               pos++;
+                       else
+                               pos = target2;
+               }
+               end = ftell(of ?: f);
+               if (pos > target2)
+                       end -= (pos - target2) - 1;
+               plist = patch_add_file(plist, np,
+                                      strdup(name), start, end);
+       }
+       return plist;
+}
index e881cea201d10f3ba08487fe159a4fa95116518e..5432b5985e23fe625fbeba2685e56e43fc7021c5 100644 (file)
--- a/vpatch.c
+++ b/vpatch.c
@@ -47,8 +47,6 @@
 
 static void term_init(void);
 
-#define assert(x) do { if (!(x)) abort(); } while (0)
-
 /* global attributes */
 unsigned int a_delete, a_added, a_common, a_sep, a_void,
        a_unmatched, a_extra, a_already;
@@ -1148,25 +1146,6 @@ static char *merge_window_help[] = {
        NULL
 };
 
-/* plist stores a list of patched files in an array
- * Each entry identifies a file, the range of the
- * original patch which applies to this file, some
- * statistics concerning how many conflicts etc, and
- * some linkage information so the list can be viewed
- * as a directory-tree.
- */
-struct plist {
-       char *file;
-       unsigned int start, end;
-       int parent;
-       int next, prev, last;
-       int open;
-       int chunks, wiggles, conflicts;
-       int calced;
-       int is_merge;
-       char *before, *after;
-};
-
 static void merge_window(struct plist *p, FILE *f, int reverse)
 {
        /* Display the merge window in one of the selectable modes,
@@ -1915,297 +1894,6 @@ static void show_merge(char *origname, FILE *patch, int reverse,
        merge_window(&p, patch, reverse);
 }
 
-static struct plist *patch_add_file(struct plist *pl, int *np, char *file,
-                                   unsigned int start, unsigned int end)
-{
-       /* size of pl is 0, 16, n^2 */
-       int n = *np;
-       int asize;
-
-       while (*file == '/')
-               /* leading '/' are bad... */
-               file++;
-
-       if (n == 0)
-               asize = 0;
-       else if (n <= 16)
-               asize = 16;
-       else if ((n&(n-1)) == 0)
-               asize = n;
-       else
-               asize = n+1; /* not accurate, but not too large */
-       if (asize <= n) {
-               /* need to extend array */
-               struct plist *npl;
-               if (asize < 16)
-                       asize = 16;
-               else
-                       asize += asize;
-               npl = realloc(pl, asize * sizeof(struct plist));
-               if (!npl) {
-                       fprintf(stderr, "realloc failed - skipping %s\n", file);
-                       return pl;
-               }
-               pl = npl;
-       }
-       pl[n].file = file;
-       pl[n].start = start;
-       pl[n].end = end;
-       pl[n].last = pl[n].next = pl[n].prev = pl[n].parent = -1;
-       pl[n].chunks = pl[n].wiggles = 0; pl[n].conflicts = 100;
-       pl[n].open = 1;
-       pl[n].calced = 0;
-       pl[n].is_merge = 0;
-       *np = n+1;
-       return pl;
-}
-
-static struct plist *parse_patch(FILE *f, FILE *of, int *np)
-{
-       /* read a multi-file patch from 'f' and record relevant
-        * details in a plist.
-        * if 'of' >= 0, fd might not be seekable so we write
-        * to 'of' and use lseek on 'of' to determine position
-        */
-       struct plist *plist = NULL;
-
-       *np = 0;
-       while (!feof(f)) {
-               /* first, find the start of a patch: "\n+++ "
-                * grab the file name and scan to the end of a line
-                */
-               char *target = "\n+++ ";
-               char *target2 = "\n--- ";
-               char *pos = target;
-               int c;
-               char name[1024];
-               unsigned start, end;
-
-               while (*pos && (c = fgetc(f)) != EOF) {
-                       if (of)
-                               fputc(c, of);
-                       if (c == *pos)
-                               pos++;
-                       else
-                               pos = target;
-               }
-               if (c == EOF)
-                       break;
-               assert(c == ' ');
-               /* now read a file name */
-               pos = name;
-               while ((c = fgetc(f)) != EOF
-                      && c != '\t' && c != '\n' && c != ' ' &&
-                      pos - name < 1023) {
-                       *pos++ = c;
-                       if (of)
-                               fputc(c, of);
-               }
-               *pos = 0;
-               if (c == EOF)
-                       break;
-               if (of)
-                       fputc(c, of);
-               while (c != '\n' && (c = fgetc(f)) != EOF)
-                       if (of)
-                               fputc(c, of);
-
-               start = ftell(of ?: f);
-
-               if (c == EOF)
-                       break;
-
-               /* now skip to end - "\n--- " */
-               pos = target2+1;
-
-               while (*pos && (c = fgetc(f)) != EOF) {
-                       if (of)
-                               fputc(c, of);
-                       if (c == *pos)
-                               pos++;
-                       else
-                               pos = target2;
-               }
-               end = ftell(of ?: f);
-               if (pos > target2)
-                       end -= (pos - target2) - 1;
-               plist = patch_add_file(plist, np,
-                                      strdup(name), start, end);
-       }
-       return plist;
-}
-
-static int pl_cmp(const void *av, const void *bv)
-{
-       const struct plist *a = av;
-       const struct plist *b = bv;
-       return strcmp(a->file, b->file);
-}
-
-static int common_depth(char *a, char *b)
-{
-       /* find number of path segments that these two have
-        * in common
-        */
-       int depth = 0;
-       while (1) {
-               char *c;
-               int al, bl;
-               c = strchr(a, '/');
-               if (c)
-                       al = c-a;
-               else
-                       al = strlen(a);
-               c = strchr(b, '/');
-               if (c)
-                       bl = c-b;
-               else
-                       bl = strlen(b);
-               if (al == 0 || al != bl || strncmp(a, b, al) != 0)
-                       return depth;
-               a += al;
-               while (*a == '/')
-                       a++;
-               b += bl;
-               while (*b == '/')
-                       b++;
-
-               depth++;
-       }
-}
-
-static struct plist *add_dir(struct plist *pl, int *np, char *file, char *curr)
-{
-       /* any parent of file that is not a parent of curr
-        * needs to be added to pl
-        */
-       int d = common_depth(file, curr);
-       char *buf = curr;
-       while (d) {
-               char *c = strchr(file, '/');
-               int l;
-               if (c)
-                       l = c-file;
-               else
-                       l = strlen(file);
-               file += l;
-               curr += l;
-               while (*file == '/')
-                       file++;
-               while (*curr == '/')
-                       curr++;
-               d--;
-       }
-       while (*file) {
-               if (curr > buf && curr[-1] != '/')
-                       *curr++ = '/';
-               while (*file && *file != '/')
-                       *curr++ = *file++;
-               while (*file == '/')
-                       file++;
-               *curr = '\0';
-               if (*file)
-                       pl = patch_add_file(pl, np, strdup(buf),
-                                           0, 0);
-       }
-       return pl;
-}
-
-static struct plist *sort_patches(struct plist *pl, int *np)
-{
-       /* sort the patches, add directory names, and re-sort */
-       char curr[1024];
-       char *prev;
-       int parents[100];
-       int prevnode[100];
-       int i, n;
-       qsort(pl, *np, sizeof(struct plist), pl_cmp);
-       curr[0] = 0;
-       n = *np;
-       for (i = 0; i < n; i++)
-               pl = add_dir(pl, np, pl[i].file, curr);
-
-       qsort(pl, *np, sizeof(struct plist), pl_cmp);
-
-       /* array is now stable, so set up parent pointers */
-       n = *np;
-       curr[0] = 0;
-       prevnode[0] = -1;
-       prev = "";
-       for (i = 0; i < n; i++) {
-               int d = common_depth(prev, pl[i].file);
-               if (d == 0)
-                       pl[i].parent = -1;
-               else {
-                       pl[i].parent = parents[d-1];
-                       pl[pl[i].parent].last = i;
-               }
-               pl[i].prev = prevnode[d];
-               if (pl[i].prev > -1)
-                       pl[pl[i].prev].next = i;
-               prev = pl[i].file;
-               parents[d] = i;
-               prevnode[d] = i;
-               prevnode[d+1] = -1;
-       }
-       return pl;
-}
-
-/* determine how much we need to stripe of the front of
- * paths to find them from current directory.  This is
- * used to guess correct '-p' value.
- */
-static int get_strip(char *file)
-{
-       int fd;
-       int strip = 0;
-
-       while (file && *file) {
-               fd  = open(file, O_RDONLY);
-               if (fd >= 0) {
-                       close(fd);
-                       return strip;
-               }
-               strip++;
-               file = strchr(file, '/');
-               if (file)
-                       while (*file == '/')
-                               file++;
-       }
-       return -1;
-
-}
-
-static int set_prefix(struct plist *pl, int n, int strip)
-{
-       int i;
-       for (i = 0; i < 4 && i < n  && strip < 0; i++)
-               strip = get_strip(pl[i].file);
-
-       if (strip < 0) {
-               fprintf(stderr, "%s: Cannot find files to patch: please specify --strip\n",
-                       Cmd);
-               return 0;
-       }
-       for (i = 0; i < n; i++) {
-               char *p = pl[i].file;
-               int j;
-               for (j = 0; j < strip; j++) {
-                       if (p)
-                               p = strchr(p, '/');
-                       while (p && *p == '/')
-                               p++;
-               }
-               if (p == NULL) {
-                       fprintf(stderr, "%s: cannot strip %d segments from %s\n",
-                               Cmd, strip, pl[i].file);
-                       return 0;
-               }
-               pl[i].file = p;
-       }
-       return 1;
-}
-
 static void calc_one(struct plist *pl, FILE *f, int reverse)
 {
        struct stream s1, s2;
index 82e8e10ff69d1892701f6e2ab3c73f5f126153b3..8e55489f6e1712c2136ae47a6cc7db7e67f9c80f 100644 (file)
--- a/wiggle.h
+++ b/wiggle.h
 #include       <string.h>
 #include       <memory.h>
 #include       <getopt.h>
+#include       <stdlib.h>
+
+static inline void assert(int a)
+{
+       if (!a)
+               abort();
+}
 
 struct stream {
        char *body;
@@ -117,8 +124,31 @@ struct merge {
                    */
 
 };
+
+/* plist stores a list of patched files in an array
+ * Each entry identifies a file, the range of the
+ * original patch which applies to this file, some
+ * statistics concerning how many conflicts etc, and
+ * some linkage information so the list can be viewed
+ * as a directory-tree.
+ */
+struct plist {
+       char *file;
+       unsigned int start, end;
+       int parent;
+       int next, prev, last;
+       int open;
+       int chunks, wiggles, conflicts;
+       int calced;
+       int is_merge;
+       char *before, *after;
+};
+
+extern struct plist *sort_patches(struct plist *pl, int *np);
+extern struct plist *parse_patch(FILE *f, FILE *of, int *np);
 extern struct stream load_segment(FILE *f, unsigned int start,
                                  unsigned int end);
+extern int set_prefix(struct plist *pl, int n, int strip);
 extern struct stream load_file(char *name);
 extern int split_patch(struct stream, struct stream*, struct stream*);
 extern int split_merge(struct stream, struct stream*, struct stream*,