};
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? */
{
* 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,
}
-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++;
}
{
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);
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)
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);
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)));
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));
}
scratch.hash[13],
scratch.hash[14],
scratch.hash[15],
- np->file, scratch.start, scratch.end);
+ np->file->name, scratch.start, scratch.end);
}
}
* 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");
/* 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;
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
{
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");
}
};
#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 */
/* 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 */
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;
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);
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)