145 lines
3.4 KiB
C
145 lines
3.4 KiB
C
/* This file is part of the software similarity tester SIM.
|
|
Written by Dick Grune, Vrije Universiteit, Amsterdam.
|
|
$Id: runs.c,v 1.17 2016-07-31 18:55:44 dick Exp $
|
|
*/
|
|
|
|
#include "sim.h"
|
|
#include "text.h"
|
|
#include "runs.h"
|
|
#include "Malloc.h"
|
|
#include "debug.par"
|
|
|
|
static struct run *runs;
|
|
static void set_chunk(
|
|
struct chunk *cnk, struct text *txt, size_t start, size_t size);
|
|
static void set_pos(
|
|
struct position *pos, int type, struct text *txt, size_t start);
|
|
|
|
void
|
|
add_to_runs(
|
|
struct text *txt0, size_t i0, struct text *txt1, size_t i1,
|
|
size_t size
|
|
) {
|
|
struct run *r = new(struct run);
|
|
/* This should always succeed, since releasing the forward_reference[]
|
|
and the last_index[] tables will have freed large amounts of memory,
|
|
and massive comparisons as in percentage.c are not reasonable and
|
|
quite useless here, due to the enormous amount of output to be
|
|
expected.
|
|
*/
|
|
|
|
set_chunk(&r->rn_chunk0, txt0, i0 - txt0->tx_start, size);
|
|
set_chunk(&r->rn_chunk1, txt1, i1 - txt1->tx_start, size);
|
|
r->rn_size = size;
|
|
|
|
#ifdef DB_RUN
|
|
fprintf(Debug_File, "add_to_runs: %s, %s, %d\n",
|
|
r->rn_chunk0.ch_text->tx_fname,
|
|
r->rn_chunk1.ch_text->tx_fname,
|
|
r->rn_size);
|
|
#endif
|
|
r->rn_next = runs;
|
|
runs = r;
|
|
}
|
|
|
|
static void
|
|
set_chunk(struct chunk *cnk, struct text *txt,
|
|
size_t start, size_t size
|
|
) {
|
|
/* Fill the chunk *cnk with info about the piece of text
|
|
in txt starting at start extending over size tokens.
|
|
*/
|
|
cnk->ch_text = txt;
|
|
set_pos(&cnk->ch_first, 0, txt, start);
|
|
set_pos(&cnk->ch_last, 1, txt, start + size - 1);
|
|
}
|
|
|
|
static void
|
|
set_pos(struct position *pos, int type, struct text *txt, size_t start) {
|
|
/* Fill a single struct position */
|
|
pos->ps_next = txt->tx_pos;
|
|
txt->tx_pos = pos;
|
|
|
|
pos->ps_type = type;
|
|
pos->ps_tk_cnt = start;
|
|
pos->ps_nl_cnt = (size_t) -1; /* uninitialized */
|
|
}
|
|
|
|
/* instantiate sort_run_list(struct run **listhook) */
|
|
#define SORT_STRUCT run
|
|
#define SORT_NAME sort_run_list
|
|
#define SORT_BEFORE(r0,r1) ((r0)->rn_size > (r1)->rn_size)
|
|
#define SORT_NEXT rn_next
|
|
#include "sortlist.bdy"
|
|
|
|
static void
|
|
reverse_runs(struct run **r_p) {
|
|
struct run *r = *r_p;
|
|
struct run *res = 0;
|
|
|
|
while (r) {
|
|
struct run *top = r;
|
|
r = top->rn_next;
|
|
top->rn_next = res;
|
|
res = top;
|
|
}
|
|
*r_p = res;
|
|
}
|
|
|
|
struct run *
|
|
unsorted_runs(void) {
|
|
reverse_runs(&runs);
|
|
return runs;
|
|
}
|
|
|
|
struct run *
|
|
sorted_runs(void) {
|
|
reverse_runs(&runs);
|
|
sort_run_list(&runs);
|
|
return runs;
|
|
}
|
|
|
|
void
|
|
discard_runs(void) {
|
|
while (runs) {
|
|
struct run *r = runs;
|
|
runs = r->rn_next;
|
|
Free(r);
|
|
}
|
|
}
|
|
|
|
#ifdef DB_RUN
|
|
|
|
void
|
|
db_run_info(const char *msg, const struct run *run, int lines_too) {
|
|
const struct chunk *cnk0 = &run->rn_chunk0;
|
|
const struct chunk *cnk1 = &run->rn_chunk1;
|
|
|
|
if (msg) {
|
|
fprintf(Debug_File, "%s: ", msg);
|
|
}
|
|
fprintf(Debug_File, "\"%s\" / \"%s\":\n",
|
|
cnk0->ch_text->tx_fname, cnk1->ch_text->tx_fname
|
|
);
|
|
fprintf(Debug_File, "from %s %s/%s to %s/%s:", Token_Name,
|
|
size_t2string(cnk0->ch_first.ps_tk_cnt),
|
|
size_t2string(cnk1->ch_first.ps_tk_cnt),
|
|
size_t2string(cnk0->ch_last.ps_tk_cnt),
|
|
size_t2string(cnk1->ch_last.ps_tk_cnt)
|
|
);
|
|
if (lines_too) {
|
|
fprintf(Debug_File, " from lines %s/%s to %s/%s:",
|
|
size_t2string(cnk0->ch_first.ps_nl_cnt),
|
|
size_t2string(cnk1->ch_first.ps_nl_cnt),
|
|
size_t2string(cnk0->ch_last.ps_nl_cnt),
|
|
size_t2string(cnk1->ch_last.ps_nl_cnt)
|
|
);
|
|
}
|
|
fprintf(Debug_File, " %s %s%s\n",
|
|
size_t2string(run->rn_size),
|
|
Token_Name, (run->rn_size == 1 ? "" : "s")
|
|
);
|
|
}
|
|
|
|
#endif /* DB_RUN */
|