From ceb4da8ae7094aef1656bf105d10e12023db7de3 Mon Sep 17 00:00:00 2001 From: "Eric S. Raymond" Date: Sat, 13 Sep 2003 01:39:45 +0000 Subject: [PATCH] Include a line length field in the range reports. --- main.c | 53 ++++++++++++++++++++++++++++++++++-------------- report.c | 12 +++++++---- scf-standard.xml | 6 +++--- shred.h | 15 +++++++++++--- shredtree.c | 10 ++++----- 5 files changed, 66 insertions(+), 30 deletions(-) diff --git a/main.c b/main.c index 343f4d9..270a6c3 100644 --- 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); } } diff --git a/report.c b/report.c index 6f0e308..b7f6691 100644 --- 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"); } diff --git a/scf-standard.xml b/scf-standard.xml index ee128d9..4d298ee 100644 --- a/scf-standard.xml +++ b/scf-standard.xml @@ -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. 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. +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. 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 425644c..c04cf8c 100644 --- 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 */ diff --git a/shredtree.c b/shredtree.c index 08537ac..f5c46a5 100644 --- a/shredtree.c +++ b/shredtree.c @@ -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) -- 2.43.0