2024-10-10
This commit is contained in:
253
core/sim/sim_3_01/sim.c
Executable file
253
core/sim/sim_3_01/sim.c
Executable file
@@ -0,0 +1,253 @@
|
||||
/* This file is part of the software similarity tester SIM.
|
||||
Written by Dick Grune, Vrije Universiteit, Amsterdam.
|
||||
$Id: sim.c,v 2.69 2017-03-19 09:30:38 dick Exp $
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "system.par"
|
||||
#include "settings.par"
|
||||
#include "sim.h"
|
||||
#include "options.h"
|
||||
#include "newargs.h"
|
||||
#include "token.h"
|
||||
#include "tokenarray.h"
|
||||
#include "language.h"
|
||||
#include "text.h"
|
||||
#include "runs.h"
|
||||
#include "hash.h"
|
||||
#include "compare.h"
|
||||
#include "pass1.h"
|
||||
#include "pass2.h"
|
||||
#include "pass3.h"
|
||||
#include "percentages.h"
|
||||
#include "stream.h"
|
||||
#include "lang.h"
|
||||
|
||||
#include "Malloc.h"
|
||||
#include "any_int.h"
|
||||
|
||||
const char *Version;
|
||||
|
||||
/* PARAMETERS */
|
||||
/* Command-line parameters, with defaults */
|
||||
int Min_Run_Size = DEFAULT_MIN_RUN_SIZE;
|
||||
int Page_Width = DEFAULT_PAGE_WIDTH;
|
||||
int Threshold_Percentage = 1;
|
||||
FILE *Output_File;
|
||||
FILE *Debug_File;
|
||||
|
||||
/* Language-specific parameters; may be changed in Init_Language() */
|
||||
const char *Token_Name = "token";
|
||||
|
||||
static const char *progname; /* for error reporting */
|
||||
static const char *output_name; /* for redirecting the output */
|
||||
|
||||
static const struct option optlist[] = {
|
||||
{'r', "set minimum run size to N", Number, &Min_Run_Size},
|
||||
|
||||
{' ', "output runs as text (default)", None, 0},
|
||||
{'d', "output in a diff-like format", None, 0},
|
||||
{'n', "suppress the text of the runs", None, 0},
|
||||
{'T', "suppress reporting the input files", None, 0},
|
||||
{'p', "output similarity in percentages", None, 0},
|
||||
{'P', "main contributing file to percentages only", None, 0},
|
||||
{'t', "threshold level of percentages", Number, &Threshold_Percentage},
|
||||
|
||||
{'e', "compare each file to each file separately", None, 0},
|
||||
|
||||
{' ', "compare a file to files after it only (default)", None, 0},
|
||||
{'a', "compare to all files", None, 0},
|
||||
{'S', "compare to old files only", None, 0},
|
||||
{'s', "do not compare a file to itself", None, 0},
|
||||
|
||||
{' ', "sorted output, most significant first (default)", None, 0},
|
||||
{'u', "unbuffered, unsorted output", None, 0},
|
||||
|
||||
{' ', "miscellaneous options:", None, 0},
|
||||
{'f', "function-like forms only", None, 0},
|
||||
{'F', "keep function identifiers in tact", None, 0},
|
||||
{'R', "recurse into subdirectories", None, 0},
|
||||
{'i', "read arguments (file names) from standard input", None, 0},
|
||||
{'o', "write output to file F", String, &output_name},
|
||||
{'w', "set page width to N", Number, &Page_Width},
|
||||
{'O', "show command line options at start-up", None, 0},
|
||||
{'M', "show memory usage info at close-down", None, 0},
|
||||
{'v', "show version number and compilation date", None, 0},
|
||||
{'-', "lexical scan output only", None, 0},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
/* SERVICE ROUTINES */
|
||||
int
|
||||
is_new_old_separator(const char *s) {
|
||||
if (strcmp(s, "/") == 0) return 1;
|
||||
if (strcmp(s, "|") == 0) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *
|
||||
size_t2string(size_t s) {
|
||||
return any_uint2string(s, 0);
|
||||
}
|
||||
|
||||
void
|
||||
fatal(const char *msg) {
|
||||
fprintf(stderr, "%s: %s\n", progname, msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* PROGRAM */
|
||||
|
||||
#ifdef ARG_TEST
|
||||
static void
|
||||
show_args(const char *msg, int argc, const char *argv[]) {
|
||||
fprintf(stdout, "%s: ", msg);
|
||||
|
||||
int i;
|
||||
for (i = 0; i < argc; i++) {
|
||||
fprintf(stdout, "arg[%d] = %s; ", i, argv[i]);
|
||||
}
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
#endif /* ARG_TEST */
|
||||
|
||||
int
|
||||
main(int argc, const char *argv[]) {
|
||||
|
||||
/* The value of Version derives from the macro VERSION in the
|
||||
Makefile if present. If not, a build time stamp is created.
|
||||
*/
|
||||
char version[40];
|
||||
#ifdef VERSION
|
||||
sprintf(version, "Version %s", VERSION);
|
||||
#else
|
||||
sprintf(version, "Build %s, %s", __DATE__, __TIME__);
|
||||
#endif
|
||||
Version = version;
|
||||
|
||||
/* Save program name */
|
||||
progname = argv[0];
|
||||
argv++, argc--; /* and skip it */
|
||||
|
||||
/* Set the default output and debug streams */
|
||||
Output_File = stdout;
|
||||
Debug_File = stdout;
|
||||
Threshold_Percentage = 1;
|
||||
|
||||
/* Options, default string values given above */
|
||||
|
||||
/* override from language file */
|
||||
Init_Language();
|
||||
|
||||
/* override from command line */
|
||||
{ int n_op = do_options(progname, optlist, argc, argv);
|
||||
argc -= n_op, argv += n_op; /* and skip them */
|
||||
}
|
||||
|
||||
/* Check options compatibility */
|
||||
allow_at_most_one_option_out_of("dnp"); /* alternative output formats */
|
||||
allow_at_most_one_option_out_of("aS"); /* alternative ranges */
|
||||
allow_at_most_one_option_out_of("sS"); /* self is outside old files */
|
||||
|
||||
if (is_set_option('t')) {
|
||||
/* threshold means percentages */
|
||||
if (!is_set_option('p'))
|
||||
fatal("option -t requires -p");
|
||||
}
|
||||
if (is_set_option('P')) {
|
||||
if (!is_set_option('p'))
|
||||
fatal("option -P requires -p");
|
||||
}
|
||||
/* ZZ
|
||||
if (is_set_option('u')) {
|
||||
if (!is_set_option('p'))
|
||||
fatal("option -u available with -p only");
|
||||
}
|
||||
*/
|
||||
|
||||
/* Treat the simple options */
|
||||
if (is_set_option('v')) {
|
||||
fprintf(stdout, "%s\n", Version);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (is_set_option('p')) {
|
||||
set_option('s');
|
||||
}
|
||||
|
||||
/* Check the value options */
|
||||
if (Min_Run_Size <= 0)
|
||||
fatal("bad run size");
|
||||
if (Page_Width <= 0)
|
||||
fatal("bad page width");
|
||||
|
||||
if (is_set_option('p')) {
|
||||
if ((Threshold_Percentage > 100) || (Threshold_Percentage <= 0))
|
||||
fatal("threshold must be between 1 and 100");
|
||||
}
|
||||
|
||||
if (output_name) {
|
||||
Output_File = fopen(output_name, "w");
|
||||
if (Output_File == 0) {
|
||||
char *msg = (char *)Malloc(strlen(output_name) + 100);
|
||||
|
||||
sprintf(msg, "cannot open output file `%s'",
|
||||
output_name);
|
||||
fatal(msg);
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
}
|
||||
|
||||
/* Treat the input-determining options */
|
||||
if (is_set_option('i')) {
|
||||
/* read input file names from standard input */
|
||||
if (argc != 0)
|
||||
fatal("-i option conflicts with file arguments");
|
||||
get_new_std_input_args(&argc, &argv);
|
||||
}
|
||||
if (is_set_option('R')) {
|
||||
get_new_recursive_args(&argc, &argv);
|
||||
}
|
||||
/* (argc, argv) now represents new_file* [ / old_file*] */
|
||||
|
||||
/* Optionally show command line options */
|
||||
if (is_set_option('O')) {
|
||||
print_options(progname, optlist);
|
||||
}
|
||||
|
||||
/* Here the real work starts */
|
||||
|
||||
if (is_set_option('-')) {
|
||||
/* Just the lexical scan */
|
||||
while (argv[0]) {
|
||||
const char *arg = argv[0];
|
||||
if (!is_new_old_separator(arg)) {
|
||||
Print_Stream(arg);
|
||||
}
|
||||
argv++;
|
||||
}
|
||||
}
|
||||
else { /* The works */
|
||||
Read_Input_Files(argc, argv);
|
||||
Make_Forward_References();
|
||||
Compare_Files();
|
||||
Free_Forward_References();
|
||||
if (is_set_option('p')) {
|
||||
Show_Percentages();
|
||||
} else {
|
||||
Retrieve_Runs();
|
||||
Show_Runs();
|
||||
}
|
||||
}
|
||||
|
||||
Free_Text();
|
||||
Free_Token_Array();
|
||||
if (is_set_option('M')) {
|
||||
ReportMemoryStatus(stderr);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user