001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package makedep;
028:
029: import java.io.*;
030: import java.util.*;
031:
032: /** This class implements the java.util.List interface as well as
033: providing functionality specific to keeping track of lists of
034: files. See the documentation for the Database class to see how
035: these are used. Each FileList must only contain other FileLists
036: (although that is not currently enforced in the mutators). */
037:
038: public class FileList extends Vector {
039: private String name; // (also the file name)
040: private boolean beenHere;
041: private boolean mayBeCycle;
042: private boolean isCycle;
043: /** Put in list because a file can refuse to */
044: private boolean useGrandInclude;
045: private String platformDependentInclude;
046: private int count;
047: private Platform plat;
048:
049: public FileList(String n, Platform plat) {
050: super ();
051: this .plat = plat;
052: beenHere = mayBeCycle = isCycle = false;
053: platformDependentInclude = null;
054: name = n;
055: count = 0;
056: useGrandInclude = plat.haveGrandInclude();
057: }
058:
059: // Change definition of equality from AbstractList so remove() works properly
060: public boolean equals(Object o) {
061: return ((Object) this ) == o;
062: }
063:
064: // Necessary accessors
065: public String getName() {
066: return name;
067: }
068:
069: public void setPlatformDependentInclude(String arg) {
070: platformDependentInclude = arg;
071: }
072:
073: public String getPlatformDependentInclude() {
074: return platformDependentInclude;
075: }
076:
077: public boolean getUseGrandInclude() {
078: return useGrandInclude;
079: }
080:
081: public void setUseGrandInclude(boolean arg) {
082: useGrandInclude = arg;
083: }
084:
085: public void incrementCount() {
086: count++;
087: }
088:
089: public int getCount() {
090: return count;
091: }
092:
093: public FileList listForFile(String fileName) {
094: for (Iterator iter = iterator(); iter.hasNext();) {
095: FileList fl = (FileList) iter.next();
096: if (plat.fileNameStringEquality(fl.name, fileName)) {
097: plat.fileNamePortabilityCheck(fl.name, fileName);
098: return fl;
099: }
100: }
101: plat.fileNamePortabilityCheck(fileName);
102: FileList newList = new FileList(fileName, plat);
103: add(newList);
104: return newList;
105: }
106:
107: public boolean hasListForFile(String fileName) {
108: for (Iterator iter = iterator(); iter.hasNext();) {
109: FileList fl = (FileList) iter.next();
110: if (plat.fileNameStringEquality(fl.name, fileName)) {
111: plat.fileNamePortabilityCheck(fl.name, fileName);
112: return true;
113: }
114: }
115: return false;
116: }
117:
118: public boolean compareLists(FileList s) {
119: Iterator myIter = iterator();
120: Iterator hisIter = s.iterator();
121:
122: while (myIter.hasNext() && hisIter.hasNext()) {
123: // crude: order dependent
124: FileList myElement = (FileList) myIter.next();
125: FileList hisElement = (FileList) hisIter.next();
126: if (!plat.fileNameStringEquality(myElement.name,
127: hisElement.name)) {
128: return false;
129: }
130: }
131:
132: if (myIter.hasNext() != hisIter.hasNext()) {
133: // One ended earlier
134: return false;
135: }
136:
137: return true;
138: }
139:
140: public void addIfAbsent(FileList s) {
141: for (Iterator iter = iterator(); iter.hasNext();) {
142: if (iter.next() == s) {
143: return;
144: }
145: }
146: add(s);
147: }
148:
149: public void sortByName() {
150: Collections.sort(this , new Comparator() {
151: public int compare(Object o1, Object o2) {
152: FileList fl1 = (FileList) o1;
153: FileList fl2 = (FileList) o2;
154: return fl1.getName().compareTo(fl2.getName());
155: }
156: });
157: }
158:
159: public void setFirstFile(FileList s) {
160: // Remove the file list if it's already here
161: remove(s);
162: add(0, s);
163: }
164:
165: public void setLastFile(FileList s) {
166: // Remove the file list if it's already here
167: remove(s);
168: add(s);
169: }
170:
171: public boolean doFiles(FileList s) {
172: boolean result = true;
173: for (Iterator iter = iterator(); iter.hasNext();) {
174: FileList h = (FileList) iter.next();
175: if (h.platformDependentInclude != null) {
176: System.err.println("Error: the source for "
177: + h.platformDependentInclude + " is " + h.name
178: + ".");
179: System.err
180: .println("\tIt shouldn't be included directly by "
181: + name + ".");
182: h.platformDependentInclude = null; // report once per file
183: result = false;
184: }
185: h.doHFile(s);
186: }
187: return result;
188: }
189:
190: public void traceCycle(FileList s) {
191: if (isCycle) // already traced
192: return;
193: isCycle = true;
194: System.err.println("\ttracing cycle for " + name);
195: // IMPL_NOTE: must return status in caller routine
196: // exitCode = 1;
197: for (Iterator iter = iterator(); iter.hasNext();) {
198: FileList q = (FileList) iter.next();
199: if (q.mayBeCycle) {
200: if (s == q) {
201: plat
202: .fatalError("\tend of cycle for "
203: + s.getName());
204: } else {
205: q.traceCycle(s);
206: }
207: }
208: }
209: }
210:
211: public void doHFile(FileList s) {
212: if (beenHere) {
213: if (mayBeCycle) {
214: traceCycle(this );
215: }
216: return;
217: }
218: beenHere = true;
219: mayBeCycle = true;
220: doFiles(s);
221: mayBeCycle = false;
222: s.add(this );
223: }
224:
225: public FileList doCFile() {
226: FileList s = new FileList(name, plat);
227: s.useGrandInclude = useGrandInclude; // propagate this
228: doFiles(s);
229: for (Iterator iter = s.iterator(); iter.hasNext();) {
230: FileList l = (FileList) iter.next();
231: l.beenHere = false;
232: }
233: return s;
234: }
235:
236: /** if .h file is included thresh times, put it in the grand
237: include file */
238: public void putInclFile(Database db) throws IOException {
239: boolean needline = true;
240: FileName inclName = plat.getInclFileTemplate().copyStem(name);
241:
242: ByteArrayOutputStream baos = new ByteArrayOutputStream();
243: OutputStreamWriter writer = new OutputStreamWriter(baos);
244: PrintWriter inclFile = new PrintWriter(writer);
245:
246: if (plat.haveGrandInclude() && plat.includeGIInEachIncl()) {
247: inclFile.println("# include \""
248: + plat.getGIFileTemplate().dirPreStemAltSuff()
249: + "\"");
250: needline = false;
251: }
252: for (Iterator iter = iterator(); iter.hasNext();) {
253: FileList hfile = (FileList) iter.next();
254: if (!db.hfileIsInGrandInclude(hfile, this )) {
255: String incname = plat.getInclFileTemplate().getInvDir()
256: + db.tryGetFullPath(hfile.name);
257: incname = plat.translateFileName(incname);
258: inclFile.println("#include \"" + incname + "\"");
259: needline = false;
260: }
261: }
262:
263: // Solaris C++ in strict mode warns about empty files
264:
265: if (needline) {
266: inclFile.println();
267: }
268: inclFile.flush();
269: Database.updateFile(inclName.dirPreStemSuff(), baos);
270: inclFile.close();
271: }
272: }
|