summaryrefslogtreecommitdiff
path: root/fpcsrc/utils/sim_pasc/pass2.c
blob: 816fb8805b6211788a280ca7d5328476f49156c8 (plain)
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
/*	This file is part of the software similarity tester SIM.
	Written by Dick Grune, Vrije Universiteit, Amsterdam.
	$Id: pass2.c,v 2.10 2004/08/05 09:49:46 dick Exp $
*/

#include	<stdio.h>

#include	"debug.par"
#include	"sim.h"
#include	"text.h"
#include	"lex.h"
#include	"pass2.h"

#ifdef	DB_POS
static void db_print_pos_list(const char *, const struct position *);
static void db_print_lex(const char *);
#endif

static void pass2_txt(struct text *txt);
static int next_eol_obtained(void);

void
Pass2(void) {
	int n;

	for (n = 0; n < NumberOfTexts; n++) {
		pass2_txt(&Text[n]);
	}
}

/* instantiate sort_pos_list() */
#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"

static void
pass2_txt(struct text *txt) {
	register struct position *pos;
	register unsigned int old_nl_cnt;

	if (!txt->tx_pos)	/* no need to scan the file */
		return;

	if (!OpenText(Second, txt)) {
		fprintf(stderr, ">>>> File %s disappeared <<<<\n",
			txt->tx_fname
		);
	}
	/* sets lex_nl_cnt and lex_tk_cnt */

#ifdef	DB_POS
	db_print_pos_list("before sorting", txt->tx_pos);
#endif	/* DB_POS */

	sort_pos_list(&txt->tx_pos);

#ifdef	DB_POS
	db_print_pos_list("after sorting", txt->tx_pos);
#endif	/* DB_POS */

#ifdef	DB_NL_BUFF
	db_print_nl_buff(txt->tx_nl_start, txt->tx_nl_limit);
#endif	/* DB_NL_BUFF */

	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) {
			/* 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->tx_pos);
#endif	/* DB_POS */

	CloseText(Second, txt);
}

static int
next_eol_obtained(void) {
	while (NextTextTokenObtained(Second)) {
		if (TOKEN_EQ(lex_token, EOL)) return 1;
	}
	return 0;
}

#ifdef	DB_POS

static void
db_print_pos(const struct position *pos) {
	fprintf(DebugFile, "pos type: %s; token count: %u",
		(pos->ps_type == 0 ? "first" : " last"),
		pos->ps_tk_cnt
	);
	fprintf(DebugFile, ", line#: ");
	if (pos->ps_nl_cnt == -1) {
		fprintf(DebugFile, "<NOT SET>");
	}
	else {
		fprintf(DebugFile, "%u", pos->ps_nl_cnt);
	}
	fprintf(DebugFile, "\n");
}

static void
db_print_pos_list(const char *msg, const struct position *pos) {
	fprintf(DebugFile, "\n**** DB_PRINT_POS_LIST, %s ****\n", msg);

	while (pos) {
		db_print_pos(pos);
		pos = pos->ps_next;
	}
	fprintf(DebugFile, "\n");
}

static void
db_print_lex(const char *fn) {
	fprintf(DebugFile, "%s: lex_tk_cnt = %u, lex_nl_cnt = %u\n",
		fn, lex_tk_cnt, lex_nl_cnt);
}

#endif	/* DB_POS */