Files
hustoj/core/sim/sim_3_01/runs.c
2024-10-10 12:56:56 +08:00

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 */