001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * If you wish your version of this file to be governed by only the CDDL
025: * or only the GPL Version 2, indicate your decision by adding
026: * "[Contributor] elects to include this software in this distribution
027: * under the [CDDL or GPL Version 2] license." If you do not indicate a
028: * single choice of license, a recipient has the option to distribute
029: * your version of this file under either the CDDL, the GPL Version 2 or
030: * to extend the choice of license to its licensees as provided above.
031: * However, if you add GPL Version 2 code and therefore, elected the GPL
032: * Version 2 license, then the option applies only if the new code is
033: * made subject to such option by the copyright holder.
034: *
035: * Contributor(s):
036: *
037: * Portions Copyrighted 2008 Sun Microsystems, Inc.
038: */
039:
040: package org.netbeans.modules.cnd.makeproject.api.compilers;
041:
042: import java.io.BufferedReader;
043: import java.io.File;
044: import java.io.IOException;
045: import java.io.InputStream;
046: import java.io.InputStreamReader;
047: import java.util.List;
048: import org.netbeans.modules.cnd.api.compilers.CompilerSet.CompilerFlavor;
049: import org.netbeans.modules.cnd.api.utils.IpeUtils;
050: import org.openide.DialogDisplayer;
051: import org.openide.ErrorManager;
052: import org.openide.NotifyDescriptor;
053: import org.openide.util.NbBundle;
054:
055: /**
056: * A common base class for GNU C and C++ compilers
057: * @author vk155633
058: */
059: public abstract class GNUCCCCompiler extends CCCCompiler {
060:
061: private PersistentList systemIncludeDirectoriesList = null;
062: private PersistentList systemPreprocessorSymbolsList = null;
063:
064: public GNUCCCCompiler(CompilerFlavor flavor, int kind, String name,
065: String displayName, String path) {
066: super (flavor, kind, name, displayName, path);
067: }
068:
069: @Override
070: public boolean setSystemIncludeDirectories(List values) {
071: assert values != null;
072: if (values.equals(systemIncludeDirectoriesList)) {
073: return false;
074: }
075: systemIncludeDirectoriesList = new PersistentList(values);
076: normalizePaths(systemIncludeDirectoriesList);
077: saveSystemIncludesAndDefines();
078: return true;
079: }
080:
081: @Override
082: public boolean setSystemPreprocessorSymbols(List values) {
083: assert values != null;
084: if (values.equals(systemPreprocessorSymbolsList)) {
085: return false;
086: }
087: systemPreprocessorSymbolsList = new PersistentList(values);
088: saveSystemIncludesAndDefines();
089: return true;
090: }
091:
092: @Override
093: public List getSystemPreprocessorSymbols() {
094: if (systemPreprocessorSymbolsList != null)
095: return systemPreprocessorSymbolsList;
096:
097: getSystemIncludesAndDefines();
098: return systemPreprocessorSymbolsList;
099: }
100:
101: @Override
102: public List getSystemIncludeDirectories() {
103: if (systemIncludeDirectoriesList != null)
104: return systemIncludeDirectoriesList;
105:
106: getSystemIncludesAndDefines();
107: return systemIncludeDirectoriesList;
108: }
109:
110: @Override
111: public void saveSystemIncludesAndDefines() {
112: if (systemIncludeDirectoriesList != null)
113: systemIncludeDirectoriesList.saveList(getUniqueID()
114: + "systemIncludeDirectoriesList"); // NOI18N
115: if (systemPreprocessorSymbolsList != null)
116: systemPreprocessorSymbolsList.saveList(getUniqueID()
117: + "systemPreprocessorSymbolsList"); // NOI18N
118: }
119:
120: private void restoreSystemIncludesAndDefines() {
121: systemIncludeDirectoriesList = PersistentList
122: .restoreList(getUniqueID()
123: + "systemIncludeDirectoriesList"); // NOI18N
124: systemPreprocessorSymbolsList = PersistentList
125: .restoreList(getUniqueID()
126: + "systemPreprocessorSymbolsList"); // NOI18N
127: }
128:
129: private void getSystemIncludesAndDefines() {
130: restoreSystemIncludesAndDefines();
131: if (systemIncludeDirectoriesList == null
132: || systemPreprocessorSymbolsList == null) {
133: getFreshSystemIncludesAndDefines();
134: }
135: }
136:
137: protected abstract String getDefaultPath();
138:
139: protected abstract String getCompilerStderrCommand();
140:
141: protected abstract String getCompilerStdoutCommand();
142:
143: private void getFreshSystemIncludesAndDefines() {
144: systemIncludeDirectoriesList = new PersistentList();
145: systemPreprocessorSymbolsList = new PersistentList();
146: String path = getPath();
147: if (path == null || !new File(path).exists()) {
148: path = getDefaultPath();
149: }
150: try {
151: getSystemIncludesAndDefines(IpeUtils.getDirName(path), path
152: + getCompilerStderrCommand(), false);
153: getSystemIncludesAndDefines(IpeUtils.getDirName(path), path
154: + getCompilerStdoutCommand(), true);
155: // a workaround for gcc bug - see http://gcc.gnu.org/ml/gcc-bugs/2006-01/msg00767.html
156: if (!containsMacro(systemPreprocessorSymbolsList,
157: "__STDC__")) { // NOI18N
158: systemPreprocessorSymbolsList.add("__STDC__=1"); // NOI18N
159: }
160: saveSystemIncludesAndDefines();
161: } catch (IOException ioe) {
162: System.err.println("IOException " + ioe);
163: String errormsg = NbBundle.getMessage(getClass(),
164: "CANTFINDCOMPILER", path); // NOI18N
165: DialogDisplayer.getDefault().notify(
166: new NotifyDescriptor.Message(errormsg,
167: NotifyDescriptor.ERROR_MESSAGE));
168: }
169: }
170:
171: @Override
172: public void resetSystemIncludesAndDefines() {
173: getFreshSystemIncludesAndDefines();
174: }
175:
176: private boolean startsWithPath(String line) {
177: line = line.trim();
178: if (line.startsWith("/")) { // NOI18N
179: return true;
180: } else if (System.getProperty("os.name").indexOf("Windows") >= 0) {
181: if (Character.isLetter(line.charAt(0))
182: && line.charAt(1) == ':') {
183: return true;
184: }
185: }
186: return false;
187: }
188:
189: @Override
190: protected void parseCompilerOutput(InputStream is) {
191: BufferedReader reader = new BufferedReader(
192: new InputStreamReader(is));
193:
194: try {
195: String line;
196: boolean startIncludes = false;
197: while ((line = reader.readLine()) != null) {
198: //System.out.println(line);
199: if (line.contains("#include <...>")) { // NOI18N
200: startIncludes = true;
201: continue;
202: }
203: if (startIncludes) {
204: if (line.startsWith("End of search")
205: || !startsWithPath(line)) { // NOI18N
206: startIncludes = false;
207: continue;
208: }
209: }
210: if (startIncludes) {
211: line = line.trim();
212: if (getFlavor() == CompilerFlavor.MinGW) {
213: if (line.toLowerCase().startsWith(
214: getIncludeFilePathPrefix()
215: .toLowerCase())) {
216: line = line
217: .substring(getIncludeFilePathPrefix()
218: .length());
219: } else if (line.toLowerCase().startsWith(
220: "/mingw")) { // NOI18N
221: line = line.substring(6);
222: }
223: }
224: systemIncludeDirectoriesList
225: .addUnique(normalizePath(getIncludeFilePathPrefix()
226: + line));
227: if (getIncludeFilePathPrefix().length() > 0
228: && line.startsWith("/usr/lib")) // NOI18N
229: systemIncludeDirectoriesList
230: .addUnique(normalizePath(getIncludeFilePathPrefix()
231: + line.substring(4)));
232: continue;
233: }
234: parseUserMacros(line, systemPreprocessorSymbolsList);
235: if (line.startsWith("#define ")) { // NOI18N
236: int i = line.indexOf(' ', 8);
237: if (i > 0) {
238: String token = line.substring(8, i) + "="
239: + line.substring(i + 1); // NOI18N
240: systemPreprocessorSymbolsList.add(token);
241: }
242: }
243: }
244: is.close();
245: reader.close();
246: } catch (IOException ioe) {
247: ErrorManager.getDefault().notify(ErrorManager.WARNING, ioe); // FIXUP
248: }
249: }
250:
251: private void dumpLists() {
252: System.out.println("=================================="
253: + getDisplayName()); // NOI18N
254: for (int i = 0; i < systemIncludeDirectoriesList.size(); i++) {
255: System.out.println("-I"
256: + systemIncludeDirectoriesList.get(i)); // NOI18N
257: }
258: for (int i = 0; i < systemPreprocessorSymbolsList.size(); i++) {
259: System.out.println("-D"
260: + systemPreprocessorSymbolsList.get(i)); // NOI18N
261: }
262: }
263:
264: }
|