-
Notifications
You must be signed in to change notification settings - Fork 3
/
pass2.c
175 lines (146 loc) · 3.89 KB
/
pass2.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/* This file is part of the software similarity tester SIM.
Written by Dick Grune, Vrije Universiteit, Amsterdam.
$Id: pass2.c,v 2.20 2012-09-30 11:55:19 Gebruiker Exp $
*/
#include <stdio.h>
#include "debug.par"
#include "sim.h"
#include "token.h"
#include "text.h"
#include "lang.h"
#include "pass2.h"
#undef DB_POS
#ifdef DB_POS
static void db_print_pos_list(const char *, const struct text *);
static void db_print_lex(const char *);
#endif
static void pass2_txt(struct text *txt);
static int next_eol_obtained(void);
void
Retrieve_Runs(void) {
int n;
for (n = 0; n < Number_Of_Texts; n++) {
pass2_txt(&Text[n]);
}
}
/* begin instantiate static void sort_pos_list(struct position **) */
#define SORT_STRUCT position
#define SORT_NAME sort_pos_list
#define SORT_BEFORE(p1,p2) ((p1)->ps_tk_cnt < (p2)->ps_tk_cnt)
#define SORT_NEXT ps_next
#include "sortlist.bdy"
/* end instantiate sort_pos_list() */
static void
pass2_txt(struct text *txt) {
struct position *pos;
size_t old_nl_cnt;
if (!txt->tx_pos) /* no need to scan the file */
return;
/* Open_Text() initializes lex_nl_cnt and lex_tk_cnt */
if (!Open_Text(Second, txt)) {
fprintf(stderr, ">>>> File %s disappeared <<<<\n",
txt->tx_fname
);
return;
}
/* Sort the positions so they can be matched to the file; the linked
list of struct positions snakes through the struct positions in the
struct chunks in the struct runs.
*/
#ifdef DB_POS
db_print_pos_list("before sorting", txt);
#endif /* DB_POS */
sort_pos_list(&txt->tx_pos);
#ifdef DB_POS
db_print_pos_list("after sorting", txt);
#endif /* DB_POS */
#ifdef DB_NL_BUFF
db_print_nl_buff(txt->tx_nl_start, txt->tx_nl_limit);
#endif /* DB_NL_BUFF */
#ifdef DB_POS
fprintf(Debug_File, "\n**** DB_PRINT_SCAN of %s ****\n", txt->tx_fname);
#endif /* DB_POS */
old_nl_cnt = 1;
pos = txt->tx_pos;
while (pos) {
/* we scan the pos list and the file in parallel */
/* find the corresponding line */
while (pos->ps_tk_cnt >= lex_tk_cnt) { /* was >= ZZ */
/* pos does not refer to this line, try the next */
/* shift the administration */
old_nl_cnt = lex_nl_cnt;
/* and get the next eol position */
if (!next_eol_obtained()) {
/* ouch! not enough lines! */
fprintf(stderr, ">>>> File %s modified <<<<\n",
txt->tx_fname
);
break;
}
#ifdef DB_POS
db_print_lex(txt->tx_fname);
#endif /* DB_POS */
}
/* fill in the pos */
switch (pos->ps_type) {
case 0: /* first token of run */
pos->ps_nl_cnt = old_nl_cnt;
break;
case 1: /* last token of run */
pos->ps_nl_cnt = lex_nl_cnt;
break;
}
/* and get the next pos */
pos = pos->ps_next;
}
#ifdef DB_POS
db_print_pos_list("after scanning", txt);
#endif /* DB_POS */
/* Flush the flex buffers; it's easier than using YY_BUFFER_STATE. */
while (Next_Text_Token_Obtained(Second));
Close_Text(Second, txt);
}
static int
next_eol_obtained(void) {
while (Next_Text_Token_Obtained(Second)) {
if (Token_EQ(lex_token, End_Of_Line)) return 1;
}
return 0;
}
#ifdef DB_POS
static void
db_print_pos(const struct position *pos) {
fprintf(Debug_File, "pos type = %s; %s count = %u",
(pos->ps_type == 0 ? "first" : " last"),
token_name,
pos->ps_tk_cnt
);
fprintf(Debug_File, ", line # = ");
if (pos->ps_nl_cnt == (size_t) -1) {
fprintf(Debug_File, "<NOT SET>");
}
else {
fprintf(Debug_File, "%u", pos->ps_nl_cnt);
}
fprintf(Debug_File, "\n");
}
static void
db_print_pos_list(const char *msg, const struct text *txt) {
fprintf(Debug_File, "\n**** DB_PRINT_POS_LIST of %s, %s ****\n",
txt->tx_fname, msg);
const struct position *pos = txt->tx_pos;
while (pos) {
db_print_pos(pos);
pos = pos->ps_next;
}
fprintf(Debug_File, "\n");
}
static void
db_print_lex(const char *fn) {
fprintf(Debug_File,
"%s: lex_tk_cnt = %u, lex_nl_cnt = %u, lex_token = ",
fn, lex_tk_cnt, lex_nl_cnt);
fprint_token(Debug_File, lex_token);
fprintf(Debug_File, "\n");
}
#endif /* DB_POS */