PageRenderTime 43ms CodeModel.GetById 16ms RepoModel.GetById 1ms app.codeStats 0ms

/scripts/tests/test.c

https://bitbucket.org/tmacwill/ac263-project
C | 170 lines | 118 code | 26 blank | 26 comment | 33 complexity | c04bdd5207b67f0e730e535c743f3b49 MD5 | raw file
  1. /*
  2. * test.c
  3. *
  4. * AC263 Final Project
  5. *
  6. * 'test' takes in an array of functions, and runs those functions over the files
  7. * defined by argv, building a json array, and writing to an output file defined by
  8. * argv.
  9. */
  10. #include "test.h"
  11. int test(void (*effs[])(char*, char*, float, char*, char*, char*, json_object*), int num_effs, int open_files, int argc, char** argv) {
  12. float threshold = 0.2;
  13. if (argc < 4) {
  14. printf("Usage: %s dir [threshold] outfile filename\n", argv[0]);
  15. return 1;
  16. }
  17. // optional threshold as third argument
  18. if (argc == 5)
  19. threshold = atof(argv[2]);
  20. // initialize json array to hold results
  21. json_object* jarray = json_object_new_array();
  22. // open directory
  23. // directory structure is dir/student/file
  24. struct dirent* student_entry;
  25. struct dirent* file_entry;
  26. // XXX: WE SHOULD HAVE A STRUCT THAT KNOWS STRLEN(ARGV[1])
  27. char student_path[PATHNAME_SIZE];
  28. char file_path[PATHNAME_SIZE];
  29. DIR* dp;
  30. DIR* student_dp;
  31. dp = opendir(argv[1]);
  32. if (dp == NULL) {
  33. printf("Failed to open directory\n");
  34. return 2;
  35. }
  36. // build linked list of files in given directory
  37. struct node* files = NULL;
  38. int n = 0;
  39. while ((student_entry = readdir(dp))) {
  40. // ignore hidden files
  41. if (student_entry->d_name[0] == '.')
  42. continue;
  43. sprintf(student_path, "%.128s%.128s", argv[1], student_entry->d_name);
  44. student_dp = opendir(student_path);
  45. if (student_dp == NULL) {
  46. printf("Failed to open directory %s\n", student_path);
  47. continue;
  48. }
  49. while ((file_entry = readdir(student_dp))) {
  50. // ignore hidden files
  51. if (file_entry->d_name[0] == '.')
  52. continue;
  53. // only process file that is requested
  54. char* filename = argv[argc-1];
  55. if (strcmp(file_entry->d_name, filename)) {
  56. printf("Skipping %s\n", file_entry->d_name);
  57. continue;
  58. }
  59. sprintf(file_path, "%.128s/%.128s", student_entry->d_name, file_entry->d_name);
  60. // add entry to linked list
  61. struct node* file = malloc(sizeof(struct node));
  62. strncpy(file->filename, file_path, FILENAME_SIZE);
  63. file->next = files;
  64. files = file;
  65. n++;
  66. }
  67. closedir(student_dp);
  68. }
  69. closedir(dp);
  70. // perform n-way comparison of file sizes
  71. struct stat buf1;
  72. struct stat buf2;
  73. struct node* i = files;
  74. struct node* j = files;
  75. while (i != NULL) {
  76. // concat filename to path
  77. char* f1 = malloc(strlen(i->filename) + strlen(argv[1]) + 1);
  78. sprintf(f1, "%s%s", argv[1], i->filename);
  79. // read files
  80. if (stat(f1, &buf1)) {
  81. printf("Failed to stat %s\n.", f1);
  82. return false;
  83. }
  84. int fd;
  85. char* source;
  86. if (open_files) {
  87. fd = open(f1, O_RDONLY);
  88. if (fd < 0) {
  89. printf("Failed to open %s\n.", f1);
  90. return false;
  91. }
  92. source = mmap(0, buf1.st_size, PROT_READ, MAP_SHARED, fd, 0);
  93. if (source == MAP_FAILED) {
  94. printf("Map failed for %s\n.", f1);
  95. return false;
  96. }
  97. }
  98. while (j != NULL) {
  99. // don't compare a file to itself
  100. if (i != j) {
  101. char* f2 = malloc(strlen(j->filename) + strlen(argv[1]) + 1);
  102. sprintf(f2, "%s%s", argv[1], j->filename);
  103. if (stat(f2, &buf2)) {
  104. printf("Failed to stat %s\n.", f2);
  105. return false;
  106. }
  107. int fdi;
  108. char* file;
  109. if (open_files) {
  110. fdi = open(f2, O_RDONLY);
  111. if (fdi < 0) {
  112. printf("Failed to open %s\n.", f2);
  113. return false;
  114. }
  115. file = mmap(0, buf2.st_size, PROT_READ, MAP_SHARED, fdi, 0);
  116. if (file == MAP_FAILED) {
  117. printf("Map failed for %s\n.", f2);
  118. return false;
  119. }
  120. }
  121. for (int k = 0; k < num_effs; k++)
  122. effs[k](source, file, threshold, argv[1], i->filename, j->filename, jarray);
  123. if (open_files) {
  124. close(fdi);
  125. munmap(file, buf2.st_size);
  126. }
  127. }
  128. // advance inner pointer
  129. j = j->next;
  130. }
  131. if (open_files) {
  132. close(fd);
  133. munmap(source, buf1.st_size);
  134. }
  135. // advance outer pointer and reset inner pointer
  136. i = i->next;
  137. j = files;
  138. }
  139. // write file
  140. const char* str = json_object_to_json_string(jarray);
  141. FILE* outfile = fopen(argv[argc-2], "w");
  142. fwrite(str, strlen(str), 1, outfile);
  143. return 0;
  144. }