diff --git a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF index 4962a0fd262..36394ef428c 100644 --- a/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF +++ b/core/org.eclipse.cdt.core/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.cdt.core; singleton:=true -Bundle-Version: 6.8.100.qualifier +Bundle-Version: 6.9.0.qualifier Bundle-Activator: org.eclipse.cdt.core.CCorePlugin Bundle-Vendor: %providerName Bundle-Localization: plugin diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/formatter/DefaultCodeFormatterConstants.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/formatter/DefaultCodeFormatterConstants.java index 8be16e9d2a8..a4cfe659344 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/formatter/DefaultCodeFormatterConstants.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/formatter/DefaultCodeFormatterConstants.java @@ -122,6 +122,36 @@ public class DefaultCodeFormatterConstants { */ public static final String FORMATTER_USE_COMMENT_TAG = CCorePlugin.PLUGIN_ID + ".formatter.use_comment_formatter_tag"; //$NON-NLS-1$ + /** + *
+	 * FORMATTER / Formatter option to format header comment
+	 *     - option id:         "org.eclipse.cdt.core.formatter.format_header_comment"
+	 *     - default:           true
+	 * 
+ * @since 6.9 + */ + public static final String FORMATTER_COMMENT_HEADER = CCorePlugin.PLUGIN_ID + + ".formatter.format_header_comment"; //$NON-NLS-1$ + /** + *
+	 * FORMATTER / Formatter option to format block comment
+	 *     - option id:         "org.eclipse.cdt.core.formatter.format_block_comment"
+	 *     - default:           true
+	 * 
+ * @since 6.9 + */ + public static final String FORMATTER_COMMENT_BLOCK = CCorePlugin.PLUGIN_ID + + ".formatter.format_block_comment"; //$NON-NLS-1$ + /** + *
+	 * FORMATTER / Formatter option to format line comment
+	 *     - option id:         "org.eclipse.cdt.core.formatter.format_line_comment"
+	 *     - default:           true
+	 * 
+ * @since 6.9 + */ + public static final String FORMATTER_COMMENT_LINE = CCorePlugin.PLUGIN_ID + + ".formatter.format_line_comment"; //$NON-NLS-1$ // /** // *
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/formatter/DefaultCodeFormatterOptions.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/formatter/DefaultCodeFormatterOptions.java
index 6a21ac31e0e..2db0bbd1290 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/formatter/DefaultCodeFormatterOptions.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/formatter/DefaultCodeFormatterOptions.java
@@ -322,6 +322,18 @@ public class DefaultCodeFormatterOptions {
 	public String comment_formatter_off_tag;
 	/** @since 6.7 */
 	public boolean use_fomatter_comment_tag;
+	/**
+	 * @since 6.9
+	 */
+	public boolean format_block_comment;
+	/**
+	 * @since 6.9
+	 */
+	public boolean format_line_comment;
+	/**
+	 * @since 6.9
+	 */
+	public boolean format_header_comment;
 
 	private DefaultCodeFormatterOptions() {
 		// cannot be instantiated
@@ -345,6 +357,12 @@ public class DefaultCodeFormatterOptions {
 		options.put(DefaultCodeFormatterConstants.FORMATTER_USE_COMMENT_TAG,
 				this.use_fomatter_comment_tag ? DefaultCodeFormatterConstants.TRUE
 						: DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE,
+				format_line_comment ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_BLOCK,
+				format_block_comment ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
+		options.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_HEADER,
+				format_header_comment ? DefaultCodeFormatterConstants.TRUE : DefaultCodeFormatterConstants.FALSE);
 		//		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_ALLOCATION_EXPRESSION, getAlignment(this.alignment_for_arguments_in_allocation_expression));
 		options.put(DefaultCodeFormatterConstants.FORMATTER_ALIGNMENT_FOR_ARGUMENTS_IN_METHOD_INVOCATION,
 				getAlignment(this.alignment_for_arguments_in_method_invocation));
@@ -2214,6 +2232,18 @@ public class DefaultCodeFormatterOptions {
 		if (useFormatterCommentTag != null) {
 			this.use_fomatter_comment_tag = DefaultCodeFormatterConstants.TRUE.equals(useFormatterCommentTag);
 		}
+		final Object formatHeaderComment = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_HEADER);
+		if (formatHeaderComment != null) {
+			this.format_header_comment = DefaultCodeFormatterConstants.TRUE.equals(formatHeaderComment);
+		}
+		final Object formatBlockComment = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_BLOCK);
+		if (formatBlockComment != null) {
+			this.format_block_comment = DefaultCodeFormatterConstants.TRUE.equals(formatBlockComment);
+		}
+		final Object formatLineComment = settings.get(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE);
+		if (formatLineComment != null) {
+			this.format_line_comment = DefaultCodeFormatterConstants.TRUE.equals(formatLineComment);
+		}
 	}
 
 	public void setDefaultSettings() {
@@ -2221,6 +2251,9 @@ public class DefaultCodeFormatterOptions {
 		this.comment_formatter_on_tag = DefaultCodeFormatterConstants.FORMATTER_ON_TAG;
 		this.comment_formatter_off_tag = DefaultCodeFormatterConstants.FORMATTER_OFF_TAG;
 		this.use_fomatter_comment_tag = true;
+		this.format_block_comment = true;
+		this.format_header_comment = true;
+		this.format_line_comment = true;
 		this.alignment_for_arguments_in_method_invocation = Alignment.M_COMPACT_SPLIT;
 		this.alignment_for_assignment = Alignment.M_COMPACT_SPLIT;
 		this.alignment_for_base_clause_in_type_declaration = Alignment.M_NEXT_PER_LINE_SPLIT;
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/InactivePosition.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/InactivePosition.java
index 0edc4fde7b8..fda70315d8b 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/InactivePosition.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/InactivePosition.java
@@ -1,7 +1,3 @@
-package org.eclipse.cdt.internal.formatter;
-
-import org.eclipse.jface.text.Position;
-
 /*******************************************************************************
  * Copyright (c) 2019 Marco Stornelli
  *
@@ -13,6 +9,10 @@ import org.eclipse.jface.text.Position;
  * SPDX-License-Identifier: EPL-2.0
  *
  *******************************************************************************/
+package org.eclipse.cdt.internal.formatter;
+
+import org.eclipse.jface.text.Position;
+
 public class InactivePosition extends Position {
 
 	private boolean preprocessorRegion;
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/Scribe.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/Scribe.java
index 8bba672f417..33e072c299e 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/Scribe.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/Scribe.java
@@ -934,78 +934,86 @@ public class Scribe {
 		int currentTokenStartPosition = scanner.getCurrentTokenStartPosition();
 		int currentTokenEndPosition = scanner.getCurrentTokenEndPosition() + 1;
 
-		scanner.resetTo(currentTokenStartPosition, currentTokenEndPosition);
-		int currentCharacter;
-		boolean isNewLine = false;
-		int start = currentTokenStartPosition;
-		int nextCharacterStart = currentTokenStartPosition;
-		printIndentationIfNecessary();
-		if (pendingSpace) {
-			addInsertEdit(currentTokenStartPosition, SPACE);
-		}
-		needSpace = false;
-		pendingSpace = false;
-		int previousStart = currentTokenStartPosition;
-
-		while (nextCharacterStart <= currentTokenEndPosition && (currentCharacter = scanner.getNextChar()) != -1) {
-			nextCharacterStart = scanner.getCurrentPosition();
-
-			switch (currentCharacter) {
-			case '\r':
-				if (isNewLine) {
-					line++;
-				}
-				start = previousStart;
-				isNewLine = true;
-				if (scanner.getNextChar('\n')) {
-					currentCharacter = '\n';
-					nextCharacterStart = scanner.getCurrentPosition();
-				}
-				break;
-			case '\n':
-				if (isNewLine) {
-					line++;
-				}
-				start = previousStart;
-				isNewLine = true;
-				break;
-			default:
-				if (isNewLine) {
-					if (Character.isWhitespace((char) currentCharacter)) {
-						int previousStartPosition = scanner.getCurrentPosition();
-						while (currentCharacter != -1 && currentCharacter != '\r' && currentCharacter != '\n'
-								&& Character.isWhitespace((char) currentCharacter)) {
-							previousStart = nextCharacterStart;
-							previousStartPosition = scanner.getCurrentPosition();
-							currentCharacter = scanner.getNextChar();
-							nextCharacterStart = scanner.getCurrentPosition();
-						}
-						if (currentCharacter == '\r' || currentCharacter == '\n') {
-							nextCharacterStart = previousStartPosition;
-						}
-					}
-					column = 1;
-					line++;
-
-					StringBuilder buffer = new StringBuilder();
-					buffer.append(lineSeparator);
-					printIndentationIfNecessary(buffer);
-					buffer.append(' ');
-
-					addReplaceEdit(start, previousStart - 1, String.valueOf(buffer));
-				} else {
-					column += (nextCharacterStart - previousStart);
-				}
-				isNewLine = false;
+		boolean oldState = inactiveState;
+		if ((currentTokenStartPosition > 0 && !preferences.format_block_comment)
+				|| (currentTokenStartPosition == 0 && !preferences.format_header_comment))
+			inactiveState = true;
+		try {
+			scanner.resetTo(currentTokenStartPosition, currentTokenEndPosition);
+			int currentCharacter;
+			boolean isNewLine = false;
+			int start = currentTokenStartPosition;
+			int nextCharacterStart = currentTokenStartPosition;
+			printIndentationIfNecessary();
+			if (pendingSpace) {
+				addInsertEdit(currentTokenStartPosition, SPACE);
 			}
-			previousStart = nextCharacterStart;
-			scanner.setCurrentPosition(nextCharacterStart);
-		}
-		lastNumberOfNewLines = 0;
-		needSpace = false;
-		scanner.resetTo(currentTokenEndPosition, scannerEndPosition);
-		if (forceNewLine) {
-			startNewLine();
+			needSpace = false;
+			pendingSpace = false;
+			int previousStart = currentTokenStartPosition;
+
+			while (nextCharacterStart <= currentTokenEndPosition && (currentCharacter = scanner.getNextChar()) != -1) {
+				nextCharacterStart = scanner.getCurrentPosition();
+
+				switch (currentCharacter) {
+				case '\r':
+					if (isNewLine) {
+						line++;
+					}
+					start = previousStart;
+					isNewLine = true;
+					if (scanner.getNextChar('\n')) {
+						currentCharacter = '\n';
+						nextCharacterStart = scanner.getCurrentPosition();
+					}
+					break;
+				case '\n':
+					if (isNewLine) {
+						line++;
+					}
+					start = previousStart;
+					isNewLine = true;
+					break;
+				default:
+					if (isNewLine) {
+						if (Character.isWhitespace((char) currentCharacter)) {
+							int previousStartPosition = scanner.getCurrentPosition();
+							while (currentCharacter != -1 && currentCharacter != '\r' && currentCharacter != '\n'
+									&& Character.isWhitespace((char) currentCharacter)) {
+								previousStart = nextCharacterStart;
+								previousStartPosition = scanner.getCurrentPosition();
+								currentCharacter = scanner.getNextChar();
+								nextCharacterStart = scanner.getCurrentPosition();
+							}
+							if (currentCharacter == '\r' || currentCharacter == '\n') {
+								nextCharacterStart = previousStartPosition;
+							}
+						}
+						column = 1;
+						line++;
+
+						StringBuilder buffer = new StringBuilder();
+						buffer.append(lineSeparator);
+						printIndentationIfNecessary(buffer);
+						buffer.append(' ');
+
+						addReplaceEdit(start, previousStart - 1, String.valueOf(buffer));
+					} else {
+						column += (nextCharacterStart - previousStart);
+					}
+					isNewLine = false;
+				}
+				previousStart = nextCharacterStart;
+				scanner.setCurrentPosition(nextCharacterStart);
+			}
+			lastNumberOfNewLines = 0;
+			needSpace = false;
+			scanner.resetTo(currentTokenEndPosition, scannerEndPosition);
+			if (forceNewLine) {
+				startNewLine();
+			}
+		} finally {
+			inactiveState = oldState;
 		}
 	}
 
@@ -1092,17 +1100,20 @@ public class Scribe {
 					if (startOffset < endOffset) {
 						int savedIndentLevel = indentationLevel;
 						scanner.resetTo(scanner.getCurrentTokenStartPosition(), scanner.eofPosition);
-						inactiveState = true;
-						/**
-						 * We are entering in inactive state so if we added a new line previously,
-						 * starting a new line, we need to remove it.
-						 */
-						if (inactivePos.isPreprocessorRegion() && editsIndex > 0
-								&& lineSeparator.equals(edits[editsIndex - 1].replacement)) {
-							editsIndex--;
+						try {
+							inactiveState = true;
+							/**
+							 * We are entering in inactive state so if we added a new line previously,
+							 * starting a new line, we need to remove it.
+							 */
+							if (inactivePos.isPreprocessorRegion() && editsIndex > 0
+									&& lineSeparator.equals(edits[editsIndex - 1].replacement)) {
+								editsIndex--;
+							}
+							printRaw(startOffset, endOffset - startOffset);
+						} finally {
+							inactiveState = false;
 						}
-						printRaw(startOffset, endOffset - startOffset);
-						inactiveState = false;
 						while (indentationLevel > savedIndentLevel) {
 							unIndent();
 						}
@@ -1329,150 +1340,158 @@ public class Scribe {
 		int start = currentTokenStartPosition;
 		int nextCharacterStart = currentTokenStartPosition;
 
-		// Print comment line indentation
-		int commentIndentationLevel;
-		boolean onFirstColumn = isOnFirstColumn(start);
-		if (!preferences.comment_line_up_line_comment_in_blocks_on_first_column && indentationLevel == 0) {
-			commentIndentationLevel = column - 1;
-		} else {
-			if (onFirstColumn && preferences.never_indent_line_comments_on_first_column) {
+		boolean oldState = inactiveState;
+		if ((currentTokenStartPosition > 0 && !preferences.format_line_comment)
+				|| (currentTokenStartPosition == 0 && !preferences.format_header_comment))
+			inactiveState = true;
+		try {
+			// Print comment line indentation
+			int commentIndentationLevel;
+			boolean onFirstColumn = isOnFirstColumn(start);
+			if (!preferences.comment_line_up_line_comment_in_blocks_on_first_column && indentationLevel == 0) {
 				commentIndentationLevel = column - 1;
 			} else {
-				// Indentation may be specific for contiguous comment
-				// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=293300
-				if (lastLineComment.contiguous) {
-					// The leading spaces have been set while looping in the printComment(int) method
-					int currentCommentIndentation = computeIndentation(lastLineComment.leadingSpaces, 0);
-					// Keep the current comment indentation when over the previous contiguous line comment
-					// and the previous comment has not been re-indented
-					int relativeIndentation = currentCommentIndentation - lastLineComment.currentIndentation;
-					boolean similarCommentsIndentation = false;
-					if (tabLength == 0) {
-						similarCommentsIndentation = relativeIndentation == 0;
-					} else if (relativeIndentation > -tabLength) {
-						similarCommentsIndentation = relativeIndentation == 0
-								|| currentCommentIndentation != 0 && lastLineComment.currentIndentation != 0;
-					}
-					if (similarCommentsIndentation && lastLineComment.indentation != indentationLevel) {
-						int currentIndentationLevel = indentationLevel;
-						indentationLevel = lastLineComment.indentation;
-						printIndentationIfNecessary();
-						indentationLevel = currentIndentationLevel;
-						commentIndentationLevel = lastLineComment.indentation;
+				if (onFirstColumn && preferences.never_indent_line_comments_on_first_column) {
+					commentIndentationLevel = column - 1;
+				} else {
+					// Indentation may be specific for contiguous comment
+					// see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=293300
+					if (lastLineComment.contiguous) {
+						// The leading spaces have been set while looping in the printComment(int) method
+						int currentCommentIndentation = computeIndentation(lastLineComment.leadingSpaces, 0);
+						// Keep the current comment indentation when over the previous contiguous line comment
+						// and the previous comment has not been re-indented
+						int relativeIndentation = currentCommentIndentation - lastLineComment.currentIndentation;
+						boolean similarCommentsIndentation = false;
+						if (tabLength == 0) {
+							similarCommentsIndentation = relativeIndentation == 0;
+						} else if (relativeIndentation > -tabLength) {
+							similarCommentsIndentation = relativeIndentation == 0
+									|| currentCommentIndentation != 0 && lastLineComment.currentIndentation != 0;
+						}
+						if (similarCommentsIndentation && lastLineComment.indentation != indentationLevel) {
+							int currentIndentationLevel = indentationLevel;
+							indentationLevel = lastLineComment.indentation;
+							printIndentationIfNecessary();
+							indentationLevel = currentIndentationLevel;
+							commentIndentationLevel = lastLineComment.indentation;
+						} else {
+							printIndentationIfNecessary();
+							commentIndentationLevel = column - 1;
+						}
 					} else {
 						printIndentationIfNecessary();
 						commentIndentationLevel = column - 1;
 					}
+				}
+			}
+
+			// Prepare white space before the comment.
+			StringBuilder whitespace = null;
+			if (!lastLineComment.contiguous && commentIndentationLevel != indentationLevel
+					&& !(preferences.never_indent_line_comments_on_first_column && onFirstColumn)) {
+				whitespace = new StringBuilder();
+				int whitespaceStartPosition = currentTokenStartPosition - lastLineComment.leadingSpaces.length;
+				int indent = getIndentationOfOffset(whitespaceStartPosition);
+				int distance = computeIndentation(lastLineComment.leadingSpaces, indent) - indent;
+				if (preferences.comment_preserve_white_space_between_code_and_line_comment
+						&& distance >= preferences.comment_min_distance_between_code_and_line_comment) {
+					whitespace.append(lastLineComment.leadingSpaces);
 				} else {
-					printIndentationIfNecessary();
-					commentIndentationLevel = column - 1;
-				}
-			}
-		}
-
-		// Prepare white space before the comment.
-		StringBuilder whitespace = null;
-		if (!lastLineComment.contiguous && commentIndentationLevel != indentationLevel
-				&& !(preferences.never_indent_line_comments_on_first_column && onFirstColumn)) {
-			whitespace = new StringBuilder();
-			int whitespaceStartPosition = currentTokenStartPosition - lastLineComment.leadingSpaces.length;
-			int indent = getIndentationOfOffset(whitespaceStartPosition);
-			int distance = computeIndentation(lastLineComment.leadingSpaces, indent) - indent;
-			if (preferences.comment_preserve_white_space_between_code_and_line_comment
-					&& distance >= preferences.comment_min_distance_between_code_and_line_comment) {
-				whitespace.append(lastLineComment.leadingSpaces);
-			} else {
-				for (int i = 0; i < preferences.comment_min_distance_between_code_and_line_comment; i++) {
-					whitespace.append(' ');
-				}
-			}
-		}
-
-		// Store line comment information
-		lastLineComment.currentIndentation = getIndentationOfOffset(currentTokenStartPosition);
-		lastLineComment.contiguous = true;
-
-		while (true) {
-			Location location = new Location(this, scanner.getCurrentPosition());
-			int commentIndent = commentIndentationLevel;
-
-			// Add pending space if necessary
-			if (whitespace != null) {
-				addInsertEdit(currentTokenStartPosition, whitespace);
-				commentIndent = computeIndentation(whitespace, commentIndentationLevel);
-				needSpace = false;
-				pendingSpace = false;
-			}
-			lastLineComment.indentation = commentIndent;
-
-			int previousStart = currentTokenStartPosition;
-
-			int indent = commentIndent;
-			loop: while (nextCharacterStart <= currentTokenEndPosition
-					&& (currentCharacter = scanner.getNextChar()) != -1) {
-				nextCharacterStart = scanner.getCurrentPosition();
-
-				switch (currentCharacter) {
-				case '\r':
-				case '\n':
-					start = previousStart;
-					break loop;
-				}
-				indent = computeIndentation((char) currentCharacter, indent);
-				previousStart = nextCharacterStart;
-			}
-
-			if (start != currentTokenStartPosition) {
-				// This means that the line comment doesn't end the file
-				addReplaceEdit(start, currentTokenEndPosition - 1, lineSeparator);
-				line++;
-				column = 1;
-				lastNumberOfNewLines = 1;
-			}
-			if (!checkLineWrapping || indent <= pageWidth || whitespace == null || commentIndent
-					- commentIndentationLevel <= preferences.comment_min_distance_between_code_and_line_comment) {
-				break;
-			}
-
-			// Maximum line length was exceeded. Try to reduce white space before the comment by
-			// removing the last white space character.
-			whitespace.deleteCharAt(whitespace.length() - 1);
-			if (computeIndentation(lastLineComment.leadingSpaces, commentIndentationLevel)
-					- commentIndentationLevel < preferences.comment_min_distance_between_code_and_line_comment) {
-				// The white space shrank too much. Rebuild it to satisfy the minimum distance
-				// requirement.
-				whitespace.delete(0, whitespace.length());
-				for (int i = 0; i < preferences.comment_min_distance_between_code_and_line_comment; i++) {
-					whitespace.append(' ');
-				}
-			}
-			resetAt(location);
-			scanner.resetTo(location.inputOffset, scanner.eofPosition);
-		}
-
-		needSpace = false;
-		pendingSpace = false;
-		// realign to the proper value
-		if (currentAlignment != null) {
-			if (memberAlignment != null) {
-				// select the last alignment
-				if (currentAlignment.location.inputOffset > memberAlignment.location.inputOffset) {
-					if (currentAlignment.couldBreak() && currentAlignment.wasSplit) {
-						currentAlignment.performFragmentEffect();
+					for (int i = 0; i < preferences.comment_min_distance_between_code_and_line_comment; i++) {
+						whitespace.append(' ');
 					}
-				} else {
-					indentationLevel = Math.max(indentationLevel, memberAlignment.breakIndentationLevel);
 				}
-			} else if (currentAlignment.couldBreak() && currentAlignment.wasSplit) {
-				currentAlignment.performFragmentEffect();
 			}
-			if (currentAlignment.name.equals(Alignment.BINARY_EXPRESSION) && currentAlignment.enclosing != null
-					&& currentAlignment.enclosing.equals(Alignment.BINARY_EXPRESSION)
-					&& indentationLevel < currentAlignment.breakIndentationLevel) {
-				indentationLevel = currentAlignment.breakIndentationLevel;
+
+			// Store line comment information
+			lastLineComment.currentIndentation = getIndentationOfOffset(currentTokenStartPosition);
+			lastLineComment.contiguous = true;
+
+			while (true) {
+				Location location = new Location(this, scanner.getCurrentPosition());
+				int commentIndent = commentIndentationLevel;
+
+				// Add pending space if necessary
+				if (whitespace != null) {
+					addInsertEdit(currentTokenStartPosition, whitespace);
+					commentIndent = computeIndentation(whitespace, commentIndentationLevel);
+					needSpace = false;
+					pendingSpace = false;
+				}
+				lastLineComment.indentation = commentIndent;
+
+				int previousStart = currentTokenStartPosition;
+
+				int indent = commentIndent;
+				loop: while (nextCharacterStart <= currentTokenEndPosition
+						&& (currentCharacter = scanner.getNextChar()) != -1) {
+					nextCharacterStart = scanner.getCurrentPosition();
+
+					switch (currentCharacter) {
+					case '\r':
+					case '\n':
+						start = previousStart;
+						break loop;
+					}
+					indent = computeIndentation((char) currentCharacter, indent);
+					previousStart = nextCharacterStart;
+				}
+
+				if (start != currentTokenStartPosition) {
+					// This means that the line comment doesn't end the file
+					addReplaceEdit(start, currentTokenEndPosition - 1, lineSeparator);
+					line++;
+					column = 1;
+					lastNumberOfNewLines = 1;
+				}
+				if (!checkLineWrapping || indent <= pageWidth || whitespace == null || commentIndent
+						- commentIndentationLevel <= preferences.comment_min_distance_between_code_and_line_comment) {
+					break;
+				}
+
+				// Maximum line length was exceeded. Try to reduce white space before the comment by
+				// removing the last white space character.
+				whitespace.deleteCharAt(whitespace.length() - 1);
+				if (computeIndentation(lastLineComment.leadingSpaces, commentIndentationLevel)
+						- commentIndentationLevel < preferences.comment_min_distance_between_code_and_line_comment) {
+					// The white space shrank too much. Rebuild it to satisfy the minimum distance
+					// requirement.
+					whitespace.delete(0, whitespace.length());
+					for (int i = 0; i < preferences.comment_min_distance_between_code_and_line_comment; i++) {
+						whitespace.append(' ');
+					}
+				}
+				resetAt(location);
+				scanner.resetTo(location.inputOffset, scanner.eofPosition);
 			}
+
+			needSpace = false;
+			pendingSpace = false;
+			// realign to the proper value
+			if (currentAlignment != null) {
+				if (memberAlignment != null) {
+					// select the last alignment
+					if (currentAlignment.location.inputOffset > memberAlignment.location.inputOffset) {
+						if (currentAlignment.couldBreak() && currentAlignment.wasSplit) {
+							currentAlignment.performFragmentEffect();
+						}
+					} else {
+						indentationLevel = Math.max(indentationLevel, memberAlignment.breakIndentationLevel);
+					}
+				} else if (currentAlignment.couldBreak() && currentAlignment.wasSplit) {
+					currentAlignment.performFragmentEffect();
+				}
+				if (currentAlignment.name.equals(Alignment.BINARY_EXPRESSION) && currentAlignment.enclosing != null
+						&& currentAlignment.enclosing.equals(Alignment.BINARY_EXPRESSION)
+						&& indentationLevel < currentAlignment.breakIndentationLevel) {
+					indentationLevel = currentAlignment.breakIndentationLevel;
+				}
+			}
+			scanner.resetTo(currentTokenEndPosition, scannerEndPosition);
+		} finally {
+			inactiveState = oldState;
 		}
-		scanner.resetTo(currentTokenEndPosition, scannerEndPosition);
 	}
 
 	public void printEmptyLines(int linesNumber) {
diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CodeFormatterTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CodeFormatterTest.java
index f37f7f6b3f1..49c01511647 100644
--- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CodeFormatterTest.java
+++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CodeFormatterTest.java
@@ -4396,4 +4396,52 @@ public class CodeFormatterTest extends BaseUITestCase {
 	public void testConstVolatileMember_Bug548512() throws Exception {
 		assertFormatterResult();
 	}
+
+	///*
+	//* A Block
+	//* comment
+	//*/
+	//int foo();
+	///*
+	//* Another Block
+	//* comment
+	//*/
+
+	///*
+	//* A Block
+	//* comment
+	//*/
+	//int foo();
+	///*
+	// * Another Block
+	// * comment
+	// */
+	public void testHeaderComment() throws Exception {
+		fOptions.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_HEADER, DefaultCodeFormatterConstants.FALSE);
+		assertFormatterResult();
+	}
+
+	//int foo();
+	///*
+	//* Another Block
+	//* comment
+	//*/
+
+	//int foo();
+	///*
+	//* Another Block
+	//* comment
+	//*/
+	public void testBlockComment() throws Exception {
+		fOptions.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_BLOCK, DefaultCodeFormatterConstants.FALSE);
+		assertFormatterResult();
+	}
+
+	//int foo();//a comment
+
+	//int foo();//a comment
+	public void testLineComment() throws Exception {
+		fOptions.put(DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE, DefaultCodeFormatterConstants.FALSE);
+		assertFormatterResult();
+	}
 }
diff --git a/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF b/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF
index 819d5ad39ee..68affeb30da 100644
--- a/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF
+++ b/core/org.eclipse.cdt.ui/META-INF/MANIFEST.MF
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
 Bundle-ManifestVersion: 2
 Bundle-Name: %pluginName
 Bundle-SymbolicName: org.eclipse.cdt.ui; singleton:=true
-Bundle-Version: 6.5.100.qualifier
+Bundle-Version: 6.6.0.qualifier
 Bundle-Activator: org.eclipse.cdt.ui.CUIPlugin
 Bundle-Vendor: %providerName
 Bundle-Localization: plugin
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/CommentsTabPage.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/CommentsTabPage.java
index 70660e6d287..92960a4e20d 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/CommentsTabPage.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/CommentsTabPage.java
@@ -80,6 +80,7 @@ public class CommentsTabPage extends FormatterTabPage {
 			"void lineComments() {\n" + //$NON-NLS-1$
 			"\tprintf(\"%d\\n\", 1234);   \t\t// Integer number\n" + //$NON-NLS-1$
 			"\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// More here\n" + //$NON-NLS-1$
+			"\t/*\n\t * Another block\n\t * comment\n\t*/\n" + //$NON-NLS-1$
 			"\tprintf(\"%.5g\\n\", 12.34);\t\t// Floating point number\n" + //$NON-NLS-1$
 			"}\n"; //$NON-NLS-1$
 
@@ -98,18 +99,24 @@ public class CommentsTabPage extends FormatterTabPage {
 		//		createPrefFalseTrue(globalGroup, numColumns, FormatterMessages.CommentsTabPage_do_not_join_lines, DefaultCodeFormatterConstants.FORMATTER_JOIN_LINES_IN_COMMENTS, true);
 
 		// Line comment group
-		final Group lineCommentGroup = createGroup(numColumns, composite,
+		final Group commentGroup = createGroup(numColumns, composite,
 				FormatterMessages.CommentsTabPage_group1_title);
 		//		final CheckboxPreference singleLineCommentsOnFirstColumn= createPrefFalseTrue(lineCommentGroup, numColumns, FormatterMessages.CommentsTabPage_format_line_comments_on_first_column, DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_LINE_COMMENT_STARTING_ON_FIRST_COLUMN, false);
 		//		((GridData) singleLineCommentsOnFirstColumn.getControl().getLayoutData()).horizontalIndent= indent;
-		createPrefFalseTrue(lineCommentGroup, numColumns,
+		createPrefFalseTrue(commentGroup, numColumns, FormatterMessages.CommentsTabPage_block_comment,
+				DefaultCodeFormatterConstants.FORMATTER_COMMENT_BLOCK, false);
+		createPrefFalseTrue(commentGroup, numColumns, FormatterMessages.CommentsTabPage_line_comment,
+				DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE, false);
+		createPrefFalseTrue(commentGroup, numColumns, FormatterMessages.CommentsTabPage_header_comment,
+				DefaultCodeFormatterConstants.FORMATTER_COMMENT_HEADER, false);
+		createPrefFalseTrue(commentGroup, numColumns,
 				FormatterMessages.CommentsTabPage_preserve_white_space_before_line_comment,
 				DefaultCodeFormatterConstants.FORMATTER_COMMENT_PRESERVE_WHITE_SPACE_BETWEEN_CODE_AND_LINE_COMMENT,
 				false);
-		createPrefFalseTrue(lineCommentGroup, numColumns,
+		createPrefFalseTrue(commentGroup, numColumns,
 				FormatterMessages.CommentsTabPage_line_up_line_comment_in_blocks_on_first_column,
 				DefaultCodeFormatterConstants.FORMATTER_COMMENT_LINE_UP_LINE_COMMENT_IN_BLOCKS_ON_FIRST_COLUMN, false);
-		createNumberPref(lineCommentGroup, numColumns, FormatterMessages.CommentsTabPage_line_width,
+		createNumberPref(commentGroup, numColumns, FormatterMessages.CommentsTabPage_line_width,
 				DefaultCodeFormatterConstants.FORMATTER_COMMENT_MIN_DISTANCE_BETWEEN_CODE_AND_LINE_COMMENT, 0, 9999);
 		//		final CheckboxPreference singleLineComments= createPrefFalseTrue(lineCommentGroup, numColumns, FormatterMessages.CommentsTabPage_enable_line_comment_formatting, DefaultCodeFormatterConstants.FORMATTER_COMMENT_FORMAT_LINE_COMMENT, false);
 		//		createPrefFalseTrue(lineCommentGroup, numColumns, FormatterMessages.CommentsTabPage_never_indent_line_comments_on_first_column, DefaultCodeFormatterConstants.FORMATTER_NEVER_INDENT_LINE_COMMENTS_ON_FIRST_COLUMN, false);
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/FormatterMessages.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/FormatterMessages.java
index 0bbea2c0003..f3f5ed02322 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/FormatterMessages.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/FormatterMessages.java
@@ -340,6 +340,9 @@ final class FormatterMessages extends NLS {
 	public static String CommentsTabPage_preserve_white_space_before_line_comment;
 	public static String CommentsTabPage_line_up_line_comment_in_blocks_on_first_column;
 	public static String CommentsTabPage_line_width;
+	public static String CommentsTabPage_block_comment;
+	public static String CommentsTabPage_line_comment;
+	public static String CommentsTabPage_header_comment;
 	public static String CustomCodeFormatterBlock_formatter_name;
 	public static String CustomCodeFormatterBlock_default_formatter;
 	public static String CustomCodeFormatterBlock_formatter_note;
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/FormatterMessages.properties b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/FormatterMessages.properties
index 4d6612f2b07..4bdc8611c37 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/FormatterMessages.properties
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/preferences/formatter/FormatterMessages.properties
@@ -389,11 +389,13 @@ CustomCodeFormatterBlock_contributed_formatter_warning=Contributed formatters ma
 
 
 CommentsTabPage_preview_header=Comments
-CommentsTabPage_group1_title=Line comments
+CommentsTabPage_group1_title=Comments
 CommentsTabPage_preserve_white_space_before_line_comment=Preserve white space between code and line comments if possible
 CommentsTabPage_line_up_line_comment_in_blocks_on_first_column=Treat indented line comments as block of comments on unindented code
 CommentsTabPage_line_width=Minimum distance between code and line comments:
-
+CommentsTabPage_block_comment=Format block comments
+CommentsTabPage_line_comment=Format line comments
+CommentsTabPage_header_comment=Format header comment
 
 ControlStatementsTabPage_preview_header=If...else
 ControlStatementsTabPage_general_group_title=General
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/CSourceViewerConfiguration.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/CSourceViewerConfiguration.java
index 03ff0a005f5..92bcd24665b 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/CSourceViewerConfiguration.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/CSourceViewerConfiguration.java
@@ -504,7 +504,7 @@ public class CSourceViewerConfiguration extends TextSourceViewerConfiguration {
 		IAutoEditStrategy[] NONE = new IAutoEditStrategy[0];
 
 		if (ICPartitions.C_MULTI_LINE_COMMENT.equals(contentType))
-			return new IAutoEditStrategy[] { new DefaultMultilineCommentAutoEditStrategy() };
+			return new IAutoEditStrategy[] { new DefaultMultilineCommentAutoEditStrategy(getCProject()) };
 		if (ICPartitions.C_SINGLE_LINE_DOC_COMMENT.equals(contentType))
 			return single != null ? new IAutoEditStrategy[] { single } : NONE;
 		else if (ICPartitions.C_MULTI_LINE_DOC_COMMENT.equals(contentType))
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/DefaultMultilineCommentAutoEditStrategy.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/DefaultMultilineCommentAutoEditStrategy.java
index a925cd994b0..1ccfec16c52 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/DefaultMultilineCommentAutoEditStrategy.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/DefaultMultilineCommentAutoEditStrategy.java
@@ -25,8 +25,10 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
 import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
 import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
 import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
+import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
 import org.eclipse.cdt.core.index.IIndex;
 import org.eclipse.cdt.core.model.CModelException;
+import org.eclipse.cdt.core.model.ICProject;
 import org.eclipse.cdt.core.model.ITranslationUnit;
 import org.eclipse.cdt.ui.CUIPlugin;
 import org.eclipse.cdt.ui.IWorkingCopyManager;
@@ -60,8 +62,34 @@ public class DefaultMultilineCommentAutoEditStrategy implements IAutoEditStrateg
 	protected static final String MULTILINE_MID = " * "; //$NON-NLS-1$
 	protected static final String MULTILINE_END = "*/"; //$NON-NLS-1$
 	private static String fgDefaultLineDelim = "\n"; //$NON-NLS-1$
+	private ICProject fProject;
 
 	public DefaultMultilineCommentAutoEditStrategy() {
+		this(null);
+	}
+
+	/**
+	 * @since 6.6
+	 */
+	public DefaultMultilineCommentAutoEditStrategy(ICProject project) {
+		fProject = project;
+	}
+
+	/**
+	 * Check if edit strategy is enabled
+	 * @return True if enabled, false otherwise
+	 * @since 6.6
+	 */
+	protected boolean isEnabled() {
+		boolean formatBlocks = false;
+		if (fProject == null) {
+			formatBlocks = DefaultCodeFormatterConstants.TRUE
+					.equals(CCorePlugin.getOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_BLOCK));
+		} else {
+			formatBlocks = DefaultCodeFormatterConstants.TRUE
+					.equals(fProject.getOption(DefaultCodeFormatterConstants.FORMATTER_COMMENT_BLOCK, true));
+		}
+		return formatBlocks;
 	}
 
 	/**
@@ -69,6 +97,8 @@ public class DefaultMultilineCommentAutoEditStrategy implements IAutoEditStrateg
 	 */
 	@Override
 	public void customizeDocumentCommand(IDocument doc, DocumentCommand cmd) {
+		if (!isEnabled())
+			return;
 		fgDefaultLineDelim = TextUtilities.getDefaultLineDelimiter(doc);
 		if (doc instanceof IDocumentExtension4) {
 			boolean forNewLine = cmd.length == 0 && cmd.text != null && endsWithDelimiter(doc, cmd.text);
@@ -119,6 +149,8 @@ public class DefaultMultilineCommentAutoEditStrategy implements IAutoEditStrateg
 	 * @param c the command to deal with
 	 */
 	public void customizeDocumentAfterNewLine(IDocument doc, final DocumentCommand c) {
+		if (!isEnabled())
+			return;
 		int offset = c.offset;
 		if (offset == -1 || doc.getLength() == 0)
 			return;
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/doxygen/DoxygenMultilineAutoEditStrategy.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/doxygen/DoxygenMultilineAutoEditStrategy.java
index adb34568c6a..2f978ad1a3c 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/doxygen/DoxygenMultilineAutoEditStrategy.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/doctools/doxygen/DoxygenMultilineAutoEditStrategy.java
@@ -62,6 +62,14 @@ public class DoxygenMultilineAutoEditStrategy extends DefaultMultilineCommentAut
 	public DoxygenMultilineAutoEditStrategy() {
 	}
 
+	/**
+	 * @since 6.6
+	 */
+	@Override
+	protected boolean isEnabled() {
+		return true;
+	}
+
 	/**
 	 * @param decl the function declarator to document
 	 * @param ds the function specifier to document