/scripts/tests/test.c
C | 170 lines | 118 code | 26 blank | 26 comment | 33 complexity | c04bdd5207b67f0e730e535c743f3b49 MD5 | raw file
- /*
- * test.c
- *
- * AC263 Final Project
- *
- * 'test' takes in an array of functions, and runs those functions over the files
- * defined by argv, building a json array, and writing to an output file defined by
- * argv.
- */
- #include "test.h"
- int test(void (*effs[])(char*, char*, float, char*, char*, char*, json_object*), int num_effs, int open_files, int argc, char** argv) {
- float threshold = 0.2;
-
- if (argc < 4) {
- printf("Usage: %s dir [threshold] outfile filename\n", argv[0]);
- return 1;
- }
- // optional threshold as third argument
- if (argc == 5)
- threshold = atof(argv[2]);
-
- // initialize json array to hold results
- json_object* jarray = json_object_new_array();
- // open directory
- // directory structure is dir/student/file
- struct dirent* student_entry;
- struct dirent* file_entry;
- // XXX: WE SHOULD HAVE A STRUCT THAT KNOWS STRLEN(ARGV[1])
- char student_path[PATHNAME_SIZE];
- char file_path[PATHNAME_SIZE];
- DIR* dp;
- DIR* student_dp;
- dp = opendir(argv[1]);
- if (dp == NULL) {
- printf("Failed to open directory\n");
- return 2;
- }
- // build linked list of files in given directory
- struct node* files = NULL;
- int n = 0;
- while ((student_entry = readdir(dp))) {
- // ignore hidden files
- if (student_entry->d_name[0] == '.')
- continue;
- sprintf(student_path, "%.128s%.128s", argv[1], student_entry->d_name);
- student_dp = opendir(student_path);
- if (student_dp == NULL) {
- printf("Failed to open directory %s\n", student_path);
- continue;
- }
- while ((file_entry = readdir(student_dp))) {
- // ignore hidden files
- if (file_entry->d_name[0] == '.')
- continue;
-
- // only process file that is requested
- char* filename = argv[argc-1];
- if (strcmp(file_entry->d_name, filename)) {
- printf("Skipping %s\n", file_entry->d_name);
- continue;
- }
- sprintf(file_path, "%.128s/%.128s", student_entry->d_name, file_entry->d_name);
- // add entry to linked list
- struct node* file = malloc(sizeof(struct node));
- strncpy(file->filename, file_path, FILENAME_SIZE);
- file->next = files;
- files = file;
- n++;
- }
- closedir(student_dp);
- }
- closedir(dp);
- // perform n-way comparison of file sizes
- struct stat buf1;
- struct stat buf2;
- struct node* i = files;
- struct node* j = files;
- while (i != NULL) {
- // concat filename to path
- char* f1 = malloc(strlen(i->filename) + strlen(argv[1]) + 1);
- sprintf(f1, "%s%s", argv[1], i->filename);
- // read files
- if (stat(f1, &buf1)) {
- printf("Failed to stat %s\n.", f1);
- return false;
- }
- int fd;
- char* source;
- if (open_files) {
- fd = open(f1, O_RDONLY);
- if (fd < 0) {
- printf("Failed to open %s\n.", f1);
- return false;
- }
- source = mmap(0, buf1.st_size, PROT_READ, MAP_SHARED, fd, 0);
- if (source == MAP_FAILED) {
- printf("Map failed for %s\n.", f1);
- return false;
- }
- }
- while (j != NULL) {
- // don't compare a file to itself
- if (i != j) {
- char* f2 = malloc(strlen(j->filename) + strlen(argv[1]) + 1);
- sprintf(f2, "%s%s", argv[1], j->filename);
- if (stat(f2, &buf2)) {
- printf("Failed to stat %s\n.", f2);
- return false;
- }
- int fdi;
- char* file;
- if (open_files) {
- fdi = open(f2, O_RDONLY);
- if (fdi < 0) {
- printf("Failed to open %s\n.", f2);
- return false;
- }
- file = mmap(0, buf2.st_size, PROT_READ, MAP_SHARED, fdi, 0);
- if (file == MAP_FAILED) {
- printf("Map failed for %s\n.", f2);
- return false;
- }
- }
- for (int k = 0; k < num_effs; k++)
- effs[k](source, file, threshold, argv[1], i->filename, j->filename, jarray);
- if (open_files) {
- close(fdi);
- munmap(file, buf2.st_size);
- }
- }
- // advance inner pointer
- j = j->next;
- }
- if (open_files) {
- close(fd);
- munmap(source, buf1.st_size);
- }
- // advance outer pointer and reset inner pointer
- i = i->next;
- j = files;
- }
- // write file
- const char* str = json_object_to_json_string(jarray);
- FILE* outfile = fopen(argv[argc-2], "w");
- fwrite(str, strlen(str), 1, outfile);
- return 0;
- }