diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Util.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Util.java
index dac4ec123c8..d095c94cda7 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Util.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/Util.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2002, 2012 IBM Corporation and others.
+ * Copyright (c) 2002, 2013 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,6 +10,7 @@
* Markus Schorn (Wind River Systems)
* Anton Leherbauer (Wind River Systems)
* IBM Corporation - EFS support
+ * Marc-Andre Laperle (Ericsson)
*******************************************************************************/
package org.eclipse.cdt.internal.core.model;
@@ -29,10 +30,16 @@ import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileInfo;
import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.preferences.DefaultScope;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.osgi.service.prefs.BackingStoreException;
+import org.osgi.service.prefs.Preferences;
import com.ibm.icu.text.MessageFormat;
@@ -405,6 +412,78 @@ public class Util implements ICLogConstants {
// not found
return null;
}
+
+ private static String getLineSeparatorFromPreferences(Preferences node) {
+ try {
+ // be careful looking up for our node so not to create any nodes as side effect
+ if (node.nodeExists(Platform.PI_RUNTIME))
+ return node.node(Platform.PI_RUNTIME).get(Platform.PREF_LINE_SEPARATOR, null);
+ } catch (BackingStoreException e) {
+ // ignore
+ }
+ return null;
+ }
+
+ /**
+ * Returns line separator appropriate for the given file. The returned value
+ * will be the first available value from the list below:
+ *
+ * - Line separator currently used in that file.
+ *
- Line separator defined in project preferences.
+ *
- Line separator defined in instance preferences.
+ *
- Line separator defined in default preferences.
+ *
- Operating system default line separator.
+ *
+ * @param file the file for which line separator should be returned
+ * @return line separator for the given file
+ *
+ * Note: This was copied from org.eclipse.core.internal.utils.FileUtil
+ */
+ public static String getLineSeparator(IFile file) {
+ if (file.exists()) {
+ InputStream input = null;
+ try {
+ input = file.getContents();
+ int c = input.read();
+ while (c != -1 && c != '\r' && c != '\n')
+ c = input.read();
+ if (c == '\n')
+ return "\n"; //$NON-NLS-1$
+ if (c == '\r') {
+ if (input.read() == '\n')
+ return "\r\n"; //$NON-NLS-1$
+ return "\r"; //$NON-NLS-1$
+ }
+ } catch (CoreException e) {
+ // ignore
+ } catch (IOException e) {
+ // ignore
+ } finally {
+ try {
+ if (input != null)
+ input.close();
+ } catch (IOException e) {
+ //ignore
+ }
+ }
+ }
+ Preferences rootNode = Platform.getPreferencesService().getRootNode();
+ String value = null;
+ // if the file does not exist or has no content yet, try with project preferences
+ value = getLineSeparatorFromPreferences(rootNode.node(ProjectScope.SCOPE).node(file.getProject().getName()));
+ if (value != null)
+ return value;
+ // try with instance preferences
+ value = getLineSeparatorFromPreferences(rootNode.node(InstanceScope.SCOPE));
+ if (value != null)
+ return value;
+ // try with default preferences
+ value = getLineSeparatorFromPreferences(rootNode.node(DefaultScope.SCOPE));
+ if (value != null)
+ return value;
+ // if there is no preference set, fall back to OS default value
+ return LINE_SEPARATOR;
+ }
/**
* Return true if the file is not a directory and has length > 0
diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml/XmlProjectDescriptionStorage.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml/XmlProjectDescriptionStorage.java
index ee65ea7b3b6..3c5b78b11dc 100644
--- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml/XmlProjectDescriptionStorage.java
+++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/settings/model/xml/XmlProjectDescriptionStorage.java
@@ -1,15 +1,16 @@
/*******************************************************************************
- * Copyright (c) 2007, 2010 Intel Corporation and others.
+ * Copyright (c) 2007, 2013 Intel Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * Intel Corporation - Initial API and implementation
- * Markus Schorn (Wind River Systems)
- * IBM Corporation
- * James Blackburn (Broadcom Corp.)
+ * Intel Corporation - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
+ * IBM Corporation
+ * James Blackburn (Broadcom Corp.)
+ * Marc-Andre Laperle (Ericsson)
*******************************************************************************/
package org.eclipse.cdt.internal.core.settings.model.xml;
@@ -43,6 +44,7 @@ import org.eclipse.cdt.core.settings.model.util.CDataUtil;
import org.eclipse.cdt.internal.core.XmlUtil;
import org.eclipse.cdt.internal.core.envvar.ContributedEnvironment;
import org.eclipse.cdt.internal.core.language.settings.providers.LanguageSettingsProvidersSerializer;
+import org.eclipse.cdt.internal.core.model.Util;
import org.eclipse.cdt.internal.core.settings.model.AbstractCProjectDescriptionStorage;
import org.eclipse.cdt.internal.core.settings.model.CProjectDescription;
import org.eclipse.cdt.internal.core.settings.model.CProjectDescriptionManager;
@@ -119,6 +121,7 @@ public class XmlProjectDescriptionStorage extends AbstractCProjectDescriptionSto
static final String CONFIGURATION = "cconfiguration"; //$NON-NLS-1$
private static final QualifiedName LOAD_FLAG = new QualifiedName(CCorePlugin.PLUGIN_ID, "descriptionLoadded"); //$NON-NLS-1$
+ private static final String LINE_SEPARATOR = "line.separator"; //$NON-NLS-1$
public XmlProjectDescriptionStorage(CProjectDescriptionStorageTypeProxy type, IProject project, Version version) {
super(type, project, version);
@@ -570,6 +573,12 @@ public class XmlProjectDescriptionStorage extends AbstractCProjectDescriptionSto
// Get the ProjectDescription as a utf-8 string
stream = write(element);
utfString = stream.toString("UTF-8"); //$NON-NLS-1$
+
+ // Make sure we keep the same line separator if the file exists
+ // or use the preferences if it's a new file
+ String fileLineSeparator = Util.getLineSeparator(projectFile);
+ String sysLineSeparator = System.getProperty(LINE_SEPARATOR);
+ utfString = utfString.replace(sysLineSeparator, fileLineSeparator);
} finally {
if (stream != null)
stream.close(); // Cleanup the stream