1 /*
   2  * Copyright (c) 1999, 2000, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *
  23  */
  24 
  25 import java.io.*;
  26 import java.util.*;
  27 
  28 /** This class implements the java.util.List interface as well as
  29     providing functionality specific to keeping track of lists of
  30     files. See the documentation for the Database class to see how
  31     these are used. Each FileList must only contain other FileLists
  32     (although that is not currently enforced in the mutators). */
  33 
  34 public class FileList extends Vector {
  35     private String name; // (also the file name)
  36     private boolean beenHere;
  37     private boolean mayBeCycle;
  38     private boolean isCycle;
  39     /** Put in list because a file can refuse to */
  40     private boolean useGrandInclude;
  41     private String platformDependentInclude;
  42     private int count;
  43     private Platform plat;
  44 
  45     public FileList(String n, Platform plat) {
  46         super();
  47         this.plat = plat;
  48         beenHere = mayBeCycle = isCycle = false;
  49         platformDependentInclude = null;
  50         name = n;
  51         count = 0;
  52         useGrandInclude = plat.haveGrandInclude();
  53     }
  54 
  55     // Change definition of equality from AbstractList so remove() works properly
  56     public boolean equals(Object o) {
  57       return ((Object) this) == o;
  58     }
  59 
  60     // Necessary accessors
  61     public String getName() {
  62         return name;
  63     }
  64 
  65     public void setPlatformDependentInclude(String arg) {
  66         platformDependentInclude = arg;
  67     }
  68 
  69     public String getPlatformDependentInclude() {
  70         return platformDependentInclude;
  71     }
  72 
  73     public boolean getUseGrandInclude() {
  74         return useGrandInclude;
  75     }
  76 
  77     public void setUseGrandInclude(boolean arg) {
  78         useGrandInclude = arg;
  79     }
  80 
  81     public void incrementCount() {
  82         count++;
  83     }
  84 
  85     public int getCount() {
  86         return count;
  87     }
  88 
  89     public FileList listForFile(String fileName) {
  90         for (Iterator iter = iterator(); iter.hasNext(); ) {
  91             FileList fl = (FileList) iter.next();
  92             if (plat.fileNameStringEquality(fl.name, fileName)) {
  93                 plat.fileNamePortabilityCheck(fl.name, fileName);
  94                 return fl;
  95             }
  96         }
  97         plat.fileNamePortabilityCheck(fileName);
  98         FileList newList = new FileList(fileName, plat);
  99         add(newList);
 100         return newList;
 101     }
 102 
 103     public boolean hasListForFile(String fileName) {
 104         for (Iterator iter = iterator(); iter.hasNext(); ) {
 105             FileList fl = (FileList) iter.next();
 106             if (plat.fileNameStringEquality(fl.name, fileName)) {
 107                 plat.fileNamePortabilityCheck(fl.name, fileName);
 108                 return true;
 109             }
 110         }
 111         return false;
 112     }
 113 
 114     public boolean compareLists(FileList s) {
 115         Iterator myIter = iterator();
 116         Iterator hisIter = s.iterator();
 117 
 118         while (myIter.hasNext() &&
 119                hisIter.hasNext()) {
 120             // crude: order dependent
 121             FileList myElement = (FileList) myIter.next();
 122             FileList hisElement = (FileList) hisIter.next();
 123             if (!plat.fileNameStringEquality(myElement.name,
 124                                              hisElement.name)) {
 125                 return false;
 126             }
 127         }
 128 
 129         if (myIter.hasNext() != hisIter.hasNext()) {
 130             // One ended earlier
 131             return false;
 132         }
 133 
 134         return true;
 135     }
 136 
 137     public void addIfAbsent(FileList s) {
 138         for (Iterator iter = iterator(); iter.hasNext(); ) {
 139             if (iter.next() == s) {
 140                 return;
 141             }
 142         }
 143         add(s);
 144     }
 145 
 146     public void sortByName() {
 147         Collections.sort(this, new Comparator() {
 148                 public int compare(Object o1, Object o2) {
 149                     FileList fl1 = (FileList) o1;
 150                     FileList fl2 = (FileList) o2;
 151                     return fl1.getName().compareTo(fl2.getName());
 152                 }
 153             });
 154     }
 155 
 156     public void setFirstFile(FileList s) {
 157       // Remove the file list if it's already here
 158       remove(s);
 159       add(0, s);
 160     }
 161 
 162     public void setLastFile(FileList s) {
 163       // Remove the file list if it's already here
 164       remove(s);
 165       add(s);
 166     }
 167 
 168     public boolean doFiles(FileList s) {
 169         boolean result = true;
 170         for (Iterator iter = iterator(); iter.hasNext(); ) {
 171             FileList h = (FileList) iter.next();
 172             if (h.platformDependentInclude != null) {
 173                 System.err.println("Error: the source for " +
 174                                    h.platformDependentInclude +
 175                                    " is " + h.name + ".");
 176                 System.err.println("\tIt shouldn't be included directly by " +
 177                                    name + ".");
 178                 h.platformDependentInclude = null; // report once per file
 179                 result = false;
 180             }
 181             h.doHFile(s);
 182         }
 183         return result;
 184     }
 185 
 186     public void traceCycle(FileList s) {
 187         if (isCycle) // already traced
 188             return;
 189         isCycle = true;
 190         System.err.println("\ttracing cycle for " + name);
 191         // FIXME: must return status in caller routine
 192         // exitCode = 1;
 193         for (Iterator iter = iterator(); iter.hasNext(); ) {
 194             FileList q = (FileList) iter.next();
 195             if (q.mayBeCycle) {
 196                 if (s == q) {
 197                     plat.fatalError("\tend of cycle for " + s.getName());
 198                 } else {
 199                     q.traceCycle(s);
 200                 }
 201             }
 202         }
 203     }
 204 
 205     public void doHFile(FileList s) {
 206         if (beenHere) {
 207             if (mayBeCycle) {
 208                 traceCycle(this);
 209             }
 210             return;
 211         }
 212         beenHere = true;
 213         mayBeCycle = true;
 214         doFiles(s);
 215         mayBeCycle = false;
 216         s.add(this);
 217     }
 218 
 219     public FileList doCFile() {
 220         FileList s = new FileList(name, plat);
 221         s.useGrandInclude = useGrandInclude; // propagate this
 222         doFiles(s);
 223         for (Iterator iter = s.iterator(); iter.hasNext(); ) {
 224             FileList l = (FileList) iter.next();
 225             l.beenHere = false;
 226         }
 227         return s;
 228     }
 229 
 230     /** if .h file is included thresh times, put it in the grand
 231         include file */
 232     public void putInclFile(Database db)
 233         throws IOException {
 234         boolean needline = true;
 235         FileName inclName = plat.getInclFileTemplate().copyStem(name);
 236         PrintWriter inclFile =
 237             new PrintWriter(new FileWriter(inclName.dirPreStemSuff()));
 238         if (plat.haveGrandInclude() && plat.includeGIInEachIncl()) {
 239             inclFile.println("# include \"" +
 240                              plat.getGIFileTemplate().dirPreStemAltSuff() +
 241                              "\"");
 242             needline = false;
 243         }
 244         for (Iterator iter = iterator(); iter.hasNext(); ) {
 245             FileList hfile = (FileList) iter.next();
 246             if (!db.hfileIsInGrandInclude(hfile, this)) {
 247                 inclFile.println("# include \"" +
 248                                  plat.getInclFileTemplate().getInvDir() +
 249                                  hfile.name +
 250                                  "\"");
 251                 needline = false;
 252             }
 253         }
 254 
 255         // Solaris C++ in strict mode warns about empty files
 256 
 257         if(needline) {
 258             inclFile.println();
 259         }
 260 
 261         inclFile.close();
 262     }
 263 }