home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume3 / sim < prev    next >
Internet Message Format  |  1986-11-30  |  41KB

  1. From: Dick Grune <talcott!seismo!mcvax!vu44!dick>
  2. Subject:  Software similarity tester for C programs
  3. Newsgroups: mod.sources
  4. Approved: jpn@panda.UUCP
  5.  
  6. Mod.sources:  Volume 3, Issue 119
  7. Submitted by: Dick Grune <talcott!seismo!mcvax!vu44!dick>
  8.  
  9.  
  10.     The enclosed shar-archive contains a program that will detect
  11. stretches in C-programs that look similar (or are just plain equal).
  12. This is useful for finding "borrowed" soft-ware or for isolating
  13. possible subroutines in large software systems.  It is very fast and
  14. gives results.  We have been using it for about half a year now.
  15.  
  16.                     Dick Grune
  17.                     Vrije Universiteit
  18.                     de Boelelaan 1081
  19.                     1081 HV  Amsterdam
  20.                     the Netherlands
  21.                     ..!mcvax!vu44!dick
  22.                     dick@vu44.UUCP
  23.  
  24.  
  25.  
  26. : This is a shar archive.  Extract with sh, not csh.
  27. : This archive ends with exit, so do not worry about trailing junk.
  28. : --------------------------- cut here --------------------------
  29. PATH=/bin:/usr/bin
  30. echo Extracting \R\E\A\D\_\M\E
  31. sed 's/^X//' > \R\E\A\D\_\M\E << '+ END-OF-FILE '\R\E\A\D\_\M\E
  32. XSat Jan 11 15:47:16 1986
  33. X
  34. XThis program tests for similar (or equal) stretches in one or more C-programs.
  35. XSee sim.1
  36. X
  37. XTo compile, call "make", which will generate one executable called sim, and
  38. Xwill run two small tests to show sample output.
  39. X
  40. XTo install, examine the Makefile and reset BINDIR and MANDIR to sensible
  41. Xpaths, and call "make install"
  42. X
  43. XTo change the default run size or the page width, adjust the file params.h
  44. Xand recompile.
  45. X
  46. XTo add another language X, write a file X.l along the lines of clang.l,
  47. Xextend the Makefile and recompile.  All knowledge about C in located in
  48. Xclang.l; the rest of the programs expect each C lexical unit to be a single
  49. Xcharacter.
  50. X
  51. X                    Dick Grune
  52. X                    Vrije Universiteit
  53. X                    de Boelelaan 1081
  54. X                    1081 HV  Amsterdam
  55. X                    the Netherlands
  56. X                    ..!mcvax!vu44!dick
  57. X                    dick@vu44.UUCP
  58. + END-OF-FILE READ_ME
  59. chmod 'u=rw,g=r,o=r' \R\E\A\D\_\M\E
  60. set `sum \R\E\A\D\_\M\E`
  61. sum=$1
  62. case $sum in
  63. 26812)    :;;
  64. *)    echo 'Bad sum in '\R\E\A\D\_\M\E >&2
  65. esac
  66. echo Extracting \M\a\k\e\f\i\l\e
  67. sed 's/^X//' > \M\a\k\e\f\i\l\e << '+ END-OF-FILE '\M\a\k\e\f\i\l\e
  68. X#    This file is part of the software similarity tester SIM.
  69. X#    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  70. X#
  71. X
  72. XBINDIR = /user1/dick/bin#        # where to put the binary (sim)
  73. XMANDIR = /user1/dick/man#        # where to put the manual page (sim.1)
  74. X
  75. X#
  76. X#    Each module (set of programs that together perform some function)
  77. X#    has the following sets defined for it:
  78. X#        FLS    all files of that module, for, e.g.,
  79. X#            printing, sharring, inventory, etc.
  80. X#        SRC    the source files, from which other files derive
  81. X#        CFS    the C-files, from which the object files derive
  82. X#        OBJ    objects
  83. X#        GRB    garbage produced by compiling the module
  84. X#
  85. X#    (This is a feeble attempt at software-engineering a Makefile.)
  86. X#
  87. X
  88. XTEST =    pass3.c#            # guinea pig
  89. X
  90. Xall:    sim.res lang.res
  91. X
  92. X# The C Language module
  93. XCLN_OBJ =    clang.o
  94. XCLN_CFS =    clang.c
  95. XCLN_SRC =    clang.l
  96. XCLN_FLS =    $(CLN_SRC)
  97. X
  98. Xclang.c:    clang.l
  99. X    lex -t clang.l >clang.c
  100. XCLN_GRB =    clang.c
  101. X
  102. X# Common modules:
  103. XCOM_OBJ =    stream.o idf.o buff.o error.o
  104. XCOM_CFS =    stream.c idf.c buff.c error.c
  105. XCOM_SRC =    $(COM_CFS)
  106. XCOM_FLS =    stream.h idf.h buff.h $(COM_SRC)
  107. X
  108. X# The top-package:
  109. XTOP_OBJ =    top.o
  110. XTOP_CFS =    top.c
  111. XTOP_SRC =    $(TOP_CFS)
  112. XTOP_FLS =    top.p top.g top.h $(TOP_SRC)
  113. X
  114. X# The similarity tester:
  115. XSIM_OBJ =    sim.o pass1.o hash.o compare.o add_run.o pass2.o pass3.o
  116. XSIM_CFS =    sim.c pass1.c hash.c compare.c add_run.c pass2.c pass3.c
  117. XSIM_SRC =    $(SIM_CFS)
  118. XSIM_FLS =    params.h text.h debug.h $(SIM_SRC)
  119. X
  120. XSIM =    $(CLN_OBJ) $(COM_OBJ) $(TOP_OBJ) $(SIM_OBJ)
  121. XCFS =    $(CLN_CFS) $(COM_CFS) $(TOP_CFS) $(SIM_CFS)
  122. X
  123. Xsim:    $(SIM)
  124. X    $(CC) $(SIM) -o sim
  125. X
  126. Xsim.res:    sim $(TEST)
  127. X    sim -hr 20 $(TEST)
  128. X
  129. Xlint:    $(CFS)
  130. X    lint -xa $(CFS)
  131. XSIM_GRB =    sim
  132. X
  133. X# The language streamliner as a main program:
  134. XSTR_OBJ =    main.o
  135. XSTR_CFS =    main.c
  136. XSTR_SRC =    $(STR_CFS)
  137. XSTR_FLS =    $(STR_SRC)
  138. X
  139. XLANG_CFS =    $(CLN_CFS) $(STR_CFS) $(COM_CFS)
  140. XLANG_OBJ =    $(CLN_OBJ) $(STR_OBJ) $(COM_OBJ)
  141. Xlang:    $(LANG_OBJ)
  142. X    $(CC) $(LANG_OBJ) -o lang
  143. X
  144. Xlang.res:    lang $(TEST)
  145. X    lang -1 $(TEST) >lang1.res
  146. X    lang -2 $(TEST) >lang2.res
  147. X    wc lang[12].res $(TEST)
  148. XLANG_GRB =    lang lang1.res lang2.res
  149. X
  150. Xlang.lint:
  151. X    lint -xa $(LANG_CFS)
  152. X
  153. X# various other entries
  154. XFLS =    READ_ME Makefile sim.1 \
  155. X    $(COM_FLS) $(TOP_FLS) $(SIM_FLS) $(STR_FLS) $(CLN_FLS)
  156. XSRC =    $(COM_SRC) $(TOP_SRC) $(SIM_SRC) $(STR_SRC) $(CLN_SRC)
  157. XOBJ =    $(COM_OBJ) $(TOP_OBJ) $(SIM_OBJ) $(STR_OBJ) $(CLN_OBJ)
  158. X
  159. Xprint:    $(FLS)
  160. X    pr $(FLS) >print
  161. XPRINT_GRB =    print
  162. X
  163. Xshar:    $(FLS)
  164. X    shar $(FLS) >shar
  165. X
  166. Xfiles:    Makefile
  167. X    ls $(FLS) >files
  168. X
  169. Xcchk:
  170. X    cchk $(CFS)
  171. X
  172. Xsimsim:    sim
  173. X    sim -hfr 20 $(SRC)
  174. X
  175. Xsimsimx:    sim
  176. X    sim -hfxr 20 $(SRC)
  177. X
  178. Xtags:    $(SRC)
  179. X    ctags $(SRC)
  180. X
  181. Xinstall:    $(BINDIR)/sim $(MANDIR)/sim.1
  182. X
  183. X$(BINDIR)/sim:    sim
  184. X    cp sim $(BINDIR)/sim
  185. X
  186. X$(MANDIR)/sim.1:    sim.1
  187. X    cp sim.1 $(MANDIR)/sim.1
  188. X
  189. Xclean:
  190. X    rm -f $(OBJ) $(CLN_GRB) $(SIM_GRB) $(LANG_GRB) $(PRINT_GRB) \
  191. X        a.out core
  192. X
  193. X#------------------------------------------------------------------------
  194. Xadd_run.o: buff.h text.h top.p top.h
  195. Xbuff.o: buff.h
  196. Xclang.o: idf.h stream.h
  197. Xcompare.o: buff.h text.h top.p top.h
  198. Xhash.o: buff.h text.h
  199. Xidf.o: idf.h
  200. Xpass1.o: buff.h text.h
  201. Xpass2.o: text.h top.p top.h debug.h
  202. Xpass3.o: params.h text.h top.p top.h debug.h buff.h
  203. Xsim.o: params.h
  204. Xstream.o: stream.h
  205. Xtop.o: text.h top.p top.h top.g
  206. + END-OF-FILE Makefile
  207. chmod 'u=rw,g=r,o=r' \M\a\k\e\f\i\l\e
  208. set `sum \M\a\k\e\f\i\l\e`
  209. sum=$1
  210. case $sum in
  211. 32570)    :;;
  212. *)    echo 'Bad sum in '\M\a\k\e\f\i\l\e >&2
  213. esac
  214. echo Extracting \s\i\m\.\1
  215. sed 's/^X//' > \s\i\m\.\1 << '+ END-OF-FILE '\s\i\m\.\1
  216. X.\"    This file is part of the software similarity tester SIM.
  217. X.\"    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  218. X.\"
  219. X.TH SIM I
  220. X.SH NAME
  221. Xsim \- find similarities in C-files
  222. X.SH SYNOPSIS
  223. X.B sim
  224. X[
  225. X.B \-[fns]
  226. X.BI \-r N
  227. X]
  228. Xfile ...
  229. X.SH DESCRIPTION
  230. X.I Sim
  231. Xreads the C-files
  232. X.I file ...
  233. Xand looks for pieces of text that are similar; two pieces of C-text
  234. Xare similar if they only differ in layout, comment, identifiers and
  235. Xthe contents of numbers, strings and characters.  If any runs
  236. Xof sufficient length
  237. Xare found, they are reported on standard output; the default length
  238. Xminimum is 24, but can be reset by the
  239. X.BR \-r -parameter.
  240. X.PP
  241. XThe program can be used for finding copied pieces of code in
  242. Xpurportedly unrelated programs (with the
  243. X.BR \-s -flag),
  244. Xor for finding accidentally duplicated code in larger projects
  245. X(without the
  246. X.BR \-s -flag
  247. Xbut with the
  248. X.BR \-f -flag).
  249. X.PP
  250. XSince it reads the files several times, it cannot read from standard input.
  251. X.PP
  252. XThere are the following options:
  253. X.TP
  254. X.B \-f
  255. XRuns are restricted to pieces with balancing parentheses, to isolate
  256. Xpotential functions.
  257. X.TP
  258. X.B \-n
  259. XSimilarities found are only summarized, not displayed.
  260. X.TP
  261. X.B \-s
  262. XThe contents of a file are not compared to itself (\-s = not self).
  263. X.PP
  264. XThe matching process uses a hash table so that tens of thousands of
  265. Xlines are processed in a few minutes; if, however, there is not
  266. Xenough memory for the table, the matching process uses sequential
  267. Xsearch, which can take hours.
  268. X.SH AUTHOR
  269. XDick Grune, Vrije Universiteit, Amsterdam.
  270. X.SH BUGS
  271. XStrong periodicity in the input text (like a table of
  272. X.I N
  273. Xalmost identical lines) causes problems.
  274. X.I Sim
  275. Xtries to cope with this but cannot avoid giving appr.
  276. X.I log N
  277. Xmessages about it.  The best advice is still to take the offending
  278. Xfiles out of the game.
  279. + END-OF-FILE sim.1
  280. chmod 'u=rw,g=r,o=r' \s\i\m\.\1
  281. set `sum \s\i\m\.\1`
  282. sum=$1
  283. case $sum in
  284. 56000)    :;;
  285. *)    echo 'Bad sum in '\s\i\m\.\1 >&2
  286. esac
  287. echo Extracting \s\t\r\e\a\m\.\h
  288. sed 's/^X//' > \s\t\r\e\a\m\.\h << '+ END-OF-FILE '\s\t\r\e\a\m\.\h
  289. X/*    This file is part of the software similarity tester SIM.
  290. X    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  291. X*/
  292. X
  293. X/*
  294. X    Interface between the language-dependent lex module and
  295. X    the stream module.
  296. X*/
  297. X
  298. X/* communication variables */
  299. Xextern int lex_no;    /* pass 1: return stream of C condensed chars */
  300. X            /* pass 2: return C-char/ASCII-char position
  301. X                pairs at each \n */
  302. Xextern int lex_ch;    /* condensed C-char produced by pass 1 */
  303. Xextern unsigned int lex_ch_cnt;
  304. X            /* C-char position reported at each \n by pass 2 */
  305. Xextern long lex_ls_pos;    /* lseek position reported at each \n by pass 2 */
  306. X
  307. X/* #defines for the lex module */
  308. X#define    cput(ch)    if (lex_ch_cnt++, lex_no == 1) \
  309. X                {lex_ch = ch; return 1;} else
  310. X#define    c_eol()        if (lex_no == 2) return 1; else
  311. X#define    count()        lex_ls_pos += yyleng
  312. + END-OF-FILE stream.h
  313. chmod 'u=rw,g=r,o=r' \s\t\r\e\a\m\.\h
  314. set `sum \s\t\r\e\a\m\.\h`
  315. sum=$1
  316. case $sum in
  317. 61866)    :;;
  318. *)    echo 'Bad sum in '\s\t\r\e\a\m\.\h >&2
  319. esac
  320. echo Extracting \i\d\f\.\h
  321. sed 's/^X//' > \i\d\f\.\h << '+ END-OF-FILE '\i\d\f\.\h
  322. X/*    This file is part of the software similarity tester SIM.
  323. X    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  324. X*/
  325. X
  326. X/* the struct for keywords etc. */
  327. Xstruct idf    {
  328. X    char *id_tag;    /* an interesting identifier */
  329. X    char id_tr;    /* with its one-character translation */
  330. X};
  331. X
  332. X#define idf2char(s,l)    findidf(s, l, sizeof l / sizeof l[0])
  333. + END-OF-FILE idf.h
  334. chmod 'u=rw,g=r,o=r' \i\d\f\.\h
  335. set `sum \i\d\f\.\h`
  336. sum=$1
  337. case $sum in
  338. 29562)    :;;
  339. *)    echo 'Bad sum in '\i\d\f\.\h >&2
  340. esac
  341. echo Extracting \b\u\f\f\.\h
  342. sed 's/^X//' > \b\u\f\f\.\h << '+ END-OF-FILE '\b\u\f\f\.\h
  343. X/*    This file is part of the software similarity tester SIM.
  344. X    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  345. X*/
  346. X
  347. Xextern char *buff;
  348. Xextern unsigned int text_length();
  349. + END-OF-FILE buff.h
  350. chmod 'u=rw,g=r,o=r' \b\u\f\f\.\h
  351. set `sum \b\u\f\f\.\h`
  352. sum=$1
  353. case $sum in
  354. 20348)    :;;
  355. *)    echo 'Bad sum in '\b\u\f\f\.\h >&2
  356. esac
  357. echo Extracting \s\t\r\e\a\m\.\c
  358. sed 's/^X//' > \s\t\r\e\a\m\.\c << '+ END-OF-FILE '\s\t\r\e\a\m\.\c
  359. X/*    This file is part of the software similarity tester SIM.
  360. X    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  361. X*/
  362. X
  363. X#include    <stdio.h>
  364. X#include    "stream.h"
  365. X
  366. X/* imports from the lex module */
  367. Xextern int yylex();
  368. Xextern yystart();
  369. Xextern FILE *yyin;
  370. X
  371. Xint lex_no;        /* pass 1: return stream of C condensed chars */
  372. X            /* pass 2: return C-char/ASCII-char position
  373. X                pairs at each \n
  374. X            */
  375. X
  376. Xint lex_ch;        /* condensed C-char produced by pass 1 */
  377. Xunsigned int lex_ch_cnt;/* C-char position reported at each \n by pass 2 */
  378. Xlong lex_ls_pos;    /* lseek position reported at each \n by pass 2 */
  379. X
  380. Xint
  381. XOpenStream(pass, fname)
  382. X    char *fname;
  383. X{
  384. X    lex_no = pass;
  385. X    lex_ch_cnt = 0;
  386. X    lex_ls_pos = 0L;
  387. X    
  388. X    /* start the lex machine */
  389. X    yyin = fopen(fname, "r");
  390. X    yystart();
  391. X    return yyin != NULL;
  392. X}
  393. X
  394. Xint
  395. XNextChar(cp)        /* lex_no must be 1 */
  396. X    char *cp;
  397. X{
  398. X    if (!yylex())
  399. X        return -1;
  400. X    *cp = lex_ch;
  401. X    return 0;
  402. X}
  403. X
  404. Xint
  405. XNextPair(ccp, lsp)    /* lex_no must be 2 */
  406. X    unsigned int *ccp;
  407. X    long *lsp;
  408. X{
  409. X    if (!yylex())
  410. X        return -1;
  411. X    *ccp = lex_ch_cnt;
  412. X    *lsp = lex_ls_pos;
  413. X    return 0;
  414. X}
  415. X
  416. XCloseStream()    {
  417. X    fclose(yyin);
  418. X}
  419. + END-OF-FILE stream.c
  420. chmod 'u=rw,g=r,o=r' \s\t\r\e\a\m\.\c
  421. set `sum \s\t\r\e\a\m\.\c`
  422. sum=$1
  423. case $sum in
  424. 24424)    :;;
  425. *)    echo 'Bad sum in '\s\t\r\e\a\m\.\c >&2
  426. esac
  427. echo Extracting \i\d\f\.\c
  428. sed 's/^X//' > \i\d\f\.\c << '+ END-OF-FILE '\i\d\f\.\c
  429. X/*    This file is part of the software similarity tester SIM.
  430. X    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  431. X*/
  432. X
  433. X#include    "idf.h"
  434. X
  435. Xint
  436. Xfindidf(str, list, size)
  437. X    char *str;
  438. X    struct idf list[];
  439. X{
  440. X    int first = 0;
  441. X    int last = size - 1;
  442. X
  443. X    while (first < last)    {
  444. X        int middle = (first + last) / 2;
  445. X
  446. X        if (strcmp(str, list[middle].id_tag) > 0)
  447. X            first = middle + 1;
  448. X        else    last = middle;
  449. X    }
  450. X    return strcmp(str, list[first].id_tag) == 0 ? list[first].id_tr : -1;
  451. X}
  452. + END-OF-FILE idf.c
  453. chmod 'u=rw,g=r,o=r' \i\d\f\.\c
  454. set `sum \i\d\f\.\c`
  455. sum=$1
  456. case $sum in
  457. 60560)    :;;
  458. *)    echo 'Bad sum in '\i\d\f\.\c >&2
  459. esac
  460. echo Extracting \b\u\f\f\.\c
  461. sed 's/^X//' > \b\u\f\f\.\c << '+ END-OF-FILE '\b\u\f\f\.\c
  462. X/*    This file is part of the software similarity tester SIM.
  463. X    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  464. X*/
  465. X
  466. X#include    "buff.h"
  467. X
  468. X#define    BFSIZE        10000
  469. X
  470. Xextern char *malloc(), *realloc(), *calloc();
  471. X
  472. Xchar *buff;            /* to be filled by malloc */
  473. Xstatic unsigned int buff_size;    /* size of buffer at this moment */
  474. Xstatic unsigned int bfree;    /* next free position in array buff[] */
  475. X
  476. Xinit_buff()    {
  477. X    /* Allocate the text buffer */
  478. X    buff = malloc(buff_size = BFSIZE);
  479. X    if (!buff)
  480. X        error("out of space");
  481. X    bfree = 1;                /* don't use position 0 */
  482. X}
  483. X
  484. Xstore(ch)    {
  485. X    if (bfree == buff_size)    {
  486. X        buff = realloc(buff, buff_size += BFSIZE);
  487. X        if (!buff || buff_size < bfree)    {
  488. X            /* overflow */
  489. X            error("out of space");
  490. X        }
  491. X    }
  492. X    buff[bfree++] = ch;
  493. X}
  494. X
  495. Xunsigned int
  496. Xtext_length()    {
  497. X    return bfree;
  498. X}
  499. + END-OF-FILE buff.c
  500. chmod 'u=rw,g=r,o=r' \b\u\f\f\.\c
  501. set `sum \b\u\f\f\.\c`
  502. sum=$1
  503. case $sum in
  504. 14186)    :;;
  505. *)    echo 'Bad sum in '\b\u\f\f\.\c >&2
  506. esac
  507. echo Extracting \e\r\r\o\r\.\c
  508. sed 's/^X//' > \e\r\r\o\r\.\c << '+ END-OF-FILE '\e\r\r\o\r\.\c
  509. X/*    This file is part of the software similarity tester SIM.
  510. X    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  511. X*/
  512. X
  513. X#include    <stdio.h>
  514. X
  515. Xerror(msg)
  516. X    char *msg;
  517. X{
  518. X    fprintf(stderr, "sim: %s\n", msg);
  519. X    exit(1);
  520. X}
  521. + END-OF-FILE error.c
  522. chmod 'u=rw,g=r,o=r' \e\r\r\o\r\.\c
  523. set `sum \e\r\r\o\r\.\c`
  524. sum=$1
  525. case $sum in
  526. 10416)    :;;
  527. *)    echo 'Bad sum in '\e\r\r\o\r\.\c >&2
  528. esac
  529. echo Extracting \t\o\p\.\p
  530. sed 's/^X//' > \t\o\p\.\p << '+ END-OF-FILE '\t\o\p\.\p
  531. X/*    This file is part of the software similarity tester SIM.
  532. X    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  533. X*/
  534. X
  535. X/*    These are the parameters with which to instantiate top.g
  536. X*/
  537. X#define        TTSIZE        100        /* the TTSIZE best objects */
  538. X#define        TTTYPE        struct run    /* the type of the object */
  539. X#define        TTBETTER    longer        /* how to compare objects */
  540. + END-OF-FILE top.p
  541. chmod 'u=rw,g=r,o=r' \t\o\p\.\p
  542. set `sum \t\o\p\.\p`
  543. sum=$1
  544. case $sum in
  545. 20036)    :;;
  546. *)    echo 'Bad sum in '\t\o\p\.\p >&2
  547. esac
  548. echo Extracting \t\o\p\.\g
  549. sed 's/^X//' > \t\o\p\.\g << '+ END-OF-FILE '\t\o\p\.\g
  550. X/*    This file is part of the software similarity tester SIM.
  551. X    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  552. X*/
  553. X
  554. X/* This is a generic package for keeping a top-10 list of objects of
  555. X/* formal type.
  556. X/*
  557. X/* Specification in Ada-style:
  558. X/* generic                -- 3 formals,supplied by #define
  559. X/*    TTSIZE: int;            -- the size of the top-N list
  560. X/*    type TTTYPE is private;        -- the type of the objects
  561. X/*    with function int TTBETTER(ip, jp) TTTYPE *ip, *jp;
  562. X/*                    -- 1 if object *ip better than
  563. X/*                    -- object *jp, 0 otherwise
  564. X/* package TOP is            -- reflected in top.h
  565. X/*    function InitTop();        -- clears the list
  566. X/*    function InsertTop(obj) TTTYPE *obj;
  567. X/*                    -- accepts a (pointer to) an object
  568. X/*    -- a generator yields the objects in best-to-worst order:
  569. X/*    type TopGen is private;        -- to declare the generator
  570. X/*    function OpenTop(tg) TopGen *tg;-- starts the generator
  571. X/*    function TTTYPE *NextTop(tg) TopGen *tg;
  572. X/*                    -- yields next object, moves generator
  573. X/*    NoObject: constant (TTTYPE*);    -- yielded at end-of-list
  574. X/*    function CloseTop(tg) TopGen *tg;-- stops the generator
  575. X/* end TOP                -- */
  576. X/* The application of this file must be preceded by
  577. X/* #include "top.h", which defines the interface, and by
  578. X/* #include "top.p", which defines the parameters of the instantiation.
  579. X
  580. X/* package body TOP is            -- */
  581. Xstatic TTTYPE val[TTSIZE];
  582. Xstatic TTTYPE *list[TTSIZE];
  583. Xstatic int cnt;
  584. X
  585. XInitTop()    {
  586. X    cnt = 0;
  587. X}
  588. X
  589. XInsertTop(obj) register TTTYPE *obj;    {
  590. X    register int i;
  591. X
  592. X    if (cnt < TTSIZE)    {    /* there is still room */
  593. X        list[cnt] = &val[cnt];
  594. X        val[cnt++] = *obj;
  595. X    }
  596. X    else
  597. X    if (TTBETTER(obj, list[TTSIZE-1]))    {
  598. X        /* preferable to worst in set */
  599. X        *list[TTSIZE-1] = *obj;
  600. X    }
  601. X    else    return;            /* we're not interested */
  602. X
  603. X    for (i = cnt-2; i >= 0 && TTBETTER(list[i+1], list[i]); i--)    {
  604. X        register TTTYPE *jp = list[i+1];
  605. X        list[i+1] = list[i];
  606. X        list[i] = jp;
  607. X    }
  608. X}
  609. X
  610. XOpenTop(tg) register TopGen *tg;    {
  611. X    *tg = 0;
  612. X}
  613. X
  614. XTTTYPE *
  615. XNextTop(tg) register TopGen *tg;    {
  616. X    return *tg >= cnt ? NoObject : list[(*tg)++];
  617. X}
  618. X
  619. XCloseTop(tg) register TopGen *tg;    {
  620. X    *tg = TTSIZE;
  621. X}
  622. X/* end TOP                -- */
  623. + END-OF-FILE top.g
  624. chmod 'u=rw,g=r,o=r' \t\o\p\.\g
  625. set `sum \t\o\p\.\g`
  626. sum=$1
  627. case $sum in
  628. 62947)    :;;
  629. *)    echo 'Bad sum in '\t\o\p\.\g >&2
  630. esac
  631. echo Extracting \t\o\p\.\h
  632. sed 's/^X//' > \t\o\p\.\h << '+ END-OF-FILE '\t\o\p\.\h
  633. X/*    This file is part of the software similarity tester SIM.
  634. X    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  635. X*/
  636. X
  637. X/* This is the public interface of top.g, a generic package for keeping
  638. X/* a top-10 list of objects of formal type.
  639. X/*
  640. X/* The application of this file must be preceded by
  641. X/* #include "top.p", which defines the parameters of the instantiation.
  642. X*/
  643. X
  644. Xextern InitTop();
  645. Xextern InsertTop();
  646. Xtypedef int TopGen;
  647. Xextern OpenTop();
  648. Xextern TTTYPE *NextTop();
  649. X#define    NoObject    ((TTTYPE*)0)
  650. Xextern CloseTop();
  651. + END-OF-FILE top.h
  652. chmod 'u=rw,g=r,o=r' \t\o\p\.\h
  653. set `sum \t\o\p\.\h`
  654. sum=$1
  655. case $sum in
  656. 48552)    :;;
  657. *)    echo 'Bad sum in '\t\o\p\.\h >&2
  658. esac
  659. echo Extracting \t\o\p\.\c
  660. sed 's/^X//' > \t\o\p\.\c << '+ END-OF-FILE '\t\o\p\.\c
  661. X/*    This file is part of the software similarity tester SIM.
  662. X    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  663. X*/
  664. X
  665. X#include    "text.h"
  666. X#include    "top.p"
  667. X#include    "top.h"
  668. X
  669. X#ifndef    lint        /* lint won't take this define ?!?!?! */
  670. X#define    longer(r0,r1)    (r0->rn_quality > r1->rn_quality)
  671. X
  672. X#else
  673. Xstatic int
  674. Xlonger(r0, r1) struct run *r0, *r1;    {
  675. X    return r0->rn_quality > r1->rn_quality;
  676. X}
  677. X#endif    lint
  678. X
  679. X/* Instantiate top.g  */
  680. X#include    "top.g"
  681. + END-OF-FILE top.c
  682. chmod 'u=rw,g=r,o=r' \t\o\p\.\c
  683. set `sum \t\o\p\.\c`
  684. sum=$1
  685. case $sum in
  686. 10035)    :;;
  687. *)    echo 'Bad sum in '\t\o\p\.\c >&2
  688. esac
  689. echo Extracting \p\a\r\a\m\s\.\h
  690. sed 's/^X//' > \p\a\r\a\m\s\.\h << '+ END-OF-FILE '\p\a\r\a\m\s\.\h
  691. X/*    This file is part of the software similarity tester SIM.
  692. X    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  693. X*/
  694. X
  695. X#define    MIN_RUN        24        /*    default minimum size
  696. X                        of interesting run
  697. X                    */
  698. X#define    PAGE_WIDTH    80
  699. + END-OF-FILE params.h
  700. chmod 'u=rw,g=r,o=r' \p\a\r\a\m\s\.\h
  701. set `sum \p\a\r\a\m\s\.\h`
  702. sum=$1
  703. case $sum in
  704. 36700)    :;;
  705. *)    echo 'Bad sum in '\p\a\r\a\m\s\.\h >&2
  706. esac
  707. echo Extracting \t\e\x\t\.\h
  708. sed 's/^X//' > \t\e\x\t\.\h << '+ END-OF-FILE '\t\e\x\t\.\h
  709. X/*    This file is part of the software similarity tester SIM.
  710. X    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  711. X*/
  712. X
  713. Xstruct text    {
  714. X    char *tx_fname;        /* the file name */
  715. X    int tx_needed;        /* set if file plays a role in final output */
  716. X    unsigned int tx_start;    /* positions in buff for the text */
  717. X    unsigned int tx_limit;
  718. X};
  719. X
  720. Xstruct chunk    {
  721. X    /* a chunk of text in various representations */
  722. X    struct text *ch_text;    /* a pointer to the file text */
  723. X    unsigned int ch_st_ch;    /* first in chunk, counted in C-chars */
  724. X    unsigned int ch_lm_ch;    /* first not in chunk */
  725. X    long ch_st_ls;        /* same in lseek positions */
  726. X    long ch_lm_ls;
  727. X    unsigned int ch_st_nl;    /* same in line numbers */
  728. X    unsigned int ch_lm_nl;
  729. X};
  730. X
  731. Xstruct run    {        /* a 'run' of coincident chars */
  732. X    struct chunk rn_cn0;    /* chunk in left file */
  733. X    struct chunk rn_cn1;    /* chunk in right file */
  734. X    unsigned int rn_quality;
  735. X};
  736. + END-OF-FILE text.h
  737. chmod 'u=rw,g=r,o=r' \t\e\x\t\.\h
  738. set `sum \t\e\x\t\.\h`
  739. sum=$1
  740. case $sum in
  741. 43449)    :;;
  742. *)    echo 'Bad sum in '\t\e\x\t\.\h >&2
  743. esac
  744. echo Extracting \d\e\b\u\g\.\h
  745. sed 's/^X//' > \d\e\b\u\g\.\h << '+ END-OF-FILE '\d\e\b\u\g\.\h
  746. X/*    This file is part of the software similarity tester SIM.
  747. X    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  748. X*/
  749. X
  750. X#define    DEBUG    0
  751. + END-OF-FILE debug.h
  752. chmod 'u=rw,g=r,o=r' \d\e\b\u\g\.\h
  753. set `sum \d\e\b\u\g\.\h`
  754. sum=$1
  755. case $sum in
  756. 64324)    :;;
  757. *)    echo 'Bad sum in '\d\e\b\u\g\.\h >&2
  758. esac
  759. echo Extracting \s\i\m\.\c
  760. sed 's/^X//' > \s\i\m\.\c << '+ END-OF-FILE '\s\i\m\.\c
  761. X/*    This file is part of the software similarity tester SIM.
  762. X    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  763. X*/
  764. X
  765. X#include    "params.h"
  766. X
  767. Xint min_run_size = MIN_RUN;
  768. X
  769. Xchar options[128];            /* for various, extensible flags */
  770. X
  771. Xmain(argc, argv)
  772. X    char *argv[];
  773. X{
  774. X    argv++, argc--;            /* skip program name */
  775. X
  776. X    while (argc > 0 && argv[0][0] == '-')    {
  777. X        char *par = &argv[0][1];
  778. X        
  779. X        while (*par)    {
  780. X            switch (*par)    {
  781. X            case 'r':
  782. X                min_run_size = atoi(argv[1]);
  783. X                argc--, argv++;
  784. X                break;
  785. X            default:
  786. X                options[*par]++;
  787. X                break;
  788. X            }
  789. X            par++;
  790. X        }
  791. X        argc--, argv++;
  792. X    }
  793. X    if (min_run_size == 0)
  794. X        error("Minimum run size equals 0");
  795. X    
  796. X    init_buff();
  797. X    
  798. X    /* Read the files */
  799. X    pass1(argv, argc);
  800. X    
  801. X    /* Set up the hash table */
  802. X    make_hash();
  803. X    
  804. X    /* Compare various files */
  805. X    compare();
  806. X    
  807. X    /* Delete hash table */
  808. X    free_hash();
  809. X    
  810. X    /* Find positions of found similarities */
  811. X    pass2();
  812. X
  813. X    /* Print the similarities */
  814. X    pass3();
  815. X    return 0;
  816. X}
  817. + END-OF-FILE sim.c
  818. chmod 'u=rw,g=r,o=r' \s\i\m\.\c
  819. set `sum \s\i\m\.\c`
  820. sum=$1
  821. case $sum in
  822. 42365)    :;;
  823. *)    echo 'Bad sum in '\s\i\m\.\c >&2
  824. esac
  825. echo Extracting \p\a\s\s\1\.\c
  826. sed 's/^X//' > \p\a\s\s\1\.\c << '+ END-OF-FILE '\p\a\s\s\1\.\c
  827. X/*    This file is part of the software similarity tester SIM.
  828. X    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  829. X*/
  830. X
  831. X#include    "buff.h"
  832. X#include    "text.h"
  833. X
  834. Xextern char *calloc();
  835. X
  836. Xstruct text *text;        /* to be filled in by calloc */
  837. Xint ntexts;            /* number of text records */
  838. X
  839. Xpass1(argv, argc)
  840. X    char *argv[];
  841. X{
  842. X    int n;
  843. X    
  844. X    /* allocate the array of text descriptors */
  845. X    ntexts = argc;
  846. X    text = (struct text *)calloc((unsigned)ntexts, sizeof (struct text));
  847. X    if (!text)
  848. X        error("Too many files");
  849. X
  850. X    /* read the files */
  851. X    for (n = 0; n < ntexts; n++)    {
  852. X        char *fname = argv[n];
  853. X        struct text *txt = &text[n];
  854. X        char ch;
  855. X    
  856. X        printf("File %s: ", fname);
  857. X    
  858. X        txt->tx_fname = fname;
  859. X        txt->tx_start = txt->tx_limit = text_length();
  860. X        if (!OpenStream(1, txt->tx_fname))    {
  861. X            printf("cannot open\n");
  862. X            OpenStream(1, "/dev/null");
  863. X        }
  864. X        while (NextChar(&ch) == 0)
  865. X            store(ch);
  866. X        CloseStream();
  867. X    
  868. X        txt->tx_limit = text_length();
  869. X        printf("%u C-units\n", txt->tx_limit - txt->tx_start);
  870. X    }
  871. X    printf("Total: %u C-units\n", text_length() - 1);
  872. X    printf("\n");
  873. X}
  874. + END-OF-FILE pass1.c
  875. chmod 'u=rw,g=r,o=r' \p\a\s\s\1\.\c
  876. set `sum \p\a\s\s\1\.\c`
  877. sum=$1
  878. case $sum in
  879. 58561)    :;;
  880. *)    echo 'Bad sum in '\p\a\s\s\1\.\c >&2
  881. esac
  882. echo Extracting \h\a\s\h\.\c
  883. sed 's/^X//' > \h\a\s\h\.\c << '+ END-OF-FILE '\h\a\s\h\.\c
  884. X/*    This file is part of the software similarity tester SIM.
  885. X    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  886. X*/
  887. X
  888. X#include    "buff.h"
  889. X#include    "text.h"
  890. X
  891. Xextern char *calloc();
  892. X
  893. Xextern char options[];
  894. Xextern int ntexts;
  895. Xextern struct text *text;
  896. Xextern int min_run_size;
  897. X
  898. Xstatic int hash_code();
  899. Xstatic print_hash();
  900. X
  901. X#define    N_HASH    10639            /* any suitable prime */
  902. X
  903. Xunsigned int *hash_table;        /* to be filled by malloc() */
  904. X
  905. X/* to judge the quality of the hash code */
  906. Xstatic tally_right = 0, tally_wrong = 0;
  907. Xstatic tally_hash(), print_tally();
  908. X
  909. Xmake_hash()    {
  910. X    unsigned int last[N_HASH];
  911. X    /*    last[i] is the index of the latest char with hash_code i,
  912. X        or 0 if there is none.
  913. X    */
  914. X    int n;
  915. X    
  916. X    for (n = 0; n < N_HASH; n++)
  917. X        last[n] = 0;
  918. X    
  919. X    hash_table = (unsigned int *)
  920. X            calloc(text_length(), sizeof (unsigned int));
  921. X    if (options['x'])
  922. X        hash_table = 0;
  923. X    if (!hash_table)    {
  924. X        printf(">>> Not enough memory for the hash table, ");
  925. X        printf("this is going to take time!\n\n");
  926. X        return;
  927. X    }
  928. X    
  929. X    for (n = 0; n < ntexts; n++)    {
  930. X        struct text *txt = &text[n];
  931. X        unsigned int j;
  932. X        
  933. X        for (
  934. X            j = txt->tx_start;
  935. X            j < txt->tx_limit - min_run_size + 1;
  936. X            j++
  937. X        )    {
  938. X            int h = hash_code(&buff[j]);
  939. X            
  940. X            if (last[h])    {
  941. X                hash_table[last[h]] = j;
  942. X                if (options['h'])
  943. X                    tally_hash(last[h], j);
  944. X            }
  945. X            last[h] = j;
  946. X        }
  947. X    }
  948. X    if (options['h'])
  949. X        print_tally();
  950. X    if (options['H'])
  951. X        print_hash();
  952. X}
  953. X
  954. Xstatic int
  955. Xhash_code(p)
  956. X    char *p;
  957. X{
  958. X    /*    hash_code(p) returns the hash code of the min_run_size first
  959. X        characters starting at p; caller guarantees that there
  960. X        are at least min_run_size chars.
  961. X    */
  962. X    int h = 0;
  963. X    int i;
  964. X    
  965. X    for (i = 0; i < min_run_size; i++)
  966. X        h = ((h << 1) + *p++) % N_HASH;
  967. X    return h;
  968. X}
  969. X
  970. Xstatic
  971. Xprint_hash()
  972. X{
  973. X    /* will not be called if hash_table == 0 */
  974. X    unsigned int i;
  975. X    
  976. X    for (i = 1; i < text_length(); i++)    {
  977. X        printf("%d: %c: ", i, buff[i]);
  978. X        printf("%u\n", hash_table[i]);
  979. X    }
  980. X}
  981. X
  982. Xstatic
  983. Xtally_hash(i0, i1)
  984. X    unsigned int i0, i1;
  985. X{
  986. X    int i;
  987. X    
  988. X    for (i = 0; i < min_run_size; i++)    {
  989. X        if (buff[i0++] != buff[i1++])    {
  990. X            tally_wrong++;
  991. X            return;
  992. X        }
  993. X    }
  994. X    tally_right++;
  995. X}
  996. X
  997. Xstatic
  998. Xprint_tally()
  999. X{
  1000. X    printf("Tally_right = %d, tally_wrong = %d, ",
  1001. X        tally_right, tally_wrong);
  1002. X    printf("hash code efficiency = %d%%\n",
  1003. X        100 * tally_right / (tally_right + tally_wrong));
  1004. X}
  1005. X
  1006. Xfree_hash()    {
  1007. X    if (hash_table)
  1008. X        free((char *)hash_table);
  1009. X}
  1010. + END-OF-FILE hash.c
  1011. chmod 'u=rw,g=r,o=r' \h\a\s\h\.\c
  1012. set `sum \h\a\s\h\.\c`
  1013. sum=$1
  1014. case $sum in
  1015. 22444)    :;;
  1016. *)    echo 'Bad sum in '\h\a\s\h\.\c >&2
  1017. esac
  1018. echo Extracting \c\o\m\p\a\r\e\.\c
  1019. sed 's/^X//' > \c\o\m\p\a\r\e\.\c << '+ END-OF-FILE '\c\o\m\p\a\r\e\.\c
  1020. X/*    This file is part of the software similarity tester SIM.
  1021. X    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  1022. X*/
  1023. X
  1024. X#include    "buff.h"
  1025. X#include    "text.h"
  1026. X#include    "top.p"
  1027. X#include    "top.h"
  1028. X
  1029. X/* from the Language Department: */
  1030. Xextern int MayBeStartOfRun();
  1031. Xextern unsigned int CheckRun();
  1032. X
  1033. Xextern char options[];
  1034. Xextern int ntexts;
  1035. Xextern struct text *text;
  1036. Xextern int min_run_size;
  1037. Xextern unsigned int *hash_table;
  1038. Xextern add_run();
  1039. X
  1040. Xstatic struct text *txt_at();
  1041. Xstatic unsigned int lcs();
  1042. X
  1043. Xcompare()
  1044. X{
  1045. X    int n;
  1046. X    
  1047. X    InitTop();
  1048. X    for (n = 0; n < ntexts; n++)    {
  1049. X        struct text *txt0 = &text[n];
  1050. X        unsigned int i0 = txt0->tx_start;
  1051. X        
  1052. X        while (i0 < txt0->tx_limit - min_run_size + 1)    {
  1053. X            i0 += lcs(txt0, i0);
  1054. X        }
  1055. X    }
  1056. X}
  1057. X
  1058. Xstatic unsigned int
  1059. Xlcs(txt0, i0)
  1060. X    struct text *txt0;
  1061. X    unsigned int i0;
  1062. X{
  1063. X    /*    find the longest common substring in:
  1064. X            txt0, starting precisely at i0 and
  1065. X            the rest of the text
  1066. X    */
  1067. X    struct text *txt1 = txt0;
  1068. X    unsigned int i1 = i0;
  1069. X    struct text *txt_best;
  1070. X    unsigned int i_best;
  1071. X    unsigned int size_best = 0;
  1072. X    
  1073. X    if (!MayBeStartOfRun(buff[i0]))    {
  1074. X        return 1;
  1075. X    }
  1076. X    
  1077. X    while(
  1078. X        i1 = hash_table ? hash_table[i1] : i1 + 1,
  1079. X        txt1 = txt_at(txt1, i1)
  1080. X    )    {
  1081. X        
  1082. X        if (    /* we don't want to compare a file to itself */
  1083. X            options['s'] && i1 < txt0->tx_limit
  1084. X        )    {
  1085. X            /* skip this possibility */
  1086. X        }
  1087. X        else
  1088. X        if (    /* we are looking at the middle of a run */
  1089. X            i0 != txt0->tx_start && i1 != txt1->tx_start &&
  1090. X            buff[i0-1] == buff[i1-1]
  1091. X        )    {
  1092. X            /* skip this possibility */
  1093. X        }
  1094. X        else    {
  1095. X            /* see how far we can get */
  1096. X            unsigned int j0 = i0, j1 = i1;
  1097. X            unsigned int size = 0;
  1098. X            unsigned int limit0 = txt0->tx_limit;
  1099. X            unsigned int limit1 = txt1->tx_limit;
  1100. X            
  1101. X            while (    size < j1 - j0 &&
  1102. X                j0 < limit0 && j1 < limit1 &&
  1103. X                buff[j0] == buff[j1]
  1104. X            )    {
  1105. X                j0++, j1++, size++;
  1106. X            }
  1107. X            
  1108. X            if (size >= min_run_size)    {
  1109. X                /*    offer the run to the
  1110. X                    Language Department
  1111. X                */
  1112. X                size = CheckRun(&buff[i0], size);
  1113. X            }
  1114. X            
  1115. X            if (    /* we still have something better */
  1116. X                size >= min_run_size && size > size_best
  1117. X            )    {
  1118. X                /* record it */
  1119. X                txt_best = txt1;
  1120. X                i_best = i1;
  1121. X                size_best = size;
  1122. X            }
  1123. X        }
  1124. X    }
  1125. X    if (size_best)    {
  1126. X        add_run(txt0, i0, txt_best, i_best, size_best);
  1127. X        return size_best;
  1128. X    }
  1129. X    else
  1130. X        return 1;
  1131. X}
  1132. X
  1133. Xstatic struct text *
  1134. Xtxt_at(txt, i)
  1135. X    struct text *txt;
  1136. X    unsigned int i;
  1137. X{
  1138. X    if (i == 0 || i >= text_length())
  1139. X        return 0;
  1140. X    while (i >= txt->tx_limit)
  1141. X        txt++;
  1142. X    return txt;
  1143. X}
  1144. + END-OF-FILE compare.c
  1145. chmod 'u=rw,g=r,o=r' \c\o\m\p\a\r\e\.\c
  1146. set `sum \c\o\m\p\a\r\e\.\c`
  1147. sum=$1
  1148. case $sum in
  1149. 22558)    :;;
  1150. *)    echo 'Bad sum in '\c\o\m\p\a\r\e\.\c >&2
  1151. esac
  1152. echo Extracting \a\d\d\_\r\u\n\.\c
  1153. sed 's/^X//' > \a\d\d\_\r\u\n\.\c << '+ END-OF-FILE '\a\d\d\_\r\u\n\.\c
  1154. X/*    This file is part of the software similarity tester SIM.
  1155. X    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  1156. X*/
  1157. X
  1158. X#include    "buff.h"
  1159. X#include    "text.h"
  1160. X#include    "top.p"
  1161. X#include    "top.h"
  1162. X
  1163. Xstatic set_chunk();
  1164. X
  1165. Xadd_run(txt0, i0, txt1, i1, size)
  1166. X    struct text *txt0, *txt1;
  1167. X    unsigned int i0, i1;
  1168. X    unsigned int size;
  1169. X{
  1170. X    /*    Adds the run of given size to our collection.
  1171. X    */
  1172. X    struct run r;
  1173. X    
  1174. X    set_chunk(&r.rn_cn0, txt0, i0 - txt0->tx_start, size);
  1175. X    set_chunk(&r.rn_cn1, txt1, i1 - txt1->tx_start, size);
  1176. X    r.rn_quality = size;
  1177. X    
  1178. X    InsertTop(&r);
  1179. X}
  1180. X
  1181. Xstatic
  1182. Xset_chunk(cnk, txt, index, size)
  1183. X    struct chunk *cnk;
  1184. X    struct text *txt;
  1185. X    unsigned int index;
  1186. X    unsigned int size;
  1187. X{
  1188. X    /*    Fill the chunk *cnk with info about the piece of text
  1189. X        in txt starting at index extending over size characters.
  1190. X    */
  1191. X    txt->tx_needed = 1;
  1192. X    cnk->ch_text = txt;
  1193. X    cnk->ch_st_ch = index;
  1194. X    cnk->ch_lm_ch = index + size;
  1195. X    cnk->ch_st_ls = cnk->ch_lm_ls = 0;
  1196. X    cnk->ch_st_nl = cnk->ch_lm_nl = 1;
  1197. X}
  1198. + END-OF-FILE add_run.c
  1199. chmod 'u=rw,g=r,o=r' \a\d\d\_\r\u\n\.\c
  1200. set `sum \a\d\d\_\r\u\n\.\c`
  1201. sum=$1
  1202. case $sum in
  1203. 53616)    :;;
  1204. *)    echo 'Bad sum in '\a\d\d\_\r\u\n\.\c >&2
  1205. esac
  1206. echo Extracting \p\a\s\s\2\.\c
  1207. sed 's/^X//' > \p\a\s\s\2\.\c << '+ END-OF-FILE '\p\a\s\s\2\.\c
  1208. X/*    This file is part of the software similarity tester SIM.
  1209. X    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  1210. X*/
  1211. X
  1212. X#include    "text.h"
  1213. X#include    "top.p"
  1214. X#include    "top.h"
  1215. X#include    "debug.h"
  1216. X
  1217. Xextern int ntexts;
  1218. Xextern struct text *text;
  1219. X
  1220. Xstatic upd_top(), upd_chunk();
  1221. X
  1222. Xpass2()    {
  1223. X    int n;
  1224. X    
  1225. X    for (n = 0; n < ntexts; n++)    {
  1226. X        struct text *txt = &text[n];
  1227. X        unsigned int ch_cnt;
  1228. X        long ls_pos;
  1229. X        unsigned int nl_cnt = 1;
  1230. X    
  1231. X        if (!txt->tx_needed)        /* an optimization */
  1232. X            continue;
  1233. X    
  1234. X        if (!OpenStream(2, txt->tx_fname))    {
  1235. X            printf("*** File %s disappeared\n", txt->tx_fname);
  1236. X            OpenStream(2, "/dev/null");
  1237. X        }
  1238. X    
  1239. X        while (NextPair(&ch_cnt, &ls_pos) == 0)    {
  1240. X            /*    fill in the lseek and line positions
  1241. X                in the collected runs
  1242. X            */
  1243. X            nl_cnt++;
  1244. X#if    DEBUG == 1
  1245. X            printf("pass2 on %s: ch_cnt = %u, ls_pos = %ld\n",
  1246. X                    txt->tx_fname, ch_cnt, ls_pos);
  1247. X#endif    DEBUG == 1
  1248. X            upd_top(txt, ch_cnt, ls_pos, nl_cnt);
  1249. X        }
  1250. X        CloseStream();
  1251. X    }
  1252. X}
  1253. X
  1254. Xstatic
  1255. Xupd_top(txt, ch_cnt, ls_pos, nl_cnt)
  1256. X    struct text *txt;
  1257. X    unsigned int ch_cnt;
  1258. X    long ls_pos;
  1259. X    unsigned int nl_cnt;
  1260. X{
  1261. X    TopGen tp;
  1262. X    struct run *run;
  1263. X    
  1264. X    OpenTop(&tp);
  1265. X    while ((run = NextTop(&tp)), run != NoObject)    {
  1266. X        struct chunk *cnk0 = &run->rn_cn0;
  1267. X        struct chunk *cnk1 = &run->rn_cn1;
  1268. X        
  1269. X        if (cnk0->ch_text == txt)
  1270. X            upd_chunk(cnk0, ch_cnt, ls_pos, nl_cnt);
  1271. X        if (cnk1->ch_text == txt)
  1272. X            upd_chunk(cnk1, ch_cnt, ls_pos, nl_cnt);
  1273. X    }
  1274. X    CloseTop(&tp);
  1275. X}
  1276. X
  1277. Xstatic
  1278. Xupd_chunk(cnk, ch_cnt, ls_pos, nl_cnt)
  1279. X    struct chunk *cnk;
  1280. X    unsigned int ch_cnt;
  1281. X    long ls_pos;
  1282. X    unsigned int nl_cnt;
  1283. X{
  1284. X    if (ch_cnt <= cnk->ch_st_ch)    {
  1285. X        cnk->ch_st_ls = ls_pos;
  1286. X        cnk->ch_st_nl = nl_cnt;
  1287. X    }
  1288. X    if (cnk->ch_lm_ls == 0 && cnk->ch_lm_ch <= ch_cnt)    {
  1289. X        cnk->ch_lm_ls = ls_pos;
  1290. X        cnk->ch_lm_nl = nl_cnt;
  1291. X    }
  1292. X}
  1293. + END-OF-FILE pass2.c
  1294. chmod 'u=rw,g=r,o=r' \p\a\s\s\2\.\c
  1295. set `sum \p\a\s\s\2\.\c`
  1296. sum=$1
  1297. case $sum in
  1298. 15182)    :;;
  1299. *)    echo 'Bad sum in '\p\a\s\s\2\.\c >&2
  1300. esac
  1301. echo Extracting \p\a\s\s\3\.\c
  1302. sed 's/^X//' > \p\a\s\s\3\.\c << '+ END-OF-FILE '\p\a\s\s\3\.\c
  1303. X/*    This file is part of the software similarity tester SIM.
  1304. X    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  1305. X*/
  1306. X
  1307. X#include    <stdio.h>
  1308. X#include    "params.h"
  1309. X#include    "text.h"
  1310. X#include    "top.p"
  1311. X#include    "top.h"
  1312. X#include    "debug.h"
  1313. X
  1314. Xextern char options[];
  1315. X
  1316. Xstatic FILE *chunk_open();
  1317. Xstatic unsigned int fill_line();
  1318. Xstatic show_chunk(), show_line(), clear_line(), print_run();
  1319. X
  1320. X#define    MAXLINE        (PAGE_WIDTH/2-2)
  1321. X
  1322. Xpass3()    {
  1323. X    TopGen tp;
  1324. X    struct run *run;
  1325. X
  1326. X    OpenTop(&tp);
  1327. X    while ((run = NextTop(&tp)), run != NoObject)    {
  1328. X        print_run(run);
  1329. X        show_chunk(run);
  1330. X        printf("\n");
  1331. X    }
  1332. X    CloseTop(&tp);
  1333. X}
  1334. X
  1335. Xstatic
  1336. Xprint_run(run)
  1337. X    struct run *run;
  1338. X{
  1339. X#if    DEBUG == 1
  1340. X#include    "buff.h"
  1341. X    unsigned int i;
  1342. X    struct chunk *cnk0 = &run->rn_cn0;
  1343. X    struct chunk *cnk1 = &run->rn_cn1;
  1344. X    
  1345. X    printf("File %s vs. file %s:\n",
  1346. X        cnk0->ch_text->tx_fname,
  1347. X        cnk1->ch_text->tx_fname
  1348. X    );
  1349. X    printf("from C-char %d,%d to %d,%d:",
  1350. X        cnk0->ch_st_ch, cnk1->ch_st_ch,
  1351. X        cnk0->ch_lm_ch, cnk1->ch_lm_ch
  1352. X    );
  1353. X    printf(" from ASCII-char %d,%d to %d,%d:",
  1354. X        cnk0->ch_st_ls, cnk1->ch_st_ls,
  1355. X        cnk0->ch_lm_ls, cnk1->ch_lm_ls
  1356. X    );
  1357. X    printf(" from lines %d,%d to %d,%d:",
  1358. X        cnk0->ch_st_nl, cnk1->ch_st_nl,
  1359. X        cnk0->ch_lm_nl - 1, cnk1->ch_lm_nl - 1
  1360. X    );
  1361. X    printf(" %d C-chars\n", run->rn_quality);
  1362. X    
  1363. X    /* show C-chars, with a one-char margin */
  1364. X    for (    i = cnk0->ch_st_ch - 1;
  1365. X        i < cnk0->ch_lm_ch + 1;
  1366. X        i++
  1367. X    )    {
  1368. X        putchar(buff[cnk0->ch_text->tx_start + i]);
  1369. X    }
  1370. X    printf("\n");
  1371. X    for (    i = cnk1->ch_st_ch - 1;
  1372. X        i < cnk1->ch_lm_ch + 1;
  1373. X        i++
  1374. X    )    {
  1375. X        putchar(buff[cnk1->ch_text->tx_start + i]);
  1376. X    }
  1377. X    printf("\n");
  1378. X#endif    DEBUG == 1
  1379. X
  1380. X#ifdef    lint
  1381. X    run = run;
  1382. X#endif    lint
  1383. X}
  1384. X
  1385. X
  1386. Xstatic
  1387. Xshow_chunk(run)
  1388. X    struct run *run;
  1389. X{
  1390. X    /* The animals came in two by two ... */
  1391. X    struct chunk *cnk0 = &run->rn_cn0;
  1392. X    struct chunk *cnk1 = &run->rn_cn1;
  1393. X    unsigned int nl_cnt0 = cnk0->ch_lm_nl - cnk0->ch_st_nl;
  1394. X    unsigned int nl_cnt1 = cnk1->ch_lm_nl - cnk1->ch_st_nl;
  1395. X    FILE *f0;
  1396. X    FILE *f1;
  1397. X    char line0[MAXLINE + 1];
  1398. X    char line1[MAXLINE + 1];
  1399. X    extern char *sprintf();
  1400. X    
  1401. X    sprintf(line0, "%s: line %d-%d",
  1402. X        cnk0->ch_text->tx_fname,
  1403. X        cnk0->ch_st_nl, cnk0->ch_lm_nl - 1, run->rn_quality);
  1404. X    sprintf(line1, "%s: line %d-%d",
  1405. X        cnk1->ch_text->tx_fname,
  1406. X        cnk1->ch_st_nl, cnk1->ch_lm_nl - 1, run->rn_quality);
  1407. X    show_line(line0, line1);
  1408. X    if (options['n'])
  1409. X        return;            /* ... had enough so soon ... */
  1410. X
  1411. X    f0 = chunk_open(cnk0);
  1412. X    f1 = chunk_open(cnk1);
  1413. X    
  1414. X    /* fill lines and print them */
  1415. X    while (nl_cnt0 != 0 || nl_cnt1 != 0)    {
  1416. X        if (nl_cnt0)    {
  1417. X            fill_line(f0, line0);
  1418. X            nl_cnt0--;
  1419. X        }
  1420. X        else    clear_line(line0);
  1421. X        if (nl_cnt1)    {
  1422. X            fill_line(f1, line1);
  1423. X            nl_cnt1--;
  1424. X        }
  1425. X        else    clear_line(line1);
  1426. X        show_line(line0, line1);
  1427. X    }
  1428. X    
  1429. X    fclose(f0);
  1430. X    fclose(f1);
  1431. X}
  1432. X
  1433. Xstatic FILE *
  1434. Xchunk_open(cnk)
  1435. X    struct chunk *cnk;
  1436. X{
  1437. X    /*    opens the file in which the chunk resides and positions
  1438. X        the file at the beginning of the chunk
  1439. X    */
  1440. X    char *fname = cnk->ch_text->tx_fname;
  1441. X    FILE *f = fopen(fname, "r");
  1442. X    
  1443. X    if (f == NULL)    {
  1444. X        printf("*** File %s disappeared\n", fname);
  1445. X        f = fopen("/dev/null", "r");
  1446. X    }
  1447. X    fseek(f, cnk->ch_st_ls, 0);
  1448. X    return f;
  1449. X}
  1450. X
  1451. Xstatic unsigned int
  1452. Xfill_line(f, ln)
  1453. X    FILE *f;
  1454. X    char ln[];
  1455. X{
  1456. X    /*    Reads one line from f and puts it in condensed form in ln.
  1457. X    */
  1458. X    int ch;
  1459. X    int indent = 0, lpos = 0;
  1460. X    
  1461. X    /* condense and skip initial blank */
  1462. X    while ((ch = getc(f)), ch == ' ' || ch == '\t')    {
  1463. X        if (ch == '\t')
  1464. X            indent = 8;
  1465. X        else
  1466. X            indent++;
  1467. X        if (indent == 8)    {
  1468. X            /* every eight blanks give one blank */
  1469. X            if (lpos < MAXLINE)
  1470. X                ln[lpos++] = ' ';
  1471. X            indent = 0;
  1472. X        }
  1473. X    }
  1474. X    
  1475. X    /* store the rest */
  1476. X    while (ch >= 0 && ch != '\n')    {
  1477. X        if (ch == '\t')        /* replace tabs by blanks */
  1478. X            ch = ' ';
  1479. X        if (lpos < MAXLINE)
  1480. X            ln[lpos++] = ch;
  1481. X        ch = getc(f);
  1482. X    }
  1483. X    ln[lpos] = '\0';        /* always room for this one */
  1484. X}
  1485. X
  1486. Xstatic
  1487. Xclear_line(ln)
  1488. X    char ln[];
  1489. X{
  1490. X    /* a simple null byte will suffice */
  1491. X    ln[0] = '\0';
  1492. X}
  1493. X
  1494. Xstatic
  1495. Xshow_line(ln0, ln1)
  1496. X    char ln0[], ln1[];
  1497. X{
  1498. X    int i;
  1499. X    
  1500. X    for (i = 0; i < MAXLINE && ln0[i] != '\0'; i++)
  1501. X        putchar(ln0[i]);
  1502. X    for (; i < MAXLINE; i++)
  1503. X        putchar(' ');
  1504. X    printf(" |");
  1505. X
  1506. X    for (i = 0; i < MAXLINE && ln1[i] != '\0'; i++)
  1507. X            putchar(ln1[i]);
  1508. X    printf("\n");
  1509. X}
  1510. + END-OF-FILE pass3.c
  1511. chmod 'u=rw,g=r,o=r' \p\a\s\s\3\.\c
  1512. set `sum \p\a\s\s\3\.\c`
  1513. sum=$1
  1514. case $sum in
  1515. 35264)    :;;
  1516. *)    echo 'Bad sum in '\p\a\s\s\3\.\c >&2
  1517. esac
  1518. echo Extracting \m\a\i\n\.\c
  1519. sed 's/^X//' > \m\a\i\n\.\c << '+ END-OF-FILE '\m\a\i\n\.\c
  1520. X/*    This file is part of the software similarity tester SIM.
  1521. X    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  1522. X*/
  1523. X
  1524. X/*
  1525. X    This is a service program for the similarity tester.
  1526. X    A call of 'cstream -1 inp.c' yields the tokens of inp.c as
  1527. X    single characters, as used by pass1 of sim.
  1528. X    A call of 'cstream -2 inp.c' yields a list of <token_number,
  1529. X    character_number> pairs, one for each line.  This is used by
  1530. X    pass3.
  1531. X*/
  1532. X
  1533. X#include    <stdio.h>
  1534. X
  1535. Xchar options[128];
  1536. X
  1537. Xmain(argc, argv)
  1538. X    char *argv[];
  1539. X{
  1540. X    if (argc != 3)    {
  1541. X        fprintf(stderr, "Call is: %s -[12] inp.c\n", argv[0]);
  1542. X        return 1;
  1543. X    }
  1544. X
  1545. X    if (!OpenStream(argv[1][1] - '0', argv[2]))    {
  1546. X        fprintf(stderr, "%s: cannot open\n", argv[2]);
  1547. X        return 1;
  1548. X    }
  1549. X
  1550. X    if (argv[1][1] == '1')    {
  1551. X        char ch;
  1552. X
  1553. X        while (NextChar(&ch) == 0)
  1554. X            putchar(ch);
  1555. X    }
  1556. X    else
  1557. X    if (argv[1][1] == '2')    {
  1558. X        unsigned int ch_cnt;
  1559. X        long ls_pos;
  1560. X
  1561. X        while (NextPair(&ch_cnt, &ls_pos) == 0)
  1562. X            printf("%ld,%ld\n", ch_cnt, ls_pos);
  1563. X    }
  1564. X    return 0;
  1565. X}
  1566. + END-OF-FILE main.c
  1567. chmod 'u=rw,g=r,o=r' \m\a\i\n\.\c
  1568. set `sum \m\a\i\n\.\c`
  1569. sum=$1
  1570. case $sum in
  1571. 07408)    :;;
  1572. *)    echo 'Bad sum in '\m\a\i\n\.\c >&2
  1573. esac
  1574. echo Extracting \c\l\a\n\g\.\l
  1575. sed 's/^X//' > \c\l\a\n\g\.\l << '+ END-OF-FILE '\c\l\a\n\g\.\l
  1576. X%{
  1577. X/*    This file is part of the software similarity tester SIM.
  1578. X    Written by Dick Grune, Vrije Universiteit, Amsterdam.
  1579. X*/
  1580. X
  1581. X/*
  1582. X    C language front end for the similarity tester.
  1583. X*/
  1584. X
  1585. X/* Language-dependent Code */
  1586. X#include    "idf.h"
  1587. X
  1588. Xstatic struct idf ppcmd[] =    {
  1589. X    "define",    'D',
  1590. X    "else",        'E',
  1591. X    "endif",    'Z',
  1592. X    "if",        'F',
  1593. X    "ifdef",    'Y',
  1594. X    "ifndef",    'N',
  1595. X    "include",    'I',
  1596. X    "line",        'L',
  1597. X    "undef",    'U'
  1598. X};
  1599. X
  1600. Xstatic struct idf reserved[] =    {
  1601. X    "auto",        'a',
  1602. X    "break",    'b',
  1603. X    "case",        'k',
  1604. X    "char",        'c',
  1605. X    "continue",    'z',
  1606. X    "default",    '_',
  1607. X    "do",        'd',
  1608. X    "double",    'm',
  1609. X    "else",        'e',
  1610. X    "enum",        'n',
  1611. X    "extern",    'q',
  1612. X    "float",    'y',
  1613. X    "for",        'f',
  1614. X    "goto",        'g',
  1615. X    "if",        'i',
  1616. X    "int",        'j',
  1617. X    "long",        'l',
  1618. X    "register",    '\0',        /* ignore */
  1619. X    "return",    'r',
  1620. X    "short",    'h',
  1621. X    "sizeof",    'o',
  1622. X    "static",    'p',
  1623. X    "struct",    's',
  1624. X    "switch",    'x',
  1625. X    "typedef",    't',
  1626. X    "union",    'u',
  1627. X    "unsigned",    'v',
  1628. X    "void",        '\0',        /* ignore */
  1629. X    "while",    'w'
  1630. X};
  1631. X
  1632. Xstatic int
  1633. Xis_trailer(ch)    {
  1634. X    return ch == ')' || ch == '}' || ch == ';';
  1635. X}
  1636. X
  1637. Xint
  1638. XMayBeStartOfRun(ch)    {
  1639. X    return !is_trailer(ch);
  1640. X}
  1641. X
  1642. Xunsigned int
  1643. XCheckRun(str, size) char *str; unsigned int size;    {
  1644. X    /*    Checks the run starting at str with length size for
  1645. X        acceptability in the language.  Cuts from the end if
  1646. X        necessary and returns the accepted length (which may
  1647. X        be zero).
  1648. X    */
  1649. X    extern char options[];
  1650. X    
  1651. X    if (options['f'])    {    /* function-like forms only */
  1652. X        unsigned int pos;
  1653. X        unsigned int lb_pos = 0;/* latest balancing position */
  1654. X        int braces = 0;
  1655. X        int parens = 0;
  1656. X        int brackets = 0;
  1657. X        
  1658. X        for (pos = 0; pos < size; pos++)    {
  1659. X            switch (str[pos])    {
  1660. X            case '{': braces++; break;
  1661. X            case '}': braces--; break;
  1662. X            case '(': parens++; break;
  1663. X            case ')': parens--; break;
  1664. X            case '[': brackets++; break;
  1665. X            case ']': brackets--; break;
  1666. X            }
  1667. X            if (    /* this was one closer too many */
  1668. X                braces < 0 || parens < 0 || brackets < 0
  1669. X            )    {
  1670. X                break;
  1671. X            }
  1672. X            if (    /* it happens to balance here */
  1673. X                braces == 0 && parens == 0 && brackets == 0
  1674. X            )    {
  1675. X                lb_pos = pos + 1;
  1676. X            }
  1677. X        }
  1678. X        size = lb_pos;            /* cut to size */
  1679. X    }
  1680. X    else    {
  1681. X        while (    /* there is trailing garbage */
  1682. X            size != 0 &&
  1683. X            (str[size - 1] == '@' || is_trailer(str[size - 1]))
  1684. X        )    {
  1685. X            /* remove it */
  1686. X            size--;
  1687. X        }
  1688. X    }
  1689. X    return size;
  1690. X}
  1691. X
  1692. X/* Language-INdependent Code */
  1693. X#include    "stream.h"
  1694. X
  1695. Xyystart()    {
  1696. X    BEGIN INITIAL;
  1697. X}
  1698. X
  1699. Xstatic int
  1700. Xyywrap()    {
  1701. X    return 1;
  1702. X}
  1703. X
  1704. X%}
  1705. X
  1706. X%Start    Comment
  1707. X
  1708. XAnyQuoted    (\\.)
  1709. XStrChar        ([^"\n\\]|{AnyQuoted})
  1710. XChrChar        ([^'\\]|{AnyQuoted})
  1711. XComChar        ([^*\n]|(\*[^/]))
  1712. XIdf        ([A-Za-z][A-Za-z0-9_]*)
  1713. X
  1714. X%%
  1715. X
  1716. X\"{StrChar}*\"    {    /* strings */
  1717. X        cput('"');
  1718. X        count();
  1719. X    }
  1720. X
  1721. X\'{ChrChar}\'    {    /* characters */
  1722. X        cput('\'');
  1723. X        count();
  1724. X    }
  1725. X
  1726. X"/*"    {    /*    We cannot have one pattern for a comment
  1727. X            (although one can be written), since the matched
  1728. X            string would overflow lex-internal buffers like
  1729. X            yysbuf and yytext. So we have to break up the string
  1730. X            into lines and keep track of where we are in a start
  1731. X            condition <Comment>.
  1732. X        */
  1733. X        BEGIN Comment;
  1734. X        count();
  1735. X    }
  1736. X
  1737. X<Comment>{ComChar}*    {    /* comment up to \n or end-of-comment */
  1738. X        count();
  1739. X    }
  1740. X
  1741. X<Comment>"*/"    {        /* end-of-comment */
  1742. X        BEGIN INITIAL;
  1743. X        count();
  1744. X    }
  1745. X
  1746. X#[ \t]*include.*    {    /* skip #include line */
  1747. X        count();
  1748. X    }
  1749. X
  1750. X#[ \t]*{Idf}    {    /* a preprocessor line */
  1751. X        char *n = yytext+1;
  1752. X        int ch;
  1753. X
  1754. X        /* skip layout in front of preprocessor identifier */
  1755. X        while (*n == ' ' || *n == '\t')
  1756. X            n++;
  1757. X        ch = idf2char(n, ppcmd);
  1758. X        if (ch < 0)    {
  1759. X            cput('#');
  1760. X        }
  1761. X        else
  1762. X            cput(ch);
  1763. X        count();
  1764. X    }
  1765. X
  1766. X{Idf}    {
  1767. X        int ch = idf2char(yytext, reserved);
  1768. X
  1769. X        if (ch < 0)
  1770. X            cput('@');
  1771. X        else
  1772. X        if (ch > 0)
  1773. X            cput(ch);
  1774. X        count();
  1775. X    }
  1776. X
  1777. X[ \t]    {    /* layout */
  1778. X        count();
  1779. X    }
  1780. X
  1781. X\n    {    /* count newlines */
  1782. X        count();
  1783. X        c_eol();
  1784. X    }
  1785. X
  1786. X.    {    /* copy other text */
  1787. X        cput(yytext[0]);
  1788. X        count();
  1789. X    }
  1790. X
  1791. X%%
  1792. + END-OF-FILE clang.l
  1793. chmod 'u=rw,g=r,o=r' \c\l\a\n\g\.\l
  1794. set `sum \c\l\a\n\g\.\l`
  1795. sum=$1
  1796. case $sum in
  1797. 21016)    :;;
  1798. *)    echo 'Bad sum in '\c\l\a\n\g\.\l >&2
  1799. esac
  1800. exit 0
  1801.  
  1802.  
  1803.