percentages.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /* This file is part of the software similarity tester SIM.
  2. Written by Dick Grune, Vrije Universiteit, Amsterdam.
  3. $Id: percentages.c,v 1.3 2007/08/27 09:57:33 dick Exp $
  4. */
  5. #include <stdio.h>
  6. #include <malloc.h>
  7. #include "sim.h"
  8. #include "runs.h"
  9. #include "error.h"
  10. #include "percentages.h"
  11. struct match {
  12. struct match *ma_next;
  13. struct text *ma_text0;
  14. struct text *ma_text1;
  15. unsigned int ma_size;
  16. };
  17. static struct match *match_start; /* to be allocated by malloc */
  18. int
  19. add_to_percentages(struct run *r) {
  20. /* fails if out of memory, in line with add_to_run() */
  21. struct match **match_hook = &match_start;
  22. /* percentages are only meaningful between different files */
  23. if (r->rn_cn0.ch_text == r->rn_cn1.ch_text) return 1;
  24. /* look (text0, text1) combination up in match list */
  25. while (*match_hook) {
  26. struct match *m = *match_hook;
  27. if ( m->ma_text0 == r->rn_cn0.ch_text
  28. && m->ma_text1 == r->rn_cn1.ch_text
  29. ) {
  30. /* found it; now update it */
  31. m->ma_size += r->rn_size;
  32. return 1;
  33. }
  34. match_hook = &m->ma_next;
  35. }
  36. { /* it's not there; make a new entry */
  37. struct match *m = *match_hook =
  38. (struct match *)malloc(sizeof (struct match));
  39. if (m == 0) return 0;
  40. m->ma_next = 0;
  41. m->ma_text0 = r->rn_cn0.ch_text;
  42. m->ma_text1 = r->rn_cn1.ch_text;
  43. m->ma_size = r->rn_size;
  44. return 1;
  45. }
  46. }
  47. static void
  48. add_reverse_entries_to_match_list(void) {
  49. struct match **match_hook = &match_start;
  50. while (*match_hook) {
  51. struct match *m = *match_hook;
  52. struct match *n =
  53. (struct match *)malloc(sizeof (struct match));
  54. if (!n) fatal("out of memory");
  55. /* hook in the double */
  56. n->ma_next = m->ma_next;
  57. m->ma_next = n;
  58. n->ma_text0 = m->ma_text1;
  59. n->ma_text1 = m->ma_text0;
  60. n->ma_size = m->ma_size;
  61. match_hook = &n->ma_next;
  62. }
  63. }
  64. static float
  65. match_percentage(struct match *m) {
  66. struct text *text0 = m->ma_text0;
  67. int size0 = text0->tx_limit - text0->tx_start;
  68. return (m->ma_size*1.0/size0);
  69. }
  70. /* instantiate sort_match_list() */
  71. #define SORT_STRUCT match
  72. #define SORT_NAME sort_match_list
  73. #define SORT_BEFORE(p1,p2) (match_percentage(p1) > match_percentage(p2))
  74. #define SORT_NEXT ma_next
  75. #include "sortlist.bdy"
  76. static void
  77. print_percentages(void) {
  78. struct match *m = match_start;
  79. while (m) {
  80. fprintf(OutputFile,
  81. "%s consists for %d %% of %s material\n",
  82. m->ma_text0->tx_fname,
  83. (int)(match_percentage(m)*100.0),
  84. m->ma_text1->tx_fname
  85. );
  86. m = m->ma_next;
  87. }
  88. }
  89. void
  90. show_percentages(void) {
  91. add_reverse_entries_to_match_list();
  92. sort_match_list(&match_start);
  93. print_percentages();
  94. }