1 /*
2
3 This file is part of the Maude 2 interpreter.
4
5 Copyright 1997-2003 SRI International, Menlo Park, CA 94025, USA.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
20
21 */
22
23 //
24 // Implementation for class FileTable.
25 //
26
27 // utility stuff
28 #include "macros.hh"
29 #include "vector.hh"
30
31 #include "fileTable.hh"
32
33 #ifdef EXPLICIT_TEMPLATES
34 template class Vector<FileTable::Entry>;
35 #endif
36
FileTable()37 FileTable::FileTable()
38 {
39 firstSilent = NONE;
40 }
41
42 void
openFile(int lineNumber,const char * name,bool silent)43 FileTable::openFile(int lineNumber, const char* name, bool silent)
44 {
45 if (silent && firstSilent == NONE)
46 firstSilent = fileStack.length();
47 if (firstSilent == NONE && fileStack.length() > 0)
48 cout << "Reading in file: \"" << name << "\"\n";
49 int nrFileChanges = fileChanges.length();
50 fileChanges.expandBy(1);
51 Entry& fc = fileChanges[nrFileChanges];
52 fc.absoluteLineNumber = lineNumber;
53 fc.fileNameIndex = fileNames.encode(name);
54 fc.relativeLineNumber = 1;
55 fileStack.append(nrFileChanges);
56 }
57
58 void
closeFile(int lineNumber)59 FileTable::closeFile(int lineNumber)
60 {
61 int topOfStack = fileStack.length() - 1;
62 int matchingOpen = fileStack[topOfStack];
63 if (firstSilent == NONE && topOfStack > 0)
64 {
65 cout << "Done reading in file: \"" <<
66 fileNames.name(fileChanges[matchingOpen].fileNameIndex) << "\"\n";
67 }
68 if (firstSilent == topOfStack)
69 firstSilent = NONE;
70 int prevFileNameIndex = NONE;
71 int prevLineNumberDiff = 0;
72 if (matchingOpen > 0)
73 {
74 Entry& fe = fileChanges[matchingOpen - 1];
75 prevFileNameIndex = fe.fileNameIndex;
76 prevLineNumberDiff = fe.absoluteLineNumber - fe.relativeLineNumber;
77 }
78 int nrFileChanges = fileChanges.length();
79 fileChanges.expandBy(1);
80 Entry& fc = fileChanges[nrFileChanges];
81 fc.absoluteLineNumber = lineNumber;
82 fc.fileNameIndex = prevFileNameIndex;
83 fc.relativeLineNumber = fileChanges[matchingOpen].absoluteLineNumber - prevLineNumberDiff;
84 fileStack.contractTo(topOfStack);
85 }
86
87 void
beginModule(Token type,Token name)88 FileTable::beginModule(Token type, Token name)
89 {
90 int nrModuleChanges = moduleChanges.length();
91 moduleChanges.expandBy(1);
92 Entry& mc = moduleChanges[nrModuleChanges];
93 mc.absoluteLineNumber = type.lineNumber();
94 mc.moduleNameIndex = name.code();
95 mc.moduleTypeIndex = type.code();
96 moduleStack.append(nrModuleChanges);
97 if (outputLine())
98 cout << type << ' ' << name << '\n';
99 }
100
101 bool
outputLine()102 FileTable::outputLine()
103 {
104 if (firstSilent == NONE && fileStack.length() > 0)
105 {
106 cout << "==========================================\n";
107 return true;
108 }
109 return false;
110 }
111
112 void
endModule(int lineNumber)113 FileTable::endModule(int lineNumber)
114 {
115 int topOfStack = moduleStack.length() - 1;
116 int matchingOpen = moduleStack[topOfStack];
117 int nrModuleChanges = moduleChanges.length();
118 moduleChanges.expandBy(1);
119 Entry& mc = moduleChanges[nrModuleChanges];
120 mc.absoluteLineNumber = lineNumber;
121 if (matchingOpen > 0)
122 {
123 mc.moduleNameIndex = moduleChanges[matchingOpen - 1].moduleNameIndex;
124 mc.moduleTypeIndex = moduleChanges[matchingOpen - 1].moduleTypeIndex;
125 }
126 else
127 {
128 mc.moduleNameIndex = NONE;
129 mc.moduleTypeIndex = NONE;
130 }
131 moduleStack.contractTo(topOfStack);
132 }
133
134 void
abortEverything(int lineNumber)135 FileTable::abortEverything(int lineNumber)
136 {
137 //
138 // Revert to top level file.
139 //
140 if (fileStack.length() > 0)
141 {
142 int matchingOpen = fileStack[0];
143 int prevLineNumberDiff = 0;
144 if (matchingOpen > 0)
145 {
146 Entry& fe = fileChanges[matchingOpen - 1];
147 prevLineNumberDiff = fe.absoluteLineNumber - fe.relativeLineNumber;
148 }
149 int nrFileChanges = fileChanges.length();
150 fileChanges.expandBy(1);
151 Entry& fc = fileChanges[nrFileChanges];
152 fc.absoluteLineNumber = lineNumber;
153 fc.fileNameIndex = NONE;
154 fc.relativeLineNumber = fileChanges[matchingOpen].absoluteLineNumber - prevLineNumberDiff;
155 fileStack.contractTo(0);
156 firstSilent = NONE;
157 }
158 //
159 // End all modules.
160 //
161 if (moduleStack.length() > 0)
162 {
163 int nrModuleChanges = moduleChanges.length();
164 moduleChanges.expandBy(1);
165 Entry& mc = moduleChanges[nrModuleChanges];
166 mc.absoluteLineNumber = lineNumber;
167 mc.moduleNameIndex = NONE;
168 mc.moduleTypeIndex = NONE;
169 moduleStack.contractTo(0);
170 }
171 }
172
173 int
binarySearch(Vector<Entry> & table,int lineNumber)174 FileTable::binarySearch(Vector<Entry>& table, int lineNumber)
175 {
176 //
177 // Find index of entry with largest absoluteLineNumber that is <= lineNumber.
178 // Return -1 if no such entry exists.
179 //
180 int max = table.length() - 1;
181 int min = 0;
182 while (max >= min)
183 {
184 int probe = (max + min) / 2;
185 int n = table[probe].absoluteLineNumber;
186 if (n == lineNumber)
187 return probe;
188 else if (n > lineNumber)
189 max = probe - 1;
190 else
191 min = probe + 1;
192 }
193 return min - 1;
194 }
195
196 void
printLineNumber(ostream & s,int lineNumber)197 FileTable::printLineNumber(ostream& s, int lineNumber)
198 {
199 switch (lineNumber)
200 {
201 case SYSTEM_CREATED:
202 {
203 s << "<automatic>";
204 break;
205 }
206 case META_LEVEL_CREATED:
207 {
208 s << "<metalevel>";
209 break;
210 }
211 case COMMAND_LINE:
212 {
213 s << "<command line>";
214 break;
215 }
216 default:
217 {
218 int fileEntry = binarySearch(fileChanges, lineNumber);
219 if (fileEntry == -1)
220 s << "<standard input>, line " << lineNumber;
221 else
222 {
223 Entry& fe = fileChanges[fileEntry];
224 if (fe.fileNameIndex == NONE)
225 s << "<standard input>";
226 else
227 s << '"' << fileNames.name(fe.fileNameIndex) << '"';
228 s << ", line " << fe.relativeLineNumber + (lineNumber - fe.absoluteLineNumber);
229 }
230 int moduleEntry = binarySearch(moduleChanges, lineNumber);
231 if (moduleEntry == -1 || moduleChanges[moduleEntry].moduleTypeIndex == NONE)
232 break;
233 Entry& me = moduleChanges[moduleEntry];
234 s << " (" << Token::name(me.moduleTypeIndex) <<
235 ' ' << Token::name(me.moduleNameIndex) << ')';
236 }
237 }
238 }
239