]> thyrsus.com Git - comparator.git/commitdiff
Include a line length field in the range reports.
authorEric S. Raymond <esr@thyrsus.com>
Sat, 13 Sep 2003 01:39:45 +0000 (01:39 +0000)
committerEric S. Raymond <esr@thyrsus.com>
Sat, 13 Sep 2003 01:39:45 +0000 (01:39 +0000)
main.c
report.c
scf-standard.xml
shred.h
shredtree.c

diff --git a/main.c b/main.c
index 343f4d97b068a0eb56d1657c7f57a764f7586598..270a6c3a63d8e4b9af9cd0a749d38829d17ea6af 100644 (file)
--- a/main.c
+++ b/main.c
@@ -24,10 +24,23 @@ struct scf_t
 };
 static struct scf_t dummy_scf, *scflist = &dummy_scf;
 
+static struct filehdr_t dummy_filehdr, *filelist = &dummy_filehdr;
+
 static int chunk_count, sort_count;
 static struct hash_t *chunk_buffer;
 static struct sorthash_t *sort_buffer;
 
+struct filehdr_t *register_file(const char *file, linenum_t length)
+/* register a file and its line count into the in-core list */
+{
+    struct filehdr_t   *new = (struct filehdr_t *)malloc(sizeof(struct filehdr_t));
+    new->name = strdup(file);
+    new->length = length;
+    new->next = filelist;
+    filelist = new;
+    return(new);
+}
+
 static int is_scf_file(const char *file)
 /* is the specified file an SCF hash list? */
 {
@@ -52,7 +65,7 @@ static int is_scf_file(const char *file)
  * can get quite large.
  */
 
-static void filehook(struct hash_t hash, const char *file)
+static void filehook(struct hash_t hash, struct filehdr_t *file)
 /* hook to store only hashes */
 {
     chunk_buffer = (struct hash_t *)realloc(chunk_buffer, 
@@ -62,14 +75,14 @@ static void filehook(struct hash_t hash, const char *file)
 }
 
 
-void corehook(struct hash_t hash, const char *file)
+void corehook(struct hash_t hash, struct filehdr_t *file)
 /* hook to store hash and file */
 {
     sort_buffer = (struct sorthash_t *)realloc(sort_buffer, 
                                      sizeof(struct sorthash_t) * (sort_count+1));
     
     sort_buffer[sort_count].hash = hash;
-    sort_buffer[sort_count].file = (char *)file;
+    sort_buffer[sort_count].file = file;
     sort_count++;
 }
 
@@ -85,7 +98,7 @@ static void write_scf(const char *tree, FILE *ofp)
 {
     char       **place, **list;
     int                file_count, progress, totalchunks;
-    u_int32_t  netfile_count, totallines = 0;
+    u_int32_t  netfile_count, lines, totallines = 0;
     char       buf[BUFSIZ];
 
     list = sorted_file_list(tree, &file_count);
@@ -114,17 +127,23 @@ static void write_scf(const char *tree, FILE *ofp)
     progress = totalchunks = 0;
     for (place = list; place < list + file_count; place++)
     {
-       linenum_t       net_chunks;
+       linenum_t       net_chunks, lines;
        struct hash_t   *np;
+       struct filehdr_t        *filep;
 
        /* shredfile adds data to chunk_buffer */
        chunk_buffer = (struct hash_t *)calloc(sizeof(struct hash_t), 1);
        chunk_count = 0;
-       totallines += shredfile(*place, filehook);
+       filep = register_file(*place, 0);
+       lines = shredfile(filep, filehook);
+       filep->length = lines;
 
        /* the actual output */
        fputs(*place, ofp);
        fputc('\n', ofp);
+       totallines += lines;
+       lines = TONET(lines);
+       fwrite((char *)&lines, sizeof(linenum_t), 1, ofp);
        net_chunks = TONET(chunk_count);
        fwrite((char *)&net_chunks, sizeof(linenum_t), 1, ofp);
        if (debug)
@@ -186,15 +205,15 @@ static void read_scf(struct scf_t *scf)
     while (filecount--)
     {
        char    buf[BUFSIZ];
-       linenum_t       chunks;
+       linenum_t       lines, chunks;
+       struct filehdr_t        *filehdr;
 
        fgets(buf, sizeof(buf), scf->fp);
        *strchr(buf, '\n') = '\0';
-       /*
-        * This isn't freed anywhere before end of execution.
-        * That's a potential memory leak if this routine is misapplied
-        */
-       scf->name = strdup(buf);
+
+       fread(&lines, sizeof(linenum_t), 1, scf->fp);
+       lines = FROMNET(lines);
+       filehdr = register_file(buf, lines);
 
        fread(&chunks, sizeof(linenum_t), 1, scf->fp);
        chunks = FROMNET(chunks);
@@ -207,7 +226,7 @@ static void read_scf(struct scf_t *scf)
            fread(this.hash, sizeof(char), HASHSIZE, scf->fp);
            this.start = FROMNET(this.start);
            this.end = FROMNET(this.end);
-           corehook(this, scf->name);
+           corehook(this, filehdr);
            hashcount++;
            if (!debug && hashcount % 10000 == 0)
                fprintf(stderr,"\b\b\b%02.0f%%",(ftell(scf->fp) / (sb.st_size * 0.01)));
@@ -239,7 +258,11 @@ static int merge_tree(char *tree)
     fprintf(stderr, "reading...   ");
     for (place = list; place < list + file_count; place++)
     {
-       totallines += shredfile(*place, corehook);
+       struct filehdr_t *filep = register_file(*place, 0);
+       linenum_t lines = shredfile(filep, corehook);
+
+       filep->length = lines; 
+       totallines += lines;
        if (!debug && !(i++ % 100))
            fprintf(stderr, "\b\b\b%02.0f%%", i / (file_count * 0.01));
     }
@@ -341,7 +364,7 @@ void dump_array(const char *legend,
               scratch.hash[13], 
               scratch.hash[14], 
               scratch.hash[15],
-              np->file, scratch.start, scratch.end);
+              np->file->name, scratch.start, scratch.end);
     }
 }
 
index 6f0e30814f34fae2314823bb6636d3a2c8542e7a..b7f66915895bdf0902fc59e77c27e417b0451ac9 100644 (file)
--- a/report.c
+++ b/report.c
@@ -36,7 +36,7 @@ static int merge_ranges(struct sorthash_t *p,
      * segments of text, which is the only case we are interested in.
      */
     for (i = 0; i < nmatches; i++)
-       if (strcmp(p[i].file, q[i].file))
+       if (strcmp(p[i].file->name, q[i].file->name))
        {
 #ifdef DEBUG
            printf("File mismatch\n");
@@ -234,7 +234,7 @@ struct match_t *reduce_matches(struct sorthash_t *obarray, int *hashcountp)
         /* if all these matches are within the same tree, toss them */
         heterogenous = 0;
         for (i = 0; i < nmatches; i++)
-            if (!sametree(np[i].file, np[(i+1) % nmatches].file))
+            if (!sametree(np[i].file->name, np[(i+1) % nmatches].file->name))
                 heterogenous++;
         if (!heterogenous)
             continue;
@@ -276,7 +276,7 @@ static int sortmatch(const void *a, const void *b)
     struct sorthash_t *s = ((struct match_t *)a)->matches;
     struct sorthash_t *t = ((struct match_t *)b)->matches;
 
-    int cmp = strcmp(s->file, t->file);
+    int cmp = strcmp(s->file->name, t->file->name);
     if (cmp)
        return(cmp);
     else
@@ -315,7 +315,11 @@ void emit_report(struct sorthash_t *obarray, int hashcount)
        {
            struct sorthash_t   *rp = match->matches+i;
 
-           printf("%s:%d:%d\n",  rp->file, rp->hash.start, rp->hash.end);
+           printf("%s:%d:%d:%d\n", 
+                  rp->file->name, 
+                  rp->hash.start, rp->hash.end,
+                  rp->file->length
+               );
        }
        printf("%%%%\n");
     }
index ee128d92daba399924f66664c28e37bdb882ffbf..4d298eed12165874ceefd06e7409c36764a016db 100644 (file)
@@ -330,9 +330,9 @@ of count lines followed by a %%\n section marker. Each linecount line
 consists of two colon-separated fields, a tree name and a line count.</para>
 
 <para>Each range set consists of two or more ranges followed by a line
-containing a %%\n section marker.  A range is represented as three
-tab-separated fields: filename, start line, and end line.  Line
-numbers are 1-origin.</para>
+containing a %%\n section marker.  A range is represented as four
+tab-separated fields: filename, start line, end line, and length of
+file in lines.  Line numbers are 1-origin.</para>
 
 <para>The natural sort order for range sets is by filename, then by
 start line, then by end line.  Ranges within range sets should be
diff --git a/shred.h b/shred.h
index 425644c9b2d13281e866dac853099d3f71ae453a..c04cf8c4b4ed9b9924a8d631e4f3dcf832d4d774 100644 (file)
--- a/shred.h
+++ b/shred.h
@@ -20,10 +20,17 @@ struct hash_t
 };
 #define HASHCMP(s, t)  memcmp((s)->hash.hash, (t)->hash.hash, HASHSIZE)
 
+struct filehdr_t
+{
+    char       *name;
+    linenum_t  length;
+    struct filehdr_t *next;
+};
+
 struct sorthash_t
 {
     struct hash_t      hash;
-    char               *file;
+    struct filehdr_t   *file;
 };
 
 /* control bits, meant to be set at startup */
@@ -35,14 +42,16 @@ extern int shredsize;
 
 /* main.c functions */
 extern void report_time(char *legend, ...);
-extern void corehook(struct hash_t hash, const char *file);
+struct filehdr_t *register_file(const char *file, linenum_t length);
+extern void corehook(struct hash_t hash, struct filehdr_t *file);
 extern void extend_current_chunk(void);
 extern void dump_array(const char *legend,
                       struct sorthash_t *obarray, int hashcount);
 
 /* shredtree.c functions */
 extern char **sorted_file_list(const char *, int *);
-extern int shredfile(const char *, void (*hook)(struct hash_t, const char *));
+extern int shredfile(struct filehdr_t *, 
+                    void (*hook)(struct hash_t, struct filehdr_t *));
 extern void sort_hashes(struct sorthash_t *hashlist, int hashcount);
 
 /* shredcompare.c functions */
index 08537ac4baaf00f274800f92bfa90d3ce2e92bf1..f5c46a5ac0824da5a4724861fee2708f4020cdbd 100644 (file)
@@ -156,8 +156,8 @@ static struct hash_t emit_chunk(shred *display, int linecount)
     return(out);
 }
 
-int shredfile(const char *file, 
-                     void (*hook)(struct hash_t, const char *))
+int shredfile(struct filehdr_t *file, 
+                     void (*hook)(struct hash_t, struct filehdr_t *))
 /* emit hash section for specified file */
 {
     FILE *fp;
@@ -165,7 +165,7 @@ int shredfile(const char *file,
     int i, linecount, accepted;
     shred *display;
 
-    if ((fp = fopen(file, "r")) == NULL)
+    if ((fp = fopen(file->name, "r")) == NULL)
     {
        fprintf(stderr, "shredtree: couldn't open %s, error %d\n",
                file, errno);
@@ -294,8 +294,8 @@ static int sortchunk(const void *a, const void *b)
     if (cmp)
        return(cmp);
     else
-       return(strcmp(((struct sorthash_t *)a)->file,
-                     ((struct sorthash_t *)b)->file));
+       return(strcmp(((struct sorthash_t *)a)->file->name,
+                     ((struct sorthash_t *)b)->file->name));
 }
 
 void sort_hashes(struct sorthash_t *hashlist, int hashcount)