### Eclipse Workspace Patch 1.0 #P org.eclipse.cdt.make.core Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CCommandDSC.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CCommandDSC.java,v retrieving revision 1.12 diff -u -r1.12 CCommandDSC.java --- src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CCommandDSC.java 6 Mar 2007 18:48:55 -0000 1.12 +++ src/org/eclipse/cdt/make/internal/core/scannerconfig/util/CCommandDSC.java 18 May 2007 12:52:08 -0000 @@ -10,10 +10,18 @@ *******************************************************************************/ package org.eclipse.cdt.make.internal.core.scannerconfig.util; +import java.io.File; import java.util.ArrayList; +import java.util.Collections; import java.util.Iterator; import java.util.List; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; @@ -38,6 +46,7 @@ private List compilerCommand; // members are KVStringPair objects private boolean discovered; private boolean cppFileType; // C or C++ file type + private IProject project; private List symbols; private List includes; @@ -47,6 +56,10 @@ * @param cppFileType2 */ public CCommandDSC(boolean cppFileType) { + this(cppFileType, null); + } + + public CCommandDSC(boolean cppFileType, IProject project) { compilerCommand = new ArrayList(); discovered = false; this.cppFileType = cppFileType; @@ -54,6 +67,7 @@ symbols = new ArrayList(); includes = new ArrayList(); quoteIncludes = new ArrayList(); + this.project = project; } public boolean appliesToCPPFileType() { @@ -61,6 +75,17 @@ } public void addSCOption(KVStringPair option) { + if (project != null && + (option.getKey().equals(SCDOptionsEnum.INCLUDE_FILE.toString()) || + option.getKey().equals(SCDOptionsEnum.INCLUDE.toString()) || + option.getKey().equals(SCDOptionsEnum.IDASH.toString()) || + option.getKey().equals(SCDOptionsEnum.IMACROS_FILE.toString()))) + { + String value = option.getValue(); + value = (String)CygpathTranslator.translateIncludePaths(project, Collections.singletonList(value)).get(0); + value = makeRelative(project, new Path(value)).toOSString(); + option = new KVStringPair(option.getKey(), value); + } compilerCommand.add(option); } @@ -87,8 +112,9 @@ String commandAsString = new String(); for (Iterator i = compilerCommand.iterator(); i.hasNext(); ) { KVStringPair optionPair = (KVStringPair)i.next(); + String value = optionPair.getValue(); commandAsString += optionPair.getKey() + SINGLE_SPACE + - optionPair.getValue() + SINGLE_SPACE; + value + SINGLE_SPACE; } return commandAsString.trim(); } @@ -113,15 +139,25 @@ if (optionPair.getKey().equals(SCDOptionsEnum.IMACROS_FILE.toString()) || optionPair.getKey().equals(SCDOptionsEnum.INCLUDE_FILE.toString())) continue; + String value = optionPair.getValue(); + if (optionPair.getKey().equals(SCDOptionsEnum.INCLUDE.toString()) || + optionPair.getKey().equals(SCDOptionsEnum.IDASH.toString())) { + value = makeAbsolute(project, value); + } if (quoteIncludePaths) { - if (optionPair.getKey().equals(SCDOptionsEnum.INCLUDE.toString())) { + if (optionPair.getKey().equals(SCDOptionsEnum.INCLUDE.toString()) || + optionPair.getKey().equals(SCDOptionsEnum.IDASH.toString())) { commandAsString += optionPair.getKey() + SINGLE_SPACE + - "\"" + optionPair.getValue() + "\"" + SINGLE_SPACE; //$NON-NLS-1$//$NON-NLS-2$ + "\"" + value + "\"" + SINGLE_SPACE; //$NON-NLS-1$//$NON-NLS-2$ } } + else if (optionPair.getKey().equals(SCDOptionsEnum.INCLUDE.toString())) { + commandAsString += optionPair.getKey() + SINGLE_SPACE + + value + SINGLE_SPACE; + } else { commandAsString += optionPair.getKey() + SINGLE_SPACE + - optionPair.getValue() + SINGLE_SPACE; + value + SINGLE_SPACE; } } } @@ -129,6 +165,22 @@ } /** + * Returns the compiler command + * @return + */ + public String getCompilerName() { + String compiler = new String(); + for (Iterator i = compilerCommand.iterator(); i.hasNext(); ) { + KVStringPair optionPair = (KVStringPair)i.next(); + if (optionPair.getKey().equals(SCDOptionsEnum.COMMAND.toString())) { + compiler = optionPair.getValue(); + break; + } + } + return compiler.trim(); + } + + /** * @return list of strings */ public List getImacrosFile() { @@ -136,7 +188,7 @@ for (Iterator i = compilerCommand.iterator(); i.hasNext(); ) { KVStringPair optionPair = (KVStringPair)i.next(); if (optionPair.getKey().equals(SCDOptionsEnum.IMACROS_FILE.toString())) { - imacrosFiles.add(optionPair.getValue()); + imacrosFiles.add(makeAbsolute(project,optionPair.getValue())); } } return imacrosFiles; @@ -150,7 +202,7 @@ for (Iterator i = compilerCommand.iterator(); i.hasNext(); ) { KVStringPair optionPair = (KVStringPair)i.next(); if (optionPair.getKey().equals(SCDOptionsEnum.INCLUDE_FILE.toString())) { - includeFiles.add(optionPair.getValue()); + includeFiles.add(makeAbsolute(project,optionPair.getValue())); } } return includeFiles; @@ -182,7 +234,7 @@ * @return Returns the includes as strings. */ public List getIncludes() { - return includes; + return makeAbsolute(project, includes); } /** * @param includes The includes to set. @@ -194,7 +246,7 @@ * @return Returns the quote include paths as strings (for #include "...") */ public List getQuoteIncludes() { - return quoteIncludes; + return makeAbsolute(project, quoteIncludes); } /** * @param includes. Quote include paths (for #include "...") @@ -308,5 +360,94 @@ setDiscovered(true); } } + + public void resolveOptions(IProject project) { + ArrayList symbols = new ArrayList(); + ArrayList includes = new ArrayList(); + ArrayList quoteincludes = new ArrayList(); + for (Iterator options = compilerCommand.iterator(); options.hasNext(); ) { + KVStringPair optionPair = (KVStringPair)options.next(); + String key = optionPair.getKey(); + String value = optionPair.getValue(); + if (key.equals(SCDOptionsEnum.INCLUDE.toString())) { + includes.add(value); + } + else if (key.equals(SCDOptionsEnum.IDASH.toString())) { + quoteincludes.add(value); + } + else if (key.equals(SCDOptionsEnum.DEFINE.toString())) { + symbols.add(value); + } + } + setIncludes(includes); + setQuoteIncludes(quoteincludes); + setSymbols(symbols); + + setDiscovered(true); + } + + public static IPath makeRelative(IProject project, IPath path) { + IResource resource = findResource(project, path); + if (resource != null) { + if (resource.getProject() == project) { + path = resource.getProjectRelativePath(); + } +// else { +// path = resource.getFullPath(); +// } + } + return path; + } + + private static IResource findResource(IProject project, IPath path) { + IResource resource = project.findMember(path, true); + if (resource == null) { + IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); + resource = root.findMember(path, true); + if (resource == null) { + IResource[] resources = root.findFilesForLocation(path); + if (resources != null) { + for (int i = 0; i < resources.length; i++) { + if (resources[i].getProject() == project) { + resource = resources[i]; + break; + } + } + // make a relative path to another project (better than an absolute path) + if (resource == null && resources.length > 0) { + resource = resources[0]; + } + } + } + } + return resource; + } + + public static List makeRelative(IProject project, List paths) { + List list = new ArrayList(paths.size()); + for (Iterator iter=paths.iterator(); iter.hasNext(); ) { + String path = (String)iter.next(); + path = makeRelative(project, new Path(path)).toOSString(); + list.add(path); + } + return list; + } + + public static final String makeAbsolute(IProject project, String path) { + if (project != null && !new Path(path).isAbsolute()) { + path = new File(project.getLocation().toOSString(), path).getAbsolutePath(); + } + return path; + } + + public static List makeAbsolute(IProject project, List paths) { + List list = new ArrayList(paths.size()); + for (Iterator iter=paths.iterator(); iter.hasNext(); ) { + String path = (String)iter.next(); + path = makeAbsolute(project, path); + list.add(path); + } + return list; + } } Index: src/org/eclipse/cdt/make/internal/core/scannerconfig2/PerFileSICollector.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig2/PerFileSICollector.java,v retrieving revision 1.19 diff -u -r1.19 PerFileSICollector.java --- src/org/eclipse/cdt/make/internal/core/scannerconfig2/PerFileSICollector.java 15 Mar 2007 17:34:32 -0000 1.19 +++ src/org/eclipse/cdt/make/internal/core/scannerconfig2/PerFileSICollector.java 18 May 2007 12:52:09 -0000 @@ -24,6 +24,8 @@ import java.util.TreeSet; import java.util.Map.Entry; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.IIncludeEntry; import org.eclipse.cdt.make.core.MakeCorePlugin; import org.eclipse.cdt.make.core.scannerconfig.PathInfo; import org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector3; @@ -39,10 +41,14 @@ import org.eclipse.cdt.make.internal.core.scannerconfig.ScannerConfigUtil; import org.eclipse.cdt.make.internal.core.scannerconfig.util.CCommandDSC; import org.eclipse.cdt.make.internal.core.scannerconfig.util.CygpathTranslator; +import org.eclipse.cdt.make.internal.core.scannerconfig.util.KVStringPair; import org.eclipse.cdt.make.internal.core.scannerconfig.util.TraceUtil; +import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; @@ -117,7 +123,7 @@ if (child.getNodeName().equals(CC_ELEM)) { Element cmdElem = (Element) child; boolean cppFileType = cmdElem.getAttribute(FILE_TYPE_ATTR).equals("c++"); //$NON-NLS-1$ - CCommandDSC command = new CCommandDSC(cppFileType); + CCommandDSC command = new CCommandDSC(cppFileType, project); command.setCommandId(Integer.parseInt(cmdElem.getAttribute(ID_ATTR))); // deserialize command command.deserialize(cmdElem); @@ -229,9 +235,10 @@ addScannerInfo(((Integer)resource), scannerInfo); return; } - else if (!(resource instanceof IFile)) { - errorMessage = "resource is not an IFile";//$NON-NLS-1$ - } +// GSA allow per project settings +// else if (!(resource instanceof IFile)) { +// errorMessage = "resource is not an IFile";//$NON-NLS-1$ +// } else if (((IFile) resource).getProject() == null) { errorMessage = "project is null";//$NON-NLS-1$ } @@ -242,19 +249,21 @@ TraceUtil.outputError("PerFileSICollector.contributeToScannerConfig : ", errorMessage); //$NON-NLS-1$ return; } - IFile file = (IFile) resource; - - for (Iterator i = scannerInfo.keySet().iterator(); i.hasNext(); ) { - ScannerInfoTypes type = (ScannerInfoTypes) i.next(); - if (type.equals(ScannerInfoTypes.COMPILER_COMMAND)) { - List commands = (List) scannerInfo.get(type); - for (Iterator j = commands.iterator(); j.hasNext(); ) { - addCompilerCommand(file, (CCommandDSC) j.next()); - } - } - else { - addScannerInfo(type, (List) scannerInfo.get(type)); - } + if (resource instanceof IFile) { + IFile file = (IFile) resource; + + for (Iterator i = scannerInfo.keySet().iterator(); i.hasNext(); ) { + ScannerInfoTypes type = (ScannerInfoTypes) i.next(); + if (type.equals(ScannerInfoTypes.COMPILER_COMMAND)) { + List commands = (List) scannerInfo.get(type); + for (Iterator j = commands.iterator(); j.hasNext(); ) { + addCompilerCommand(file, (CCommandDSC) j.next()); + } + } + else { + addScannerInfo(type, (List) scannerInfo.get(type)); + } + } } } @@ -268,8 +277,12 @@ List siItem = (List) scannerInfo.get(ScannerInfoTypes.SYMBOL_DEFINITIONS); cmd.setSymbols(siItem); siItem = (List) scannerInfo.get(ScannerInfoTypes.INCLUDE_PATHS); - cmd.setIncludes(CygpathTranslator.translateIncludePaths(project, siItem)); + siItem = CygpathTranslator.translateIncludePaths(project, siItem); + siItem = CCommandDSC.makeAbsolute(project, siItem); + cmd.setIncludes(siItem); siItem = (List) scannerInfo.get(ScannerInfoTypes.QUOTE_INCLUDE_PATHS); + siItem = CygpathTranslator.translateIncludePaths(project, siItem); + siItem = CCommandDSC.makeAbsolute(project, siItem); cmd.setQuoteIncludes(siItem); cmd.setDiscovered(true); @@ -336,6 +349,10 @@ if (fileSet == null) { fileSet = new HashSet(); sid.commandIdToFilesMap.put(commandId, fileSet); + CCommandDSC cmd = (CCommandDSC) sid.commandIdCommandMap.get(commandId); + if (cmd != null) { + cmd.resolveOptions(project); + } } if (fileSet.add(file)) { // update fileToCommandIdsMap @@ -827,6 +844,7 @@ } for (Iterator j = discovered.iterator(); j.hasNext(); ) { String include = (String) j.next(); + include = CCommandDSC.makeRelative(project, new Path(include)).toPortableString(); if (!allIncludes.contains(include)) { allIncludes.add(include); } @@ -872,5 +890,4 @@ } return symbols; } - } Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParser.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParser.java,v retrieving revision 1.16 diff -u -r1.16 GCCPerFileBOPConsoleParser.java --- src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParser.java 24 Apr 2007 15:47:21 -0000 1.16 +++ src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParser.java 18 May 2007 12:52:07 -0000 @@ -41,6 +41,9 @@ private String[] compilerInvocation; private GCCPerFileBOPConsoleParserUtility fUtil; + /* (non-Javadoc) + * @see org.eclipse.cdt.make.core.scannerconfig.IScannerInfoConsoleParser#startup(org.eclipse.core.resources.IProject, org.eclipse.core.runtime.IPath, org.eclipse.cdt.make.core.scannerconfig.IScannerInfoCollector, org.eclipse.cdt.core.IMarkerGenerator) + */ public void startup(IProject project, IPath workingDirectory, IScannerInfoCollector collector, IMarkerGenerator markerGenerator) { fUtil = (project != null && workingDirectory != null && markerGenerator != null) ? new GCCPerFileBOPConsoleParserUtility(project, workingDirectory, markerGenerator) : null; @@ -50,10 +53,16 @@ compilerInvocation = getCompilerCommands(); } + /* (non-Javadoc) + * @see org.eclipse.cdt.make.internal.core.scannerconfig.gnu.AbstractGCCBOPConsoleParser#getUtility() + */ protected AbstractGCCBOPConsoleParserUtility getUtility() { return fUtil; } + /* (non-Javadoc) + * @see org.eclipse.cdt.make.internal.core.scannerconfig.gnu.AbstractGCCBOPConsoleParser#processSingleLine(java.lang.String) + */ protected boolean processSingleLine(String line) { boolean rc = false; // GCC C/C++ compiler invocation @@ -66,86 +75,84 @@ if (compilerInvocationIndex == -1) return rc; - // Search for the compiler invocation command - - // expecting that compiler invocation is the first token in the line - String[] split = line.split("\\s+"); //$NON-NLS-1$ - boolean found = false; - for (int i = 0; i < split.length; ++i) { - String command = split[i]; + // split and unquote all segments; supports build command such as + // sh -c 'gcc -g -O0 -I"includemath" -I "include abc" -Iincludeprint -c impl/testmath.c' + ArrayList split = splitLine(line, compilerInvocationIndex); + + // get the position of the compiler command in the build command + for (compilerInvocationIndex=0; compilerInvocationIndex= 0) { - found = true; - if (i > 0) { - // strip off anything before the compiler command - String[] old = split; - split = new String[old.length - i]; - System.arraycopy(old, i, split, 0, split.length); - } - break; - } + cii2 = command.indexOf(compilerInvocation[cii]); + if (cii2 >= 0) + break; } - if (found) - break; - } - if (!found) { + if (cii2 >= 0) + break; + } + if (compilerInvocationIndex >= split.size()) { TraceUtil.outputTrace("Error identifying compiler command", line, TraceUtil.EOL); //$NON-NLS-1$ return rc; } - // find a file name int extensionsIndex = -1; - found = false; + boolean found = false; String filePath = null; - for (int i = 1; i < split.length; ++i) { - int k = split[i].lastIndexOf('.'); - if (k != -1 && (split[i].length() - k < 5)) { - String fileExtension = split[i].substring(k); + for (int i = compilerInvocationIndex+1; i < split.size(); ++i) { + String segment = (String)split.get(i); + int k = segment.lastIndexOf('.'); + if (k != -1 && (segment.length() - k < 5)) { + String fileExtension = segment.substring(k); extensionsIndex = FILE_EXTENSIONS_LIST.indexOf(fileExtension); if (extensionsIndex != -1) { - filePath = split[i]; + filePath = segment; found = true; break; } } } - +// for (int j = 0; j < FILE_EXTENSIONS.length; ++j) { +// if (split[i].endsWith(FILE_EXTENSIONS[j])) { +// filePath = split[i]; +// extensionsIndex = j; +// found = true; +// break; +// } +// } +// if (found) break; if (!found) { TraceUtil.outputTrace("Error identifying file name :1", line, TraceUtil.EOL); //$NON-NLS-1$ return rc; } - // sanity check if (filePath.indexOf(FILE_EXTENSIONS[extensionsIndex]) == -1) { TraceUtil.outputTrace("Error identifying file name :2", line, TraceUtil.EOL); //$NON-NLS-1$ return rc; } - if (fUtil != null) { IPath pFilePath = fUtil.getAbsolutePath(filePath); String shortFileName = pFilePath.removeFileExtension().lastSegment(); // generalize occurances of the file name - StringBuffer genericLine = new StringBuffer(); - for (int i = 0; i < split.length; i++) { - String token = split[i]; - if (token.equals("-include") || token.equals("-imacros")) { //$NON-NLS-1$ //$NON-NLS-2$ + for (int i = 0; i < split.size(); i++) { + String token = (String)split.get(i); + if (token.equals("-include")) { //$NON-NLS-1$ + ++i; + } + else if (token.equals("-imacros")) { //$NON-NLS-1$ ++i; - genericLine.append(token); - genericLine.append(' '); } else if (token.equals(filePath)) { - split[i] = "LONG_NAME"; //$NON-NLS-1$ + split.set(i, "LONG_NAME"); //$NON-NLS-1$ } else if (token.startsWith(shortFileName)) { - split[i] = token.replaceFirst(shortFileName, "SHORT_NAME"); //$NON-NLS-1$ + split.set(i, token.replaceFirst(shortFileName, "SHORT_NAME")); //$NON-NLS-1$ } - genericLine.append(split[i]); - genericLine.append(' '); } - CCommandDSC cmd = fUtil.getNewCCommandDSC(genericLine.toString(), extensionsIndex > 0); + CCommandDSC cmd = fUtil.getNewCCommandDSC((String[])split.toArray(new String[split.size()]), extensionsIndex > 0); IPath baseDirectory = fUtil.getBaseDirectory(); if (baseDirectory.isPrefixOf(pFilePath)) { List cmdList = new ArrayList(); @@ -173,4 +180,127 @@ return rc; } + /** + * Splits and unquotes all compiler command segments; supports build command such as + * sh -c 'gcc -g -O0 -I"includemath" -I "include abc" -Iincludeprint -c impl/testmath.c' + */ + private ArrayList splitLine(String line, int compilerInvocationIndex) { + ArrayList split = new ArrayList(); + boolean bSingleQuotes = false; + boolean bIgnoreSingleQuotes = false; + boolean bDoubleQuotes = false; + boolean bIgnoreDoubleQuotes = false; + char[] chars = line.toCharArray(); + int charPos = 0; + int length = line.length(); + boolean quit = false; + boolean acceptExtraSingleQuote = false; + boolean acceptExtraDoubleQuote = false; + + // eat whitespace + while (charPos < length) { + char ch = chars[charPos]; + if (!Character.isWhitespace(ch)) { + break; + } + charPos++; + } + // read token + while (charPos= 0) { + endPos = charPos; // end of a token + } + quit = true; // quit after closed quote containing the actual compiler command + } + else { + bSingleQuotes = !bSingleQuotes; + } + } +// do split token here: allow -DMYKEY='MYVALUE' or-DMYKEY=\'MYVALUE\' + if (startPos >= 0) { + char prevch = charPos > 0 ? chars[charPos-1] : '\0'; + if (acceptExtraSingleQuote) { + acceptExtraSingleQuote = false; + } + else if (prevch != '=' && prevch != '\\') { + endPos = charPos; // end of a token + } + else { + acceptExtraSingleQuote = true; + } + } + } + else if (ch == '"') { + // ignore quotes before the actual compiler command (the command itself including its options + // could be within quotes--in this case we nevertheless want to split the compiler command into segments) + if (charPos <= compilerInvocationIndex) { + bIgnoreDoubleQuotes = !bIgnoreDoubleQuotes; + } + else { + if (bIgnoreDoubleQuotes) { + bIgnoreDoubleQuotes = false; + if (startPos >= 0) { + endPos = charPos; // end of a token + } + quit = true; // quit after closed quote containing the actual compiler command + } + else { + bDoubleQuotes = !bDoubleQuotes; + } + } +// do split token here: allow -DMYKEY="MYVALUE" or-DMYKEY=\"MYVALUE\" + if (startPos >= 0) { + char prevch = charPos > 0 ? chars[charPos-1] : '\0'; + if (acceptExtraDoubleQuote) { + acceptExtraDoubleQuote = false; + } + else if (prevch != '=' && prevch != '\\') { + endPos = charPos; // end of a token + } + else { + acceptExtraDoubleQuote = true; + } + } + } + else if (Character.isWhitespace(ch) || ch == ';') { + if (startPos < 0 && (bSingleQuotes || bDoubleQuotes)) { + startPos = charPos; + } + else if (startPos >= 0 && !bSingleQuotes && !bDoubleQuotes) { + endPos = charPos; // end of a token + } + } + else { // a valid character, starts or continues a token + if (startPos < 0) { + startPos = charPos; + } + if (charPos == length-1) { + endPos = charPos+1; // end of token + } + } + charPos++; + // a complete token has been found + if (startPos >= 0 && endPos > startPos) { + break; + } + } + if (startPos >= 0 && endPos >= 0 && startPos >= compilerInvocationIndex) { + split.add(line.substring(startPos, endPos)); + } + } + return split; + } } Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/AbstractGCCBOPConsoleParser.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/AbstractGCCBOPConsoleParser.java,v retrieving revision 1.8 diff -u -r1.8 AbstractGCCBOPConsoleParser.java --- src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/AbstractGCCBOPConsoleParser.java 6 Mar 2007 18:48:55 -0000 1.8 +++ src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/AbstractGCCBOPConsoleParser.java 18 May 2007 12:52:07 -0000 @@ -83,9 +83,20 @@ */ public boolean processLine(String line) { boolean rc = false; + int lineBreakPos = line.length()-1; + char[] lineChars = line.toCharArray(); + while(lineBreakPos >= 0 && Character.isWhitespace(lineChars[lineBreakPos])) { + lineBreakPos--; + } + if (lineBreakPos >= 0) { + if (lineChars[lineBreakPos] != '\\' + || (lineBreakPos > 0 && lineChars[lineBreakPos-1] == '\\')) { + lineBreakPos = -1; + } + } // check for multiline commands (ends with '\') - if (line.endsWith("\\")) { //$NON-NLS-1$ - sMultiline += line.substring(0, line.length()-1);// + " "; + if (lineBreakPos >= 0) { + sMultiline += line.substring(0, lineBreakPos); bMultiline = true; return rc; } Index: src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParserUtility.java =================================================================== RCS file: /cvsroot/tools/org.eclipse.cdt-build/org.eclipse.cdt.make.core/src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParserUtility.java,v retrieving revision 1.10 diff -u -r1.10 GCCPerFileBOPConsoleParserUtility.java --- src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParserUtility.java 6 Mar 2007 18:48:55 -0000 1.10 +++ src/org/eclipse/cdt/make/internal/core/scannerconfig/gnu/GCCPerFileBOPConsoleParserUtility.java 18 May 2007 12:52:07 -0000 @@ -111,7 +111,8 @@ return; compiledFileList.add(longFileName); - CCommandDSC command = getNewCCommandDSC(genericLine, false); // assume .c file type + String[] tokens = genericLine.split("\\s+"); //$NON-NLS-1$ + CCommandDSC command = getNewCCommandDSC(tokens, false); // assume .c file type int index = commandsList2.indexOf(command); if (index == -1) { commandsList2.add(command); @@ -130,9 +131,8 @@ * @param cppFileType * @return CCommandDSC compile command description */ - public CCommandDSC getNewCCommandDSC(String genericLine, boolean cppFileType) { - CCommandDSC command = new CCommandDSC(cppFileType); - String[] tokens = genericLine.split("\\s+"); //$NON-NLS-1$ + public CCommandDSC getNewCCommandDSC(String[] tokens, boolean cppFileType) { + CCommandDSC command = new CCommandDSC(cppFileType, getProject()); command.addSCOption(new KVStringPair(SCDOptionsEnum.COMMAND.toString(), tokens[0])); for (int i = 1; i < tokens.length; ++i) { String token = tokens[i];